diff --git a/lib/core.js b/lib/core.js index e54548399..94ae22480 100644 --- a/lib/core.js +++ b/lib/core.js @@ -3,7 +3,8 @@ import * as pluginUtils from './loader/utils.js'; import * as utils from './utils.js'; import log from '../logging.js'; - import * as oembedUtils from './oembed.js'; + import { getOembed } from './oembed.js'; + import * as oembedUtils from './plugins/system/oembed/oembedUtils.js'; import * as pluginLoader from './loader/pluginLoader.js'; import requestWrapper from './request.js'; import { cache } from './cache.js'; @@ -22,14 +23,16 @@ templates = pluginLoader._templates, PLUGIN_METHODS = pluginUtils.PLUGIN_METHODS; + // Keys must be synced with `lib/loader/utils.js: DEFAULT_PARAMS`. const utilsModules = { - utils: utils, - htmlUtils: htmlUtils, - metaUtils: metaUtils, + utils, + htmlUtils, + metaUtils, + oembedUtils, plugins: pluginsModules, prepareLinkMedia: mediaPlugin.prepareLink, - log: log, - cache: cache + log, + cache }; /* @@ -944,19 +947,65 @@ for(var key in r.data) { var v = r.data[key]; + // TODO: work with arrays? if (v !== '' && v !== null && ((typeof v === 'string' && !/^\s+$/.test(v)) || typeof v === 'number' || typeof v === 'object')) { // Check meta plugins order. allResults.vars._sources = allResults.vars._sources || {}; - var prevOrder = null, nextOrder = null, pluginId = allResults.vars._sources[key]; + var prevOrder = null, nextOrder = null, prevPluginId = allResults.vars._sources[key]; - if (pluginId && plugins[pluginId] && plugins[r.method.pluginId]) { - prevOrder = plugins[pluginId].order; + if (prevPluginId && plugins[prevPluginId] && plugins[r.method.pluginId]) { + prevOrder = plugins[prevPluginId].order; nextOrder = plugins[r.method.pluginId].order; } - if (!prevOrder || !nextOrder || prevOrder < nextOrder) { + var oldValue = allResults.vars[key]; + + var newValueOverrides = !prevOrder || !nextOrder || prevOrder < nextOrder; + + if (typeof v === 'object' && typeof oldValue === 'object' || Array.isArray(oldValue)) { + + var isArrayMode = Array.isArray(v) || Array.isArray(oldValue); + + if (isArrayMode) { + // Join arrays mode. + if (!Array.isArray(v)) { + v = [v]; + } + if (!Array.isArray(oldValue)) { + oldValue = [oldValue]; + } + + // Keep order by priority. + if (newValueOverrides) { + allResults.vars[key] = oldValue.concat(v); + } else { + allResults.vars[key] = v.concat(oldValue); + } + + allResults.vars[key] = utils.filterSameObjects(allResults.vars[key]); + + } else { + // Merge object mode. + if (newValueOverrides) { + // Extend existing object. + Object.assign(oldValue, v); + } else { + // Extend with old values on top. + allResults.vars[key] = Object.assign(v, oldValue); + } + } + + if (!Array.isArray(allResults.vars._sources[key])) { + // Convert sources list to array. + allResults.vars._sources[key] = [allResults.vars._sources[key]]; + } + allResults.vars._sources[key].push(r.method.pluginId); + + } else if (newValueOverrides) { + + // Assign new non object value. allResults.vars[key] = v; allResults.vars._sources[key] = r.method.pluginId; } @@ -2028,6 +2077,4 @@ }, cb); }; - var getOembed = oembedUtils.getOembed; - export { getOembed }; diff --git a/lib/loader/pluginLoader.js b/lib/loader/pluginLoader.js index 55bf9473d..e9b7b807c 100644 --- a/lib/loader/pluginLoader.js +++ b/lib/loader/pluginLoader.js @@ -269,6 +269,23 @@ return; } + // Log custom plugin attributes. + // for(var plugin_key in plugin) { + // if (PLUGINS_FIELDS.indexOf(plugin_key) === -1 + // && PLUGIN_METHODS.indexOf(plugin_key) === -1 + // && ['provides', + // 'listed', + // 'tests', + // 're', + // 'notPlugin', + // 'highestPriority', + // 'lowestPriority', + // 'startIteration', + // 'finishIteration'].indexOf(plugin_key) === -1) { + // console.log('--- unknown plugin attr', getFileName(bits[bits.length - 1]), plugin_key) + // } + // } + // Check post plugin. // TODO: only prapereLink method abailable. // TODO: exclude prapereLink method from other plugins. diff --git a/lib/loader/utils.js b/lib/loader/utils.js index cb78392dd..d6decc3e7 100644 --- a/lib/loader/utils.js +++ b/lib/loader/utils.js @@ -11,7 +11,9 @@ "utils", "htmlUtils", "metaUtils", + "oembedUtils", "plugins", + "prepareLinkMedia", "log", "cache" ]; diff --git a/lib/plugins/system/oembed/autoDiscovery.js b/lib/plugins/system/oembed/autoDiscovery.js index 050963729..062a802aa 100644 --- a/lib/plugins/system/oembed/autoDiscovery.js +++ b/lib/plugins/system/oembed/autoDiscovery.js @@ -1,4 +1,3 @@ -import * as oembedUtils from './oembedUtils.js'; const RE = CONFIG.IGNORE_DOMAINS_RE || CONFIG.BLACKLIST_DOMAINS_RE; export default { @@ -9,7 +8,7 @@ export default { * "__" two underscores means super mandatory param. Without that param plugin dependencies will not be searched. * * */ - getData: function(meta, __noOembedLinks) { + getData: function(meta, oembedUtils, __noOembedLinks) { var oembedLinks = oembedUtils.findOembedLinks(null, meta); @@ -31,4 +30,4 @@ export default { } } -}; \ No newline at end of file +}; diff --git a/lib/plugins/system/oembed/knownEndpoints.js b/lib/plugins/system/oembed/knownEndpoints.js index b767eca7c..f083b1da8 100644 --- a/lib/plugins/system/oembed/knownEndpoints.js +++ b/lib/plugins/system/oembed/knownEndpoints.js @@ -1,14 +1,12 @@ -import * as oembedUtils from './oembedUtils.js'; - export default { provides: ['oembedLinks', '__noOembedLinks'], - getData: function(url) { + getData: function(url, oembedUtils) { var oembedLinks = oembedUtils.findOembedLinks(url); return { oembedLinks: oembedLinks, __noOembedLinks: !oembedLinks || !oembedLinks.length || null // null - means value not in context. }; } -}; \ No newline at end of file +}; diff --git a/lib/plugins/system/oembed/oembed.js b/lib/plugins/system/oembed/oembed.js index cde1d04e1..6e7d6c1ff 100644 --- a/lib/plugins/system/oembed/oembed.js +++ b/lib/plugins/system/oembed/oembed.js @@ -1,4 +1,3 @@ -import * as oembedUtils from './oembedUtils.js'; import * as cheerio from 'cheerio'; import * as entities from 'entities'; @@ -113,7 +112,7 @@ export default { getIframe: _getOembedIframe, // available via export for fallbacks as plugins['oembed'].getIframe(obj) - getData: function(url, oembedLinks, options, cb) { + getData: function(url, oembedLinks, oembedUtils, options, cb) { var href = oembedLinks[0].href; diff --git a/lib/utils.js b/lib/utils.js index f76657331..94098c49a 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1496,3 +1496,14 @@ export function isBlocked(url, options, cb) { } }); } + +export function filterSameObjects(array) { + const seen = new Set(); + return array.filter(obj => { + // Generate JSON with sorted keys. + const key = JSON.stringify(Object.fromEntries(Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)))); + if (seen.has(key)) return false; + seen.add(key); + return true; + }); +} diff --git a/plugins/meta/noindex-robots.js b/plugins/meta/noindex-robots.js index 523662922..b72cf735e 100644 --- a/plugins/meta/noindex-robots.js +++ b/plugins/meta/noindex-robots.js @@ -1,8 +1,6 @@ -import * as oembedUtils from '../../lib/plugins/system/oembed/oembedUtils.js'; - export default { - getData: function(url, meta, __noOembedLinks, options, cb) { + getData: function(url, meta, oembedUtils, __noOembedLinks, options, cb) { return cb( meta.robots @@ -19,4 +17,4 @@ export default { } : null); } -}; \ No newline at end of file +};