From 4efc0af1199ce63e318ccd47ab03f720495b0326 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 11 Sep 2020 02:27:05 -0400 Subject: [PATCH] Translator sandbox: Update attr()/text() and add innerText() - Remove TODO comment to add a warning if a Document is passed, since a document will always be required when operating on something other than the main page (e.g., for multiples). - Always return a string instead of null. A translator can always use querySelector() if it really needs to know if a node exists. - Automatically trim the returned string - Add innerText() function that uses .innerText instead of .textContent, since there are situations where that might be helpful. Some of those we currently address with trimInternal(), but there can be other cases where .innerText gives cleaner, user-centric output. Translators won't be able to rely on these changes for a while, so we'll need to be careful to watch for problems here, or translators will need to include a v3 polyfill. Addresses zotero/translators#1913 --- .../zotero/xpcom/translation/translate.js | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js index 71db9dfea8..ed3893690e 100644 --- a/chrome/content/zotero/xpcom/translation/translate.js +++ b/chrome/content/zotero/xpcom/translation/translate.js @@ -1851,11 +1851,14 @@ Zotero.Translate.Base.prototype = { if (this.type == 'web') { this._sandboxManager.sandbox.attr = this._attr.bind(this); this._sandboxManager.sandbox.text = this._text.bind(this); + this._sandboxManager.sandbox.innerText = this._innerText.bind(this); } }, /** * Helper function to extract HTML attribute text + * + * Text is automatically trimmed */ _attr: function (selector, attr, index) { if (typeof arguments[0] == 'string') { @@ -1863,18 +1866,18 @@ Zotero.Translate.Base.prototype = { } // Document or element passed as first argument else { - // TODO: Warn if Document rather than Element is passed once we drop 4.0 translator - // support [docOrElem, selector, attr, index] = arguments; } var elem = index ? docOrElem.querySelectorAll(selector).item(index) : docOrElem.querySelector(selector); - return elem ? elem.getAttribute(attr) : null; + return (elem ? elem.getAttribute(attr) : "").trim(); }, /** * Helper function to extract HTML element text + * + * Text is extracted using textContent and is automatically trimmed */ _text: function (selector, index) { if (typeof arguments[0] == 'string') { @@ -1882,14 +1885,32 @@ Zotero.Translate.Base.prototype = { } // Document or element passed as first argument else { - // TODO: Warn if Document rather than Element is passed once we drop 4.0 translator - // support [docOrElem, selector, index] = arguments; } var elem = index ? docOrElem.querySelectorAll(selector).item(index) : docOrElem.querySelector(selector); - return elem ? elem.textContent : null; + return (elem ? elem.textContent : "").trim(); + }, + + /** + * Helper function to extract rendered HTML element text + * + * Text is extracted using innerText, not textContent, so it reflects the rendered content, and + * is automatically trimmed + */ + _innerText: function (selector, index) { + if (typeof arguments[0] == 'string') { + var docOrElem = this.document; + } + // Document or element passed as first argument + else { + [docOrElem, selector, index] = arguments; + } + var elem = index + ? docOrElem.querySelectorAll(selector).item(index) + : docOrElem.querySelector(selector); + return (elem ? elem.innerText : "").trim(); }, /**