Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1001)

Unified Diff: ui/webui/resources/js/i18n_template_no_process.js

Issue 1233883005: Fix i18nTemplate.process() for DocumentFragments. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: stronger typing Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/webui/resources/css/i18n_process.css ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/webui/resources/js/i18n_template_no_process.js
diff --git a/ui/webui/resources/js/i18n_template_no_process.js b/ui/webui/resources/js/i18n_template_no_process.js
index 18f7cb775eac418fa0b1e00b4f4e562520b21471..a1cb47a2007f41900824f10a981f43bc3598f4c4 100644
--- a/ui/webui/resources/js/i18n_template_no_process.js
+++ b/ui/webui/resources/js/i18n_template_no_process.js
@@ -38,27 +38,27 @@ var i18nTemplate = (function() {
var handlers = {
/**
* This handler sets the textContent of the element.
- * @param {HTMLElement} element The node to modify.
- * @param {string} key The name of the value in the dictionary.
- * @param {LoadTimeData} dictionary The dictionary of strings to draw from.
+ * @param {!HTMLElement} element The node to modify.
+ * @param {string} key The name of the value in |data|.
+ * @param {!LoadTimeData} data The data source to draw from.
* @param {!Array<ProcessingRoot>} visited
*/
- 'i18n-content': function(element, key, dictionary, visited) {
- element.textContent = dictionary.getString(key);
+ 'i18n-content': function(element, key, data, visited) {
+ element.textContent = data.getString(key);
},
/**
* This handler adds options to a <select> element.
- * @param {HTMLElement} select The node to modify.
- * @param {string} key The name of the value in the dictionary. It should
+ * @param {!HTMLElement} select The node to modify.
+ * @param {string} key The name of the value in |data|. It should
* identify an array of values to initialize an <option>. Each value,
* if a pair, represents [content, value]. Otherwise, it should be a
* content string with no value.
- * @param {LoadTimeData} dictionary The dictionary of strings to draw from.
+ * @param {!LoadTimeData} data The data source to draw from.
* @param {!Array<ProcessingRoot>} visited
*/
- 'i18n-options': function(select, key, dictionary, visited) {
- var options = dictionary.getValue(key);
+ 'i18n-options': function(select, key, data, visited) {
+ var options = data.getValue(key);
options.forEach(function(optionData) {
var option = typeof optionData == 'string' ?
new Option(optionData) :
@@ -72,14 +72,14 @@ var i18nTemplate = (function() {
* attributename:key;
* .domProperty:key;
* .nested.dom.property:key
- * @param {HTMLElement} element The node to modify.
+ * @param {!HTMLElement} element The node to modify.
* @param {string} attributeAndKeys The path of the attribute to modify
- * followed by a colon, and the name of the value in the dictionary.
+ * followed by a colon, and the name of the value in |data|.
* Multiple attribute/key pairs may be separated by semicolons.
- * @param {LoadTimeData} dictionary The dictionary of strings to draw from.
+ * @param {!LoadTimeData} data The data source to draw from.
* @param {!Array<ProcessingRoot>} visited
*/
- 'i18n-values': function(element, attributeAndKeys, dictionary, visited) {
+ 'i18n-values': function(element, attributeAndKeys, data, visited) {
var parts = attributeAndKeys.replace(/\s/g, '').split(/;/);
parts.forEach(function(part) {
if (!part)
@@ -92,7 +92,7 @@ var i18nTemplate = (function() {
var propName = attributeAndKeyPair[1];
var propExpr = attributeAndKeyPair[2];
- var value = dictionary.getValue(propExpr);
+ var value = data.getValue(propExpr);
// Allow a property of the form '.foo.bar' to assign a value into
// element.foo.bar.
@@ -107,9 +107,8 @@ var i18nTemplate = (function() {
// In case we set innerHTML (ignoring others) we need to recursively
// check the content.
if (path == 'innerHTML') {
- for (var temp = element.firstElementChild; temp;
- temp = temp.nextElementSibling) {
- processWithoutCycles(temp, dictionary, visited);
+ for (var i = 0; i < element.children.length; ++i) {
+ processWithoutCycles(element.children[i], data, visited, false);
}
}
}
@@ -120,28 +119,35 @@ var i18nTemplate = (function() {
}
};
+ var prefixes = [''];
+
+ // Only look through shadow DOM when it's supported. As of April 2015, iOS
+ // Chrome doesn't support shadow DOM.
+ if (Element.prototype.createShadowRoot)
+ prefixes.push('::shadow ');
+
var attributeNames = Object.keys(handlers);
- // Only use /deep/ when shadow DOM is supported. As of April 2015 iOS Chrome
- // doesn't support shadow DOM.
- var prefix = Element.prototype.createShadowRoot ? ':root /deep/ ' : '';
- var selector = prefix + '[' + attributeNames.join('],' + prefix + '[') + ']';
+ var selector = prefixes.map(function(prefix) {
+ return prefix + '[' + attributeNames.join('], ' + prefix + '[') + ']';
+ }).join(', ');
/**
- * Processes a DOM tree with the {@code dictionary} map.
- * @param {ProcessingRoot} root The root of the DOM tree to process.
- * @param {LoadTimeData} dictionary The dictionary to draw from.
+ * Processes a DOM tree using a |data| source to populate template values.
+ * @param {!ProcessingRoot} root The root of the DOM tree to process.
+ * @param {!LoadTimeData} data The data to draw from.
*/
- function process(root, dictionary) {
- processWithoutCycles(root, dictionary, []);
+ function process(root, data) {
+ processWithoutCycles(root, data, [], true);
}
/**
* Internal process() method that stops cycles while processing.
- * @param {ProcessingRoot} root
- * @param {LoadTimeData} dictionary
+ * @param {!ProcessingRoot} root
+ * @param {!LoadTimeData} data
* @param {!Array<ProcessingRoot>} visited Already visited roots.
+ * @param {boolean} mark Whether nodes should be marked processed.
*/
- function processWithoutCycles(root, dictionary, visited) {
+ function processWithoutCycles(root, data, visited, mark) {
if (visited.indexOf(root) >= 0) {
// Found a cycle. Stop it.
return;
@@ -158,47 +164,44 @@ var i18nTemplate = (function() {
// TODO(dbeam): should we log an error if we detect that here?
continue;
}
- processWithoutCycles(importLink.import, dictionary, visited);
+ processWithoutCycles(importLink.import, data, visited, mark);
}
var templates = root.querySelectorAll('template');
for (var i = 0; i < templates.length; ++i) {
var template = /** @type {HTMLTemplateElement} */(templates[i]);
- processWithoutCycles(template.content, dictionary, visited);
+ processWithoutCycles(template.content, data, visited, mark);
}
- var firstElement = root instanceof Element ? root : root.querySelector('*');
-
- if (prefix) {
- // Prefixes skip root level elements. This is typically <html> but can
- // differ inside of DocumentFragments (i.e. <template>s). Process them
- // explicitly.
- for (var temp = firstElement; temp; temp = temp.nextElementSibling) {
- processElement(/** @type {Element} */(temp), dictionary, visited);
- }
- }
+ var isElement = root instanceof Element;
+ if (isElement && root.matches(selector))
+ processElement(/** @type {!Element} */(root), data, visited);
var elements = root.querySelectorAll(selector);
- for (var element, i = 0; element = elements[i]; i++) {
- processElement(element, dictionary, visited);
+ for (var i = 0; i < elements.length; ++i) {
+ processElement(elements[i], data, visited);
}
- if (firstElement)
- firstElement.setAttribute('i18n-processed', '');
+ if (mark) {
+ var processed = isElement ? [root] : root.children;
+ for (var i = 0; i < processed.length; ++i) {
+ processed[i].setAttribute('i18n-processed', '');
+ }
+ }
}
/**
- * Run through various [i18n-*] attributes and do activate replacements.
- * @param {Element} element
- * @param {LoadTimeData} dictionary
+ * Run through various [i18n-*] attributes and populate.
+ * @param {!Element} element
+ * @param {!LoadTimeData} data
* @param {!Array<ProcessingRoot>} visited
*/
- function processElement(element, dictionary, visited) {
+ function processElement(element, data, visited) {
for (var i = 0; i < attributeNames.length; i++) {
var name = attributeNames[i];
var attribute = element.getAttribute(name);
if (attribute != null)
- handlers[name](element, attribute, dictionary, visited);
+ handlers[name](element, attribute, data, visited);
}
}
« no previous file with comments | « ui/webui/resources/css/i18n_process.css ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698