Bug 1642731: Turn excessive calls to document.l10n.formatValue to a single document.l10n.formatValues call. r=Gijs

Rather than sending the strings down to the content process and back up instead
have the content process just send the media type which when prefixed with
`media-` gives us the fluent ID for the string. Ideally this would allow us to
just set that as the `data-l10n-id` for the items but since this tree is
generated by a custom `nsITreeView` implementation that isn't an option so this
still caches the strings on load.

A single formatValues call will be more performant.

Differential Revision: https://phabricator.services.mozilla.com/D77897
This commit is contained in:
Dave Townsend 2020-06-26 19:17:17 +00:00
Родитель 3a5412ba07
Коммит 2d4a0f50de
2 изменённых файлов: 78 добавлений и 79 удалений

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

@ -16,8 +16,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
class PageInfoChild extends JSWindowActorChild {
async receiveMessage(message) {
let strings = message.data.strings;
let window = this.contentWindow;
let document = window.document;
@ -33,7 +31,7 @@ class PageInfoChild extends JSWindowActorChild {
}
case "PageInfo:getMediaData": {
return Promise.resolve({
mediaItems: await this.getDocumentMedia(document, strings),
mediaItems: await this.getDocumentMedia(document),
});
}
}
@ -109,7 +107,7 @@ class PageInfoChild extends JSWindowActorChild {
* Calls getMediaItems for all nodes within the constructed tree walker and forms
* resulting array.
*/
async getDocumentMedia(document, strings) {
async getDocumentMedia(document) {
let nodeCount = 0;
let content = document.ownerGlobal;
let iterator = document.createTreeWalker(
@ -120,11 +118,7 @@ class PageInfoChild extends JSWindowActorChild {
let totalMediaItems = [];
while (iterator.nextNode()) {
let mediaItems = this.getMediaItems(
document,
strings,
iterator.currentNode
);
let mediaItems = this.getMediaItems(document, iterator.currentNode);
if (++nodeCount % 500 == 0) {
// setTimeout every 500 elements so we don't keep blocking the content process.
@ -136,7 +130,7 @@ class PageInfoChild extends JSWindowActorChild {
return totalMediaItems;
}
getMediaItems(document, strings, elem) {
getMediaItems(document, elem) {
// Check for images defined in CSS (e.g. background, borders)
let computedStyle = elem.ownerGlobal.getComputedStyle(elem);
// A node can have multiple media items associated with it - for example,
@ -144,22 +138,22 @@ class PageInfoChild extends JSWindowActorChild {
let mediaItems = [];
let content = document.ownerGlobal;
let addImage = (url, type, alt, el, isBg) => {
let element = this.serializeElementInfo(
document,
let addMedia = (url, type, alt, el, isBg, altNotProvided = false) => {
let element = this.serializeElementInfo(document, url, el, isBg);
mediaItems.push({
url,
type,
alt,
el,
isBg
);
mediaItems.push([url, type, alt, element, isBg]);
altNotProvided,
element,
isBg,
});
};
if (computedStyle) {
let addImgFunc = (label, urls) => {
let addImgFunc = (type, urls) => {
for (let url of urls) {
addImage(url, label, strings.notSet, elem, true);
addMedia(url, type, "", elem, true, true);
}
};
// FIXME: This is missing properties. See the implementation of
@ -167,29 +161,24 @@ class PageInfoChild extends JSWindowActorChild {
//
// If you don't care about the message you can also pass "all" here and
// get all the ones the browser knows about.
addImgFunc("bg-img", computedStyle.getCSSImageURLs("background-image"));
addImgFunc(
strings.mediaBGImg,
computedStyle.getCSSImageURLs("background-image")
);
addImgFunc(
strings.mediaBorderImg,
"border-img",
computedStyle.getCSSImageURLs("border-image-source")
);
addImgFunc(
strings.mediaListImg,
computedStyle.getCSSImageURLs("list-style-image")
);
addImgFunc(strings.mediaCursor, computedStyle.getCSSImageURLs("cursor"));
addImgFunc("list-img", computedStyle.getCSSImageURLs("list-style-image"));
addImgFunc("cursor", computedStyle.getCSSImageURLs("cursor"));
}
// One swi^H^H^Hif-else to rule them all.
if (elem instanceof content.HTMLImageElement) {
addImage(
addMedia(
elem.src,
strings.mediaImg,
elem.hasAttribute("alt") ? elem.alt : strings.notSet,
"img",
elem.getAttribute("alt"),
elem,
false
false,
!elem.hasAttribute("alt")
);
} else if (elem instanceof content.SVGImageElement) {
try {
@ -201,40 +190,35 @@ class PageInfoChild extends JSWindowActorChild {
null,
Services.io.newURI(elem.baseURI)
).spec;
addImage(href, strings.mediaImg, "", elem, false);
addMedia(href, "img", "", elem, false);
}
} catch (e) {}
} else if (elem instanceof content.HTMLVideoElement) {
addImage(elem.currentSrc, strings.mediaVideo, "", elem, false);
addMedia(elem.currentSrc, "video", "", elem, false);
} else if (elem instanceof content.HTMLAudioElement) {
addImage(elem.currentSrc, strings.mediaAudio, "", elem, false);
addMedia(elem.currentSrc, "audio", "", elem, false);
} else if (elem instanceof content.HTMLLinkElement) {
if (elem.rel && /\bicon\b/i.test(elem.rel)) {
addImage(elem.href, strings.mediaLink, "", elem, false);
addMedia(elem.href, "link", "", elem, false);
}
} else if (
elem instanceof content.HTMLInputElement ||
elem instanceof content.HTMLButtonElement
) {
if (elem.type.toLowerCase() == "image") {
addImage(
addMedia(
elem.src,
strings.mediaInput,
elem.hasAttribute("alt") ? elem.alt : strings.notSet,
"input",
elem.getAttribute("alt"),
elem,
false
false,
!elem.hasAttribute("alt")
);
}
} else if (elem instanceof content.HTMLObjectElement) {
addImage(
elem.data,
strings.mediaObject,
this.getValueText(elem),
elem,
false
);
addMedia(elem.data, "object", this.getValueText(elem), elem, false);
} else if (elem instanceof content.HTMLEmbedElement) {
addImage(elem.src, strings.mediaEmbed, "", elem, false);
addMedia(elem.src, "embed", "", elem, false);
}
return mediaItems;
@ -245,7 +229,7 @@ class PageInfoChild extends JSWindowActorChild {
* makePreview in pageInfo.js uses to figure out how to display the preview.
*/
serializeElementInfo(document, url, type, alt, item, isBG) {
serializeElementInfo(document, url, item, isBG) {
let result = {};
let content = document.ownerGlobal;

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

@ -245,9 +245,9 @@ gImageView.onPageMediaSort = function(columnname) {
var gImageHash = {};
// localized strings (will be filled in when the document is loaded)
// this isn't all of them, these are just the ones that would otherwise have been loaded inside a loop
var gStrings = {};
var gBundle;
const MEDIA_STRINGS = {};
let SIZE_UNKNOWN = "";
let ALT_NOT_SET = "";
// a number of services I'll need later
// the cache services
@ -288,19 +288,35 @@ const gClipboardHelper = getClipboardHelper();
* - initialTab: (optional) id of the inital tab to display
*/
async function onLoadPageInfo() {
gStrings.unknown = await document.l10n.formatValue("image-size-unknown");
gStrings.notSet = await document.l10n.formatValue("not-set-alternative-text");
gStrings.mediaImg = await document.l10n.formatValue("media-img");
gStrings.mediaBGImg = await document.l10n.formatValue("media-bg-img");
gStrings.mediaBorderImg = await document.l10n.formatValue("media-border-img");
gStrings.mediaListImg = await document.l10n.formatValue("media-list-img");
gStrings.mediaCursor = await document.l10n.formatValue("media-cursor");
gStrings.mediaObject = await document.l10n.formatValue("media-object");
gStrings.mediaEmbed = await document.l10n.formatValue("media-embed");
gStrings.mediaLink = await document.l10n.formatValue("media-link");
gStrings.mediaInput = await document.l10n.formatValue("media-input");
gStrings.mediaVideo = await document.l10n.formatValue("media-video");
gStrings.mediaAudio = await document.l10n.formatValue("media-audio");
[
SIZE_UNKNOWN,
ALT_NOT_SET,
MEDIA_STRINGS.img,
MEDIA_STRINGS["bg-img"],
MEDIA_STRINGS["border-img"],
MEDIA_STRINGS["list-img"],
MEDIA_STRINGS.cursor,
MEDIA_STRINGS.object,
MEDIA_STRINGS.embed,
MEDIA_STRINGS.link,
MEDIA_STRINGS.input,
MEDIA_STRINGS.video,
MEDIA_STRINGS.audio,
] = await document.l10n.formatValues([
"image-size-unknown",
"not-set-alternative-text",
"media-img",
"media-bg-img",
"media-border-img",
"media-list-img",
"media-cursor",
"media-object",
"media-embed",
"media-link",
"media-input",
"media-video",
"media-audio",
]);
const args =
"arguments" in window &&
@ -328,9 +344,7 @@ async function loadPageInfo(browsingContext, imageElement, browser) {
let actor = browsingContext.currentWindowGlobal.getActor("PageInfo");
let result = await actor.sendQuery("PageInfo:getData", {
strings: gStrings,
});
let result = await actor.sendQuery("PageInfo:getData");
await onNonMediaPageInfoLoad(browser, result, imageElement);
// Here, we are walking the frame tree via BrowsingContexts to collect all of the
@ -345,9 +359,7 @@ async function loadPageInfo(browsingContext, imageElement, browser) {
}
let subframeActor = global.getActor("PageInfo");
let mediaResult = await subframeActor.sendQuery("PageInfo:getMediaData", {
strings: gStrings,
});
let mediaResult = await subframeActor.sendQuery("PageInfo:getMediaData");
for (let item of mediaResult.mediaItems) {
addImage(item);
}
@ -538,12 +550,15 @@ async function makeGeneralTab(metaViewRows, docInfo) {
});
}
async function addImage(imageViewRow) {
let [url, type, alt, elem, isBg] = imageViewRow;
async function addImage({ url, type, alt, altNotProvided, element, isBg }) {
if (!url) {
return;
}
if (altNotProvided) {
alt = ALT_NOT_SET;
}
if (!gImageHash.hasOwnProperty(url)) {
gImageHash[url] = {};
}
@ -552,7 +567,7 @@ async function addImage(imageViewRow) {
}
if (!gImageHash[url][type].hasOwnProperty(alt)) {
gImageHash[url][type][alt] = gImageView.data.length;
var row = [url, type, gStrings.unknown, alt, 1, elem, isBg];
var row = [url, MEDIA_STRINGS[type], SIZE_UNKNOWN, alt, 1, element, isBg];
gImageView.addRow(row);
// Fill in cache data asynchronously
@ -587,11 +602,11 @@ async function addImage(imageViewRow) {
!gImageView.data[i][COL_IMAGE_BG] &&
gImageElement &&
url == gImageElement.currentSrc &&
gImageElement.width == elem.width &&
gImageElement.height == elem.height &&
gImageElement.imageText == elem.imageText
gImageElement.width == element.width &&
gImageElement.height == element.height &&
gImageElement.imageText == element.imageText
) {
gImageView.data[i][COL_IMAGE_NODE] = elem;
gImageView.data[i][COL_IMAGE_NODE] = element;
}
}
}