diff --git a/package-lock.json b/package-lock.json index 0c0c8d2a..8ffd56ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6559,6 +6559,16 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=" + }, + "lodash.uniqueid": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.uniqueid/-/lodash.uniqueid-4.0.1.tgz", + "integrity": "sha1-MmjyanyI5PSxdY1nknGBTjH6WyY=" + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", diff --git a/package.json b/package.json index 837e4a8f..e9c633e4 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ "dependencies": { "deepmerge": "^2.2.1", "lodash.isplainobject": "^4.0.6", + "lodash.uniqby": "^4.7.0", + "lodash.uniqueid": "^4.0.1", "object-assign": "^4.1.1" }, "devDependencies": { diff --git a/src/shared/getComponentOption.js b/src/shared/getComponentOption.js index 1df2c0eb..82ce6a29 100644 --- a/src/shared/getComponentOption.js +++ b/src/shared/getComponentOption.js @@ -1,4 +1,6 @@ import deepmerge from 'deepmerge' +import uniqBy from 'lodash.uniqby' +import uniqueId from 'lodash.uniqueid' /** * Returns the `opts.option` $option value of the given `opts.component`. @@ -15,7 +17,7 @@ import deepmerge from 'deepmerge' * @return {Object} result - final aggregated result */ export default function getComponentOption (opts, result = {}) { - const { component, option, deep, arrayMerge, metaTemplateKeyName, contentKeyName } = opts + const { component, option, deep, arrayMerge, metaTemplateKeyName, tagIDKeyName, contentKeyName } = opts const { $options } = component if (component._inactive) return result @@ -64,6 +66,10 @@ export default function getComponentOption (opts, result = {}) { return metaObject }) + result.meta = uniqBy( + result.meta.reverse(), + metaObject => metaObject.hasOwnProperty(tagIDKeyName) ? metaObject[tagIDKeyName] : uniqueId() + ) } return result } diff --git a/src/shared/getMetaInfo.js b/src/shared/getMetaInfo.js index 0c1b7415..0e3786e7 100644 --- a/src/shared/getMetaInfo.js +++ b/src/shared/getMetaInfo.js @@ -53,6 +53,7 @@ export default function _getMetaInfo (options = {}) { option: keyName, deep: true, metaTemplateKeyName, + tagIDKeyName, contentKeyName, arrayMerge (target, source) { // we concat the arrays without merging objects contained in, diff --git a/test/getMetaInfo.spec.js b/test/getMetaInfo.spec.js index e72ab33c..87627c17 100644 --- a/test/getMetaInfo.spec.js +++ b/test/getMetaInfo.spec.js @@ -75,6 +75,47 @@ describe('getMetaInfo', () => { __dangerouslyDisableSanitizersByTagID: {} }) }) + it('removes duplicate metaInfo in same component', () => { + component = new Vue({ + metaInfo: { + title: 'Hello', + meta: [ + { + vmid: 'a', + property: 'a', + content: 'a' + }, + { + vmid: 'a', + property: 'a', + content: 'b' + } + ] + } + }) + expect(getMetaInfo(component)).to.eql({ + title: 'Hello', + titleChunk: 'Hello', + titleTemplate: '%s', + htmlAttrs: {}, + headAttrs: {}, + bodyAttrs: {}, + meta: [ + { + vmid: 'a', + property: 'a', + content: 'b' + } + ], + base: [], + link: [], + style: [], + script: [], + noscript: [], + __dangerouslyDisableSanitizers: [], + __dangerouslyDisableSanitizersByTagID: {} + }) + }) it('properly uses string titleTemplates', () => { component = new Vue({