Bug 1576147 - Use async/await for frame processing in pageInfo. r=frg

This commit is contained in:
Ian Neal 2019-09-15 12:43:47 +02:00
Родитель 500cf705c0
Коммит 45e763ae70
2 изменённых файлов: 77 добавлений и 66 удалений

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

@ -18,6 +18,8 @@ ChromeUtils.defineModuleGetter(this, "LoginFormFactory",
"resource://gre/modules/LoginManagerContent.jsm");
ChromeUtils.defineModuleGetter(this, "PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm");
ChromeUtils.defineModuleGetter(this, "setTimeout",
"resource://gre/modules/Timer.jsm");
ChromeUtils.defineModuleGetter(this, "Feeds",
"resource:///modules/Feeds.jsm");
@ -67,9 +69,6 @@ let PageInfoListener = {
},
receiveMessage: function(message) {
this.imageViewRows = [];
this.linkViewRows = [];
this.formViewRows = [];
let strings = message.data.strings;
let window;
let document;
@ -99,17 +98,6 @@ let PageInfoListener = {
// Separate step so page info dialog isn't blank while waiting for this
// to finish.
this.getMediaInfo(document, window, strings);
// Send the message after all the media elements have been walked through.
let pageInfoMediaData = {imageViewRows: this.imageViewRows,
linkViewRows: this.linkViewRows,
formViewRows: this.formViewRows};
this.imageViewRows = null;
this.linkViewRows = null;
this.formViewRows = null;
sendAsyncMessage("PageInfo:mediaData", pageInfoMediaData);
},
getImageInfo: function(imageElement) {
@ -228,26 +216,40 @@ let PageInfoListener = {
return frameList;
},
processFrames: function(document, frameList, strings)
async processFrames(document, frameList, strings)
{
let nodeCount = 0;
for (let doc of frameList) {
let iterator = doc.createTreeWalker(doc, content.NodeFilter.SHOW_ELEMENT);
// Goes through all the elements on the doc.
while (iterator.nextNode()) {
this.getMediaNode(document, strings, iterator.currentNode);
this.getMediaItems(document, strings, iterator.currentNode);
if (++nodeCount % 500 == 0) {
// setTimeout every 500 elements so we don't keep blocking the
// content process.
await new Promise(resolve => setTimeout(resolve, 10));
}
}
}
// Send that page info media fetching has finished.
sendAsyncMessage("PageInfo:mediaData", {isComplete: true});
},
getMediaNode: function(document, strings, elem)
getMediaItems: function(document, strings, elem)
{
// Check for images defined in CSS (e.g. background, borders),
// any node may have multiple.
// Check for images defined in CSS (e.g. background, borders).
let computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, "");
// A node can have multiple media items associated with it - for example,
// multiple background images.
let imageItems = [];
let formItems = [];
let linkItems = [];
let addImage = (url, type, alt, elem, isBg) => {
let element = this.serializeElementInfo(document, url, type, alt, elem, isBg);
this.imageViewRows.push([url, type, alt, element, isBg]);
imageItems.push([url, type, alt, element, isBg]);
};
if (computedStyle) {
@ -280,13 +282,13 @@ let PageInfoListener = {
let addForm = (elem) => {
let element = this.serializeFormInfo(document, elem, strings);
this.formViewRows.push([elem.name, elem.method, elem.action, element]);
formItems.push([elem.name, elem.method, elem.action, element]);
};
// One swi^H^H^Hif-else to rule them all.
if (elem instanceof content.HTMLAnchorElement) {
this.linkViewRows.push([this.getValueText(elem), elem.href,
strings.linkAnchor, elem.target, elem.accessKey]);
linkItems.push([this.getValueText(elem), elem.href, strings.linkAnchor,
elem.target, elem.accessKey]);
}
else if (elem instanceof content.HTMLImageElement) {
addImage(elem.src, strings.mediaImg,
@ -294,8 +296,7 @@ let PageInfoListener = {
elem, false);
}
else if (elem instanceof content.HTMLAreaElement) {
this.linkViewRows.push([elem.alt, elem.href,
strings.linkArea, elem.target, ""]);
linkItems.push([elem.alt, elem.href, strings.linkArea, elem.target, ""]);
}
else if (elem instanceof content.HTMLVideoElement) {
addImage(elem.currentSrc, strings.mediaVideo, "", elem, false);
@ -310,17 +311,16 @@ let PageInfoListener = {
addImage(elem.href, strings.mediaLink, "", elem, false);
}
else if (/(?:^|\s)stylesheet(?:\s|$)/i.test(rel)) {
this.linkViewRows.push([elem.rel, elem.href,
strings.linkStylesheet, elem.target, ""]);
linkItems.push([elem.rel, elem.href, strings.linkStylesheet,
elem.target, ""]);
}
else {
this.linkViewRows.push([elem.rel, elem.href,
strings.linkRel, elem.target, ""]);
linkItems.push([elem.rel, elem.href, strings.linkRel,
elem.target, ""]);
}
}
else {
this.linkViewRows.push([elem.rev, elem.href,
strings.linkRev, elem.target, ""]);
linkItems.push([elem.rev, elem.href, strings.linkRev, elem.target, ""]);
}
}
else if (elem instanceof content.HTMLInputElement ||
@ -333,15 +333,14 @@ let PageInfoListener = {
// Fall through, <input type="image"> submits, too
case "submit":
if ("form" in elem && elem.form) {
this.linkViewRows.push([elem.value || this.getValueText(elem) ||
strings.linkSubmit, elem.form.action,
strings.linkSubmission,
elem.form.target, ""]);
linkItems.push([elem.value || this.getValueText(elem) ||
strings.linkSubmit, elem.form.action,
strings.linkSubmission, elem.form.target, ""]);
}
else {
this.linkViewRows.push([elem.value || this.getValueText(elem) ||
strings.linkSubmit, "",
strings.linkSubmission, "", ""]);
linkItems.push([elem.value || this.getValueText(elem) ||
strings.linkSubmit, "",
strings.linkSubmission, "", ""]);
}
}
}
@ -361,8 +360,7 @@ let PageInfoListener = {
href = makeURLAbsolute(elem.baseURI, href,
elem.ownerDocument.characterSet);
} catch (e) {}
this.linkViewRows.push([this.getValueText(elem), href, strings.linkX,
"", ""]);
linkItems.push([this.getValueText(elem), href, strings.linkX, "", ""]);
}
else if (elem.hasAttributeNS(XLinkNS, "href")) {
let href = elem.getAttributeNS(XLinkNS, "href");
@ -375,15 +373,17 @@ let PageInfoListener = {
addImage(href, strings.mediaImg, "", elem, false);
}
else {
this.linkViewRows.push([this.getValueText(elem), href, strings.linkX,
"", ""]);
linkItems.push([this.getValueText(elem), href, strings.linkX, "", ""]);
}
}
else if (elem instanceof content.HTMLScriptElement) {
this.linkViewRows.push([elem.type || elem.getAttribute("language") ||
strings.notSet,
elem.src || strings.linkScriptInline,
strings.linkScript, "", "", ""]);
linkItems.push([elem.type || elem.getAttribute("language") ||
strings.notSet, elem.src || strings.linkScriptInline,
strings.linkScript, "", "", ""]);
}
if (imageItems.length || formItems.length || linkItems.length) {
sendAsyncMessage("PageInfo:mediaData",
{imageItems, formItems, linkItems, isComplete: false});
}
},

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

@ -316,7 +316,7 @@ function loadPageInfo(frameOuterWindowID, imageElement, browser)
frameOuterWindowID: frameOuterWindowID},
{ imageElement });
let pageInfoData = null;
let pageInfoData;
// Get initial pageInfoData needed to display the general, feeds, permission
// and security tabs.
@ -347,14 +347,34 @@ function loadPageInfo(frameOuterWindowID, imageElement, browser)
});
// Get the media elements from content script to setup the media tab.
mm.addMessageListener("PageInfo:mediaData", function onmessage(message){
mm.removeMessageListener("PageInfo:mediaData", onmessage);
makeMediaTab(message.data.imageViewRows);
gLinkView.addRows(message.data.linkViewRows);
gFormView.addRows(message.data.formViewRows);
mm.addMessageListener("PageInfo:mediaData", function onmessage(message) {
// Page info window was closed.
if (window.closed) {
mm.removeMessageListener("PageInfo:mediaData", onmessage);
return;
}
// Loop through onFinished and execute the functions on it.
onFinished.forEach(function(func) { func(pageInfoData); });
// The page info media fetching has been completed.
if (message.data.isComplete) {
mm.removeMessageListener("PageInfo:mediaData", onmessage);
onFinished.forEach(function(func) { func(pageInfoData); });
return;
}
if (message.data.imageItems) {
for (let item of message.data.imageItems) {
addImage(item);
}
selectImage();
}
if (message.data.linkItems) {
gLinkView.addRows(message.data.linkItems);
}
if (message.data.formItems) {
gFormView.addRows(message.data.formItems);
}
});
/* Call registered overlay init functions */
@ -525,17 +545,6 @@ function makeGeneralTab(metaViewRows, docInfo)
});
}
function makeMediaTab(imageViewRows)
{
// Call addImage passing in the image rows to add to the view on the
// Media Tab.
for (let image of imageViewRows) {
let [url, type, alt, elem, isBg] = image;
addImage(url, type, alt, elem, isBg);
}
selectImage();
}
function ensureSelection(view)
{
// only select something if nothing is currently selected
@ -544,8 +553,10 @@ function ensureSelection(view)
view.selection.select(0);
}
function addImage(url, type, alt, elem, isBg)
function addImage(imageViewRow)
{
let [url, type, alt, elem, isBg] = imageViewRow;
if (!url)
return;