summaryrefslogtreecommitdiffstats
path: root/components/pageinfo/pageInfo.js
diff options
context:
space:
mode:
authorThomas Groman <tgroman@nuegia.net>2020-04-20 20:49:37 -0700
committerThomas Groman <tgroman@nuegia.net>2020-04-20 20:49:37 -0700
commitf9cab004186edb425a9b88ad649726605080a17c (patch)
treee2dae51d3144e83d097a12e7a1499e3ea93f90be /components/pageinfo/pageInfo.js
parentf428692de8b59ab89a66502c079e1823dfda8aeb (diff)
downloadwebbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.gz
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.lz
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.xz
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.zip
move browser to webbrowser/
Diffstat (limited to 'components/pageinfo/pageInfo.js')
-rw-r--r--components/pageinfo/pageInfo.js1286
1 files changed, 0 insertions, 1286 deletions
diff --git a/components/pageinfo/pageInfo.js b/components/pageinfo/pageInfo.js
deleted file mode 100644
index 600174a..0000000
--- a/components/pageinfo/pageInfo.js
+++ /dev/null
@@ -1,1286 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-var Cu = Components.utils;
-Cu.import("resource://gre/modules/LoadContextInfo.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-//******** define a js object to implement nsITreeView
-function pageInfoTreeView(treeid, copycol)
-{
- // copycol is the index number for the column that we want to add to
- // the copy-n-paste buffer when the user hits accel-c
- this.treeid = treeid;
- this.copycol = copycol;
- this.rows = 0;
- this.tree = null;
- this.data = [ ];
- this.selection = null;
- this.sortcol = -1;
- this.sortdir = false;
-}
-
-pageInfoTreeView.prototype = {
- set rowCount(c) { throw "rowCount is a readonly property"; },
- get rowCount() { return this.rows; },
-
- setTree: function(tree)
- {
- this.tree = tree;
- },
-
- getCellText: function(row, column)
- {
- // row can be null, but js arrays are 0-indexed.
- // colidx cannot be null, but can be larger than the number
- // of columns in the array. In this case it's the fault of
- // whoever typoed while calling this function.
- return this.data[row][column.index] || "";
- },
-
- setCellValue: function(row, column, value)
- {
- },
-
- setCellText: function(row, column, value)
- {
- this.data[row][column.index] = value;
- },
-
- addRow: function(row)
- {
- this.rows = this.data.push(row);
- this.rowCountChanged(this.rows - 1, 1);
- if (this.selection.count == 0 && this.rowCount && !gImageElement)
- this.selection.select(0);
- },
-
- rowCountChanged: function(index, count)
- {
- this.tree.rowCountChanged(index, count);
- },
-
- invalidate: function()
- {
- this.tree.invalidate();
- },
-
- clear: function()
- {
- if (this.tree)
- this.tree.rowCountChanged(0, -this.rows);
- this.rows = 0;
- this.data = [ ];
- },
-
- handleCopy: function(row)
- {
- return (row < 0 || this.copycol < 0) ? "" : (this.data[row][this.copycol] || "");
- },
-
- performActionOnRow: function(action, row)
- {
- if (action == "copy") {
- var data = this.handleCopy(row)
- this.tree.treeBody.parentNode.setAttribute("copybuffer", data);
- }
- },
-
- onPageMediaSort : function(columnname)
- {
- var tree = document.getElementById(this.treeid);
- var treecol = tree.columns.getNamedColumn(columnname);
-
- this.sortdir =
- gTreeUtils.sort(
- tree,
- this,
- this.data,
- treecol.index,
- function textComparator(a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); },
- this.sortcol,
- this.sortdir
- );
-
- this.sortcol = treecol.index;
- },
-
- getRowProperties: function(row) { return ""; },
- getCellProperties: function(row, column) { return ""; },
- getColumnProperties: function(column) { return ""; },
- isContainer: function(index) { return false; },
- isContainerOpen: function(index) { return false; },
- isSeparator: function(index) { return false; },
- isSorted: function() { },
- canDrop: function(index, orientation) { return false; },
- drop: function(row, orientation) { return false; },
- getParentIndex: function(index) { return 0; },
- hasNextSibling: function(index, after) { return false; },
- getLevel: function(index) { return 0; },
- getImageSrc: function(row, column) { },
- getProgressMode: function(row, column) { },
- getCellValue: function(row, column) { },
- toggleOpenState: function(index) { },
- cycleHeader: function(col) { },
- selectionChanged: function() { },
- cycleCell: function(row, column) { },
- isEditable: function(row, column) { return false; },
- isSelectable: function(row, column) { return false; },
- performAction: function(action) { },
- performActionOnCell: function(action, row, column) { }
-};
-
-// mmm, yummy. global variables.
-var gWindow = null;
-var gDocument = null;
-var gImageElement = null;
-
-// column number to help using the data array
-const COL_IMAGE_ADDRESS = 0;
-const COL_IMAGE_TYPE = 1;
-const COL_IMAGE_SIZE = 2;
-const COL_IMAGE_ALT = 3;
-const COL_IMAGE_COUNT = 4;
-const COL_IMAGE_NODE = 5;
-const COL_IMAGE_BG = 6;
-
-// column number to copy from, second argument to pageInfoTreeView's constructor
-const COPYCOL_NONE = -1;
-const COPYCOL_META_CONTENT = 1;
-const COPYCOL_IMAGE = COL_IMAGE_ADDRESS;
-
-// one nsITreeView for each tree in the window
-var gMetaView = new pageInfoTreeView('metatree', COPYCOL_META_CONTENT);
-var gImageView = new pageInfoTreeView('imagetree', COPYCOL_IMAGE);
-
-gImageView.getCellProperties = function(row, col) {
- var data = gImageView.data[row];
- var item = gImageView.data[row][COL_IMAGE_NODE];
- var props = "";
- if (!checkProtocol(data) ||
- item instanceof HTMLEmbedElement ||
- (item instanceof HTMLObjectElement && !item.type.startsWith("image/")))
- props += "broken";
-
- if (col.element.id == "image-address")
- props += " ltr";
-
- return props;
-};
-
-gImageView.getCellText = function(row, column) {
- var value = this.data[row][column.index];
- if (column.index == COL_IMAGE_SIZE) {
- if (value == -1) {
- return gStrings.unknown;
- } else {
- var kbSize = Number(Math.round(value / 1024 * 100) / 100);
- return gBundle.getFormattedString("mediaFileSize", [kbSize]);
- }
- }
- return value || "";
-};
-
-gImageView.onPageMediaSort = function(columnname) {
- var tree = document.getElementById(this.treeid);
- var treecol = tree.columns.getNamedColumn(columnname);
-
- var comparator;
- if (treecol.index == COL_IMAGE_SIZE || treecol.index == COL_IMAGE_COUNT) {
- comparator = function numComparator(a, b) { return a - b; };
- } else {
- comparator = function textComparator(a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); };
- }
-
- this.sortdir =
- gTreeUtils.sort(
- tree,
- this,
- this.data,
- treecol.index,
- comparator,
- this.sortcol,
- this.sortdir
- );
-
- this.sortcol = treecol.index;
-};
-
-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 PERMISSION_CONTRACTID = "@mozilla.org/permissionmanager;1";
-const PREFERENCES_CONTRACTID = "@mozilla.org/preferences-service;1";
-const ATOM_CONTRACTID = "@mozilla.org/atom-service;1";
-
-// a number of services I'll need later
-// the cache services
-const nsICacheStorageService = Components.interfaces.nsICacheStorageService;
-const nsICacheStorage = Components.interfaces.nsICacheStorage;
-const cacheService = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"].getService(nsICacheStorageService);
-
-var loadContextInfo = LoadContextInfo.fromLoadContext(
- window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsILoadContext), false);
-var diskStorage = cacheService.diskCacheStorage(loadContextInfo, false);
-
-const nsICookiePermission = Components.interfaces.nsICookiePermission;
-const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
-
-const nsICertificateDialogs = Components.interfaces.nsICertificateDialogs;
-const CERTIFICATEDIALOGS_CONTRACTID = "@mozilla.org/nsCertificateDialogs;1"
-
-// clipboard helper
-function getClipboardHelper() {
- try {
- return Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
- } catch(e) {
- // do nothing, later code will handle the error
- }
-}
-const gClipboardHelper = getClipboardHelper();
-
-// Interface for image loading content
-const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent;
-
-// namespaces, don't need all of these yet...
-const XLinkNS = "http://www.w3.org/1999/xlink";
-const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-const XMLNS = "http://www.w3.org/XML/1998/namespace";
-const XHTMLNS = "http://www.w3.org/1999/xhtml";
-const XHTML2NS = "http://www.w3.org/2002/06/xhtml2"
-
-const XHTMLNSre = "^http\:\/\/www\.w3\.org\/1999\/xhtml$";
-const XHTML2NSre = "^http\:\/\/www\.w3\.org\/2002\/06\/xhtml2$";
-const XHTMLre = RegExp(XHTMLNSre + "|" + XHTML2NSre, "");
-
-/* Overlays register functions here.
- * These arrays are used to hold callbacks that Page Info will call at
- * various stages. Use them by simply appending a function to them.
- * For example, add a function to onLoadRegistry by invoking
- * "onLoadRegistry.push(XXXLoadFunc);"
- * The XXXLoadFunc should be unique to the overlay module, and will be
- * 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.
-var onLoadRegistry = [ ];
-
-// These functions are called to remove old data still displayed in
-// the window when the document whose information is displayed
-// changes. For example, at this time, the list of images of the Media
-// 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 = [ ];
-
-// 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,
- * the calling window's document will be used
- * - initialTab: (optional) id of the inital tab to display
- */
-function onLoadPageInfo()
-{
- gBundle = document.getElementById("pageinfobundle");
- gStrings.unknown = gBundle.getString("unknown");
- gStrings.notSet = gBundle.getString("notset");
- gStrings.mediaImg = gBundle.getString("mediaImg");
- gStrings.mediaBGImg = gBundle.getString("mediaBGImg");
- gStrings.mediaBorderImg = gBundle.getString("mediaBorderImg");
- gStrings.mediaListImg = gBundle.getString("mediaListImg");
- gStrings.mediaCursor = gBundle.getString("mediaCursor");
- gStrings.mediaObject = gBundle.getString("mediaObject");
- gStrings.mediaEmbed = gBundle.getString("mediaEmbed");
- gStrings.mediaLink = gBundle.getString("mediaLink");
- gStrings.mediaInput = gBundle.getString("mediaInput");
- gStrings.mediaVideo = gBundle.getString("mediaVideo");
- gStrings.mediaAudio = gBundle.getString("mediaAudio");
-
- var args = "arguments" in window &&
- window.arguments.length >= 1 &&
- window.arguments[0];
-
- if (!args || !args.doc) {
- gWindow = window.opener.content;
- gDocument = gWindow.document;
- }
-
- // init media view
- var imageTree = document.getElementById("imagetree");
- imageTree.view = gImageView;
-
- /* Select the requested tab, if the name is specified */
- loadTab(args);
- Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService)
- .notifyObservers(window, "page-info-dialog-loaded", null);
-
- // Make sure the page info window gets focus even if a doorhanger might
- // otherwise (async) steal it.
- window.focus();
-}
-
-function loadPageInfo()
-{
- var titleFormat = gWindow != gWindow.top ? "pageInfo.frame.title"
- : "pageInfo.page.title";
- document.title = gBundle.getFormattedString(titleFormat, [gDocument.location]);
-
- document.getElementById("main-window").setAttribute("relatedUrl", gDocument.location);
-
- // do the easy stuff first
- makeGeneralTab();
-
- // and then the hard stuff
- makeTabs(gDocument, gWindow);
-
- initFeedTab();
- onLoadPermission(gDocument.nodePrincipal);
-
- /* Call registered overlay init functions */
- onLoadRegistry.forEach(function(func) { func(); });
-}
-
-function resetPageInfo(args)
-{
- /* Reset Meta tags part */
- gMetaView.clear();
-
- /* Reset Media tab */
- var mediaTab = document.getElementById("mediaTab");
- if (!mediaTab.hidden) {
- Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService)
- .removeObserver(imagePermissionObserver, "perm-changed");
- mediaTab.hidden = true;
- }
- gImageView.clear();
- gImageHash = {};
-
- /* Reset Feeds Tab */
- var feedListbox = document.getElementById("feedListbox");
- while (feedListbox.firstChild)
- feedListbox.removeChild(feedListbox.firstChild);
-
- /* Call registered overlay reset functions */
- onResetRegistry.forEach(function(func) { func(); });
-
- /* Rebuild the data */
- loadTab(args);
-}
-
-function onUnloadPageInfo()
-{
- // Remove the observer, only if there is at least 1 image.
- if (!document.getElementById("mediaTab").hidden) {
- Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService)
- .removeObserver(imagePermissionObserver, "perm-changed");
- }
-
- /* Call registered overlay unload functions */
- onUnloadRegistry.forEach(function(func) { func(); });
-}
-
-function doHelpButton()
-{
- const helpTopics = {
- "generalPanel": "pageinfo_general",
- "mediaPanel": "pageinfo_media",
- "feedPanel": "pageinfo_feed",
- "permPanel": "pageinfo_permissions",
- "securityPanel": "pageinfo_security"
- };
-
- var deck = document.getElementById("mainDeck");
- var helpdoc = helpTopics[deck.selectedPanel.id] || "pageinfo_general";
- openHelpLink(helpdoc);
-}
-
-function showTab(id)
-{
- var deck = document.getElementById("mainDeck");
- var pagel = document.getElementById(id + "Panel");
- deck.selectedPanel = pagel;
-}
-
-function loadTab(args)
-{
- if (args && args.doc) {
- gDocument = args.doc;
- gWindow = gDocument.defaultView;
- }
-
- gImageElement = args && args.imageElement;
-
- /* Load the page info */
- loadPageInfo();
-
- var initialTab = (args && args.initialTab) || "generalTab";
- var radioGroup = document.getElementById("viewGroup");
- initialTab = document.getElementById(initialTab) || document.getElementById("generalTab");
- radioGroup.selectedItem = initialTab;
- radioGroup.selectedItem.doCommand();
- radioGroup.focus();
-}
-
-function onClickMore()
-{
- var radioGrp = document.getElementById("viewGroup");
- var radioElt = document.getElementById("securityTab");
- radioGrp.selectedItem = radioElt;
- showTab('security');
-}
-
-function toggleGroupbox(id)
-{
- var elt = document.getElementById(id);
- if (elt.hasAttribute("closed")) {
- elt.removeAttribute("closed");
- if (elt.flexWhenOpened)
- elt.flex = elt.flexWhenOpened;
- }
- else {
- elt.setAttribute("closed", "true");
- if (elt.flex) {
- elt.flexWhenOpened = elt.flex;
- elt.flex = 0;
- }
- }
-}
-
-function openCacheEntry(key, cb)
-{
- var checkCacheListener = {
- onCacheEntryCheck: function(entry, appCache) {
- return Components.interfaces.nsICacheEntryOpenCallback.ENTRY_WANTED;
- },
- onCacheEntryAvailable: function(entry, isNew, appCache, status) {
- cb(entry);
- },
- get mainThreadOnly() { return true; }
- };
- diskStorage.asyncOpenURI(Services.io.newURI(key, null, null), "", nsICacheStorage.OPEN_READONLY, checkCacheListener);
-}
-
-function makeGeneralTab()
-{
- var title = (gDocument.title) ? gBundle.getFormattedString("pageTitle", [gDocument.title]) : gBundle.getString("noPageTitle");
- document.getElementById("titletext").value = title;
-
- var url = gDocument.location.toString();
- setItemValue("urltext", url);
-
- var referrer = ("referrer" in gDocument && gDocument.referrer);
- setItemValue("refertext", referrer);
-
- var mode = ("compatMode" in gDocument && gDocument.compatMode == "BackCompat") ? "generalQuirksMode" : "generalStrictMode";
- document.getElementById("modetext").value = gBundle.getString(mode);
-
- // find out the mime type
- var mimeType = gDocument.contentType;
- setItemValue("typetext", mimeType);
-
- // get the document characterset
- var encoding = gDocument.characterSet;
- document.getElementById("encodingtext").value = encoding;
-
- // get the meta tags
- var metaNodes = gDocument.getElementsByTagName("meta");
- var length = metaNodes.length;
-
- var metaGroup = document.getElementById("metaTags");
- if (!length)
- metaGroup.collapsed = true;
- else {
- var metaTagsCaption = document.getElementById("metaTagsCaption");
- if (length == 1)
- metaTagsCaption.label = gBundle.getString("generalMetaTag");
- else
- metaTagsCaption.label = gBundle.getFormattedString("generalMetaTags", [length]);
- 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].content]);
-
- metaGroup.collapsed = false;
- }
-
- // get the date of last modification
- var modifiedText = formatDate(gDocument.lastModified, gStrings.notSet);
- document.getElementById("modifiedtext").value = modifiedText;
-
- // get cache info
- var cacheKey = url.replace(/#.*$/, "");
- openCacheEntry(cacheKey, function(cacheEntry) {
- var sizeText;
- if (cacheEntry) {
- var pageSize = cacheEntry.dataSize;
- var kbSize = formatNumber(Math.round(pageSize / 1024 * 100) / 100);
- sizeText = gBundle.getFormattedString("generalSize", [kbSize, formatNumber(pageSize)]);
- }
- 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)
-{
- 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
- }
-}
-
-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);
-}
-
-function addImage(url, type, alt, elem, isBg)
-{
- if (!url)
- return;
-
- if (!gImageHash.hasOwnProperty(url))
- gImageHash[url] = { };
- if (!gImageHash[url].hasOwnProperty(type))
- gImageHash[url][type] = { };
- if (!gImageHash[url][type].hasOwnProperty(alt)) {
- gImageHash[url][type][alt] = gImageView.data.length;
- var row = [url, type, -1, alt, 1, elem, isBg];
- gImageView.addRow(row);
-
- // Fill in cache data asynchronously
- openCacheEntry(url, function(cacheEntry) {
- // The data at row[2] corresponds to the data size.
- if (cacheEntry) {
- row[2] = cacheEntry.dataSize;
- // Invalidate the row to trigger a repaint.
- gImageView.tree.invalidateRow(gImageView.data.indexOf(row));
- }
- });
-
- // Add the observer, only once.
- if (gImageView.data.length == 1) {
- document.getElementById("mediaTab").hidden = false;
- Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService)
- .addObserver(imagePermissionObserver, "perm-changed", false);
- }
- }
- else {
- var i = gImageHash[url][type][alt];
- gImageView.data[i][COL_IMAGE_COUNT]++;
- if (elem == gImageElement)
- 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)
-{
- var url = target.parentNode.childNodes[2].value;
- window.open(url, "_blank", "chrome");
-}
-
-function onBeginLinkDrag(event,urlField,descField)
-{
- if (event.originalTarget.localName != "treechildren")
- return;
-
- var tree = event.target;
- if (!("treeBoxObject" in tree))
- tree = tree.parentNode;
-
- var row = tree.treeBoxObject.getRowAt(event.clientX, event.clientY);
- if (row == -1)
- return;
-
- // Adding URL flavor
- var col = tree.columns[urlField];
- var url = tree.view.getCellText(row, col);
- col = tree.columns[descField];
- var desc = tree.view.getCellText(row, col);
-
- var dt = event.dataTransfer;
- dt.setData("text/x-moz-url", url + "\n" + desc);
- dt.setData("text/url-list", url);
- dt.setData("text/plain", url);
-}
-
-//******** Image Stuff
-function getSelectedRows(tree)
-{
- var start = { };
- var end = { };
- var numRanges = tree.view.selection.getRangeCount();
-
- var rowArray = [ ];
- for (var t = 0; t < numRanges; t++) {
- tree.view.selection.getRangeAt(t, start, end);
- for (var v = start.value; v <= end.value; v++)
- rowArray.push(v);
- }
-
- return rowArray;
-}
-
-function getSelectedRow(tree)
-{
- var rows = getSelectedRows(tree);
- return (rows.length == 1) ? rows[0] : -1;
-}
-
-function selectSaveFolder(aCallback)
-{
- const nsILocalFile = Components.interfaces.nsILocalFile;
- const nsIFilePicker = Components.interfaces.nsIFilePicker;
- let titleText = gBundle.getString("mediaSelectFolder");
- let fp = Components.classes["@mozilla.org/filepicker;1"].
- createInstance(nsIFilePicker);
- let fpCallback = function fpCallback_done(aResult) {
- if (aResult == nsIFilePicker.returnOK) {
- aCallback(fp.file.QueryInterface(nsILocalFile));
- } else {
- aCallback(null);
- }
- };
-
- fp.init(window, titleText, nsIFilePicker.modeGetFolder);
- fp.appendFilters(nsIFilePicker.filterAll);
- try {
- let prefs = Components.classes[PREFERENCES_CONTRACTID].
- getService(Components.interfaces.nsIPrefBranch);
- let initialDir = prefs.getComplexValue("browser.download.dir", nsILocalFile);
- if (initialDir) {
- fp.displayDirectory = initialDir;
- }
- } catch (ex) {
- }
- fp.open(fpCallback);
-}
-
-function saveMedia()
-{
- var tree = document.getElementById("imagetree");
- var rowArray = getSelectedRows(tree);
- if (rowArray.length == 1) {
- var row = rowArray[0];
- var item = gImageView.data[row][COL_IMAGE_NODE];
- var url = gImageView.data[row][COL_IMAGE_ADDRESS];
-
- if (url) {
- var titleKey = "SaveImageTitle";
-
- if (item instanceof HTMLVideoElement)
- titleKey = "SaveVideoTitle";
- else if (item instanceof HTMLAudioElement)
- titleKey = "SaveAudioTitle";
-
- saveURL(url, null, titleKey, false, false, makeURI(item.baseURI), gDocument);
- }
- } else {
- selectSaveFolder(function(aDirectory) {
- if (aDirectory) {
- var saveAnImage = function(aURIString, aChosenData, aBaseURI) {
- internalSave(aURIString, null, null, null, null, false, "SaveImageTitle",
- aChosenData, aBaseURI, gDocument);
- };
-
- for (var i = 0; i < rowArray.length; i++) {
- var v = rowArray[i];
- var dir = aDirectory.clone();
- var item = gImageView.data[v][COL_IMAGE_NODE];
- var uriString = gImageView.data[v][COL_IMAGE_ADDRESS];
- var uri = makeURI(uriString);
-
- try {
- uri.QueryInterface(Components.interfaces.nsIURL);
- dir.append(decodeURIComponent(uri.fileName));
- } catch(ex) {
- /* data: uris */
- }
-
- if (i == 0) {
- saveAnImage(uriString, new AutoChosen(dir, uri), makeURI(item.baseURI));
- } else {
- // This delay is a hack which prevents the download manager
- // from opening many times. See bug 377339.
- setTimeout(saveAnImage, 200, uriString, new AutoChosen(dir, uri),
- makeURI(item.baseURI));
- }
- }
- }
- });
- }
-}
-
-function onBlockImage()
-{
- var permissionManager = Components.classes[PERMISSION_CONTRACTID]
- .getService(nsIPermissionManager);
-
- var checkbox = document.getElementById("blockImage");
- var uri = makeURI(document.getElementById("imageurltext").value);
- if (checkbox.checked)
- permissionManager.add(uri, "image", nsIPermissionManager.DENY_ACTION);
- else
- permissionManager.remove(uri, "image");
-}
-
-function onImageSelect()
-{
- var previewBox = document.getElementById("mediaPreviewBox");
- var mediaSaveBox = document.getElementById("mediaSaveBox");
- var splitter = document.getElementById("mediaSplitter");
- var tree = document.getElementById("imagetree");
- var count = tree.view.selection.count;
- if (count == 0) {
- previewBox.collapsed = true;
- mediaSaveBox.collapsed = true;
- splitter.collapsed = true;
- tree.flex = 1;
- }
- else if (count > 1) {
- splitter.collapsed = true;
- previewBox.collapsed = true;
- mediaSaveBox.collapsed = false;
- tree.flex = 1;
- }
- else {
- mediaSaveBox.collapsed = true;
- splitter.collapsed = false;
- previewBox.collapsed = false;
- tree.flex = 0;
- makePreview(getSelectedRows(tree)[0]);
- }
-}
-
-function makePreview(row)
-{
- var imageTree = document.getElementById("imagetree");
- var item = gImageView.data[row][COL_IMAGE_NODE];
- var url = gImageView.data[row][COL_IMAGE_ADDRESS];
- var isBG = gImageView.data[row][COL_IMAGE_BG];
- 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("imagelongdesctext", item.longDesc);
-
- // get cache info
- var cacheKey = url.replace(/#.*$/, "");
- openCacheEntry(cacheKey, function(cacheEntry) {
- // find out the file size
- var sizeText;
- if (cacheEntry) {
- var imageSize = cacheEntry.dataSize;
- var kbSize = Math.round(imageSize / 1024 * 100) / 100;
- sizeText = gBundle.getFormattedString("generalSize",
- [formatNumber(kbSize), formatNumber(imageSize)]);
- }
- else
- 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 imageType;
- if (mimeType) {
- // We found the type, try to display it nicely
- let imageMimeType = /^image\/(.*)/i.exec(mimeType);
- if (imageMimeType) {
- imageType = imageMimeType[1].toUpperCase();
- if (numFrames > 1)
- imageType = gBundle.getFormattedString("mediaAnimatedImageType",
- [imageType, numFrames]);
- else
- imageType = gBundle.getFormattedString("mediaImageType", [imageType]);
- }
- else {
- // the MIME type doesn't begin with image/, display the raw type
- imageType = mimeType;
- }
- }
- else {
- // We couldn't find the type, fall back to the value in the treeview
- imageType = gImageView.data[row][COL_IMAGE_TYPE];
- }
- setItemValue("imagetypetext", imageType);
-
- var imageContainer = document.getElementById("theimagecontainer");
- var oldImage = document.getElementById("thepreviewimage");
-
- var isProtocolAllowed = checkProtocol(gImageView.data[row]);
-
- var newImage = new Image;
- newImage.id = "thepreviewimage";
- 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) {
- newImage.setAttribute("src", url);
- physWidth = newImage.width || 0;
- physHeight = newImage.height || 0;
-
- // "width" and "height" attributes must be set to newImage,
- // even if there is no "width" or "height attribute in item;
- // otherwise, the preview image cannot be displayed correctly.
- if (!isBG) {
- newImage.width = ("width" in item && item.width) || newImage.naturalWidth;
- newImage.height = ("height" in item && item.height) || newImage.naturalHeight;
- }
- else {
- // the Width and Height of an HTML tag should not be used for its background image
- // (for example, "table" can have "width" or "height" attributes)
- newImage.width = newImage.naturalWidth;
- newImage.height = newImage.naturalHeight;
- }
-
- if (item instanceof SVGImageElement) {
- newImage.width = item.width.baseVal.value;
- newImage.height = item.height.baseVal.value;
- }
-
- width = newImage.width;
- height = newImage.height;
-
- document.getElementById("theimagecontainer").collapsed = false
- document.getElementById("brokenimagecontainer").collapsed = true;
- }
- else if (item instanceof HTMLVideoElement && isProtocolAllowed) {
- newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video");
- newImage.id = "thepreviewimage";
- newImage.src = url;
- newImage.controls = true;
- width = physWidth = item.videoWidth;
- height = physHeight = item.videoHeight;
-
- document.getElementById("theimagecontainer").collapsed = false;
- document.getElementById("brokenimagecontainer").collapsed = true;
- }
- else if (item instanceof HTMLAudioElement && isProtocolAllowed) {
- newImage = new Audio;
- newImage.id = "thepreviewimage";
- newImage.src = url;
- newImage.controls = true;
- isAudio = true;
-
- document.getElementById("theimagecontainer").collapsed = false;
- document.getElementById("brokenimagecontainer").collapsed = true;
- }
- else {
- // fallback image for protocols not allowed (e.g., javascript:)
- // or elements not [yet] handled (e.g., object, embed).
- document.getElementById("brokenimagecontainer").collapsed = false;
- document.getElementById("theimagecontainer").collapsed = true;
- }
-
- var imageSize = "";
- if (url && !isAudio) {
- if (width != physWidth || height != physHeight) {
- imageSize = gBundle.getFormattedString("mediaDimensionsScaled",
- [formatNumber(physWidth),
- formatNumber(physHeight),
- formatNumber(width),
- formatNumber(height)]);
- }
- else {
- imageSize = gBundle.getFormattedString("mediaDimensions",
- [formatNumber(width),
- formatNumber(height)]);
- }
- }
- setItemValue("imagedimensiontext", imageSize);
-
- makeBlockImage(url);
-
- imageContainer.removeChild(oldImage);
- imageContainer.appendChild(newImage);
-
- onImagePreviewShown.forEach(function(func) { func(); });
- });
-}
-
-function makeBlockImage(url)
-{
- var permissionManager = Components.classes[PERMISSION_CONTRACTID]
- .getService(nsIPermissionManager);
- var prefs = Components.classes[PREFERENCES_CONTRACTID]
- .getService(Components.interfaces.nsIPrefBranch);
-
- var checkbox = document.getElementById("blockImage");
- var imagePref = prefs.getIntPref("permissions.default.image");
- if (!(/^https?:/.test(url)) || imagePref == 2)
- // We can't block the images from this host because either is is not
- // for http(s) or we don't load images at all
- checkbox.hidden = true;
- else {
- var uri = makeURI(url);
- if (uri.host) {
- checkbox.hidden = false;
- checkbox.label = gBundle.getFormattedString("mediaBlockImage", [uri.host]);
- var perm = permissionManager.testPermission(uri, "image");
- checkbox.checked = perm == nsIPermissionManager.DENY_ACTION;
- }
- else
- checkbox.hidden = true;
- }
-}
-
-var imagePermissionObserver = {
- observe: function (aSubject, aTopic, aData)
- {
- if (document.getElementById("mediaPreviewBox").collapsed)
- return;
-
- if (aTopic == "perm-changed") {
- var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission);
- if (permission.type == "image") {
- var imageTree = document.getElementById("imagetree");
- var row = getSelectedRow(imageTree);
- var item = gImageView.data[row][COL_IMAGE_NODE];
- var url = gImageView.data[row][COL_IMAGE_ADDRESS];
- if (permission.matchesURI(makeURI(url), true)) {
- makeBlockImage(url);
- }
- }
- }
- }
-}
-
-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, "");
-}
-
-function setItemValue(id, value)
-{
- var item = document.getElementById(id);
- if (value) {
- item.parentNode.collapsed = false;
- item.value = value;
- }
- else
- item.parentNode.collapsed = true;
-}
-
-function formatNumber(number)
-{
- return (+number).toLocaleString(); // coerce number to a numeric value before calling toLocaleString()
-}
-
-function formatDate(datestr, unknown)
-{
- // scriptable date formatter, for pretty printing dates
- var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
- .getService(Components.interfaces.nsIScriptableDateFormat);
-
- var date = new Date(datestr);
- if (!date.valueOf())
- return unknown;
-
- return dateService.FormatDateTime("", dateService.dateFormatLong,
- dateService.timeFormatSeconds,
- date.getFullYear(), date.getMonth()+1, date.getDate(),
- date.getHours(), date.getMinutes(), date.getSeconds());
-}
-
-function doCopy()
-{
- if (!gClipboardHelper)
- return;
-
- var elem = document.commandDispatcher.focusedElement;
-
- if (elem && "treeBoxObject" in elem) {
- var view = elem.view;
- var selection = view.selection;
- var text = [], tmp = '';
- var min = {}, max = {};
-
- var count = selection.getRangeCount();
-
- for (var i = 0; i < count; i++) {
- selection.getRangeAt(i, min, max);
-
- for (var row = min.value; row <= max.value; row++) {
- view.performActionOnRow("copy", row);
-
- tmp = elem.getAttribute("copybuffer");
- if (tmp)
- text.push(tmp);
- elem.removeAttribute("copybuffer");
- }
- }
- gClipboardHelper.copyString(text.join("\n"), document);
- }
-}
-
-function doSelectAll()
-{
- var elem = document.commandDispatcher.focusedElement;
-
- if (elem && "treeBoxObject" in elem)
- elem.view.selection.selectAll();
-}
-
-function selectImage()
-{
- if (!gImageElement)
- return;
-
- 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]) {
- tree.view.selection.select(i);
- tree.treeBoxObject.ensureRowIsVisible(i);
- tree.focus();
- return;
- }
- }
-}
-
-function checkProtocol(img)
-{
- var url = img[COL_IMAGE_ADDRESS];
- return /^data:image\//i.test(url) ||
- /^(https?|ftp|file|about|chrome|resource):/.test(url);
-}