mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1040947 - Opening page info from a remote tab is sluggish. r=florian
This commit is contained in:
parent
23e59a8b07
commit
48054a7edd
@ -2411,8 +2411,10 @@ function BrowserViewSource(browser) {
|
||||
// doc - document to use for source, or null for this window's document
|
||||
// initialTab - name of the initial tab to display, or null for the first tab
|
||||
// imageElement - image to load in the Media Tab of the Page Info window; can be null/omitted
|
||||
function BrowserPageInfo(doc, initialTab, imageElement) {
|
||||
var args = {doc: doc, initialTab: initialTab, imageElement: imageElement};
|
||||
// frameOuterWindowID - the id of the frame that the context menu opened in; can be null/omitted
|
||||
function BrowserPageInfo(doc, initialTab, imageElement, frameOuterWindowID) {
|
||||
var args = {doc: doc, initialTab: initialTab, imageElement: imageElement,
|
||||
frameOuterWindowID: frameOuterWindowID};
|
||||
var windows = Services.wm.getEnumerator("Browser:page-info");
|
||||
|
||||
var documentURL = doc ? doc.location : window.gBrowser.selectedBrowser.contentDocumentAsCPOW.location;
|
||||
|
@ -39,6 +39,8 @@ XPCOMUtils.defineLazyGetter(this, "PageMenuChild", function() {
|
||||
return new tmp.PageMenuChild();
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Feeds", "resource:///modules/Feeds.jsm");
|
||||
|
||||
// TabChildGlobal
|
||||
var global = this;
|
||||
|
||||
@ -840,3 +842,396 @@ addMessageListener("ContextMenu:SetAsDesktopBackground", (message) => {
|
||||
if (disable)
|
||||
sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result", { disable });
|
||||
});
|
||||
|
||||
let pageInfoListener = {
|
||||
|
||||
init: function(chromeGlobal) {
|
||||
chromeGlobal.addMessageListener("PageInfo:getData", this, false, true);
|
||||
},
|
||||
|
||||
receiveMessage: function(message) {
|
||||
this.imageViewRows = [];
|
||||
this.frameList = [];
|
||||
this.strings = message.data.strings;
|
||||
|
||||
let frameOuterWindowID = message.data.frameOuterWindowID;
|
||||
|
||||
// If inside frame then get the frame's window and document.
|
||||
if (frameOuterWindowID) {
|
||||
this.window = Services.wm.getOuterWindowWithId(frameOuterWindowID);
|
||||
this.document = this.window.document;
|
||||
}
|
||||
else {
|
||||
this.document = content.document;
|
||||
this.window = content.window;
|
||||
}
|
||||
|
||||
let pageInfoData = {metaViewRows: this.getMetaInfo(), docInfo: this.getDocumentInfo(),
|
||||
feeds: this.getFeedsInfo(), windowInfo: this.getWindowInfo()};
|
||||
sendAsyncMessage("PageInfo:data", pageInfoData);
|
||||
|
||||
// Separate step so page info dialog isn't blank while waiting for this to finish.
|
||||
this.getMediaInfo();
|
||||
|
||||
// Send the message after all the media elements have been walked through.
|
||||
let pageInfoMediaData = {imageViewRows: this.imageViewRows};
|
||||
|
||||
this.imageViewRows = null;
|
||||
this.frameList = null;
|
||||
this.strings = null;
|
||||
this.window = null;
|
||||
this.document = null;
|
||||
|
||||
sendAsyncMessage("PageInfo:mediaData", pageInfoMediaData);
|
||||
},
|
||||
|
||||
getMetaInfo: function() {
|
||||
let metaViewRows = [];
|
||||
|
||||
// Get the meta tags from the page.
|
||||
let metaNodes = this.document.getElementsByTagName("meta");
|
||||
|
||||
for (let metaNode of metaNodes) {
|
||||
metaViewRows.push([metaNode.name || metaNode.httpEquiv || metaNode.getAttribute("property"),
|
||||
metaNode.content]);
|
||||
}
|
||||
|
||||
return metaViewRows;
|
||||
},
|
||||
|
||||
getWindowInfo: function() {
|
||||
let windowInfo = {};
|
||||
windowInfo.isTopWindow = this.window == this.window.top;
|
||||
|
||||
let hostName = null;
|
||||
try {
|
||||
hostName = this.window.location.host;
|
||||
}
|
||||
catch (exception) { }
|
||||
|
||||
windowInfo.hostName = hostName;
|
||||
return windowInfo;
|
||||
},
|
||||
|
||||
getDocumentInfo: function() {
|
||||
let docInfo = {};
|
||||
docInfo.title = this.document.title;
|
||||
docInfo.location = this.document.location.toString();
|
||||
docInfo.referrer = this.document.referrer;
|
||||
docInfo.compatMode = this.document.compatMode;
|
||||
docInfo.contentType = this.document.contentType;
|
||||
docInfo.characterSet = this.document.characterSet;
|
||||
docInfo.lastModified = this.document.lastModified;
|
||||
|
||||
let documentURIObject = {};
|
||||
documentURIObject.spec = this.document.documentURIObject.spec;
|
||||
documentURIObject.originCharset = this.document.documentURIObject.originCharset;
|
||||
docInfo.documentURIObject = documentURIObject;
|
||||
|
||||
docInfo.isContentWindowPrivate = PrivateBrowsingUtils.isContentWindowPrivate(content);
|
||||
|
||||
return docInfo;
|
||||
},
|
||||
|
||||
getFeedsInfo: function() {
|
||||
let feeds = [];
|
||||
// Get the feeds from the page.
|
||||
let linkNodes = this.document.getElementsByTagName("link");
|
||||
let length = linkNodes.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
let link = linkNodes[i];
|
||||
if (!link.href) {
|
||||
continue;
|
||||
}
|
||||
let rel = link.rel && link.rel.toLowerCase();
|
||||
let rels = {};
|
||||
|
||||
if (rel) {
|
||||
for each (let relVal in rel.split(/\s+/)) {
|
||||
rels[relVal] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rels.feed || (link.type && rels.alternate && !rels.stylesheet)) {
|
||||
let type = Feeds.isValidFeed(link, this.document.nodePrincipal, "feed" in rels);
|
||||
if (type) {
|
||||
type = this.strings[type] || this.strings["application/rss+xml"];
|
||||
feeds.push([link.title, type, link.href]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return feeds;
|
||||
},
|
||||
|
||||
// Only called once to get the media tab's media elements from the content page.
|
||||
// The actual work is done with a TreeWalker that calls doGrab() once for
|
||||
// each element node in the document.
|
||||
getMediaInfo: function()
|
||||
{
|
||||
this.goThroughFrames(this.document, this.window);
|
||||
this.processFrames();
|
||||
},
|
||||
|
||||
goThroughFrames: function(aDocument, aWindow)
|
||||
{
|
||||
this.frameList.push(aDocument);
|
||||
if (aWindow && aWindow.frames.length > 0) {
|
||||
let num = aWindow.frames.length;
|
||||
for (let i = 0; i < num; i++) {
|
||||
this.goThroughFrames(aWindow.frames[i].document, aWindow.frames[i]); // recurse through the frames
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
processFrames: function()
|
||||
{
|
||||
if (this.frameList.length) {
|
||||
let doc = this.frameList[0];
|
||||
let iterator = doc.createTreeWalker(doc, content.NodeFilter.SHOW_ELEMENT, elem => this.grabAll(elem));
|
||||
this.frameList.shift();
|
||||
this.doGrab(iterator);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function's previous purpose in pageInfo.js was to get loop through 500 elements at a time.
|
||||
* The iterator filter will filter for media elements.
|
||||
* #TODO Bug 1175794: refactor pageInfo.js to receive a media element at a time
|
||||
* from messages and continually update UI.
|
||||
*/
|
||||
doGrab: function(iterator)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!iterator.nextNode()) {
|
||||
this.processFrames();
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
grabAll: function(elem)
|
||||
{
|
||||
// Check for images defined in CSS (e.g. background, borders), any node may have multiple.
|
||||
let computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, "");
|
||||
|
||||
let addImage = (url, type, alt, elem, isBg) => {
|
||||
let element = this.serializeElementInfo(url, type, alt, elem, isBg);
|
||||
this.imageViewRows.push([url, type, alt, element, isBg]);
|
||||
};
|
||||
|
||||
if (computedStyle) {
|
||||
let addImgFunc = (label, val) => {
|
||||
if (val.primitiveType == content.CSSPrimitiveValue.CSS_URI) {
|
||||
addImage(val.getStringValue(), label, this.strings.notSet, elem, true);
|
||||
}
|
||||
else if (val.primitiveType == content.CSSPrimitiveValue.CSS_STRING) {
|
||||
// This is for -moz-image-rect.
|
||||
// TODO: Reimplement once bug 714757 is fixed.
|
||||
let strVal = val.getStringValue();
|
||||
if (strVal.search(/^.*url\(\"?/) > -1) {
|
||||
let url = strVal.replace(/^.*url\(\"?/,"").replace(/\"?\).*$/,"");
|
||||
addImage(url, label, this.strings.notSet, elem, true);
|
||||
}
|
||||
}
|
||||
else if (val.cssValueType == content.CSSValue.CSS_VALUE_LIST) {
|
||||
// Recursively resolve multiple nested CSS value lists.
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
addImgFunc(label, val.item(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addImgFunc(this.strings.mediaBGImg, computedStyle.getPropertyCSSValue("background-image"));
|
||||
addImgFunc(this.strings.mediaBorderImg, computedStyle.getPropertyCSSValue("border-image-source"));
|
||||
addImgFunc(this.strings.mediaListImg, computedStyle.getPropertyCSSValue("list-style-image"));
|
||||
addImgFunc(this.strings.mediaCursor, computedStyle.getPropertyCSSValue("cursor"));
|
||||
}
|
||||
|
||||
// One swi^H^H^Hif-else to rule them all.
|
||||
if (elem instanceof content.HTMLImageElement) {
|
||||
addImage(elem.src, this.strings.mediaImg,
|
||||
(elem.hasAttribute("alt")) ? elem.alt : this.strings.notSet, elem, false);
|
||||
}
|
||||
else if (elem instanceof content.SVGImageElement) {
|
||||
try {
|
||||
// Note: makeURLAbsolute will throw if either the baseURI is not a valid URI
|
||||
// or the URI formed from the baseURI and the URL is not a valid URI.
|
||||
let href = makeURLAbsolute(elem.baseURI, elem.href.baseVal);
|
||||
addImage(href, this.strings.mediaImg, "", elem, false);
|
||||
} catch (e) { }
|
||||
}
|
||||
else if (elem instanceof content.HTMLVideoElement) {
|
||||
addImage(elem.currentSrc, this.strings.mediaVideo, "", elem, false);
|
||||
}
|
||||
else if (elem instanceof content.HTMLAudioElement) {
|
||||
addImage(elem.currentSrc, this.strings.mediaAudio, "", elem, false);
|
||||
}
|
||||
else if (elem instanceof content.HTMLLinkElement) {
|
||||
if (elem.rel && /\bicon\b/i.test(elem.rel)) {
|
||||
addImage(elem.href, this.strings.mediaLink, "", elem, false);
|
||||
}
|
||||
}
|
||||
else if (elem instanceof content.HTMLInputElement || elem instanceof content.HTMLButtonElement) {
|
||||
if (elem.type.toLowerCase() == "image") {
|
||||
addImage(elem.src, this.strings.mediaInput,
|
||||
(elem.hasAttribute("alt")) ? elem.alt : this.strings.notSet, elem, false);
|
||||
}
|
||||
}
|
||||
else if (elem instanceof content.HTMLObjectElement) {
|
||||
addImage(elem.data, this.strings.mediaObject, this.getValueText(elem), elem, false);
|
||||
}
|
||||
else if (elem instanceof content.HTMLEmbedElement) {
|
||||
addImage(elem.src, this.strings.mediaEmbed, "", elem, false);
|
||||
}
|
||||
|
||||
return content.NodeFilter.FILTER_ACCEPT;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up a JSON element object with all the instanceOf and other infomation that
|
||||
* makePreview in pageInfo.js uses to figure out how to display the preview.
|
||||
*/
|
||||
|
||||
serializeElementInfo: function(url, type, alt, item, isBG)
|
||||
{
|
||||
// Interface for image loading content.
|
||||
const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent;
|
||||
|
||||
let result = {};
|
||||
|
||||
let imageText;
|
||||
if (!isBG &&
|
||||
!(item instanceof content.SVGImageElement) &&
|
||||
!(this.document instanceof content.ImageDocument)) {
|
||||
imageText = item.title || item.alt;
|
||||
|
||||
if (!imageText && !(item instanceof content.HTMLImageElement)) {
|
||||
imageText = this.getValueText(item);
|
||||
}
|
||||
}
|
||||
|
||||
result.imageText = imageText;
|
||||
result.longDesc = item.longDesc;
|
||||
result.numFrames = 1;
|
||||
|
||||
if (item instanceof content.HTMLObjectElement ||
|
||||
item instanceof content.HTMLEmbedElement ||
|
||||
item instanceof content.HTMLLinkElement) {
|
||||
result.mimeType = item.type;
|
||||
}
|
||||
|
||||
if (!result.mimeType && !isBG && item instanceof nsIImageLoadingContent) {
|
||||
// Interface for image loading content.
|
||||
const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent;
|
||||
let imageRequest = item.getRequest(nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
if (imageRequest) {
|
||||
result.mimeType = imageRequest.mimeType;
|
||||
let image = !(imageRequest.imageStatus & imageRequest.STATUS_ERROR) && imageRequest.image;
|
||||
if (image) {
|
||||
result.numFrames = image.numFrames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we have a data url, get the MIME type from the url
|
||||
if (!result.mimeType && url.startsWith("data:")) {
|
||||
let dataMimeType = /^data:(image\/[^;,]+)/i.exec(url);
|
||||
if (dataMimeType)
|
||||
result.mimeType = dataMimeType[1].toLowerCase();
|
||||
}
|
||||
|
||||
result.HTMLLinkElement = item instanceof content.HTMLLinkElement;
|
||||
result.HTMLInputElement = item instanceof content.HTMLInputElement;
|
||||
result.HTMLImageElement = item instanceof content.HTMLImageElement;
|
||||
result.HTMLObjectElement = item instanceof content.HTMLObjectElement;
|
||||
result.SVGImageElement = item instanceof content.SVGImageElement;
|
||||
result.HTMLVideoElement = item instanceof content.HTMLVideoElement;
|
||||
result.HTMLAudioElement = item instanceof content.HTMLAudioElement;
|
||||
|
||||
if (!isBG) {
|
||||
result.width = item.width;
|
||||
result.height = item.height;
|
||||
}
|
||||
|
||||
if (item instanceof content.SVGImageElement) {
|
||||
result.SVGImageElementWidth = item.width.baseVal.value;
|
||||
result.SVGImageElementHeight = item.height.baseVal.value;
|
||||
}
|
||||
|
||||
result.baseURI = item.baseURI;
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
//******** Other Misc Stuff
|
||||
// Modified from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html
|
||||
// parse a node to extract the contents of the node
|
||||
getValueText: function(node)
|
||||
{
|
||||
|
||||
let valueText = "";
|
||||
|
||||
// Form input elements don't generally contain information that is useful to our callers, so return nothing.
|
||||
if (node instanceof content.HTMLInputElement ||
|
||||
node instanceof content.HTMLSelectElement ||
|
||||
node instanceof content.HTMLTextAreaElement) {
|
||||
return valueText;
|
||||
}
|
||||
|
||||
// Otherwise recurse for each child.
|
||||
let length = node.childNodes.length;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
let childNode = node.childNodes[i];
|
||||
let nodeType = childNode.nodeType;
|
||||
|
||||
// Text nodes are where the goods are.
|
||||
if (nodeType == content.Node.TEXT_NODE) {
|
||||
valueText += " " + childNode.nodeValue;
|
||||
}
|
||||
// And elements can have more text inside them.
|
||||
else if (nodeType == content.Node.ELEMENT_NODE) {
|
||||
// Images are special, we want to capture the alt text as if the image weren't there.
|
||||
if (childNode instanceof content.HTMLImageElement) {
|
||||
valueText += " " + this.getAltText(childNode);
|
||||
}
|
||||
else {
|
||||
valueText += " " + this.getValueText(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.stripWS(valueText);
|
||||
},
|
||||
|
||||
// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html.
|
||||
// Traverse the tree in search of an img or area element and grab its alt tag.
|
||||
getAltText: function(node)
|
||||
{
|
||||
let altText = "";
|
||||
|
||||
if (node.alt) {
|
||||
return node.alt;
|
||||
}
|
||||
let length = node.childNodes.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
if ((altText = this.getAltText(node.childNodes[i]) != undefined)) { // stupid js warning...
|
||||
return altText;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html.
|
||||
// Strip leading and trailing whitespace, and replace multiple consecutive whitespace characters with a single space.
|
||||
stripWS: function(text)
|
||||
{
|
||||
let middleRE = /\s+/g;
|
||||
let endRE = /(^\s+)|(\s+$)/g;
|
||||
|
||||
text = text.replace(middleRE, " ");
|
||||
return text.replace(endRE, "");
|
||||
}
|
||||
};
|
||||
pageInfoListener.init(this);
|
@ -1051,7 +1051,8 @@ nsContextMenu.prototype = {
|
||||
},
|
||||
|
||||
viewFrameInfo: function() {
|
||||
BrowserPageInfo(this.target.ownerDocument);
|
||||
BrowserPageInfo(this.target.ownerDocument, null, null,
|
||||
this.frameOuterWindowID);
|
||||
},
|
||||
|
||||
reloadImage: function() {
|
||||
|
@ -3,41 +3,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Feeds",
|
||||
"resource:///modules/Feeds.jsm");
|
||||
|
||||
function initFeedTab()
|
||||
function initFeedTab(feeds)
|
||||
{
|
||||
const feedTypes = {
|
||||
"application/rss+xml": gBundle.getString("feedRss"),
|
||||
"application/atom+xml": gBundle.getString("feedAtom"),
|
||||
"text/xml": gBundle.getString("feedXML"),
|
||||
"application/xml": gBundle.getString("feedXML"),
|
||||
"application/rdf+xml": gBundle.getString("feedXML")
|
||||
};
|
||||
|
||||
// get the feeds
|
||||
var linkNodes = gDocument.getElementsByTagName("link");
|
||||
var length = linkNodes.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var link = linkNodes[i];
|
||||
if (!link.href)
|
||||
continue;
|
||||
|
||||
var rel = link.rel && link.rel.toLowerCase();
|
||||
var rels = {};
|
||||
if (rel) {
|
||||
for each (let relVal in rel.split(/\s+/))
|
||||
rels[relVal] = true;
|
||||
}
|
||||
|
||||
if (rels.feed || (link.type && rels.alternate && !rels.stylesheet)) {
|
||||
var type = Feeds.isValidFeed(link, gDocument.nodePrincipal, "feed" in rels);
|
||||
if (type) {
|
||||
type = feedTypes[type] || feedTypes["application/rss+xml"];
|
||||
addRow(link.title, type, link.href);
|
||||
}
|
||||
}
|
||||
for (let feed of feeds) {
|
||||
let [name, type, url] = feed;
|
||||
addRow(name, type, url);
|
||||
}
|
||||
|
||||
var feedListbox = document.getElementById("feedListbox");
|
||||
|
@ -52,8 +52,19 @@ pageInfoTreeView.prototype = {
|
||||
{
|
||||
this.rows = this.data.push(row);
|
||||
this.rowCountChanged(this.rows - 1, 1);
|
||||
if (this.selection.count == 0 && this.rowCount && !gImageElement)
|
||||
if (this.selection.count == 0 && this.rowCount && !gImageElement) {
|
||||
this.selection.select(0);
|
||||
}
|
||||
},
|
||||
|
||||
addRows: function(rows)
|
||||
{
|
||||
this.data = this.data.concat(rows);
|
||||
this.rowCountChanged(this.rows, rows.length);
|
||||
this.rows = this.data.length;
|
||||
if (this.selection.count == 0 && this.rowCount && !gImageElement) {
|
||||
this.selection.select(0);
|
||||
}
|
||||
},
|
||||
|
||||
rowCountChanged: function(index, count)
|
||||
@ -140,8 +151,7 @@ pageInfoTreeView.prototype = {
|
||||
};
|
||||
|
||||
// mmm, yummy. global variables.
|
||||
var gWindow = null;
|
||||
var gDocument = null;
|
||||
var gDocInfo = null;
|
||||
var gImageElement = null;
|
||||
|
||||
// column number to help using the data array
|
||||
@ -286,8 +296,7 @@ const XHTMLre = RegExp(XHTMLNSre + "|" + XHTML2NSre, "");
|
||||
* invoked as "XXXLoadFunc();"
|
||||
*/
|
||||
|
||||
// These functions are called to build the data displayed in the Page
|
||||
// Info window. The global variables gDocument and gWindow are set.
|
||||
// These functions are called to build the data displayed in the Page Info window.
|
||||
var onLoadRegistry = [ ];
|
||||
|
||||
// These functions are called to remove old data still displayed in
|
||||
@ -296,14 +305,6 @@ var onLoadRegistry = [ ];
|
||||
// tab is cleared.
|
||||
var onResetRegistry = [ ];
|
||||
|
||||
// These are called once for each subframe of the target document and
|
||||
// the target document itself. The frame is passed as an argument.
|
||||
var onProcessFrame = [ ];
|
||||
|
||||
// These functions are called once for each element (in all subframes, if any)
|
||||
// in the target document. The element is passed as an argument.
|
||||
var onProcessElement = [ ];
|
||||
|
||||
// These functions are called once when all the elements in all of the target
|
||||
// document (and all of its subframes, if any) have been processed
|
||||
var onFinished = [ ];
|
||||
@ -311,9 +312,6 @@ var onFinished = [ ];
|
||||
// These functions are called once when the Page Info window is closed.
|
||||
var onUnloadRegistry = [ ];
|
||||
|
||||
// These functions are called once when an image preview is shown.
|
||||
var onImagePreviewShown = [ ];
|
||||
|
||||
/* Called when PageInfo window is loaded. Arguments are:
|
||||
* window.arguments[0] - (optional) an object consisting of
|
||||
* - doc: (optional) document to use for source. if not provided,
|
||||
@ -341,11 +339,6 @@ function onLoadPageInfo()
|
||||
window.arguments.length >= 1 &&
|
||||
window.arguments[0];
|
||||
|
||||
if (!args || !args.doc) {
|
||||
gWindow = window.opener.gBrowser.selectedBrowser.contentWindowAsCPOW;
|
||||
gDocument = gWindow.document;
|
||||
}
|
||||
|
||||
// init media view
|
||||
var imageTree = document.getElementById("imagetree");
|
||||
imageTree.view = gImageView;
|
||||
@ -357,22 +350,52 @@ function onLoadPageInfo()
|
||||
.notifyObservers(window, "page-info-dialog-loaded", null);
|
||||
}
|
||||
|
||||
function loadPageInfo()
|
||||
function loadPageInfo(frameOuterWindowID)
|
||||
{
|
||||
var titleFormat = gWindow != gWindow.top ? "pageInfo.frame.title"
|
||||
: "pageInfo.page.title";
|
||||
document.title = gBundle.getFormattedString(titleFormat, [gDocument.location]);
|
||||
let mm = window.opener.gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
document.getElementById("main-window").setAttribute("relatedUrl", gDocument.location);
|
||||
gStrings["application/rss+xml"] = gBundle.getString("feedRss");
|
||||
gStrings["application/atom+xml"] = gBundle.getString("feedAtom");
|
||||
gStrings["text/xml"] = gBundle.getString("feedXML");
|
||||
gStrings["application/xml"] = gBundle.getString("feedXML");
|
||||
gStrings["application/rdf+xml"] = gBundle.getString("feedXML");
|
||||
|
||||
// do the easy stuff first
|
||||
makeGeneralTab();
|
||||
// Look for pageInfoListener in content.js. Sends message to listener with arguments.
|
||||
mm.sendAsyncMessage("PageInfo:getData", {strings: gStrings,
|
||||
frameOuterWindowID: frameOuterWindowID});
|
||||
|
||||
// and then the hard stuff
|
||||
makeTabs(gDocument, gWindow);
|
||||
let pageInfoData = null;
|
||||
|
||||
initFeedTab();
|
||||
onLoadPermission();
|
||||
// Get initial pageInfoData needed to display the general, feeds, permission and security tabs.
|
||||
mm.addMessageListener("PageInfo:data", function onmessage(message) {
|
||||
mm.removeMessageListener("PageInfo:data", onmessage);
|
||||
pageInfoData = message.data;
|
||||
let docInfo = pageInfoData.docInfo;
|
||||
let windowInfo = pageInfoData.windowInfo;
|
||||
let uri = makeURI(docInfo.documentURIObject.spec,
|
||||
docInfo.documentURIObject.originCharset);
|
||||
gDocInfo = docInfo;
|
||||
|
||||
var titleFormat = windowInfo.isTopWindow ? "pageInfo.frame.title"
|
||||
: "pageInfo.page.title";
|
||||
document.title = gBundle.getFormattedString(titleFormat, [docInfo.location]);
|
||||
|
||||
document.getElementById("main-window").setAttribute("relatedUrl", docInfo.location);
|
||||
|
||||
makeGeneralTab(pageInfoData.metaViewRows, docInfo);
|
||||
initFeedTab(pageInfoData.feeds);
|
||||
onLoadPermission(uri);
|
||||
securityOnLoad(uri, windowInfo);
|
||||
});
|
||||
|
||||
// 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);
|
||||
|
||||
// Loop through onFinished and execute the functions on it.
|
||||
onFinished.forEach(function(func) { func(pageInfoData); });
|
||||
});
|
||||
|
||||
/* Call registered overlay init functions */
|
||||
onLoadRegistry.forEach(function(func) { func(); });
|
||||
@ -443,15 +466,22 @@ function showTab(id)
|
||||
|
||||
function loadTab(args)
|
||||
{
|
||||
if (args && args.doc) {
|
||||
gDocument = args.doc;
|
||||
gWindow = gDocument.defaultView;
|
||||
// If the "View Image Info" context menu item was used, the related image
|
||||
// element is provided as an argument. This can't be a background image.
|
||||
let imageElement = args && args.imageElement;
|
||||
if (imageElement) {
|
||||
gImageElement = {currentSrc: imageElement.currentSrc,
|
||||
width: imageElement.width, height: imageElement.height,
|
||||
imageText: imageElement.title || imageElement.alt};
|
||||
}
|
||||
else {
|
||||
gImageElement = null;
|
||||
}
|
||||
|
||||
gImageElement = args && args.imageElement;
|
||||
let frameOuterWindowID = args && args.frameOuterWindowID;
|
||||
|
||||
/* Load the page info */
|
||||
loadPageInfo();
|
||||
loadPageInfo(frameOuterWindowID);
|
||||
|
||||
var initialTab = (args && args.initialTab) || "generalTab";
|
||||
var radioGroup = document.getElementById("viewGroup");
|
||||
@ -491,31 +521,29 @@ function openCacheEntry(key, cb)
|
||||
diskStorage.asyncOpenURI(Services.io.newURI(key, null, null), "", nsICacheStorage.OPEN_READONLY, checkCacheListener);
|
||||
}
|
||||
|
||||
function makeGeneralTab()
|
||||
function makeGeneralTab(metaViewRows, docInfo)
|
||||
{
|
||||
var title = (gDocument.title) ? gBundle.getFormattedString("pageTitle", [gDocument.title]) : gBundle.getString("noPageTitle");
|
||||
var title = (docInfo.title) ? gBundle.getFormattedString("pageTitle", [docInfo.title]) : gBundle.getString("noPageTitle");
|
||||
document.getElementById("titletext").value = title;
|
||||
|
||||
var url = gDocument.location.toString();
|
||||
var url = docInfo.location;
|
||||
setItemValue("urltext", url);
|
||||
|
||||
var referrer = ("referrer" in gDocument && gDocument.referrer);
|
||||
var referrer = ("referrer" in docInfo && docInfo.referrer);
|
||||
setItemValue("refertext", referrer);
|
||||
|
||||
var mode = ("compatMode" in gDocument && gDocument.compatMode == "BackCompat") ? "generalQuirksMode" : "generalStrictMode";
|
||||
var mode = ("compatMode" in docInfo && docInfo.compatMode == "BackCompat") ? "generalQuirksMode" : "generalStrictMode";
|
||||
document.getElementById("modetext").value = gBundle.getString(mode);
|
||||
|
||||
// find out the mime type
|
||||
var mimeType = gDocument.contentType;
|
||||
var mimeType = docInfo.contentType;
|
||||
setItemValue("typetext", mimeType);
|
||||
|
||||
// get the document characterset
|
||||
var encoding = gDocument.characterSet;
|
||||
var encoding = docInfo.characterSet;
|
||||
document.getElementById("encodingtext").value = encoding;
|
||||
|
||||
// get the meta tags
|
||||
var metaNodes = gDocument.getElementsByTagName("meta");
|
||||
var length = metaNodes.length;
|
||||
let length = metaViewRows.length;
|
||||
|
||||
var metaGroup = document.getElementById("metaTags");
|
||||
if (!length)
|
||||
@ -529,15 +557,14 @@ function makeGeneralTab()
|
||||
var metaTree = document.getElementById("metatree");
|
||||
metaTree.view = gMetaView;
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
gMetaView.addRow([metaNodes[i].name || metaNodes[i].httpEquiv || metaNodes[i].getAttribute("property"),
|
||||
metaNodes[i].content]);
|
||||
// Add the metaViewRows onto the general tab's meta info tree.
|
||||
gMetaView.addRows(metaViewRows);
|
||||
|
||||
metaGroup.collapsed = false;
|
||||
}
|
||||
|
||||
// get the date of last modification
|
||||
var modifiedText = formatDate(gDocument.lastModified, gStrings.notSet);
|
||||
var modifiedText = formatDate(docInfo.lastModified, gStrings.notSet);
|
||||
document.getElementById("modifiedtext").value = modifiedText;
|
||||
|
||||
// get cache info
|
||||
@ -551,57 +578,16 @@ function makeGeneralTab()
|
||||
}
|
||||
setItemValue("sizetext", sizeText);
|
||||
});
|
||||
|
||||
securityOnLoad();
|
||||
}
|
||||
|
||||
//******** Generic Build-a-tab
|
||||
// Assumes the views are empty. Only called once to build the tabs, and
|
||||
// does so by farming the task off to another thread via setTimeout().
|
||||
// The actual work is done with a TreeWalker that calls doGrab() once for
|
||||
// each element node in the document.
|
||||
|
||||
var gFrameList = [ ];
|
||||
|
||||
function makeTabs(aDocument, aWindow)
|
||||
function makeMediaTab(imageViewRows)
|
||||
{
|
||||
goThroughFrames(aDocument, aWindow);
|
||||
processFrames();
|
||||
}
|
||||
|
||||
function goThroughFrames(aDocument, aWindow)
|
||||
{
|
||||
gFrameList.push(aDocument);
|
||||
if (aWindow && aWindow.frames.length > 0) {
|
||||
var num = aWindow.frames.length;
|
||||
for (var i = 0; i < num; i++)
|
||||
goThroughFrames(aWindow.frames[i].document, aWindow.frames[i]); // recurse through the frames
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
function processFrames()
|
||||
{
|
||||
if (gFrameList.length) {
|
||||
var doc = gFrameList[0];
|
||||
onProcessFrame.forEach(function(func) { func(doc); });
|
||||
var iterator = doc.createTreeWalker(doc, NodeFilter.SHOW_ELEMENT, grabAll);
|
||||
gFrameList.shift();
|
||||
setTimeout(doGrab, 10, iterator);
|
||||
onFinished.push(selectImage);
|
||||
}
|
||||
else
|
||||
onFinished.forEach(function(func) { func(); });
|
||||
}
|
||||
|
||||
function doGrab(iterator)
|
||||
{
|
||||
for (var i = 0; i < 500; ++i)
|
||||
if (!iterator.nextNode()) {
|
||||
processFrames();
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(doGrab, 10, iterator);
|
||||
selectImage();
|
||||
}
|
||||
|
||||
function addImage(url, type, alt, elem, isBg)
|
||||
@ -639,80 +625,19 @@ function addImage(url, type, alt, elem, isBg)
|
||||
else {
|
||||
var i = gImageHash[url][type][alt];
|
||||
gImageView.data[i][COL_IMAGE_COUNT]++;
|
||||
if (elem == gImageElement)
|
||||
// The same image can occur several times on the page at different sizes.
|
||||
// If the "View Image Info" context menu item was used, ensure we select
|
||||
// the correct element.
|
||||
if (!gImageView.data[i][COL_IMAGE_BG] &&
|
||||
gImageElement && url == gImageElement.currentSrc &&
|
||||
gImageElement.width == elem.width &&
|
||||
gImageElement.height == elem.height &&
|
||||
gImageElement.imageText == elem.imageText) {
|
||||
gImageView.data[i][COL_IMAGE_NODE] = elem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function grabAll(elem)
|
||||
{
|
||||
// check for images defined in CSS (e.g. background, borders), any node may have multiple
|
||||
var computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, "");
|
||||
|
||||
if (computedStyle) {
|
||||
var addImgFunc = function (label, val) {
|
||||
if (val.primitiveType == CSSPrimitiveValue.CSS_URI) {
|
||||
addImage(val.getStringValue(), label, gStrings.notSet, elem, true);
|
||||
}
|
||||
else if (val.primitiveType == CSSPrimitiveValue.CSS_STRING) {
|
||||
// This is for -moz-image-rect.
|
||||
// TODO: Reimplement once bug 714757 is fixed
|
||||
var strVal = val.getStringValue();
|
||||
if (strVal.search(/^.*url\(\"?/) > -1) {
|
||||
url = strVal.replace(/^.*url\(\"?/,"").replace(/\"?\).*$/,"");
|
||||
addImage(url, label, gStrings.notSet, elem, true);
|
||||
}
|
||||
}
|
||||
else if (val.cssValueType == CSSValue.CSS_VALUE_LIST) {
|
||||
// recursively resolve multiple nested CSS value lists
|
||||
for (var i = 0; i < val.length; i++)
|
||||
addImgFunc(label, val.item(i));
|
||||
}
|
||||
};
|
||||
|
||||
addImgFunc(gStrings.mediaBGImg, computedStyle.getPropertyCSSValue("background-image"));
|
||||
addImgFunc(gStrings.mediaBorderImg, computedStyle.getPropertyCSSValue("border-image-source"));
|
||||
addImgFunc(gStrings.mediaListImg, computedStyle.getPropertyCSSValue("list-style-image"));
|
||||
addImgFunc(gStrings.mediaCursor, computedStyle.getPropertyCSSValue("cursor"));
|
||||
}
|
||||
|
||||
// one swi^H^H^Hif-else to rule them all
|
||||
if (elem instanceof HTMLImageElement)
|
||||
addImage(elem.src, gStrings.mediaImg,
|
||||
(elem.hasAttribute("alt")) ? elem.alt : gStrings.notSet, elem, false);
|
||||
else if (elem instanceof SVGImageElement) {
|
||||
try {
|
||||
// Note: makeURLAbsolute will throw if either the baseURI is not a valid URI
|
||||
// or the URI formed from the baseURI and the URL is not a valid URI
|
||||
var href = makeURLAbsolute(elem.baseURI, elem.href.baseVal);
|
||||
addImage(href, gStrings.mediaImg, "", elem, false);
|
||||
} catch (e) { }
|
||||
}
|
||||
else if (elem instanceof HTMLVideoElement) {
|
||||
addImage(elem.currentSrc, gStrings.mediaVideo, "", elem, false);
|
||||
}
|
||||
else if (elem instanceof HTMLAudioElement) {
|
||||
addImage(elem.currentSrc, gStrings.mediaAudio, "", elem, false);
|
||||
}
|
||||
else if (elem instanceof HTMLLinkElement) {
|
||||
if (elem.rel && /\bicon\b/i.test(elem.rel))
|
||||
addImage(elem.href, gStrings.mediaLink, "", elem, false);
|
||||
}
|
||||
else if (elem instanceof HTMLInputElement || elem instanceof HTMLButtonElement) {
|
||||
if (elem.type.toLowerCase() == "image")
|
||||
addImage(elem.src, gStrings.mediaInput,
|
||||
(elem.hasAttribute("alt")) ? elem.alt : gStrings.notSet, elem, false);
|
||||
}
|
||||
else if (elem instanceof HTMLObjectElement)
|
||||
addImage(elem.data, gStrings.mediaObject, getValueText(elem), elem, false);
|
||||
else if (elem instanceof HTMLEmbedElement)
|
||||
addImage(elem.src, gStrings.mediaEmbed, "", elem, false);
|
||||
|
||||
onProcessElement.forEach(function(func) { func(elem); });
|
||||
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
}
|
||||
|
||||
//******** Link Stuff
|
||||
function openURL(target)
|
||||
{
|
||||
@ -814,14 +739,15 @@ function saveMedia()
|
||||
else if (item instanceof HTMLAudioElement)
|
||||
titleKey = "SaveAudioTitle";
|
||||
|
||||
saveURL(url, null, titleKey, false, false, makeURI(item.baseURI), gDocument);
|
||||
saveURL(url, null, titleKey, false, false, makeURI(item.baseURI),
|
||||
null, gDocInfo.isContentWindowPrivate);
|
||||
}
|
||||
} else {
|
||||
selectSaveFolder(function(aDirectory) {
|
||||
if (aDirectory) {
|
||||
var saveAnImage = function(aURIString, aChosenData, aBaseURI) {
|
||||
internalSave(aURIString, null, null, null, null, false, "SaveImageTitle",
|
||||
aChosenData, aBaseURI, gDocument);
|
||||
aChosenData, aBaseURI, null, gDocInfo.isContentWindowPrivate);
|
||||
};
|
||||
|
||||
for (var i = 0; i < rowArray.length; i++) {
|
||||
@ -893,6 +819,7 @@ function onImageSelect()
|
||||
}
|
||||
}
|
||||
|
||||
// Makes the media preview (image, video, etc) for the selected row on the media tab.
|
||||
function makePreview(row)
|
||||
{
|
||||
var imageTree = document.getElementById("imagetree");
|
||||
@ -902,18 +829,7 @@ function makePreview(row)
|
||||
var isAudio = false;
|
||||
|
||||
setItemValue("imageurltext", url);
|
||||
|
||||
var imageText;
|
||||
if (!isBG &&
|
||||
!(item instanceof SVGImageElement) &&
|
||||
!(gDocument instanceof ImageDocument)) {
|
||||
imageText = item.title || item.alt;
|
||||
|
||||
if (!imageText && !(item instanceof HTMLImageElement))
|
||||
imageText = getValueText(item);
|
||||
}
|
||||
setItemValue("imagetext", imageText);
|
||||
|
||||
setItemValue("imagetext", item.imageText);
|
||||
setItemValue("imagelongdesctext", item.longDesc);
|
||||
|
||||
// get cache info
|
||||
@ -931,32 +847,8 @@ function makePreview(row)
|
||||
sizeText = gBundle.getString("mediaUnknownNotCached");
|
||||
setItemValue("imagesizetext", sizeText);
|
||||
|
||||
var mimeType;
|
||||
var numFrames = 1;
|
||||
if (item instanceof HTMLObjectElement ||
|
||||
item instanceof HTMLEmbedElement ||
|
||||
item instanceof HTMLLinkElement)
|
||||
mimeType = item.type;
|
||||
|
||||
if (!mimeType && !isBG && item instanceof nsIImageLoadingContent) {
|
||||
var imageRequest = item.getRequest(nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
if (imageRequest) {
|
||||
mimeType = imageRequest.mimeType;
|
||||
var image = imageRequest.image;
|
||||
if (image)
|
||||
numFrames = image.numFrames;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mimeType)
|
||||
mimeType = getContentTypeFromHeaders(cacheEntry);
|
||||
|
||||
// if we have a data url, get the MIME type from the url
|
||||
if (!mimeType && url.startsWith("data:")) {
|
||||
let dataMimeType = /^data:(image\/[^;,]+)/i.exec(url);
|
||||
if (dataMimeType)
|
||||
mimeType = dataMimeType[1].toLowerCase();
|
||||
}
|
||||
var mimeType = item.mimeType || this.getContentTypeFromHeaders(cacheEntry);
|
||||
var numFrames = item.numFrames;
|
||||
|
||||
var imageType;
|
||||
if (mimeType) {
|
||||
@ -991,10 +883,10 @@ function makePreview(row)
|
||||
var physWidth = 0, physHeight = 0;
|
||||
var width = 0, height = 0;
|
||||
|
||||
if ((item instanceof HTMLLinkElement || item instanceof HTMLInputElement ||
|
||||
item instanceof HTMLImageElement ||
|
||||
item instanceof SVGImageElement ||
|
||||
(item instanceof HTMLObjectElement && mimeType && mimeType.startsWith("image/")) || isBG) && isProtocolAllowed) {
|
||||
if ((item.HTMLLinkElement || item.HTMLInputElement ||
|
||||
item.HTMLImageElement || item.SVGImageElement ||
|
||||
(item.HTMLObjectElement && mimeType && mimeType.startsWith("image/")) ||
|
||||
isBG) && isProtocolAllowed) {
|
||||
newImage.setAttribute("src", url);
|
||||
physWidth = newImage.width || 0;
|
||||
physHeight = newImage.height || 0;
|
||||
@ -1013,9 +905,9 @@ function makePreview(row)
|
||||
newImage.height = newImage.naturalHeight;
|
||||
}
|
||||
|
||||
if (item instanceof SVGImageElement) {
|
||||
newImage.width = item.width.baseVal.value;
|
||||
newImage.height = item.height.baseVal.value;
|
||||
if (item.SVGImageElement) {
|
||||
newImage.width = item.SVGImageElementWidth;
|
||||
newImage.height = item.SVGImageElementHeight;
|
||||
}
|
||||
|
||||
width = newImage.width;
|
||||
@ -1024,7 +916,7 @@ function makePreview(row)
|
||||
document.getElementById("theimagecontainer").collapsed = false
|
||||
document.getElementById("brokenimagecontainer").collapsed = true;
|
||||
}
|
||||
else if (item instanceof HTMLVideoElement && isProtocolAllowed) {
|
||||
else if (item.HTMLVideoElement && isProtocolAllowed) {
|
||||
newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video");
|
||||
newImage.id = "thepreviewimage";
|
||||
newImage.src = url;
|
||||
@ -1035,7 +927,7 @@ function makePreview(row)
|
||||
document.getElementById("theimagecontainer").collapsed = false;
|
||||
document.getElementById("brokenimagecontainer").collapsed = true;
|
||||
}
|
||||
else if (item instanceof HTMLAudioElement && isProtocolAllowed) {
|
||||
else if (item.HTMLAudioElement && isProtocolAllowed) {
|
||||
newImage = new Audio;
|
||||
newImage.id = "thepreviewimage";
|
||||
newImage.src = url;
|
||||
@ -1073,8 +965,6 @@ function makePreview(row)
|
||||
|
||||
imageContainer.removeChild(oldImage);
|
||||
imageContainer.appendChild(newImage);
|
||||
|
||||
onImagePreviewShown.forEach(function(func) { func(); });
|
||||
});
|
||||
}
|
||||
|
||||
@ -1130,69 +1020,9 @@ function getContentTypeFromHeaders(cacheEntryDescriptor)
|
||||
if (!cacheEntryDescriptor)
|
||||
return null;
|
||||
|
||||
return (/^Content-Type:\s*(.*?)\s*(?:\;|$)/mi
|
||||
.exec(cacheEntryDescriptor.getMetaDataElement("response-head")))[1];
|
||||
}
|
||||
|
||||
//******** Other Misc Stuff
|
||||
// Modified from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html
|
||||
// parse a node to extract the contents of the node
|
||||
function getValueText(node)
|
||||
{
|
||||
var valueText = "";
|
||||
|
||||
// form input elements don't generally contain information that is useful to our callers, so return nothing
|
||||
if (node instanceof HTMLInputElement ||
|
||||
node instanceof HTMLSelectElement ||
|
||||
node instanceof HTMLTextAreaElement)
|
||||
return valueText;
|
||||
|
||||
// otherwise recurse for each child
|
||||
var length = node.childNodes.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var childNode = node.childNodes[i];
|
||||
var nodeType = childNode.nodeType;
|
||||
|
||||
// text nodes are where the goods are
|
||||
if (nodeType == Node.TEXT_NODE)
|
||||
valueText += " " + childNode.nodeValue;
|
||||
// and elements can have more text inside them
|
||||
else if (nodeType == Node.ELEMENT_NODE) {
|
||||
// images are special, we want to capture the alt text as if the image weren't there
|
||||
if (childNode instanceof HTMLImageElement)
|
||||
valueText += " " + getAltText(childNode);
|
||||
else
|
||||
valueText += " " + getValueText(childNode);
|
||||
}
|
||||
}
|
||||
|
||||
return stripWS(valueText);
|
||||
}
|
||||
|
||||
// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html
|
||||
// traverse the tree in search of an img or area element and grab its alt tag
|
||||
function getAltText(node)
|
||||
{
|
||||
var altText = "";
|
||||
|
||||
if (node.alt)
|
||||
return node.alt;
|
||||
var length = node.childNodes.length;
|
||||
for (var i = 0; i < length; i++)
|
||||
if ((altText = getAltText(node.childNodes[i]) != undefined)) // stupid js warning...
|
||||
return altText;
|
||||
return "";
|
||||
}
|
||||
|
||||
// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html
|
||||
// strip leading and trailing whitespace, and replace multiple consecutive whitespace characters with a single space
|
||||
function stripWS(text)
|
||||
{
|
||||
var middleRE = /\s+/g;
|
||||
var endRE = /(^\s+)|(\s+$)/g;
|
||||
|
||||
text = text.replace(middleRE, " ");
|
||||
return text.replace(endRE, "");
|
||||
let headers = cacheEntryDescriptor.getMetaDataElement("response-head");
|
||||
let type = /^Content-Type:\s*(.*?)\s*(?:\;|$)/mi.exec(headers);
|
||||
return type && type[1];
|
||||
}
|
||||
|
||||
function setItemValue(id, value)
|
||||
@ -1281,8 +1111,13 @@ function selectImage()
|
||||
|
||||
var tree = document.getElementById("imagetree");
|
||||
for (var i = 0; i < tree.view.rowCount; i++) {
|
||||
if (gImageElement == gImageView.data[i][COL_IMAGE_NODE] &&
|
||||
!gImageView.data[i][COL_IMAGE_BG]) {
|
||||
// If the image row element is the image selected from the "View Image Info" context menu item.
|
||||
let image = gImageView.data[i][COL_IMAGE_NODE];
|
||||
if (!gImageView.data[i][COL_IMAGE_BG] &&
|
||||
gImageElement.currentSrc == gImageView.data[i][COL_IMAGE_ADDRESS] &&
|
||||
gImageElement.width == image.width &&
|
||||
gImageElement.height == image.height &&
|
||||
gImageElement.imageText == image.imageText) {
|
||||
tree.view.selection.select(i);
|
||||
tree.treeBoxObject.ensureRowIsVisible(i);
|
||||
tree.focus();
|
||||
|
@ -28,9 +28,8 @@ var permissionObserver = {
|
||||
}
|
||||
};
|
||||
|
||||
function onLoadPermission()
|
||||
function onLoadPermission(uri)
|
||||
{
|
||||
var uri = BrowserUtils.makeURIFromCPOW(gDocument.documentURIObject);
|
||||
var permTab = document.getElementById("permTab");
|
||||
if (SitePermissions.isSupportedURI(uri)) {
|
||||
gPermURI = uri;
|
||||
|
@ -9,6 +9,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
|
||||
"resource://gre/modules/LoginHelper.jsm");
|
||||
|
||||
var security = {
|
||||
init: function(uri, windowInfo) {
|
||||
this.uri = uri;
|
||||
this.windowInfo = windowInfo;
|
||||
},
|
||||
|
||||
// Display the server certificate (static)
|
||||
viewCert : function () {
|
||||
var cert = security._cert;
|
||||
@ -24,14 +29,10 @@ var security = {
|
||||
|
||||
// We don't have separate info for a frame, return null until further notice
|
||||
// (see bug 138479)
|
||||
if (gWindow != gWindow.top)
|
||||
if (!this.windowInfo.isTopWindow)
|
||||
return null;
|
||||
|
||||
var hName = null;
|
||||
try {
|
||||
hName = gWindow.location.host;
|
||||
}
|
||||
catch (exception) { }
|
||||
var hostName = this.windowInfo.hostName;
|
||||
|
||||
var ui = security._getSecurityUI();
|
||||
if (!ui)
|
||||
@ -56,7 +57,7 @@ var security = {
|
||||
this.mapIssuerOrganization(cert.issuerOrganization) || cert.issuerName;
|
||||
|
||||
var retval = {
|
||||
hostName : hName,
|
||||
hostName : hostName,
|
||||
cAName : issuerName,
|
||||
encryptionAlgorithm : undefined,
|
||||
encryptionStrength : undefined,
|
||||
@ -64,8 +65,7 @@ var security = {
|
||||
isBroken : isBroken,
|
||||
isMixed : isMixed,
|
||||
isEV : isEV,
|
||||
cert : cert,
|
||||
fullLocation : gWindow.location
|
||||
cert : cert
|
||||
};
|
||||
|
||||
var version;
|
||||
@ -95,7 +95,7 @@ var security = {
|
||||
return retval;
|
||||
} else {
|
||||
return {
|
||||
hostName : hName,
|
||||
hostName : hostName,
|
||||
cAName : "",
|
||||
encryptionAlgorithm : "",
|
||||
encryptionStrength : 0,
|
||||
@ -103,8 +103,8 @@ var security = {
|
||||
isBroken : isBroken,
|
||||
isMixed : isMixed,
|
||||
isEV : isEV,
|
||||
cert : null,
|
||||
fullLocation : gWindow.location
|
||||
cert : null
|
||||
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -140,13 +140,12 @@ var security = {
|
||||
getService(Components.interfaces.nsIEffectiveTLDService);
|
||||
|
||||
var eTLD;
|
||||
var uri = BrowserUtils.makeURIFromCPOW(gDocument.documentURIObject);
|
||||
try {
|
||||
eTLD = eTLDService.getBaseDomain(uri);
|
||||
eTLD = eTLDService.getBaseDomain(this.uri);
|
||||
}
|
||||
catch (e) {
|
||||
// getBaseDomain will fail if the host is an IP address or is empty
|
||||
eTLD = uri.asciiHost;
|
||||
eTLD = this.uri.asciiHost;
|
||||
}
|
||||
|
||||
if (win) {
|
||||
@ -168,7 +167,9 @@ var security = {
|
||||
_cert : null
|
||||
};
|
||||
|
||||
function securityOnLoad() {
|
||||
function securityOnLoad(uri, windowInfo) {
|
||||
security.init(uri, windowInfo);
|
||||
|
||||
var info = security._getSecurityInfo();
|
||||
if (!info) {
|
||||
document.getElementById("securityTab").hidden = true;
|
||||
@ -226,7 +227,6 @@ function securityOnLoad() {
|
||||
var yesStr = pageInfoBundle.getString("yes");
|
||||
var noStr = pageInfoBundle.getString("no");
|
||||
|
||||
var uri = BrowserUtils.makeURIFromCPOW(gDocument.documentURIObject);
|
||||
setText("security-privacy-cookies-value",
|
||||
hostHasCookies(uri) ? yesStr : noStr);
|
||||
setText("security-privacy-passwords-value",
|
||||
|
@ -14,7 +14,7 @@ function test() {
|
||||
|
||||
pageInfo.addEventListener("load", function () {
|
||||
pageInfo.removeEventListener("load", arguments.callee, true);
|
||||
pageInfo.onImagePreviewShown.push(function () {
|
||||
pageInfo.onFinished.push(function () {
|
||||
executeSoon(function () {
|
||||
var pageInfoImg = pageInfo.document.getElementById("thepreviewimage");
|
||||
|
||||
|
@ -15,7 +15,7 @@ function test() {
|
||||
|
||||
function observer(win, topic, data) {
|
||||
Services.obs.removeObserver(observer, "page-info-dialog-loaded");
|
||||
handlePageInfo();
|
||||
pageInfo.onFinished.push(handlePageInfo);
|
||||
}
|
||||
|
||||
function handlePageInfo() {
|
||||
|
@ -34,7 +34,7 @@ function doOnOpenPageInfo(continuation) {
|
||||
|
||||
function pageInfoObserve(win, topic, data) {
|
||||
Services.obs.removeObserver(pageInfoObserve, "page-info-dialog-loaded");
|
||||
executeSoon(gNextTest);
|
||||
gPageInfo.onFinished.push(() => executeSoon(gNextTest));
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
|
@ -80,7 +80,7 @@ function forbidCPOW(arg, func, argname)
|
||||
// - A linked document using Alt-click Save Link As...
|
||||
//
|
||||
function saveURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
|
||||
aSkipPrompt, aReferrer, aSourceDocument)
|
||||
aSkipPrompt, aReferrer, aSourceDocument, aIsContentWindowPrivate)
|
||||
{
|
||||
forbidCPOW(aURL, "saveURL", "aURL");
|
||||
forbidCPOW(aReferrer, "saveURL", "aReferrer");
|
||||
@ -88,7 +88,7 @@ function saveURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
|
||||
|
||||
internalSave(aURL, null, aFileName, null, null, aShouldBypassCache,
|
||||
aFilePickerTitleKey, null, aReferrer, aSourceDocument,
|
||||
aSkipPrompt, null);
|
||||
aSkipPrompt, null, aIsContentWindowPrivate);
|
||||
}
|
||||
|
||||
// Just like saveURL, but will get some info off the image before
|
||||
@ -264,19 +264,24 @@ const kSaveAsType_Text = 2; // Save document, converting to plain text.
|
||||
* @param aReferrer
|
||||
* the referrer URI object (not URL string) to use, or null
|
||||
* if no referrer should be sent.
|
||||
* @param aInitiatingDocument
|
||||
* @param aInitiatingDocument [optional]
|
||||
* The document from which the save was initiated.
|
||||
* If this is omitted then aIsContentWindowPrivate has to be provided.
|
||||
* @param aSkipPrompt [optional]
|
||||
* If set to true, we will attempt to save the file to the
|
||||
* default downloads folder without prompting.
|
||||
* @param aCacheKey [optional]
|
||||
* If set will be passed to saveURI. See nsIWebBrowserPersist for
|
||||
* allowed values.
|
||||
* @param aIsContentWindowPrivate [optional]
|
||||
* This parameter is provided when the aInitiatingDocument is not a
|
||||
* real document object. Stores whether aInitiatingDocument.defaultView
|
||||
* was private or not.
|
||||
*/
|
||||
function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
|
||||
aContentType, aShouldBypassCache, aFilePickerTitleKey,
|
||||
aChosenData, aReferrer, aInitiatingDocument, aSkipPrompt,
|
||||
aCacheKey)
|
||||
aCacheKey, aIsContentWindowPrivate)
|
||||
{
|
||||
forbidCPOW(aURL, "internalSave", "aURL");
|
||||
forbidCPOW(aReferrer, "internalSave", "aReferrer");
|
||||
@ -357,7 +362,8 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
|
||||
sourceCacheKey : aCacheKey,
|
||||
sourcePostData : nonCPOWDocument ? getPostData(aDocument) : null,
|
||||
bypassCache : aShouldBypassCache,
|
||||
initiatingWindow : aInitiatingDocument.defaultView
|
||||
initiatingWindow : aInitiatingDocument && aInitiatingDocument.defaultView,
|
||||
isContentWindowPrivate : aIsContentWindowPrivate
|
||||
};
|
||||
|
||||
// Start the actual save process
|
||||
@ -392,8 +398,12 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
|
||||
* "text/plain" is meaningful.
|
||||
* @param persistArgs.bypassCache
|
||||
* If true, the document will always be refetched from the server
|
||||
* @param persistArgs.initiatingWindow
|
||||
* @param persistArgs.initiatingWindow [optional]
|
||||
* The window from which the save operation was initiated.
|
||||
* If this is omitted then isContentWindowPrivate has to be provided.
|
||||
* @param persistArgs.isContentWindowPrivate [optional]
|
||||
* If present then isPrivate is set to this value without using
|
||||
* persistArgs.initiatingWindow.
|
||||
*/
|
||||
function internalPersist(persistArgs)
|
||||
{
|
||||
@ -414,7 +424,10 @@ function internalPersist(persistArgs)
|
||||
// Find the URI associated with the target file
|
||||
var targetFileURL = makeFileURI(persistArgs.targetFile);
|
||||
|
||||
let isPrivate = PrivateBrowsingUtils.isContentWindowPrivate(persistArgs.initiatingWindow);
|
||||
let isPrivate = persistArgs.isContentWindowPrivate;
|
||||
if (isPrivate === undefined) {
|
||||
isPrivate = PrivateBrowsingUtils.isContentWindowPrivate(persistArgs.initiatingWindow);
|
||||
}
|
||||
|
||||
// Create download and initiate it (below)
|
||||
var tr = Components.classes["@mozilla.org/transfer;1"].createInstance(Components.interfaces.nsITransfer);
|
||||
|
Loading…
Reference in New Issue
Block a user