From 7cd22a5102842cfbb51e06c626d769d81bb78210 Mon Sep 17 00:00:00 2001 From: "arv@google.com" Date: Tue, 14 Jul 2009 00:40:25 +0000 Subject: This provides a simpler js template engine than JsTemplate. It has been optimized for the way we do internationalization with JST before and is about 4 times faster (average 4.8ms vs 22.8ms) for the history page. The syntax for this is very similar to JsTemplates. It uses the attributes i18n-values and i18n-content which worls like jsvalues and jscontent except that it does not allow arbitrary expressions. BUG=None TEST=All UI pages should work as before Review URL: http://codereview.chromium.org/149420 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20590 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/app/generated_resources.grd | 56 ++++++------- chrome/browser/browser_about_handler.cc | 4 +- chrome/browser/browser_main.cc | 5 +- chrome/browser/browser_resources.grd | 2 +- chrome/browser/dom_ui/downloads_ui.cc | 4 +- chrome/browser/dom_ui/history_ui.cc | 5 +- chrome/browser/dom_ui/new_tab_ui.cc | 11 ++- chrome/browser/extensions/extensions_ui.cc | 9 +- chrome/browser/resources/about_version.html | 18 ++-- chrome/browser/resources/downloads.html | 12 +-- chrome/browser/resources/extensions_ui.html | 8 +- chrome/browser/resources/history.html | 8 +- chrome/browser/resources/i18n_template.js | 91 ++++++++++++++++++++ chrome/browser/resources/incognito_tab.html | 9 +- chrome/browser/resources/new_new_tab.html | 40 ++++----- chrome/browser/resources/new_tab.html | 40 ++++----- .../resources/safe_browsing_malware_block.html | 19 +++-- .../safe_browsing_multiple_threat_block.html | 22 ++--- .../resources/safe_browsing_phishing_block.html | 21 ++--- .../safe_browsing/safe_browsing_blocking_page.cc | 2 +- chrome/browser/security/resources/ssl_error.html | 33 ++++---- .../browser/security/resources/ssl_roadblock.html | 35 ++++---- chrome/browser/ssl/ssl_blocking_page.cc | 2 +- chrome/browser/ssl/ssl_policy.cc | 4 +- chrome/common/common_resources.grd | 1 + chrome/common/jstemplate_builder.cc | 98 +++++++++++++++++----- chrome/common/jstemplate_builder.h | 50 +++++++++-- chrome/renderer/render_view.cc | 3 +- chrome/renderer/resources/error_no_details.html | 20 ++--- chrome/renderer/resources/neterror.html | 27 +++--- net/base/dir_header.html | 13 +-- 31 files changed, 436 insertions(+), 236 deletions(-) create mode 100644 chrome/browser/resources/i18n_template.js diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d035b1e..a61314d 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -186,7 +186,7 @@ each locale. --> Customize and control $1Google Chrome - + Did you mean to go to $1http://intranetsite/? @@ -1524,7 +1524,7 @@ each locale. --> Discard - + Close find bar - + Exit full screen ($1F11) @@ -2254,7 +2254,7 @@ each locale. --> Stop import - + Continue Importing @@ -2273,7 +2273,7 @@ each locale. --> Skip Import - + Report Bug or Broken Web Site @@ -2448,7 +2448,7 @@ each locale. --> Transferring from $1www.google.com... - + New tab @@ -2640,13 +2640,13 @@ each locale. --> - <a jsvalues="href:reloadUrl">Reload</a> this web page later. + <a i18n-values="href:reloadUrl">Reload</a> this web page later. Go to the homepage of the site: - <a jsvalues="href:learnMoreUrl">Learn more</a> about this problem. + <a i18n-values="href:learnMoreUrl">Learn more</a> about this problem. @@ -2668,13 +2668,13 @@ each locale. --> This webpage has a redirect loop. - The webpage at <strong jscontent="failedUrl"></strong> might be temporarily down or it may have moved permanently to a new web address. + The webpage at <strong i18n-content="failedUrl"></strong> might be temporarily down or it may have moved permanently to a new web address. - No webpage was found for the web address: <strong jscontent="failedUrl"></strong> + No webpage was found for the web address: <strong i18n-content="failedUrl"></strong> - The webpage at <strong jscontent="failedUrl"></strong> has resulted in + The webpage at <strong i18n-content="failedUrl"></strong> has resulted in too many redirects. Clearing your cookies for this site may fix the problem. If not, it is possibly a server configuration issue and not a problem with your computer. @@ -2709,7 +2709,7 @@ each locale. --> This web page requires data that you entered earlier in order to be properly displayed. You can send this data again, but by doing so you will repeat any action this page previously performed. Press Reload to resend that data and display this page. - + All Files @@ -2758,7 +2758,7 @@ each locale. --> The identity of $1Google at $2Mountain View, CA US has been verified by $3VeriSign. - + unknown name @@ -2894,7 +2894,7 @@ each locale. --> Cancel - + (empty) @@ -2951,7 +2951,7 @@ each locale. --> Exit Install - + Customize Your Settings @@ -3020,7 +3020,7 @@ each locale. --> To hide access to this program, you need to uninstall it by using\n$1Add/Remove Programs in Control Panel.\n\nWould you like to start $1Add/Remove Programs? - + $1Google Chrome Options @@ -3123,7 +3123,7 @@ each locale. --> Clear auto-opening settings - + Gears: @@ -3137,7 +3137,7 @@ each locale. --> Manage certificates - + Passwords: @@ -3621,8 +3621,8 @@ each locale. --> Script on the page used too much memory. Reload to enable scripts again. - - Visit history @@ -3651,7 +3651,7 @@ each locale. --> Remember my choice for all links of this type. - + JavaScript Debugger - Busy @@ -3673,7 +3673,7 @@ each locale. --> Shift+$1C - + Esc @@ -3737,7 +3737,7 @@ each locale. --> Date Modified - + Web Page, HTML Only @@ -3757,7 +3757,7 @@ each locale. --> $15 / $213 files - + Report phishing website... @@ -3769,7 +3769,7 @@ each locale. --> Service URL: - + Use a suggestion service to help complete searches and URLs typed in the address bar @@ -3783,7 +3783,7 @@ each locale. --> Change font and language settings - + Change the language of the spell-checking dictionary. @@ -3796,7 +3796,7 @@ each locale. --> Correct spelling automatically: - + Reset to defaults @@ -3806,7 +3806,7 @@ each locale. --> Don't reset - + Failed To Create Data Directory diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 1e29d7f..4b8da31 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -381,8 +381,8 @@ std::string AboutVersion() { ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_ABOUT_VERSION_HTML)); - return jstemplate_builder::GetTemplateHtml( - version_html, &localized_strings, "t" /* template root node id */); + return jstemplate_builder::GetI18nTemplateHtml( + version_html, &localized_strings); } // AboutSource ----------------------------------------------------------------- diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index aef62de..15906f9 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -168,11 +168,10 @@ struct LazyDirectoryListerCacher { l10n_util::GetString(IDS_DIRECTORY_LISTING_SIZE)); value.SetString(L"headerDateModified", l10n_util::GetString(IDS_DIRECTORY_LISTING_DATE_MODIFIED)); - html_data = jstemplate_builder::GetTemplateHtml( + html_data = jstemplate_builder::GetI18nTemplateHtml( ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_DIR_HEADER_HTML), - &value, - "t"); + &value); } std::string html_data; diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index a8b8fa7..218cd07 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -29,7 +29,7 @@ without changes to the corresponding grd file. --> - + diff --git a/chrome/browser/dom_ui/downloads_ui.cc b/chrome/browser/dom_ui/downloads_ui.cc index 60b5a369..aac3a86 100644 --- a/chrome/browser/dom_ui/downloads_ui.cc +++ b/chrome/browser/dom_ui/downloads_ui.cc @@ -99,8 +99,8 @@ void DownloadsUIHTMLSource::StartDataRequest(const std::string& path, static const StringPiece downloads_html( ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_DOWNLOADS_HTML)); - const std::string full_html = jstemplate_builder::GetTemplateHtml( - downloads_html, &localized_strings, "t"); + const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( + downloads_html, &localized_strings); scoped_refptr html_bytes(new RefCountedBytes); html_bytes->data.resize(full_html.size()); diff --git a/chrome/browser/dom_ui/history_ui.cc b/chrome/browser/dom_ui/history_ui.cc index 1e0bd75..62e2e5d 100644 --- a/chrome/browser/dom_ui/history_ui.cc +++ b/chrome/browser/dom_ui/history_ui.cc @@ -81,8 +81,8 @@ void HistoryUIHTMLSource::StartDataRequest(const std::string& path, static const StringPiece history_html( ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_HISTORY_HTML)); - const std::string full_html = jstemplate_builder::GetTemplateHtml( - history_html, &localized_strings, "t"); + const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( + history_html, &localized_strings); scoped_refptr html_bytes(new RefCountedBytes); html_bytes->data.resize(full_html.size()); @@ -99,7 +99,6 @@ void HistoryUIHTMLSource::StartDataRequest(const std::string& path, BrowsingHistoryHandler::BrowsingHistoryHandler() : search_text_(), remover_(NULL) { - } BrowsingHistoryHandler::~BrowsingHistoryHandler() { diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc index 8525e08..3a53b24 100644 --- a/chrome/browser/dom_ui/new_tab_ui.cc +++ b/chrome/browser/dom_ui/new_tab_ui.cc @@ -371,8 +371,11 @@ void NewTabHTMLSource::StartDataRequest(const std::string& path, IDR_NEW_NEW_TAB_HTML); } - const std::string full_html = jstemplate_builder::GetTemplateHtml( - new_tab_html, &localized_strings, "t" /* template root node id */); + std::string full_html(new_tab_html.data(), new_tab_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 html_bytes(new RefCountedBytes); html_bytes->data.resize(full_html.size()); @@ -442,8 +445,8 @@ void IncognitoTabHTMLSource::StartDataRequest(const std::string& path, ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_INCOGNITO_TAB_HTML)); - const std::string full_html = jstemplate_builder::GetTemplateHtml( - incognito_tab_html, &localized_strings, "t" /* template root node id */); + const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( + incognito_tab_html, &localized_strings); scoped_refptr html_bytes(new RefCountedBytes); html_bytes->data.resize(full_html.size()); diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index 62fb559..ffd2d04 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -46,8 +46,11 @@ void ExtensionsUIHTMLSource::StartDataRequest(const std::string& path, static const StringPiece extensions_html( ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_EXTENSIONS_UI_HTML)); - const std::string full_html = jstemplate_builder::GetTemplateHtml( - extensions_html, &localized_strings, "root"); + std::string full_html(extensions_html.data(), extensions_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 html_bytes(new RefCountedBytes); html_bytes->data.resize(full_html.size()); @@ -63,7 +66,7 @@ void ExtensionsUIHTMLSource::StartDataRequest(const std::string& path, /////////////////////////////////////////////////////////////////////////////// ExtensionsDOMHandler::ExtensionsDOMHandler( - ExtensionsService* extension_service) + ExtensionsService* extension_service) : extensions_service_(extension_service) { } diff --git a/chrome/browser/resources/about_version.html b/chrome/browser/resources/about_version.html index 7216c48..6a8489f 100644 --- a/chrome/browser/resources/about_version.html +++ b/chrome/browser/resources/about_version.html @@ -6,7 +6,7 @@ about:version template page - + - +
diff --git a/chrome/browser/resources/i18n_template.js b/chrome/browser/resources/i18n_template.js new file mode 100644 index 0000000..7a367f7 --- /dev/null +++ b/chrome/browser/resources/i18n_template.js @@ -0,0 +1,91 @@ +/** + * @fileoverview This is a simple template engine inspired by JsTemplates + * optimized for i18n. + * + * It currently supports two handlers: + * + * * i18n-content which sets the textContent of the element + * + * + * i18nTemplate.process(element, {'myContent': 'Content'}); + * + * * i18n-values is a list of attribute-value or property-value pairs. + * Properties are prefixed with a '.' and can contain nested properties. + * + * + * i18nTemplate.process(element, { + * 'myTitle': 'Title', + * 'fontSize': '13px' + * }); + */ + +var i18nTemplate = (function() { + /** + * This provides the handlers for the templating engine. The key is used as + * the attribute name and the value is the function that gets called for every + * single node that has this attribute. + * @type {Object} + */ + var handlers = { + /** + * This handler sets the textContent of the element. + */ + 'i18n-content': function(element, attributeValue, obj) { + element.textContent = obj[attributeValue]; + }, + + /** + * This is used to set HTML attributes and DOM properties,. The syntax is: + * attributename:key; + * .domProperty:key; + * .nested.dom.property:key + */ + 'i18n-values': function(element, attributeValue, obj) { + var parts = attributeValue.replace(/\s/g, '').split(/;/); + for (var j = 0; j < parts.length; j++) { + var a = parts[j].match(/^([^:]+):(.+)$/); + if (a) { + var propName = a[1]; + var propExpr = a[2]; + var value = obj[propExpr]; + if (propName.charAt(0) == '.') { + var path = propName.slice(1).split('.'); + var object = element; + while (object && path.length > 1) { + object = object[path.shift()]; + } + if (object) { + object[path] = value; + } + } else { + element.setAttribute(propName, value); + } + } + } + } + }; + + var attributeNames = []; + for (var key in handlers) { + attributeNames.push(key); + } + var selector = '[' + attributeNames.join('],[') + ']'; + + return { + /** + * Processes a DOM tree with the {@code obj} map. + */ + process: function(node, obj) { + var elements = node.querySelectorAll(selector); + for (var element, i = 0; element = elements[i]; i++) { + for (var j = 0; j < attributeNames.length; j++) { + var name = attributeNames[j]; + var att = element.getAttribute(name); + if (att != null) { + handlers[name](element, att, obj); + } + } + } + } + }; +})(); diff --git a/chrome/browser/resources/incognito_tab.html b/chrome/browser/resources/incognito_tab.html index 9abb85f..064aa32 100644 --- a/chrome/browser/resources/incognito_tab.html +++ b/chrome/browser/resources/incognito_tab.html @@ -1,6 +1,7 @@ - + + - + -
+
- +
diff --git a/chrome/browser/resources/new_new_tab.html b/chrome/browser/resources/new_new_tab.html index 13a06b2..086553f 100644 --- a/chrome/browser/resources/new_new_tab.html +++ b/chrome/browser/resources/new_new_tab.html @@ -1,8 +1,8 @@ - + - + - + - -

+

-

+

diff --git a/chrome/renderer/resources/neterror.html b/chrome/renderer/resources/neterror.html index 4625561..1a2406a 100644 --- a/chrome/renderer/resources/neterror.html +++ b/chrome/renderer/resources/neterror.html @@ -1,9 +1,9 @@ - - + + - +<title i18n-content="title"> - - + -

+

-

+

-

+

  • - +
  • - +
@@ -93,11 +92,11 @@ function toggleDiv(id) {
- +
-

-
+

+
diff --git a/net/base/dir_header.html b/net/base/dir_header.html index ec4eb3a..afdfcf2 100644 --- a/net/base/dir_header.html +++ b/net/base/dir_header.html @@ -1,4 +1,5 @@ - + +