From cf91d62e59661f33eef57b41c31172d7c7279459 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 7 Aug 2025 00:59:20 -0400 Subject: [PATCH] Update citeproc.js to include Juris-M/citeproc-js#256 --- chrome/content/zotero/xpcom/citeproc.js | 58 +++++++++++++++++-------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js index a21c5a2805..9028310767 100644 --- a/chrome/content/zotero/xpcom/citeproc.js +++ b/chrome/content/zotero/xpcom/citeproc.js @@ -1794,31 +1794,53 @@ CSL.XmlJSON.prototype.nodeCopy = function (myjson,clone) { return clone; } -CSL.XmlJSON.prototype.getNodesByName = function (myjson,name,nameattrval,ret) { +CSL.XmlJSON._nodesByNameCaches = new WeakMap(); + +CSL.XmlJSON.prototype.getNodesByName = function (myjson,name,nameattrval) { //print("getNodesByName()"); - var nodes, node, pos, len; - if (!ret) { - var ret = []; - } if (!myjson || !myjson.children) { - return ret; + return []; } - if (name === myjson.name) { - if (nameattrval) { - if (nameattrval === myjson.attrs.name) { - ret.push(myjson); + + let getCache = (myjson) => { + if (CSL.XmlJSON._nodesByNameCaches.has(myjson)) { + return CSL.XmlJSON._nodesByNameCaches.get(myjson); + } + + let cache = new Map(); + CSL.XmlJSON._nodesByNameCaches.set(myjson, cache); + + let name = myjson.name; + if (!cache.has(name)) { + cache.set(name, []); + } + cache.get(name).push(myjson); + + for (let child of myjson.children) { + if (typeof child !== "object") continue; + let childCache = getCache(child); + // Copy cache entries upwards + for (let [cacheKey, nodes] of childCache) { + if (!cache.has(cacheKey)) { + cache.set(cacheKey, []); + } + cache.get(cacheKey).push(...nodes); } - } else { - ret.push(myjson); } + + return cache; + }; + + let cache = getCache(myjson); + let nodes = cache.get(name); + if (!nodes) { + return []; } - for (var i=0,ilen=myjson.children.length;i node.attrs.name === nameattrval); + } else { + return Array.from(nodes); } - return ret; } CSL.XmlJSON.prototype.nodeNameIs = function (myjson,name) {