| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview This is a simple template engine inspired by JsTemplates | 6 * @fileoverview This is a simple template engine inspired by JsTemplates |
| 7 * optimized for i18n. | 7 * optimized for i18n. |
| 8 * | 8 * |
| 9 * It currently supports three handlers: | 9 * It currently supports three handlers: |
| 10 * | 10 * |
| 11 * * i18n-content which sets the textContent of the element. | 11 * * i18n-content which sets the textContent of the element. |
| 12 * | 12 * |
| 13 * <span i18n-content="myContent"></span> | 13 * <span i18n-content="myContent"></span> |
| 14 * | 14 * |
| 15 * * i18n-options which generates <option> elements for a <select>. | 15 * * i18n-options which generates <option> elements for a <select>. |
| 16 * | 16 * |
| 17 * <select i18n-options="myOptionList"></select> | 17 * <select i18n-options="myOptionList"></select> |
| 18 * | 18 * |
| 19 * * i18n-values is a list of attribute-value or property-value pairs. | 19 * * i18n-values is a list of attribute-value or property-value pairs. |
| 20 * Properties are prefixed with a '.' and can contain nested properties. | 20 * Properties are prefixed with a '.' and can contain nested properties. |
| 21 * | 21 * |
| 22 * <span i18n-values="title:myTitle;.style.fontSize:fontSize"></span> | 22 * <span i18n-values="title:myTitle;.style.fontSize:fontSize"></span> |
| 23 * | 23 * |
| 24 * This file is a copy of i18n_template.js, with minor tweaks to support using | 24 * This file is a copy of i18n_template.js, with minor tweaks to support using |
| 25 * load_time_data.js. It should replace i18n_template.js eventually. | 25 * load_time_data.js. It should replace i18n_template.js eventually. |
| 26 */ | 26 */ |
| 27 | 27 |
| 28 var i18nTemplate = (function() { | 28 var i18nTemplate = (function() { |
| 29 'use strict'; | |
| 30 /** | 29 /** |
| 31 * This provides the handlers for the templating engine. The key is used as | 30 * This provides the handlers for the templating engine. The key is used as |
| 32 * the attribute name and the value is the function that gets called for every | 31 * the attribute name and the value is the function that gets called for every |
| 33 * single node that has this attribute. | 32 * single node that has this attribute. |
| 34 * @type {!Object} | 33 * @type {!Object} |
| 35 */ | 34 */ |
| 36 var handlers = { | 35 var handlers = { |
| 37 /** | 36 /** |
| 38 * This handler sets the textContent of the element. | 37 * This handler sets the textContent of the element. |
| 39 * @param {HTMLElement} element The node to modify. | 38 * @param {HTMLElement} element The node to modify. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 process(element, dictionary); | 104 process(element, dictionary); |
| 106 } | 105 } |
| 107 } else { | 106 } else { |
| 108 element.setAttribute(propName, /** @type {string} */(value)); | 107 element.setAttribute(propName, /** @type {string} */(value)); |
| 109 } | 108 } |
| 110 }); | 109 }); |
| 111 } | 110 } |
| 112 }; | 111 }; |
| 113 | 112 |
| 114 var attributeNames = Object.keys(handlers); | 113 var attributeNames = Object.keys(handlers); |
| 115 var selector = '[' + attributeNames.join('],[') + ']'; | 114 // Chrome for iOS must use Apple's UIWebView, which (as of April 2015) does |
| 115 // not have native shadow DOM support. If shadow DOM is supported (or |
| 116 // polyfilled), search for i18n attributes using the /deep/ selector; |
| 117 // otherwise, do not attempt to search within the shadow DOM. |
| 118 var selector = |
| 119 (window.document.body && window.document.body.createShadowRoot) ? |
| 120 'html /deep/ [' + attributeNames.join('],[') + ']' : |
| 121 '[' + attributeNames.join('],[') + ']'; |
| 116 | 122 |
| 117 /** | 123 /** |
| 118 * Processes a DOM tree with the {@code dictionary} map. | 124 * Processes a DOM tree with the {@code dictionary} map. |
| 119 * @param {Document|DocumentFragment|Element} root The root of the DOM tree to | 125 * @param {Document|Element} root The root of the DOM tree to process. |
| 120 * process. | |
| 121 * @param {LoadTimeData} dictionary The dictionary to draw from. | 126 * @param {LoadTimeData} dictionary The dictionary to draw from. |
| 122 */ | 127 */ |
| 123 function process(root, dictionary) { | 128 function process(root, dictionary) { |
| 124 var importLinks = root.querySelectorAll('link[rel=import]'); | |
| 125 for (var i = 0; i < importLinks.length; ++i) { | |
| 126 var importLink = /** @type {!HTMLLinkElement} */(importLinks[i]); | |
| 127 if (!importLink.import) { | |
| 128 // Happens when a <link rel=import> is inside a <template>. | |
| 129 // TODO(dbeam): should we log an error if we detect that here? | |
| 130 continue; | |
| 131 } | |
| 132 process(importLink.import, dictionary); | |
| 133 } | |
| 134 | |
| 135 var templates = root.querySelectorAll('template'); | |
| 136 for (var i = 0; i < templates.length; ++i) { | |
| 137 var template = /** @type {HTMLTemplateElement} */(templates[i]); | |
| 138 process(template.content, dictionary); | |
| 139 } | |
| 140 | |
| 141 var elements = root.querySelectorAll(selector); | 129 var elements = root.querySelectorAll(selector); |
| 142 for (var element, i = 0; element = elements[i]; i++) { | 130 for (var element, i = 0; element = elements[i]; i++) { |
| 143 for (var j = 0; j < attributeNames.length; j++) { | 131 for (var j = 0; j < attributeNames.length; j++) { |
| 144 var name = attributeNames[j]; | 132 var name = attributeNames[j]; |
| 145 var attribute = element.getAttribute(name); | 133 var attribute = element.getAttribute(name); |
| 146 if (attribute != null) | 134 if (attribute != null) |
| 147 handlers[name](element, attribute, dictionary); | 135 handlers[name](element, attribute, dictionary); |
| 148 } | 136 } |
| 149 } | 137 } |
| 150 | |
| 151 var doc = root instanceof Document ? root : root.ownerDocument; | 138 var doc = root instanceof Document ? root : root.ownerDocument; |
| 152 if (doc && doc.documentElement) | 139 if (doc) |
| 153 doc.documentElement.classList.add('i18n-processed'); | 140 doc.documentElement.classList.add('i18n-processed'); |
| 154 } | 141 } |
| 155 | 142 |
| 156 return { | 143 return { |
| 157 process: process | 144 process: process |
| 158 }; | 145 }; |
| 159 }()); | 146 }()); |
| OLD | NEW |