Bug 1400626 - Metadata not saved when opening multiple pages. r=ursula

MozReview-Commit-ID: 3am9OptKj4z

--HG--
extra : rebase_source : a65c2e77bbbee11b1f86273d1c485b79751bad76
This commit is contained in:
Ed Lee 2017-09-16 18:05:29 -07:00
Родитель ca76254683
Коммит 2ccefc0859
5 изменённых файлов: 81 добавлений и 32 удалений

Просмотреть файл

@ -1,4 +1,5 @@
[DEFAULT]
support-files =
head.js
meta_tags.html
[browser_meta_tags.js]

Просмотреть файл

@ -2,29 +2,47 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* globals gBrowser */
/* This tests that with the page meta_tags.html, ContentMetaHandler.jsm parses out
* the meta tags avilable and only stores the best one for description and one for
* preview image url. In the case of this test, the best defined meta tags are
* "og:description" and "og:image:url". The list of meta tags and their order of
* preference is found in ContentMetaHandler.jsm. Because there is debounce logic
* in ContentLinkHandler.jsm to only make one single SQL update, we have to wait
* for some time before checking that the page info was stored correctly.
*/
add_task(async function test() {
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
const URL = "https://example.com/browser/browser/base/content/test/metaTags/meta_tags.html";
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
const URL = "https://example.com/browser/browser/base/content/test/metaTags/meta_tags.html";
// Wait until places has stored the page info
let pageInfo;
await BrowserTestUtils.waitForCondition(async () => {
pageInfo = await PlacesUtils.history.fetch(URL, {"includeMeta": true});
const {previewImageURL, description} = pageInfo;
return previewImageURL && description;
});
is(pageInfo.description, "og:description", "got the correct description");
is(pageInfo.previewImageURL.href, "og:image:url", "got the correct preview image");
await BrowserTestUtils.removeTab(tab);
/**
* This tests that with the page meta_tags.html, ContentMetaHandler.jsm parses
* out the meta tags avilable and only stores the best one for description and
* one for preview image url. In the case of this test, the best defined meta
* tags are "og:description" and "og:image:secure_url". The list of meta tags
* and order of preference is found in ContentMetaHandler.jsm. Because there is
* debounce logic in ContentLinkHandler.jsm to only make one single SQL update,
* we have to wait for some time before checking that the page info was stored.
*/
add_task(async function test_metadata() {
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
// Wait until places has stored the page info
const pageInfo = await waitForPageInfo(URL);
is(pageInfo.description, "og:description", "got the correct description");
is(pageInfo.previewImageURL.href, "og:image:secure_url", "got the correct preview image");
await BrowserTestUtils.removeTab(tab);
await PlacesTestUtils.clearHistory();
});
/**
* This test is almost like the previous one except it opens a second tab to
* make sure the extra tab does not cause the debounce logic to be skipped. If
* incorrectly skipped, the updated metadata would not include the delayed meta.
*/
add_task(async function multiple_tabs() {
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
// Add a background tab to cause another page to load *without* putting the
// desired URL in a background tab, which results in its timers being throttled.
gBrowser.addTab();
// Wait until places has stored the page info
const pageInfo = await waitForPageInfo(URL);
is(pageInfo.description, "og:description", "got the correct description");
is(pageInfo.previewImageURL.href, "og:image:secure_url", "got the correct preview image");
await BrowserTestUtils.removeTab(tab);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
await PlacesTestUtils.clearHistory();
});

Просмотреть файл

@ -0,0 +1,18 @@
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
/**
* Wait for url's page info (non-null description and preview url) to be set.
*/
async function waitForPageInfo(url) {
let pageInfo;
await BrowserTestUtils.waitForCondition(async () => {
pageInfo = await PlacesUtils.history.fetch(url, {"includeMeta": true});
return pageInfo && pageInfo.description && pageInfo.previewImageURL;
});
return pageInfo;
}

Просмотреть файл

@ -13,6 +13,18 @@
<meta name="thumbnail" content="thumbnail" />
</head>
<body>
<script>
function addMeta(tag) {
const meta = document.createElement("meta");
meta.content = tag;
meta.setAttribute("property", tag);
document.head.appendChild(meta);
}
// Delay adding this "best" image tag to test that later tags are used.
// Use a delay that is long enough for tests to check for wrong metadata.
setTimeout(() => addMeta("og:image:secure_url"), 100);
</script>
</body>
</html>

Просмотреть файл

@ -54,6 +54,9 @@ this.EXPORTED_SYMBOLS = [ "ContentMetaHandler" ];
this.ContentMetaHandler = {
init(chromeGlobal) {
// Store a locally-scoped (for this chromeGlobal) mapping of the best
// description and preview image collected so far for a given URL
const metaTags = new Map();
chromeGlobal.addEventListener("DOMMetaAdded", event => {
const metaTag = event.originalTarget;
const window = metaTag.ownerGlobal;
@ -62,15 +65,12 @@ this.ContentMetaHandler = {
if (!metaTag || !metaTag.ownerDocument || window != window.top) {
return;
}
this.handleMetaTag(metaTag, chromeGlobal);
this.handleMetaTag(metaTag, chromeGlobal, metaTags);
});
// Stores a mapping of the best description and preview image collected so far
// for a given URL
this._metaTags = new Map();
},
handleMetaTag(metaTag, chromeGlobal) {
handleMetaTag(metaTag, chromeGlobal, metaTags) {
const url = metaTag.ownerDocument.documentURI;
let name = metaTag.name;
@ -81,7 +81,7 @@ this.ContentMetaHandler = {
let tag = name || prop;
const entry = this._metaTags.get(url) || {
const entry = metaTags.get(url) || {
description: {value: null, currMaxScore: -1},
image: {value: null, currMaxScore: -1},
timeout: null
@ -106,8 +106,8 @@ this.ContentMetaHandler = {
return;
}
if (!this._metaTags.has(url)) {
this._metaTags.set(url, entry);
if (!metaTags.has(url)) {
metaTags.set(url, entry);
}
if (entry.timeout) {
@ -125,7 +125,7 @@ this.ContentMetaHandler = {
description: entry.description.value,
previewImageURL: entry.image.value
});
this._metaTags.delete(url);
metaTags.delete(url);
}, TIMEOUT_DELAY, Ci.nsITimer.TYPE_ONE_SHOT);
}
}