diff options
-rw-r--r-- | chrome/browser/browser_resources.grd | 3 | ||||
-rw-r--r-- | chrome/browser/resources/plugins.html | 256 | ||||
-rw-r--r-- | chrome/browser/resources/plugins.js | 255 | ||||
-rw-r--r-- | chrome/browser/resources/shared/js/jstemplate_compiled.js | 10 | ||||
-rw-r--r-- | chrome/browser/resources/shared_resources.grd | 2 | ||||
-rw-r--r-- | chrome/browser/ui/webui/plugins_ui.cc | 120 | ||||
-rw-r--r-- | chrome/common/common_resources.grd | 2 | ||||
-rw-r--r-- | chrome/third_party/jstemplate/README.chromium | 15 | ||||
-rwxr-xr-x | chrome/third_party/jstemplate/compile.py | 9 | ||||
-rw-r--r-- | chrome/third_party/jstemplate/jstemplate_compiled.js | 13 |
10 files changed, 359 insertions, 326 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 67bf93f..689b212 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -61,7 +61,8 @@ <include name="IDR_NOTIFICATION_1LINE_HTML" file="resources\notification_1line.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_NOTIFICATION_2LINE_HTML" file="resources\notification_2line.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_NOTIFICATION_ICON_HTML" file="resources\notification_icon.html" type="BINDATA" /> - <include name="IDR_PLUGINS_HTML" file="resources\plugins.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_PLUGINS_HTML" file="resources\plugins.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_PLUGINS_JS" file="resources\plugins.js" type="BINDATA" /> <include name="IDR_READER_OUT_OF_DATE_HTML" file="resources\reader_out_of_date.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PRINT_PREVIEW_HTML" file="resources\print_preview.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SAFE_BROWSING_MALWARE_BLOCK" file="resources\safe_browsing_malware_block.html" flattenhtml="true" type="BINDATA" /> diff --git a/chrome/browser/resources/plugins.html b/chrome/browser/resources/plugins.html index 07d61f7..6d4517a 100644 --- a/chrome/browser/resources/plugins.html +++ b/chrome/browser/resources/plugins.html @@ -2,6 +2,11 @@ <html i18n-values="dir:textdirection;"> <head> <meta charset="utf-8"> +<!-- X-WebKit-CSP is our development name for Content-Security-Policy. + The 'unsafe-eval' is required for jstemplate_compiled.js. + TODO(tsepez) rename when Content-security-policy is done. +--> +<meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src chrome://resources 'self' 'unsafe-eval'"> <title i18n-content="pluginsTitle"></title> <style> body { @@ -242,230 +247,7 @@ body.showTmiMode .showInTmiMode { button { font-size: 104%; } - </style> -<script> - -/** - * This variable structure is here to document the structure that the template - * expects to correctly populate the page. - */ -var pluginDataFormat = { - 'plugins': [ - { - 'name': 'Group Name', - 'description': 'description', - 'version': 'version', - 'update_url': 'http://update/', - 'critical': true, - 'enabled': true, - 'plugin_files': [ - { - 'path': '/blahblah/blahblah/MyCrappyPlugin.plugin', - 'name': 'MyCrappyPlugin', - 'version': '1.2.3', - 'description': 'My crappy plugin', - 'mimeTypes': [ - { 'description': 'Foo Media', - 'fileExtensions': [ 'foo' ], - 'mimeType': 'application/x-my-foo' }, - { 'description': 'Bar Stuff', - 'fileExtensions': [ 'bar','baz' ], - 'mimeType': 'application/my-bar' } - ], - 'enabledMode': 'enabledByUser' - }, - { - 'path': '/tmp/MyFirst.plugin', - 'name': 'MyFirstPlugin', - 'version': '3.14r15926', - 'description': 'My first plugin', - 'mimeTypes': [ - { 'description': 'New Guy Media', - 'fileExtensions': [ 'mfp' ], - 'mimeType': 'application/x-my-first' } - ], - 'enabledMode': 'enabledByPolicy' - }, - { - 'path': '/foobar/baz/YourGreatPlugin.plugin', - 'name': 'YourGreatPlugin', - 'version': '4.5', - 'description': 'Your great plugin', - 'mimeTypes': [ - { 'description': 'Baz Stuff', - 'fileExtensions': [ 'baz' ], - 'mimeType': 'application/x-your-baz' } - ], - 'enabledMode': 'disabledByUser' - }, - { - 'path': '/foobiz/bar/HisGreatPlugin.plugin', - 'name': 'HisGreatPlugin', - 'version': '1.2', - 'description': 'His great plugin', - 'mimeTypes': [ - { 'description': 'More baz Stuff', - 'fileExtensions': [ 'bor' ], - 'mimeType': 'application/x-his-bor' } - ], - 'enabledMode': 'disabledByPolicy' - } - ] - } - ] -}; - -/** - * Takes the |pluginsData| input argument which represents data about the - * currently installed/running plugins and populates the html jstemplate with - * that data. It expects an object structure like the above. - * @param {Object} pluginsData Detailed info about installed plugins - */ -function renderTemplate(pluginsData) { - // This is the javascript code that processes the template: - var input = new JsEvalContext(pluginsData); - var output = document.getElementById('pluginTemplate'); - jstProcess(input, output); -} - -/** - * Asks the C++ PluginsDOMHandler to get details about the installed plugins and - * return detailed data about the configuration. The PluginsDOMHandler should - * reply to returnPluginsData() (below). - */ -function requestPluginsData() { - chrome.send('requestPluginsData', []); - chrome.send('getShowDetails', []); -} - -function loadShowDetailsFromPrefs(show_details) { - tmiModeExpanded = show_details; - document.getElementById('collapse').style.display = - show_details ? 'inline' : 'none'; - document.getElementById('expand').style.display = - show_details ? 'none' : 'inline'; - - document.body.className = - show_details ? 'showTmiMode' : 'hideTmiMode'; -} - -/** - * Asks the C++ PluginsDOMHandler to show the terms of service (about:terms). - */ -function showTermsOfService() { - chrome.send('showTermsOfService', []); -} - -/** - * Called by the web_ui_ to re-populate the page with data representing the - * current state of installed plugins. - */ -function returnPluginsData(pluginsData){ - var bodyContainer = document.getElementById('body-container'); - var body = document.body; - - // Set all page content to be visible so we can measure heights. - bodyContainer.style.visibility = 'hidden'; - body.className = ''; - var slidables = document.getElementsByClassName('showInTmiMode'); - for (var i = 0; i < slidables.length; i++) - slidables[i].style.height = 'auto'; - - renderTemplate(pluginsData); - - // Make sure the left column (with "Description:", "Location:", etc.) is the - // same size for all plugins. - var labels = document.getElementsByClassName('plugin-details-label'); - var maxLabelWidth = 0; - for (var i = 0; i < labels.length; i++) - labels[i].style.width = 'auto'; - for (var i = 0; i < labels.length; i++) - maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth); - for (var i = 0; i < labels.length; i++) - labels[i].style.width = maxLabelWidth + 'px'; - - // Explicitly set the height for each element that wants to be "slid" in and - // out when the tmiModeExpanded is toggled. - var slidables = document.getElementsByClassName('showInTmiMode'); - for (var i = 0; i < slidables.length; i++) - slidables[i].style.height = slidables[i].offsetHeight + 'px'; - - // Reset visibility of page based on the current tmi mode. - document.getElementById('collapse').style.display = - tmiModeExpanded ? 'inline' : 'none'; - document.getElementById('expand').style.display = - tmiModeExpanded ? 'none' : 'inline'; - bodyContainer.style.visibility = 'visible'; - body.className = tmiModeExpanded ? - 'showTmiModeInitial' : 'hideTmiModeInitial'; -} - -/** - * Handles a 'enable' or 'disable' button getting clicked. - */ -function handleEnablePlugin(node, enable, isGroup) { - // Tell the C++ PluginsDOMHandler to enable/disable the plugin. - chrome.send('enablePlugin', [String(node.path), String(enable), - String(isGroup)]); -} - -// Keeps track of whether details have been made visible (expanded) or not. -var tmiModeExpanded = false; - -/* - * Toggles visibility of details. - */ -function toggleTmiMode() { - tmiModeExpanded = !tmiModeExpanded; - - document.getElementById('collapse').style.display = - tmiModeExpanded ? 'inline' : 'none'; - document.getElementById('expand').style.display = - tmiModeExpanded ? 'none' : 'inline'; - - document.body.className = - tmiModeExpanded ? 'showTmiMode' : 'hideTmiMode'; - - chrome.send('saveShowDetailsToPrefs', [String(tmiModeExpanded)]); -} - -/** - * Determines whether a plugin's version should be displayed. - */ -function shouldDisplayPluginVersion(plugin) { - return !!plugin.version && plugin.version != '0'; -} - -/** - * Determines whether a plugin's description should be displayed. - */ -function shouldDisplayPluginDescription(plugin) { - // Only display the description if it's not blank and if it's not just the - // name, version, or combination thereof. - return plugin.description && - plugin.description != plugin.name && - plugin.description != plugin.version && - plugin.description != 'Version ' + plugin.version && - plugin.description != plugin.name + ' ' + plugin.version; -} - -/** - * Determines whether a plugin is enabled or not. - */ -function isPluginEnabled(plugin) { - return plugin.enabledMode == 'enabledByUser' || - plugin.enabledMode == 'enabledByPolicy'; -} - -// Unfortunately, we don't have notifications for plugin (list) status changes -// (yet), so in the meanwhile just update regularly. -setInterval(requestPluginsData, 30000); - -// Get data and have it displayed upon loading. -document.addEventListener('DOMContentLoaded', requestPluginsData); - -</script> </head> <body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> <div id="body-container" style="visibility:hidden"> @@ -487,15 +269,14 @@ document.addEventListener('DOMContentLoaded', requestPluginsData); jscontent="plugins.length"></span>)</span> </td> <td width="18"> - <img id="collapse" class="tmi-mode-image" - style="display:none" onclick="toggleTmiMode();" + <img id="collapse" class="tmi-mode-image" style="display:none" src="shared/images/minus.png"> <img id="expand" class="tmi-mode-image" - onclick="toggleTmiMode();" src="shared/images/plus.png"> + src="shared/images/plus.png"> </td> <td> <div class="tmi-mode-link"> - <a onclick="toggleTmiMode();" style="cursor: default" + <a id="details-link" style="cursor: default" i18n-content="pluginsDetailsModeLink">DETAILS</a> </div> </td> @@ -578,17 +359,17 @@ document.addEventListener('DOMContentLoaded', requestPluginsData); i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span> <span> <a + class="disable-plugin-link" jsvalues=".path:path" jsdisplay="enabledMode == 'enabledByUser'" - onclick="handleEnablePlugin(this, false, false)" - href="javascript:void(0);" + href="#" i18n-content="disable" >DISABLE</a> <a + class="enable-plugin-link" jsvalues=".path:path" jsdisplay="enabledMode == 'disabledByUser'" - onclick="handleEnablePlugin(this, true, false)" - href="javascript:void(0);" + href="#" i18n-content="enable" >ENABLE</a> <span @@ -635,17 +416,17 @@ document.addEventListener('DOMContentLoaded', requestPluginsData); <div class="plugin-actions"> <span> <a + class="disable-group-link" jsvalues=".path:name" jsdisplay="enabledMode == 'enabledByUser'" - onclick="handleEnablePlugin(this, false, true)" - href="javascript:void(0);" + href="#" i18n-content="disable" >DISABLE</a> <a + class="enable-group-link" jsvalues=".path:name" jsdisplay="enabledMode == 'disabledByUser'" - onclick="handleEnablePlugin(this, true, true)" - href="javascript:void(0);" + href="#" i18n-content="enable" >ENABLE</a> <span @@ -666,5 +447,10 @@ document.addEventListener('DOMContentLoaded', requestPluginsData); </div> </div> </div> +<script src="chrome://plugins/plugins.js"></script> +<script src="chrome://plugins/strings.js"></script> +<script src="chrome://resources/js/i18n_template.js"></script> +<script src="chrome://resources/js/i18n_process.js"></script> +<script src="chrome://resources/js/jstemplate_compiled.js"></script> </body> </html> diff --git a/chrome/browser/resources/plugins.js b/chrome/browser/resources/plugins.js new file mode 100644 index 0000000..3851192 --- /dev/null +++ b/chrome/browser/resources/plugins.js @@ -0,0 +1,255 @@ + +/** + * This variable structure is here to document the structure that the template + * expects to correctly populate the page. + */ +var pluginDataFormat = { + 'plugins': [ + { + 'name': 'Group Name', + 'description': 'description', + 'version': 'version', + 'update_url': 'http://update/', + 'critical': true, + 'enabled': true, + 'plugin_files': [ + { + 'path': '/blahblah/blahblah/MyCrappyPlugin.plugin', + 'name': 'MyCrappyPlugin', + 'version': '1.2.3', + 'description': 'My crappy plugin', + 'mimeTypes': [ + { 'description': 'Foo Media', + 'fileExtensions': [ 'foo' ], + 'mimeType': 'application/x-my-foo' }, + { 'description': 'Bar Stuff', + 'fileExtensions': [ 'bar','baz' ], + 'mimeType': 'application/my-bar' } + ], + 'enabledMode': 'enabledByUser' + }, + { + 'path': '/tmp/MyFirst.plugin', + 'name': 'MyFirstPlugin', + 'version': '3.14r15926', + 'description': 'My first plugin', + 'mimeTypes': [ + { 'description': 'New Guy Media', + 'fileExtensions': [ 'mfp' ], + 'mimeType': 'application/x-my-first' } + ], + 'enabledMode': 'enabledByPolicy' + }, + { + 'path': '/foobar/baz/YourGreatPlugin.plugin', + 'name': 'YourGreatPlugin', + 'version': '4.5', + 'description': 'Your great plugin', + 'mimeTypes': [ + { 'description': 'Baz Stuff', + 'fileExtensions': [ 'baz' ], + 'mimeType': 'application/x-your-baz' } + ], + 'enabledMode': 'disabledByUser' + }, + { + 'path': '/foobiz/bar/HisGreatPlugin.plugin', + 'name': 'HisGreatPlugin', + 'version': '1.2', + 'description': 'His great plugin', + 'mimeTypes': [ + { 'description': 'More baz Stuff', + 'fileExtensions': [ 'bor' ], + 'mimeType': 'application/x-his-bor' } + ], + 'enabledMode': 'disabledByPolicy' + } + ] + } + ] +}; + +/** + * Takes the |pluginsData| input argument which represents data about the + * currently installed/running plugins and populates the html jstemplate with + * that data. It expects an object structure like the above. + * @param {Object} pluginsData Detailed info about installed plugins + */ +function renderTemplate(pluginsData) { + // This is the javascript code that processes the template: + var input = new JsEvalContext(pluginsData); + var output = document.getElementById('pluginTemplate'); + jstProcess(input, output); +} + +/** + * Asks the C++ PluginsDOMHandler to get details about the installed plugins and + * return detailed data about the configuration. The PluginsDOMHandler should + * reply to returnPluginsData() (below). + */ +function requestPluginsData() { + chrome.send('requestPluginsData', []); + chrome.send('getShowDetails', []); +} + +function loadShowDetailsFromPrefs(show_details) { + tmiModeExpanded = show_details; + document.getElementById('collapse').style.display = + show_details ? 'inline' : 'none'; + document.getElementById('expand').style.display = + show_details ? 'none' : 'inline'; + + document.body.className = + show_details ? 'showTmiMode' : 'hideTmiMode'; +} + +/** + * Asks the C++ PluginsDOMHandler to show the terms of service (about:terms). + */ +function showTermsOfService() { + chrome.send('showTermsOfService', []); +} + +/** + * Called by the web_ui_ to re-populate the page with data representing the + * current state of installed plugins. + */ +function returnPluginsData(pluginsData){ + var bodyContainer = document.getElementById('body-container'); + var body = document.body; + + // Set all page content to be visible so we can measure heights. + bodyContainer.style.visibility = 'hidden'; + body.className = ''; + var slidables = document.getElementsByClassName('showInTmiMode'); + for (var i = 0; i < slidables.length; i++) + slidables[i].style.height = 'auto'; + + renderTemplate(pluginsData); + + // Add handlers to dynamically created HTML elements. + var links = document.getElementsByClassName('disable-plugin-link'); + for (var i = 0; i < links.length; ++i) { + links[i].onclick = function () { + handleEnablePlugin(this, false, false); + return false; + }; + } + links = document.getElementsByClassName('enable-plugin-link'); + for (var i = 0; i < links.length; ++i) { + links[i].onclick = function () { + handleEnablePlugin(this, true, false); + return false; + }; + } + links = document.getElementsByClassName('disable-group-link'); + for (var i = 0; i < links.length; ++i) { + links[i].onclick = function () { + handleEnablePlugin(this, false, true); + return false; + }; + } + links = document.getElementsByClassName('enable-group-link'); + for (var i = 0; i < links.length; ++i) { + links[i].onclick = function () { + handleEnablePlugin(this, true, true); + return false; + }; + } + + // Make sure the left column (with "Description:", "Location:", etc.) is the + // same size for all plugins. + var labels = document.getElementsByClassName('plugin-details-label'); + var maxLabelWidth = 0; + for (var i = 0; i < labels.length; i++) + labels[i].style.width = 'auto'; + for (var i = 0; i < labels.length; i++) + maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth); + for (var i = 0; i < labels.length; i++) + labels[i].style.width = maxLabelWidth + 'px'; + + // Explicitly set the height for each element that wants to be "slid" in and + // out when the tmiModeExpanded is toggled. + var slidables = document.getElementsByClassName('showInTmiMode'); + for (var i = 0; i < slidables.length; i++) + slidables[i].style.height = slidables[i].offsetHeight + 'px'; + + // Reset visibility of page based on the current tmi mode. + document.getElementById('collapse').style.display = + tmiModeExpanded ? 'inline' : 'none'; + document.getElementById('expand').style.display = + tmiModeExpanded ? 'none' : 'inline'; + bodyContainer.style.visibility = 'visible'; + body.className = tmiModeExpanded ? + 'showTmiModeInitial' : 'hideTmiModeInitial'; +} + +/** + * Handles a 'enable' or 'disable' button getting clicked. + */ +function handleEnablePlugin(node, enable, isGroup) { + // Tell the C++ PluginsDOMHandler to enable/disable the plugin. + chrome.send('enablePlugin', [String(node.path), String(enable), + String(isGroup)]); +} + +// Keeps track of whether details have been made visible (expanded) or not. +var tmiModeExpanded = false; + +/* + * Toggles visibility of details. + */ +function toggleTmiMode() { + tmiModeExpanded = !tmiModeExpanded; + + document.getElementById('collapse').style.display = + tmiModeExpanded ? 'inline' : 'none'; + document.getElementById('expand').style.display = + tmiModeExpanded ? 'none' : 'inline'; + + document.body.className = + tmiModeExpanded ? 'showTmiMode' : 'hideTmiMode'; + + chrome.send('saveShowDetailsToPrefs', [String(tmiModeExpanded)]); +} + +/** + * Determines whether a plugin's version should be displayed. + */ +function shouldDisplayPluginVersion(plugin) { + return !!plugin.version && plugin.version != '0'; +} + +/** + * Determines whether a plugin's description should be displayed. + */ +function shouldDisplayPluginDescription(plugin) { + // Only display the description if it's not blank and if it's not just the + // name, version, or combination thereof. + return plugin.description && + plugin.description != plugin.name && + plugin.description != plugin.version && + plugin.description != 'Version ' + plugin.version && + plugin.description != plugin.name + ' ' + plugin.version; +} + +/** + * Determines whether a plugin is enabled or not. + */ +function isPluginEnabled(plugin) { + return plugin.enabledMode == 'enabledByUser' || + plugin.enabledMode == 'enabledByPolicy'; +} + +// Unfortunately, we don't have notifications for plugin (list) status changes +// (yet), so in the meanwhile just update regularly. +setInterval(requestPluginsData, 30000); + +// Get data and have it displayed upon loading. +document.addEventListener('DOMContentLoaded', requestPluginsData); + +// Add handlers to static HTML elements. +document.getElementById('collapse').onclick = toggleTmiMode; +document.getElementById('expand').onclick = toggleTmiMode; +document.getElementById('details-link').onclick = toggleTmiMode; + diff --git a/chrome/browser/resources/shared/js/jstemplate_compiled.js b/chrome/browser/resources/shared/js/jstemplate_compiled.js new file mode 100644 index 0000000..d503e90 --- /dev/null +++ b/chrome/browser/resources/shared/js/jstemplate_compiled.js @@ -0,0 +1,10 @@ +(function(){var i=null;function k(){return Function.prototype.call.apply(Array.prototype.slice,arguments)}function l(a,b){var c=k(arguments,2);return function(){return b.apply(a,c)}}function m(a,b){var c=new n(b);for(c.f=[a];c.f.length;){var e=c,d=c.f.shift();e.g(d);for(d=d.firstChild;d;d=d.nextSibling)d.nodeType==1&&e.f.push(d)}}function n(a){this.g=a}function o(a){a.style.display=""}function p(a){a.style.display="none"};var q=":",r=/\s*;\s*/;function s(){this.i.apply(this,arguments)}s.prototype.i=function(a,b){if(!this.a)this.a={};if(b){var c=this.a,e=b.a,d;for(d in e)c[d]=e[d]}else for(c in d=this.a,e=t,e)d[c]=e[c];this.a.$this=a;this.a.$context=this;this.d=typeof a!="undefined"&&a!=i?a:"";if(!b)this.a.$top=this.d};var t={$default:i},u=[];function v(a){for(var b in a.a)delete a.a[b];a.d=i;u.push(a)}function w(a,b,c){try{return b.call(c,a.a,a.d)}catch(e){return t.$default}} +function x(a,b,c,e){if(u.length>0){var d=u.pop();s.call(d,b,a);a=d}else a=new s(b,a);a.a.$index=c;a.a.$count=e;return a}var y="a_",z="b_",A="with (a_) with (b_) return ",D={};function E(a){if(!D[a])try{D[a]=new Function(y,z,A+a)}catch(b){}return D[a]}function F(a){for(var b=[],a=a.split(r),c=0,e=a.length;c<e;++c){var d=a[c].indexOf(q);if(!(d<0)){var f;f=a[c].substr(0,d).replace(/^\s+/,"").replace(/\s+$/,"");d=E(a[c].substr(d+1));b.push(f,d)}}return b};var G="jsinstance",H="jsts",I="*",J="div",K="id";function L(){}var M=0,N={0:{}},P={},Q={},R=[];function S(a){a.__jstcache||m(a,function(a){T(a)})}var U=[["jsselect",E],["jsdisplay",E],["jsvalues",F],["jsvars",F],["jseval",function(a){for(var b=[],a=a.split(r),c=0,e=a.length;c<e;++c)if(a[c]){var d=E(a[c]);b.push(d)}return b}],["transclude",function(a){return a}],["jscontent",E],["jsskip",E]]; +function T(a){if(a.__jstcache)return a.__jstcache;var b=a.getAttribute("jstcache");if(b!=i)return a.__jstcache=N[b];for(var b=R.length=0,c=U.length;b<c;++b){var e=U[b][0],d=a.getAttribute(e);Q[e]=d;d!=i&&R.push(e+"="+d)}if(R.length==0)return a.setAttribute("jstcache","0"),a.__jstcache=N[0];var f=R.join("&");if(b=P[f])return a.setAttribute("jstcache",b),a.__jstcache=N[b];for(var h={},b=0,c=U.length;b<c;++b){var d=U[b],e=d[0],g=d[1],d=Q[e];d!=i&&(h[e]=g(d))}b=""+ ++M;a.setAttribute("jstcache",b);N[b]= +h;P[f]=b;return a.__jstcache=h}function V(a,b){a.h.push(b);a.k.push(0)}function W(a){return a.c.length?a.c.pop():[]} +L.prototype.e=function(a,b){var c=X(b),e=c.transclude;if(e)(c=Y(e))?(b.parentNode.replaceChild(c,b),e=W(this),e.push(this.e,a,c),V(this,e)):b.parentNode.removeChild(b);else if(c=c.jsselect){var c=w(a,c,b),d=b.getAttribute(G),f=!1;d&&(d.charAt(0)==I?(d=parseInt(d.substr(1),10),f=!0):d=parseInt(d,10));var h=c!=i&&typeof c=="object"&&typeof c.length=="number",e=h?c.length:1,g=h&&e==0;if(h)if(g)d?b.parentNode.removeChild(b):(b.setAttribute(G,"*0"),p(b));else if(o(b),d===i||d===""||f&&d<e-1){f=W(this); +d=d||0;for(h=e-1;d<h;++d){var j=b.cloneNode(!0);b.parentNode.insertBefore(j,b);Z(j,c,d);g=x(a,c[d],d,e);f.push(this.b,g,j,v,g,i)}Z(b,c,d);g=x(a,c[d],d,e);f.push(this.b,g,b,v,g,i);V(this,f)}else d<e?(f=c[d],Z(b,c,d),g=x(a,f,d,e),f=W(this),f.push(this.b,g,b,v,g,i),V(this,f)):b.parentNode.removeChild(b);else c==i?p(b):(o(b),g=x(a,c,0,1),f=W(this),f.push(this.b,g,b,v,g,i),V(this,f))}else this.b(a,b)}; +L.prototype.b=function(a,b){var c=X(b),e=c.jsdisplay;if(e){if(!w(a,e,b)){p(b);return}o(b)}if(e=c.jsvars)for(var d=0,f=e.length;d<f;d+=2){var h=e[d],g=w(a,e[d+1],b);a.a[h]=g}if(e=c.jsvalues){d=0;for(f=e.length;d<f;d+=2)if(g=e[d],h=w(a,e[d+1],b),g.charAt(0)=="$")a.a[g]=h;else if(g.charAt(0)=="."){for(var g=g.substr(1).split("."),j=b,O=g.length,B=0,$=O-1;B<$;++B){var C=g[B];j[C]||(j[C]={});j=j[C]}j[g[O-1]]=h}else g&&(typeof h=="boolean"?h?b.setAttribute(g,g):b.removeAttribute(g):b.setAttribute(g,""+ +h))}if(e=c.jseval){d=0;for(f=e.length;d<f;++d)w(a,e[d],b)}e=c.jsskip;if(!e||!w(a,e,b))if(c=c.jscontent){if(c=""+w(a,c,b),b.innerHTML!=c){for(;b.firstChild;)e=b.firstChild,e.parentNode.removeChild(e);b.appendChild(this.j.createTextNode(c))}}else{c=W(this);for(e=b.firstChild;e;e=e.nextSibling)e.nodeType==1&&c.push(this.e,a,e);c.length&&V(this,c)}};function X(a){if(a.__jstcache)return a.__jstcache;var b=a.getAttribute("jstcache");if(b)return a.__jstcache=N[b];return T(a)} +function Y(a,b){var c=document;if(b){var e=c.getElementById(a);if(!e){var e=b(),d=H,f=c.getElementById(d);if(!f)f=c.createElement(J),f.id=d,p(f),f.style.position="absolute",c.body.appendChild(f);d=c.createElement(J);f.appendChild(d);d.innerHTML=e;e=c.getElementById(a)}c=e}else c=c.getElementById(a);return c?(S(c),c=c.cloneNode(!0),c.removeAttribute(K),c):i}function Z(a,b,c){c==b.length-1?a.setAttribute(G,I+c):a.setAttribute(G,""+c)};window.jstGetTemplate=Y;window.JsEvalContext=s;window.jstProcess=function(a,b){var c=new L;S(b);c.j=b?b.nodeType==9?b:b.ownerDocument||document:document;var e=l(c,c.e,a,b),d=c.h=[],f=c.k=[];c.c=[];e();for(var h,g,j;d.length;)h=d[d.length-1],e=f[f.length-1],e>=h.length?(e=c,g=d.pop(),g.length=0,e.c.push(g),f.pop()):(g=h[e++],j=h[e++],h=h[e++],f[f.length-1]=e,g.call(c,j,h))}; +})()
\ No newline at end of file diff --git a/chrome/browser/resources/shared_resources.grd b/chrome/browser/resources/shared_resources.grd index a66ece9..3cf1dfd 100644 --- a/chrome/browser/resources/shared_resources.grd +++ b/chrome/browser/resources/shared_resources.grd @@ -110,6 +110,8 @@ without changes to the corresponding grd file. paaaae --> file="shared/js/i18n_process.js" type="BINDATA" /> <include name="IDR_SHARED_JS_I18N_TEMPLATE" file="shared/js/i18n_template.js" type="BINDATA" /> + <include name="IDR_SHARED_JS_JSTEMPLATE_COMPILED" + file="shared/js/jstemplate_compiled.js" type="BINDATA" /> <include name="IDR_SHARED_JS_LOCAL_STRINGS" file="shared/js/local_strings.js" type="BINDATA" /> <include name="IDR_SHARED_JS_MEDIA_COMMON" diff --git a/chrome/browser/ui/webui/plugins_ui.cc b/chrome/browser/ui/webui/plugins_ui.cc index 7672fd4..8fa1446 100644 --- a/chrome/browser/ui/webui/plugins_ui.cc +++ b/chrome/browser/ui/webui/plugins_ui.cc @@ -20,9 +20,9 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h" +#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/jstemplate_builder.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" @@ -31,31 +31,30 @@ #include "grit/browser_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" -#include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "webkit/plugins/npapi/plugin_list.h" +static const char kStringsJsFile[] = "strings.js"; +static const char kPluginsJsFile[] = "plugins.js"; + namespace { /////////////////////////////////////////////////////////////////////////////// // -// PluginsHTMLSource +// PluginsUIHTMLSource // /////////////////////////////////////////////////////////////////////////////// -class PluginsUIHTMLSource : public ChromeURLDataManager::DataSource { +class PluginsUIHTMLSource : public ChromeWebUIDataSource { public: - PluginsUIHTMLSource() - : DataSource(chrome::kChromeUIPluginsHost, MessageLoop::current()) {} + PluginsUIHTMLSource(); // Called when the network layer has requested a resource underneath // the path we registered. virtual void StartDataRequest(const std::string& path, bool is_incognito, int request_id); - virtual std::string GetMimeType(const std::string&) const { - return "text/html"; - } + virtual std::string GetMimeType(const std::string&) const; private: ~PluginsUIHTMLSource() {} @@ -63,67 +62,54 @@ class PluginsUIHTMLSource : public ChromeURLDataManager::DataSource { DISALLOW_COPY_AND_ASSIGN(PluginsUIHTMLSource); }; +PluginsUIHTMLSource::PluginsUIHTMLSource() + : ChromeWebUIDataSource(chrome::kChromeUIPluginsHost) { + AddLocalizedString("pluginsTitle", IDS_PLUGINS_TITLE); + AddLocalizedString("pluginsDetailsModeLink", + IDS_PLUGINS_DETAILS_MODE_LINK); + AddLocalizedString("pluginsNoneInstalled", IDS_PLUGINS_NONE_INSTALLED); + AddLocalizedString("pluginDisabled", IDS_PLUGINS_DISABLED_PLUGIN); + AddLocalizedString("pluginDisabledByPolicy", + IDS_PLUGINS_DISABLED_BY_POLICY_PLUGIN); + AddLocalizedString("pluginCannotBeEnabledDueToPolicy", + IDS_PLUGINS_CANNOT_ENABLE_DUE_TO_POLICY); + AddLocalizedString("pluginEnabledByPolicy", + IDS_PLUGINS_ENABLED_BY_POLICY_PLUGIN); + AddLocalizedString("pluginCannotBeDisabledDueToPolicy", + IDS_PLUGINS_CANNOT_DISABLE_DUE_TO_POLICY); + AddLocalizedString("pluginDownload", IDS_PLUGINS_DOWNLOAD); + AddLocalizedString("pluginName", IDS_PLUGINS_NAME); + AddLocalizedString("pluginVersion", IDS_PLUGINS_VERSION); + AddLocalizedString("pluginDescription", IDS_PLUGINS_DESCRIPTION); + AddLocalizedString("pluginPath", IDS_PLUGINS_PATH); + AddLocalizedString("pluginMimeTypes", IDS_PLUGINS_MIME_TYPES); + AddLocalizedString("pluginMimeTypesMimeType", + IDS_PLUGINS_MIME_TYPES_MIME_TYPE); + AddLocalizedString("pluginMimeTypesDescription", + IDS_PLUGINS_MIME_TYPES_DESCRIPTION); + AddLocalizedString("pluginMimeTypesFileExtensions", + IDS_PLUGINS_MIME_TYPES_FILE_EXTENSIONS); + AddLocalizedString("disable", IDS_PLUGINS_DISABLE); + AddLocalizedString("enable", IDS_PLUGINS_ENABLE); + AddLocalizedString("noPlugins", IDS_PLUGINS_NO_PLUGINS); +} + void PluginsUIHTMLSource::StartDataRequest(const std::string& path, bool is_incognito, int request_id) { - // Strings used in the JsTemplate file. - DictionaryValue localized_strings; - localized_strings.SetString("pluginsTitle", - l10n_util::GetStringUTF16(IDS_PLUGINS_TITLE)); - localized_strings.SetString("pluginsDetailsModeLink", - l10n_util::GetStringUTF16(IDS_PLUGINS_DETAILS_MODE_LINK)); - localized_strings.SetString("pluginsNoneInstalled", - l10n_util::GetStringUTF16(IDS_PLUGINS_NONE_INSTALLED)); - localized_strings.SetString("pluginDisabled", - l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_PLUGIN)); - localized_strings.SetString("pluginDisabledByPolicy", - l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_BY_POLICY_PLUGIN)); - localized_strings.SetString("pluginCannotBeEnabledDueToPolicy", - l10n_util::GetStringUTF16(IDS_PLUGINS_CANNOT_ENABLE_DUE_TO_POLICY)); - localized_strings.SetString("pluginEnabledByPolicy", - l10n_util::GetStringUTF16(IDS_PLUGINS_ENABLED_BY_POLICY_PLUGIN)); - localized_strings.SetString("pluginCannotBeDisabledDueToPolicy", - l10n_util::GetStringUTF16(IDS_PLUGINS_CANNOT_DISABLE_DUE_TO_POLICY)); - localized_strings.SetString("pluginDownload", - l10n_util::GetStringUTF16(IDS_PLUGINS_DOWNLOAD)); - localized_strings.SetString("pluginName", - l10n_util::GetStringUTF16(IDS_PLUGINS_NAME)); - localized_strings.SetString("pluginVersion", - l10n_util::GetStringUTF16(IDS_PLUGINS_VERSION)); - localized_strings.SetString("pluginDescription", - l10n_util::GetStringUTF16(IDS_PLUGINS_DESCRIPTION)); - localized_strings.SetString("pluginPath", - l10n_util::GetStringUTF16(IDS_PLUGINS_PATH)); - localized_strings.SetString("pluginMimeTypes", - l10n_util::GetStringUTF16(IDS_PLUGINS_MIME_TYPES)); - localized_strings.SetString("pluginMimeTypesMimeType", - l10n_util::GetStringUTF16(IDS_PLUGINS_MIME_TYPES_MIME_TYPE)); - localized_strings.SetString("pluginMimeTypesDescription", - l10n_util::GetStringUTF16(IDS_PLUGINS_MIME_TYPES_DESCRIPTION)); - localized_strings.SetString("pluginMimeTypesFileExtensions", - l10n_util::GetStringUTF16(IDS_PLUGINS_MIME_TYPES_FILE_EXTENSIONS)); - localized_strings.SetString("disable", - l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLE)); - localized_strings.SetString("enable", - l10n_util::GetStringUTF16(IDS_PLUGINS_ENABLE)); - localized_strings.SetString("noPlugins", - l10n_util::GetStringUTF16(IDS_PLUGINS_NO_PLUGINS)); - - ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings); - - static const base::StringPiece plugins_html( - ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_PLUGINS_HTML)); - std::string full_html(plugins_html.data(), plugins_html.size()); - jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html); - jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html); - jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html); - jstemplate_builder::AppendJsTemplateSourceHtml(&full_html); - - scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); - html_bytes->data.resize(full_html.size()); - std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); - - SendResponse(request_id, html_bytes); + if (path == kStringsJsFile) { + SendLocalizedStringsAsJSON(request_id); + } else { + int idr = (path == kPluginsJsFile) ? IDR_PLUGINS_JS : IDR_PLUGINS_HTML; + SendFromResourceBundle(request_id, idr); + } +} + +std::string PluginsUIHTMLSource::GetMimeType(const std::string& path) const { + if (path == kStringsJsFile || path == kPluginsJsFile) + return "application/javascript"; + + return "text/html"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/common/common_resources.grd b/chrome/common/common_resources.grd index a90b009..efc8179 100644 --- a/chrome/common/common_resources.grd +++ b/chrome/common/common_resources.grd @@ -12,7 +12,7 @@ <include name="IDR_EXTENSION_API_JSON" file="extensions\api\extension_api.json" type="BINDATA" /> <include name="IDR_I18N_PROCESS_JS" file="..\browser\resources\shared\js\i18n_process.js" type="BINDATA" /> <include name="IDR_I18N_TEMPLATE_JS" file="..\browser\resources\shared\js\i18n_template.js" type="BINDATA" /> - <include name="IDR_JSTEMPLATE_JS" file="..\third_party\jstemplate\jstemplate_compiled.js" type="BINDATA" /> + <include name="IDR_JSTEMPLATE_JS" file="..\browser\resources\shared\js\jstemplate_compiled.js" type="BINDATA" /> <include name="IDR_WEB_APP_SCHEMA" file="web_app_schema.json" type="BINDATA" /> </includes> </release> diff --git a/chrome/third_party/jstemplate/README.chromium b/chrome/third_party/jstemplate/README.chromium index 153d6a6..439ac77 100644 --- a/chrome/third_party/jstemplate/README.chromium +++ b/chrome/third_party/jstemplate/README.chromium @@ -10,8 +10,15 @@ output with an incremental change to the original input data." Uncalled functions have been removed from util.js to make the resulting javascript smaller. -compile.py is a simple program used to generate the single compiled -jsfile. +compile.py is a simple program used to generate the single compiled jsfile. + +NOTE: output is now simply written to stdout so as to allow you to redirect +it to a location required by the shared resource bundle. + +See IDR_SHARED_JS_JSTEMPLATE_COMPILED's file attribute in shared_resources.grd +to determine the correct location for the output. + +The jstemplate_compiled.js file which formerly resided in this directory is +no longer used. + -jstemplate_compiled.js is the output after passing the code through -compile.sh. diff --git a/chrome/third_party/jstemplate/compile.py b/chrome/third_party/jstemplate/compile.py index 3d16d96..ddfc4fe 100755 --- a/chrome/third_party/jstemplate/compile.py +++ b/chrome/third_party/jstemplate/compile.py @@ -4,13 +4,14 @@ # found in the LICENSE file. # A python script that combines the javascript files needed by jstemplate into -# a single file. +# a single file. Writes to standard output; you are responsible for putting +# the file into the tree where it belongs. import httplib +import sys import urllib srcs ="util.js jsevalcontext.js jstemplate.js exports.js".split() -out = "jstemplate_compiled.js" # Wrap the output in an anonymous function to prevent poluting the global # namespace. @@ -32,7 +33,5 @@ headers = {'Content-type': 'application/x-www-form-urlencoded'} conn = httplib.HTTPConnection('closure-compiler.appspot.com') conn.request('POST', '/compile', params, headers) response = conn.getresponse() -out_file = file(out, 'w') -out_file.write(output_wrapper % response.read()) -out_file.close() +sys.stdout.write(output_wrapper % response.read()) conn.close() diff --git a/chrome/third_party/jstemplate/jstemplate_compiled.js b/chrome/third_party/jstemplate/jstemplate_compiled.js deleted file mode 100644 index afe2769..0000000 --- a/chrome/third_party/jstemplate/jstemplate_compiled.js +++ /dev/null @@ -1,13 +0,0 @@ -(function(){function j(a,b){for(var c in b)a[c]=b[c]}function l(){return Function.prototype.call.apply(Array.prototype.slice,arguments)}function m(a,b){var c=l(arguments,2);return function(){return b.apply(a,c)}}var n=9;function o(a,b){b=new p(b);for(b.f=[a];b.f.length;){a=b.f.shift();b.g(a);for(a=a.firstChild;a;a=a.nextSibling)a.nodeType==1&&b.f.push(a)}}function p(a){this.g=a}function q(a,b,c){a.setAttribute(b,c)}function r(a,b){a.removeAttribute(b)}function s(a){a.style.display=""} -function t(a){a.style.display="none"};var u=":",v=/\s*;\s*/;function w(){this.i.apply(this,arguments)}w.prototype.i=function(a,b){var c=this;if(!c.a)c.a={};b?j(c.a,b.a):j(c.a,x);c.a.$this=a;c.a.$context=c;c.d=typeof a!="undefined"&&a!=null?a:"";if(!b)c.a.$top=c.d};var x={};(function(a,b){x[a]=b})("$default",null);var y=[];function z(a){for(var b in a.a)delete a.a[b];a.d=null;y.push(a)}function A(a,b,c){try{return b.call(c,a.a,a.d)}catch(e){return x.$default}} -function B(a,b,c,e){if(y.length>0){var d=y.pop();w.call(d,b,a);a=d}else a=new w(b,a);a.a.$index=c;a.a.$count=e;return a}var C="a_",E="b_",F="with (a_) with (b_) return ",G={};function H(a){if(!G[a])try{G[a]=new Function(C,E,F+a)}catch(b){}return G[a]}function I(a){return a}function J(a){var b=[];a=a.split(v);for(var c=0,e=a.length;c<e;++c){var d=a[c].indexOf(u);if(!(d<0)){var f;f=a[c].substr(0,d).replace(/^\s+/,"").replace(/\s+$/,"");d=H(a[c].substr(d+1));b.push(f,d)}}return b} -function K(a){var b=[];a=a.split(v);for(var c=0,e=a.length;c<e;++c)if(a[c]){var d=H(a[c]);b.push(d)}return b};var L="jsinstance",aa="jsts",M="*",N="div",ba="id";function ca(a,b){var c=new O;P(b);c.j=b?b.nodeType==n?b:b.ownerDocument||document:document;var e=m(c,c.e,a,b);a=c.h=[];b=c.k=[];c.c=[];e();for(var d,f,g;a.length;){d=a[a.length-1];e=b[b.length-1];if(e>=d.length){e=a.pop();e.length=0;c.c.push(e);b.pop()}else{f=d[e++];g=d[e++];d=d[e++];b[b.length-1]=e;f.call(c,g,d)}}}function O(){}var da=0,Q={};Q[0]={};var R={},S={},T=[];function P(a){a.__jstcache||o(a,function(b){U(b)})} -var V=[["jsselect",H],["jsdisplay",H],["jsvalues",J],["jsvars",J],["jseval",K],["transclude",I],["jscontent",H],["jsskip",H]]; -function U(a){if(a.__jstcache)return a.__jstcache;var b=a.getAttribute("jstcache");if(b!=null)return a.__jstcache=Q[b];b=T.length=0;for(var c=V.length;b<c;++b){var e=V[b][0],d=a.getAttribute(e);S[e]=d;d!=null&&T.push(e+"="+d)}if(T.length==0){a.setAttribute("jstcache","0");return a.__jstcache=Q[0]}var f=T.join("&");if(b=R[f]){a.setAttribute("jstcache",b);return a.__jstcache=Q[b]}var g={};b=0;for(c=V.length;b<c;++b){d=V[b];e=d[0];var i=d[1];d=S[e];if(d!=null)g[e]=i(d)}b=""+ ++da;a.setAttribute("jstcache", -b);Q[b]=g;R[f]=b;return a.__jstcache=g}function W(a,b){a.h.push(b);a.k.push(0)}function X(a){return a.c.length?a.c.pop():[]}O.prototype.e=function(a,b){var c=this,e=Y(c,b),d=e.transclude;if(d)if(e=Z(d)){b.parentNode.replaceChild(e,b);b=X(c);b.push(c.e,a,e);W(c,b)}else b.parentNode.removeChild(b);else(e=e.jsselect)?ea(c,a,b,e):c.b(a,b)}; -O.prototype.b=function(a,b){var c=this,e=Y(c,b),d=e.jsdisplay;if(d){if(!A(a,d,b)){t(b);return}s(b)}(d=e.jsvars)&&fa(c,a,b,d);(d=e.jsvalues)&&ga(c,a,b,d);if(d=e.jseval)for(var f=0,g=d.length;f<g;++f)A(a,d[f],b);if(d=e.jsskip)if(A(a,d,b))return;if(e=e.jscontent){a=""+A(a,e,b);if(b.innerHTML!=a){for(;b.firstChild;)b.firstChild.parentNode.removeChild(b.firstChild);c=c.j.createTextNode(a);b.appendChild(c)}}else{e=X(c);for(b=b.firstChild;b;b=b.nextSibling)b.nodeType==1&&e.push(c.e,a,b);e.length&&W(c,e)}}; -function ea(a,b,c,e){e=A(b,e,c);var d=c.getAttribute(L),f=false;if(d)if(d.charAt(0)==M){var g=d.substr(1);d=parseInt(g,10);f=true}else d=parseInt(d,10);var i=e!=null&&typeof e=="object"&&typeof e.length=="number";g=i?e.length:1;var h=i&&g==0;if(i)if(h)if(d)c.parentNode.removeChild(c);else{c.setAttribute(L,"*0");t(c)}else{s(c);if(d===null||d===""||f&&d<g-1){f=X(a);d=d||0;for(i=g-1;d<i;++d){var k=c.cloneNode(true);c.parentNode.insertBefore(k,c);$(k,e,d);h=B(b,e[d],d,g);f.push(a.b,h,k,z,h,null)}$(c, -e,d);h=B(b,e[d],d,g);f.push(a.b,h,c,z,h,null);W(a,f)}else if(d<g){f=e[d];$(c,e,d);h=B(b,f,d,g);f=X(a);f.push(a.b,h,c,z,h,null);W(a,f)}else c.parentNode.removeChild(c)}else if(e==null)t(c);else{s(c);h=B(b,e,0,1);f=X(a);f.push(a.b,h,c,z,h,null);W(a,f)}}function fa(a,b,c,e){a=0;for(var d=e.length;a<d;a+=2){var f=e[a],g=A(b,e[a+1],c);b.a[f]=g}} -function ga(a,b,c,e){a=0;for(var d=e.length;a<d;a+=2){var f=e[a],g=A(b,e[a+1],c);if(f.charAt(0)=="$")b.a[f]=g;else if(f.charAt(0)=="."){f=f.substr(1).split(".");for(var i=c,h=f.length,k=0,ha=h-1;k<ha;++k){var D=f[k];i[D]||(i[D]={});i=i[D]}i[f[h-1]]=g}else if(f)if(typeof g=="boolean")g?q(c,f,f):r(c,f);else c.setAttribute(f,""+g)}}function Y(a,b){if(b.__jstcache)return b.__jstcache;if(a=b.getAttribute("jstcache"))return b.__jstcache=Q[a];return U(b)} -function Z(a,b){var c=document;if(a=b?ia(c,a,b):c.getElementById(a)){P(a);a=a.cloneNode(true);a.removeAttribute(ba);return a}else return null}function ia(a,b,c,e){var d=a.getElementById(b);if(d)return d;c=c();e=e||aa;if(d=a.getElementById(e))d=d;else{d=a.createElement(N);d.id=e;t(d);d.style.position="absolute";a.body.appendChild(d)}e=a.createElement(N);d.appendChild(e);e.innerHTML=c;return d=a.getElementById(b)}function $(a,b,c){c==b.length-1?q(a,L,M+c):q(a,L,""+c)};window.jstGetTemplate=Z;window.JsEvalContext=w;window.jstProcess=ca; -})()
\ No newline at end of file |