Revision: 5462
Author: ihab.awad
Date: Thu Jun 27 13:45:40 2013
Log: Fix various bugs in API taming
https://codereview.appspot.com/10648043
Fixes the following bugs:
https://code.google.com/p/google-caja/issues/detail?id=1766
https://code.google.com/p/google-caja/issues/detail?id=1767
https://code.google.com/p/google-caja/issues/detail?id=1775
https://code.google.com/p/google-caja/issues/detail?id=1776
https://code.google.com/p/google-caja/issues/detail?id=1777
Issue 1777 was "fixed" by simply realizing that whatever issue was causing
garbled data many, many CL's ago was no longer an issue.
[email protected]
http://code.google.com/p/google-caja/source/detail?r=5462
Added:
/trunk/tests/com/google/caja/apitaming/visualization/chart-range-filter.html
/trunk/tests/com/google/caja/apitaming/visualization/formatters-table.html
/trunk/tests/com/google/caja/plugin/apitaming-tests.json
Modified:
/trunk/src/com/google/caja/apitaming/cajaTamingGoogleLoader.js
/trunk/src/com/google/caja/apitaming/google.visualization.policyFactory.js
/trunk/src/com/google/caja/plugin/guest-manager.js
/trunk/tests/com/google/caja/apitaming/visualization/table.html
/trunk/tests/com/google/caja/apitaming/visualization-list.json
/trunk/tests/com/google/caja/plugin/test-index.js
=======================================
--- /dev/null
+++
/trunk/tests/com/google/caja/apitaming/visualization/chart-range-filter.html
Thu Jun 27 13:45:40 2013
@@ -0,0 +1,111 @@
+<!--
+You are free to copy and use this sample in accordance with the terms of
the
+Apache license (http://www.apache.org/licenses/LICENSE-2.0.html)
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+ <title>
+ Google Visualization API Sample
+ </title>
+ <script type="text/javascript"
src="http://www.google.com/jsapi"></script>
+ <script type="text/javascript">
+ google.load('visualization', '1.1', {packages:
['corechart', 'controls']});
+ </script>
+ <script type="text/javascript">
+ function drawVisualization() {
+ var dashboard = new google.visualization.Dashboard(
+ document.getElementById('dashboard'));
+
+ debugger;
+
+ var control = new google.visualization.ControlWrapper({
+ 'controlType': 'ChartRangeFilter',
+ 'containerId': 'control',
+ 'options': {
+ // Filter by the date axis.
+ 'filterColumnIndex': 0,
+ 'ui': {
+ 'chartType': 'LineChart',
+ 'chartOptions': {
+ 'chartArea': {'width': '90%'},
+ 'hAxis': {'baselineColor': 'none'}
+ },
+ // Display a single series that shows the closing value of
the stock.
+ // Thus, this view has two columns: the date (axis) and the
stock value (line series).
+ 'chartView': {
+ 'columns': [0, 3]
+ },
+ // 1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
+ 'minRangeSize': 86400000
+ }
+ },
+ // Initial range: 2012-02-09 to 2012-03-20.
+ 'state': {'range': {'start': new Date(2012, 1, 9), 'end': new
Date(2012, 2, 20)}}
+ });
+
+ debugger;
+
+ var chart = new google.visualization.ChartWrapper({
+ 'chartType': 'CandlestickChart',
+ 'containerId': 'chart',
+ 'options': {
+ // Use the same chart area width as the control for axis
alignment.
+ 'chartArea': {'height': '80%', 'width': '90%'},
+ 'hAxis': {'slantedText': false},
+ 'vAxis': {'viewWindow': {'min': 0, 'max': 2000}},
+ 'legend': {'position': 'none'}
+ },
+ // Convert the first column from 'date' to 'string'.
+ 'view': {
+ 'columns': [
+ {
+ 'calc': function(dataTable, rowIndex) {
+ return dataTable.getFormattedValue(rowIndex, 0);
+ },
+ 'type': 'string'
+ }, 1, 2, 3, 4]
+ }
+ });
+
+ debugger;
+
+ var data = new google.visualization.DataTable();
+ data.addColumn('date', 'Date');
+ data.addColumn('number', 'Stock low');
+ data.addColumn('number', 'Stock open');
+ data.addColumn('number', 'Stock close');
+ data.addColumn('number', 'Stock high');
+
+ // Create random stock values, just like it works in reality.
+ var open, close = 300;
+ var low, high;
+ for (var day = 1; day < 121; ++day) {
+ var change = (Math.sin(day / 2.5 + Math.PI) + Math.sin(day / 3)
- Math.cos(day * 0.7)) * 150;
+ change = change >= 0 ? change + 10 : change - 10;
+ open = close;
+ close = Math.max(50, open + change);
+ low = Math.min(open, close) - (Math.cos(day * 1.7) + 1) * 15;
+ low = Math.max(0, low);
+ high = Math.max(open, close) + (Math.cos(day * 1.3) + 1) * 15;
+ var date = new Date(2012, 0 ,day);
+ data.addRow([date, Math.round(low), Math.round(open),
Math.round(close), Math.round(high)]);
+ }
+
+ dashboard.bind(control, chart);
+ dashboard.draw(data);
+ }
+
+
+ google.setOnLoadCallback(drawVisualization);
+ </script>
+ </head>
+ <body>
+ <div id="dashboard">
+ <div id="chart" style='width: 915px; height: 300px;'></div>
+ <div id="control" style='width: 915px; height: 50px;'></div>
+ </div>
+ </body>
+</html>
=======================================
--- /dev/null
+++
/trunk/tests/com/google/caja/apitaming/visualization/formatters-table.html
Thu Jun 27 13:45:40 2013
@@ -0,0 +1,75 @@
+<html>
+ <head>
+ <script type="text/javascript"
src="https://www.google.com/jsapi"></script>
+ <script type="text/javascript">
+ google.load("visualization", "1", {packages:["corechart","table"]});
+ google.setOnLoadCallback(testFormatters);
+
+ function testFormatters() {
+ var data = new google.visualization.DataTable();
+
+ data.addColumn('number', 'Arrow');
+ data.addColumn('number', 'Bar');
+ data.addColumn('number', 'Color range');
+ data.addColumn('number', 'Color gradient');
+ data.addColumn('date', 'Date');
+ data.addColumn('number', 'Number');
+ data.addColumn('string', 'Pattern');
+
+ data.addRows([
+ [ +4, +250, 50, 50, new Date(1977, 1, 1), -1234.87654321, '' ],
+ [ 1, -50, 150, 150, new Date(1978, 2, 2), 1234.87654321, '' ],
+ [ +3, +200, 250, 250, new Date(1979, 3, 3), -8765.12345678, '' ],
+ [ 0, 0, 350, 350, new Date(1980, 4, 4), 8765.12345678, '' ],
+ ]);
+
+ new google.visualization.TableArrowFormat({
+ base: 2
+ })
+ .format(data, 0);
+ new google.visualization.TableBarFormat({
+ base: 100,
+ colorNegative: 'blue',
+ colorPositive: 'red',
+ drawZeroLine: true,
+ min: -100,
+ max: +300,
+ showValue: false,
+ width: 50
+ })
+ .format(data, 1);
+ var cf1 = new google.visualization.TableColorFormat();
+ cf1.addRange(100, 300, '#9C2542', '#A1CAF1');
+ cf1.format(data, 2);
+ var cf2 = new google.visualization.TableColorFormat();
+ cf2.addGradientRange(0, 400, '#9C2542', '#ff0000', '#ffffff');
+ cf2.format(data, 3);
+ new google.visualization.TableDateFormat({
+ formatType: 'medium',
+ timeZone: -5
+ })
+ .format(data, 4);
+ new google.visualization.TableNumberFormat({
+ decimalSymbol: ',',
+ fractionDigits: 3,
+ groupingSymbol: '.',
+ negativeColor: 'red',
+ negativeParens: false,
+ prefix: '\'Bout ',
+ suffix: ' big \'uns.'
+ })
+ .format(data, 5);
+ new google.visualization.TablePatternFormat(
+ '\u003cstrong\u003e{0}\u003c/strong\u003e for
\u003cem\u003e{2}\u003c/em\u003e!\u003cscript\u003ealert(42);\u003c/script\u003e'
+
+ '\u003cbr\u003eGefurfifier!')
+ .format(data, [0, 1, 2, 3, 4, 5], 6);
+
+ var table = new
google.visualization.Table(document.getElementById('chart_div'));
+ table.draw(data, {showRowNumber: true, allowHtml: true });
+ }
+ </script>
+ </head>
+ <body>
+ <div id="chart_div"></div>
+ </body>
+</html>
=======================================
--- /dev/null
+++ /trunk/tests/com/google/caja/plugin/apitaming-tests.json Thu Jun 27
13:45:40 2013
@@ -0,0 +1,33 @@
+[
+ {
+ "label": "apitaming",
+ "mode": "none",
+ "tests":
+ [
+ {
+ "bare":
"../apitaming/tests-index.html?testsList=maps-list.json&cajaServer=/caja",
+ "label": "API taming Maps individual list"
+ },
+ {
+ "bare":
"../apitaming/tests-index.html?testsList=picker-list.json&cajaServer=/caja",
+ "label": "API taming Picker individual list"
+ },
+ {
+ "bare":
"../apitaming/tests-index.html?testsList=visualization-list.json&cajaServer=/caja",
+ "label": "API taming GViz individual list"
+ },
+ {
+ "bare":
"../apitaming/tests-side-by-side.html?testsList=maps-list.json&cajaServer=/caja",
+ "label": "API taming Maps all (large/slow page)"
+ },
+ {
+ "bare":
"../apitaming/tests-side-by-side.html?testsList=picker-list.json&cajaServer=/caja",
+ "label": "API taming Picker all (large/slow page)"
+ },
+ {
+ "bare":
"../apitaming/tests-side-by-side.html?testsList=visualization-list.json&cajaServer=/caja",
+ "label": "API taming GViz all (large/slow page)"
+ }
+ ]
+ }
+]
=======================================
--- /trunk/src/com/google/caja/apitaming/cajaTamingGoogleLoader.js Thu Feb
28 09:33:35 2013
+++ /trunk/src/com/google/caja/apitaming/cajaTamingGoogleLoader.js Thu Jun
27 13:45:40 2013
@@ -174,7 +174,7 @@
if (!frame.hasOwnProperty('opaqueNodeByIdCounter___')) {
frame.opaqueNodeByIdCounter___ = 0;
}
- var node =
frame.untame(frame.imports.document.getElementById(origId));
+ var node = frame.getElementByGuestId(origId);
var d = node.ownerDocument.createElement('div');
var opaqueId = 'opaqueNodeById__' + frame.opaqueNodeByIdCounter___++
+ '__' + frame.idSuffix;
d.setAttribute('id', opaqueId);
=======================================
---
/trunk/src/com/google/caja/apitaming/google.visualization.policyFactory.js
Tue Jan 22 12:48:15 2013
+++
/trunk/src/com/google/caja/apitaming/google.visualization.policyFactory.js
Thu Jun 27 13:45:40 2013
@@ -38,7 +38,7 @@
if (args.length < 1) { return []; }
var spec = args[0];
if (typeof spec === 'string') { spec = JSON.parse(spec); }
- spec = utils.copyJson(spec);
+ spec = utils.copyMixed(spec);
if (spec.containerId) {
tameContainerId = spec.containerId;
spec.containerId = utils.opaqueNodeById(spec.containerId);
@@ -94,7 +94,7 @@
// result has HTML in tooltips turned off
function copyDrawOpts(opts) {
- opts = utils.copyJson(opts);
+ opts = !!opts ? utils.copyJson(opts) : {};
opts.allowHtml = false;
opts.tooltip = { isHtml: false };
return opts;
@@ -289,43 +289,63 @@
////////////////////////////////////////////////////////////////////////
// Formatters
- v.ArrowFormat = function(opt_options) {};
- v.ArrowFormat.__super__ = Object;
- v.ArrowFormat.__before__ = [ utils.mapArgs(utils.copyJson) ];
- v.ArrowFormat.prototype.format = function(dataTable, columnIndex) {};
+ function formatter(name, cb) {
+ cb(name + 'Format');
+ cb('Table' + name + 'Format');
+ }
- v.BarFormat = function(opt_options) {};
- v.BarFormat.__super__ = Object;
- v.BarFormat.__before__ = [ utils.mapArgs(utils.copyJson) ];
- v.BarFormat.prototype.format = function(dataTable, columnIndex) {};
+ formatter('Arrow', function(name) {
+ v[name] = function(opt_options) {};
+ v[name].__super__ = Object;
+ v[name].__before__ = [ utils.mapArgs(utils.copyJson) ];
+ v[name].prototype.format = function(dataTable, columnIndex) {};
+ });
- v.ColorFormat = function() {};
- v.ColorFormat.__super__ = Object;
- v.ColorFormat.__before__ = [ utils.mapArgs(utils.copyJson) ];
- v.ColorFormat.prototype.addRange = function(from, to, color, bgcolor) {};
- v.ColorFormat.prototype.addGradientRange = function(from, to, color,
fromBgColor, toBgColor) {};
- v.ColorFormat.prototype.format = function(dataTable, columnIndex) {};
+ formatter('Bar', function(name) {
+ v[name] = function(opt_options) {};
+ v[name].__super__ = Object;
+ v[name].__before__ = [ utils.mapArgs(utils.copyJson) ];
+ v[name].prototype.format = function(dataTable, columnIndex) {};
+ });
- v.DateFormat = function(opt_options) {};
- v.DateFormat.__super__ = Object;
- v.DateFormat.__before__ = [ utils.mapArgs(utils.copyJson) ];
- v.DateFormat.prototype.format = function(dataTable, columnIndex) {};
- v.DateFormat.prototype.formatValue = function(value) {};
+ formatter('Color', function(name) {
+ v[name] = function() {};
+ v[name].__super__ = Object;
+ v[name].__before__ = [ utils.mapArgs(utils.copyJson) ];
+ v[name].prototype.addRange = function(from, to, color, bgcolor) {};
+ v[name].prototype.addGradientRange =
+ function(from, to, color, fromBgColor, toBgColor) {};
+ v[name].prototype.format = function(dataTable, columnIndex) {};
+ });
- v.NumberFormat = function(opt_options) {};
- v.NumberFormat.__super__ = Object;
- v.NumberFormat.__before__ = [ utils.mapArgs(utils.copyJson) ];
- v.NumberFormat.prototype.format = function(dataTable, columnIndex) {};
- v.NumberFormat.prototype.formatValue = function(value) {};
- v.NumberFormat.DECIMAL_SEP = 1;
- v.NumberFormat.GROUP_SEP = 1;
- v.NumberFormat.DECIMAL_PATTERN = 1;
+ formatter('Date', function(name) {
+ v[name] = function(opt_options) {};
+ v[name].__super__ = Object;
+ v[name].__before__ = [ utils.mapArgs(utils.copyJson) ];
+ v[name].prototype.format = function(dataTable, columnIndex) {};
+ v[name].prototype.formatValue = function(value) {};
+ });
- v.PatternFormat = function(pattern) {};
- v.PatternFormat.__super__ = Object;
- v.PatternFormat.prototype.format = function(dataTable, srcColumnIndices,
opt_dstColumnIndex) {};
- v.PatternFormat.prototype.format.__before__ = [
utils.mapArgs(utils.identity, utils.copyJson, utils.identity) ];
+ formatter('Number', function(name) {
+ v[name] = function(opt_options) {};
+ v[name].__super__ = Object;
+ v[name].__before__ = [ utils.mapArgs(utils.copyJson) ];
+ v[name].prototype.format = function(dataTable, columnIndex) {};
+ v[name].prototype.formatValue = function(value) {};
+ v[name].DECIMAL_SEP = 1;
+ v[name].GROUP_SEP = 1;
+ v[name].DECIMAL_PATTERN = 1;
+ });
+ formatter('Pattern', function(name) {
+ v[name] = function(pattern) {};
+ v[name].__super__ = Object;
+ v[name].prototype.format =
+ function(dataTable, srcColumnIndices, opt_dstColumnIndex) {};
+ v[name].prototype.format.__before__ = [
+ utils.mapArgs(utils.identity, utils.copyJson, utils.identity)
+ ];
+ });
////////////////////////////////////////////////////////////////////////
// GadgetHelper
@@ -528,27 +548,24 @@
v.CandlestickChart.prototype.getSelection = function() {};
v.CandlestickChart.prototype.setSelection = function(selection) {};
- // TODO(ihab.awad): AnnotatedTimeLine data is garbled in testing under
ES5.
- // This is disabled until we fix this.
-
- // v.AnnotatedTimeLine = function(container) {};
- // v.AnnotatedTimeLine.__super__ = Object;
- // v.AnnotatedTimeLine.__before__ = [
- // function(f, self, args) {
- // var outer = args[0];
- // var inner = utils.opaqueNode(outer);
- // inner.style.width = outer.style.width;
- // inner.style.height = outer.style.height;
- // return [ inner ];
- // }
- // ];
- // v.AnnotatedTimeLine.prototype.draw = function(data, opt_options) {};
- // v.AnnotatedTimeLine.prototype.draw.__before__ = [
utils.mapArgs(utils.identity, copyDrawOpts, utils.copyJson) ];
- // v.AnnotatedTimeLine.prototype.getSelection = function() {};
- // v.AnnotatedTimeLine.prototype.getVisibleChartRange = function() {};
- // v.AnnotatedTimeLine.prototype.setVisibleChartRange =
function(firstDate, lastDate, opt_animate) {};
- // v.AnnotatedTimeLine.prototype.showDataColumns =
function(columnIndexes) {};
- // v.AnnotatedTimeLine.prototype.hideDataColumns =
function(columnIndexes) {};
+ v.AnnotatedTimeLine = function(container) {};
+ v.AnnotatedTimeLine.__super__ = Object;
+ v.AnnotatedTimeLine.__before__ = [
+ function(f, self, args) {
+ var outer = args[0];
+ var inner = utils.opaqueNode(outer);
+ inner.style.width = outer.style.width;
+ inner.style.height = outer.style.height;
+ return [ inner ];
+ }
+ ];
+ v.AnnotatedTimeLine.prototype.draw = function(data, opt_options) {};
+ v.AnnotatedTimeLine.prototype.draw.__before__ = [
utils.mapArgs(utils.identity, copyDrawOpts, utils.copyJson) ];
+ v.AnnotatedTimeLine.prototype.getSelection = function() {};
+ v.AnnotatedTimeLine.prototype.getVisibleChartRange = function() {};
+ v.AnnotatedTimeLine.prototype.setVisibleChartRange = function(firstDate,
lastDate, opt_animate) {};
+ v.AnnotatedTimeLine.prototype.showDataColumns = function(columnIndexes)
{};
+ v.AnnotatedTimeLine.prototype.hideDataColumns = function(columnIndexes)
{};
v.GeoMap = function(container) {};
v.GeoMap.__super__ = Object;
@@ -648,9 +665,9 @@
v.ControlWrapper.prototype.setContainerId.__before__ = [
containerIdBeforeSet ];
v.ControlWrapper.prototype.setOption = function(key, value) {};
v.ControlWrapper.prototype.setOptions = function(options_obj) {};
- v.ControlWrapper.prototype.setOptions.__before__ = [
utils.mapArgs(utils.copyJson) ];
+ v.ControlWrapper.prototype.setOptions.__before__ = [
utils.mapArgs(utils.copyMixed) ];
v.ControlWrapper.prototype.setState = function(state_obj) {};
- v.ControlWrapper.prototype.setState.__before__ = [
utils.mapArgs(utils.copyJson) ];
+ v.ControlWrapper.prototype.setState.__before__ = [
utils.mapArgs(utils.copyMixed) ];
return {
=======================================
--- /trunk/src/com/google/caja/plugin/guest-manager.js Thu Apr 11 19:45:31
2013
+++ /trunk/src/com/google/caja/plugin/guest-manager.js Thu Jun 27 13:45:40
2013
@@ -62,6 +62,16 @@
flash: true
};
+ function copyStringMap(o) {
+ var r = {};
+ for (var k in o) {
+ if (Object.prototype.hasOwnProperty.call(o, k)) {
+ r[k] = o[k];
+ }
+ }
+ return r;
+ }
+
var self = {
// Public state
div: divs.outer && divs.outer.parentNode,
@@ -69,6 +79,34 @@
getUrl: function() { return args.url; },
getUriPolicy: function() { return uriPolicy; },
+ getElementByGuestId: domicile
+ ? function(id) {
+ return self.untame(
+ Object.prototype.v___
+ ? self.imports.v___('document').m___('getElementById',
[id])
+ : self.imports.document.getElementById(id));
+ }
+ : function(_) {
+ return null;
+ },
+
+ rewriteUri: domicile
+ ? function(url, mime, opts) {
+ return self.untame(
+ Object.prototype.v___
+ ? domicile.m___('rewriteUri', [
+ url,
+ mime,
+ copyStringMap(opts)])
+ : domicile.rewriteUri(
+ url,
+ mime,
+ copyStringMap(opts)));
+ }
+ : function(_) {
+ return null;
+ },
+
// deprecated; idSuffix in domado means '-' + idClass, but idSuffix
// exposed here is without the leading '-'. Future code should use the
// idClass property instead.
@@ -90,8 +128,6 @@
domicile: domicile, // Currently exposed only for the test suite
htmlEmitter: htmlEmitter,
- rewriteUri: domicile ? domicile.rewriteUri : function() { return null;
},
-
// Taming utilities
tame: frameTamingMembrane.tame,
untame: frameTamingMembrane.untame,
=======================================
--- /trunk/tests/com/google/caja/apitaming/visualization/table.html Tue
Nov 6 10:03:09 2012
+++ /trunk/tests/com/google/caja/apitaming/visualization/table.html Thu Jun
27 13:45:40 2013
@@ -16,13 +16,23 @@
['Bob', {v: 7000, f: '$7,000'}, true]
]);
- var table = new
google.visualization.Table(document.getElementById('table_div'));
- table.draw(data, {showRowNumber: true});
+ // Show a regular table being drawn
+
+ new google.visualization.Table(
+ document.getElementById('table_plain_div'))
+ .draw(data, {showRowNumber: true});
+
+ // Demonstrate 'draw' being called with 'null' options (2nd arg)
+
+ new google.visualization.Table(
+ document.getElementById('table_nullopts_div'))
+ .draw(data, null);
}
</script>
</head>
- <body>
- <div id='table_div'></div>
+ <body style="overflow: scroll;">
+ <div id="table_plain_div"></div>
+ <div id="table_nullopts_div"></div>
</body>
</html>
=======================================
--- /trunk/tests/com/google/caja/apitaming/visualization-list.json Tue Nov
6 10:03:09 2012
+++ /trunk/tests/com/google/caja/apitaming/visualization-list.json Thu Jun
27 13:45:40 2013
@@ -5,6 +5,7 @@
"visualization/bubblechart.html",
"visualization/candlestickchart.html",
"visualization/charteditor.html",
+ "visualization/chart-range-filter.html",
"visualization/chartwrapper.html",
"visualization/columnchart.html",
"visualization/combochart.html",
@@ -18,6 +19,7 @@
"visualization/errrors-test.html",
"visualization/events-test.html",
"visualization/formatters.html",
+ "visualization/formatters-table.html",
"visualization/gaugechart.html",
"visualization/geochart-markers.html",
"visualization/geochart-regions.html",
=======================================
--- /trunk/tests/com/google/caja/plugin/test-index.js Wed Jun 12 12:11:32
2013
+++ /trunk/tests/com/google/caja/plugin/test-index.js Thu Jun 27 13:45:40
2013
@@ -110,9 +110,14 @@
};
request.send();
}
+
+ // TODO(kpreid): Refactor to avoid unnecessary latency and dependencies,
+ // perhaps using Q.
loadCatalog('tests', 'browser-tests.json', function() {
- loadCatalog('tests', '../ses/ses-tests.json');
+ loadCatalog('tests', '../ses/ses-tests.json', function() {
+ loadCatalog('tests', 'apitaming-tests.json');
+ });
});
loadCatalog('thirdparty', 'third-party-tests.json');
--
---
You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.