зеркало из https://github.com/mozilla/pjs.git
Fold nsContextMenu.js into browser.js, remove two script includes, fix search in context menu.
This commit is contained in:
Родитель
66e98ced58
Коммит
ea42bd5eb2
|
@ -1899,6 +1899,12 @@ function ensureDefaultEnginePrefs(aRDF,aDS)
|
|||
}
|
||||
}
|
||||
|
||||
function readRDFString(aDS,aRes,aProp)
|
||||
{
|
||||
var n = aDS.GetTarget(aRes, aProp, true);
|
||||
return n ? n.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
|
||||
}
|
||||
|
||||
function ensureSearchPref()
|
||||
{
|
||||
var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
|
||||
|
@ -3283,3 +3289,852 @@ function focusSearchBar()
|
|||
searchBar.focus();
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------ nsContextMenu ---------------------------------
|
||||
| This JavaScript "class" is used to implement the browser's content-area |
|
||||
| context menu. |
|
||||
| |
|
||||
| For usage, see references to this class in navigator.xul. |
|
||||
| |
|
||||
| Currently, this code is relatively useless for any other purpose. In the |
|
||||
| longer term, this code will be restructured to make it more reusable. |
|
||||
------------------------------------------------------------------------------*/
|
||||
const IMAGEPERMISSION = 1;
|
||||
function nsContextMenu( xulMenu ) {
|
||||
this.target = null;
|
||||
this.menu = null;
|
||||
this.onTextInput = false;
|
||||
this.onImage = false;
|
||||
this.onLink = false;
|
||||
this.onMailtoLink = false;
|
||||
this.onSaveableLink = false;
|
||||
this.onMetaDataItem = false;
|
||||
this.onMathML = false;
|
||||
this.link = false;
|
||||
this.inFrame = false;
|
||||
this.hasBGImage = false;
|
||||
this.isTextSelected = false;
|
||||
this.inDirList = false;
|
||||
this.shouldDisplay = true;
|
||||
|
||||
// Initialize new menu.
|
||||
this.initMenu( xulMenu );
|
||||
}
|
||||
|
||||
// Prototype for nsContextMenu "class."
|
||||
nsContextMenu.prototype = {
|
||||
// onDestroy is a no-op at this point.
|
||||
onDestroy : function () {
|
||||
},
|
||||
// Initialize context menu.
|
||||
initMenu : function ( popup ) {
|
||||
// Save menu.
|
||||
this.menu = popup;
|
||||
|
||||
// Get contextual info.
|
||||
this.setTarget( document.popupNode );
|
||||
|
||||
this.isTextSelected = this.isTextSelection();
|
||||
|
||||
// Initialize (disable/remove) menu items.
|
||||
this.initItems();
|
||||
},
|
||||
initItems : function () {
|
||||
this.initOpenItems();
|
||||
this.initNavigationItems();
|
||||
this.initViewItems();
|
||||
this.initMiscItems();
|
||||
this.initSaveItems();
|
||||
this.initClipboardItems();
|
||||
this.initMetadataItems();
|
||||
},
|
||||
initOpenItems : function () {
|
||||
this.showItem( "context-openlink", this.onSaveableLink || ( this.inDirList && this.onLink ) );
|
||||
this.showItem( "context-openlinkintab", this.onSaveableLink || ( this.inDirList && this.onLink ) );
|
||||
|
||||
this.showItem( "context-sep-open", this.onSaveableLink || ( this.inDirList && this.onLink ) );
|
||||
},
|
||||
initNavigationItems : function () {
|
||||
// Back determined by canGoBack broadcaster.
|
||||
this.setItemAttrFromNode( "context-back", "disabled", "canGoBack" );
|
||||
|
||||
// Forward determined by canGoForward broadcaster.
|
||||
this.setItemAttrFromNode( "context-forward", "disabled", "canGoForward" );
|
||||
|
||||
this.showItem( "context-back", !( this.isTextSelected || this.onLink || this.onImage || this.onTextInput ) );
|
||||
this.showItem( "context-forward", !( this.isTextSelected || this.onLink || this.onImage || this.onTextInput ) );
|
||||
|
||||
this.showItem( "context-reload", !( this.isTextSelected || this.onLink || this.onImage || this.onTextInput ) );
|
||||
|
||||
this.showItem( "context-stop", !( this.isTextSelected || this.onLink || this.onImage || this.onTextInput ) );
|
||||
this.showItem( "context-sep-stop", !( this.isTextSelected || this.onLink || this.onTextInput ) );
|
||||
|
||||
// XXX: Stop is determined in navigator.js; the canStop broadcaster is broken
|
||||
//this.setItemAttrFromNode( "context-stop", "disabled", "canStop" );
|
||||
},
|
||||
initSaveItems : function () {
|
||||
this.showItem( "context-savepage", !( this.inDirList || this.isTextSelected || this.onTextInput || this.onLink ));
|
||||
|
||||
// Save link depends on whether we're in a link.
|
||||
this.showItem( "context-savelink", this.onSaveableLink );
|
||||
|
||||
// Save image depends on whether there is one.
|
||||
this.showItem( "context-saveimage", this.onImage );
|
||||
|
||||
this.showItem( "context-sendimage", this.onImage );
|
||||
},
|
||||
initViewItems : function () {
|
||||
// View source is always OK, unless in directory listing.
|
||||
this.showItem( "context-viewpartialsource-selection", this.isTextSelected );
|
||||
this.showItem( "context-viewpartialsource-mathml", this.onMathML && !this.isTextSelected );
|
||||
this.showItem( "context-viewsource", !( this.inDirList || this.onImage || this.isTextSelected || this.onLink || this.onTextInput ) );
|
||||
this.showItem( "context-viewinfo", !( this.inDirList || this.onImage || this.isTextSelected || this.onLink || this.onTextInput ) );
|
||||
|
||||
this.showItem( "context-sep-properties", !( this.inDirList || this.isTextSelected || this.onTextInput ) );
|
||||
// Set As Wallpaper depends on whether an image was clicked on, and only works on Windows.
|
||||
var isWin = navigator.appVersion.indexOf("Windows") != -1;
|
||||
this.showItem( "context-setWallpaper", isWin && this.onImage );
|
||||
|
||||
if( isWin && this.onImage )
|
||||
// Disable the Set As Wallpaper menu item if we're still trying to load the image
|
||||
this.setItemAttr( "context-setWallpaper", "disabled", (("complete" in this.target) && !this.target.complete) ? "true" : null );
|
||||
|
||||
// View Image depends on whether an image was clicked on.
|
||||
this.showItem( "context-viewimage", this.onImage );
|
||||
|
||||
// View background image depends on whether there is one.
|
||||
this.showItem( "context-viewbgimage", !( this.inDirList || this.onImage || this.isTextSelected || this.onLink || this.onTextInput ) );
|
||||
this.showItem( "context-sep-viewbgimage", !( this.inDirList || this.onImage || this.isTextSelected || this.onLink || this.onTextInput ) );
|
||||
this.setItemAttr( "context-viewbgimage", "disabled", this.hasBGImage ? null : "true");
|
||||
},
|
||||
initMiscItems : function () {
|
||||
// Use "Bookmark This Link" if on a link.
|
||||
this.showItem( "context-bookmarkpage", !( this.isTextSelected || this.onTextInput || this.onLink ) );
|
||||
this.showItem( "context-bookmarklink", this.onLink && !this.onMailtoLink );
|
||||
this.showItem( "context-searchselect", this.isTextSelected );
|
||||
this.showItem( "frame", this.inFrame );
|
||||
this.showItem( "frame-sep", this.inFrame );
|
||||
this.showItem( "context-blockimage", this.onImage);
|
||||
if (this.onImage) {
|
||||
var blockImage = document.getElementById("context-blockimage");
|
||||
if (this.isImageBlocked()) {
|
||||
blockImage.setAttribute("checked", "true");
|
||||
}
|
||||
else
|
||||
blockImage.removeAttribute("checked");
|
||||
}
|
||||
},
|
||||
initClipboardItems : function () {
|
||||
|
||||
// Copy depends on whether there is selected text.
|
||||
// Enabling this context menu item is now done through the global
|
||||
// command updating system
|
||||
// this.setItemAttr( "context-copy", "disabled", !this.isTextSelected() );
|
||||
|
||||
goUpdateGlobalEditMenuItems();
|
||||
|
||||
this.showItem( "context-undo", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-sep-undo", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-cut", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-copy", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-paste", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-delete", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-sep-paste", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-selectall", this.isTextSelected || this.onTextInput );
|
||||
this.showItem( "context-sep-selectall", this.isTextSelected );
|
||||
|
||||
// XXX dr
|
||||
// ------
|
||||
// nsDocumentViewer.cpp has code to determine whether we're
|
||||
// on a link or an image. we really ought to be using that...
|
||||
|
||||
// Copy email link depends on whether we're on an email link.
|
||||
this.showItem( "context-copyemail", this.onMailtoLink );
|
||||
|
||||
// Copy link location depends on whether we're on a link.
|
||||
this.showItem( "context-copylink", this.onLink );
|
||||
this.showItem( "context-sep-copylink", this.onLink && this.onImage);
|
||||
|
||||
// Copy image location depends on whether we're on an image.
|
||||
this.showItem( "context-copyimage", this.onImage );
|
||||
this.showItem( "context-sep-copyimage", this.onImage );
|
||||
},
|
||||
initMetadataItems : function () {
|
||||
// Show if user clicked on something which has metadata.
|
||||
this.showItem( "context-metadata", this.onMetaDataItem );
|
||||
},
|
||||
// Set various context menu attributes based on the state of the world.
|
||||
setTarget : function ( node ) {
|
||||
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
if ( node.namespaceURI == xulNS ) {
|
||||
this.shouldDisplay = false;
|
||||
return;
|
||||
}
|
||||
// Initialize contextual info.
|
||||
this.onImage = false;
|
||||
this.onMetaDataItem = false;
|
||||
this.onTextInput = false;
|
||||
this.imageURL = "";
|
||||
this.onLink = false;
|
||||
this.onMathML = false;
|
||||
this.inFrame = false;
|
||||
this.hasBGImage = false;
|
||||
this.bgImageURL = "";
|
||||
|
||||
// Remember the node that was clicked.
|
||||
this.target = node;
|
||||
|
||||
// See if the user clicked on an image.
|
||||
if ( this.target.nodeType == Node.ELEMENT_NODE ) {
|
||||
if ( this.target.localName.toUpperCase() == "IMG" ) {
|
||||
this.onImage = true;
|
||||
this.imageURL = this.target.src;
|
||||
// Look for image map.
|
||||
var mapName = this.target.getAttribute( "usemap" );
|
||||
if ( mapName ) {
|
||||
// Find map.
|
||||
var map = this.target.ownerDocument.getElementById( mapName.substr(1) );
|
||||
if ( map ) {
|
||||
// Search child <area>s for a match.
|
||||
var areas = map.childNodes;
|
||||
//XXX Client side image maps are too hard for now!
|
||||
areas.length = 0;
|
||||
for ( var i = 0; i < areas.length && !this.onLink; i++ ) {
|
||||
var area = areas[i];
|
||||
if ( area.nodeType == Node.ELEMENT_NODE
|
||||
&&
|
||||
area.localName.toUpperCase() == "AREA" ) {
|
||||
// Get type (rect/circle/polygon/default).
|
||||
var type = area.getAttribute( "type" );
|
||||
var coords = this.parseCoords( area );
|
||||
switch ( type.toUpperCase() ) {
|
||||
case "RECT":
|
||||
case "RECTANGLE":
|
||||
break;
|
||||
case "CIRC":
|
||||
case "CIRCLE":
|
||||
break;
|
||||
case "POLY":
|
||||
case "POLYGON":
|
||||
break;
|
||||
case "DEFAULT":
|
||||
// Default matches entire image.
|
||||
this.onLink = true;
|
||||
this.link = area;
|
||||
this.onSaveableLink = this.isLinkSaveable( this.link );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ( this.target.localName.toUpperCase() == "OBJECT"
|
||||
&&
|
||||
// See if object tag is for an image.
|
||||
this.objectIsImage( this.target ) ) {
|
||||
// This is an image.
|
||||
this.onImage = true;
|
||||
// URL must be constructed.
|
||||
this.imageURL = this.objectImageURL( this.target );
|
||||
} else if ( this.target.localName.toUpperCase() == "INPUT") {
|
||||
type = this.target.getAttribute("type");
|
||||
if(type && type.toUpperCase() == "IMAGE") {
|
||||
this.onImage = true;
|
||||
// Convert src attribute to absolute URL.
|
||||
this.imageURL = this.makeURLAbsolute( this.target.baseURI,
|
||||
this.target.src );
|
||||
} else /* if (this.target.getAttribute( "type" ).toUpperCase() == "TEXT") */ {
|
||||
this.onTextInput = this.isTargetATextBox(this.target);
|
||||
}
|
||||
} else if ( this.target.localName.toUpperCase() == "TEXTAREA" ) {
|
||||
this.onTextInput = true;
|
||||
} else if ( this.target.localName.toUpperCase() == "HTML" ) {
|
||||
// pages with multiple <body>s are lame. we'll teach them a lesson.
|
||||
var bodyElt = this.target.ownerDocument.getElementsByTagName("body")[0];
|
||||
if ( bodyElt ) {
|
||||
var computedURL = this.getComputedURL( bodyElt, "background-image" );
|
||||
if ( computedURL ) {
|
||||
this.hasBGImage = true;
|
||||
this.bgImageURL = this.makeURLAbsolute( bodyElt.baseURI,
|
||||
computedURL );
|
||||
}
|
||||
}
|
||||
} else if ( "HTTPIndex" in _content &&
|
||||
_content.HTTPIndex instanceof Components.interfaces.nsIHTTPIndex ) {
|
||||
this.inDirList = true;
|
||||
// Bubble outward till we get to an element with URL attribute
|
||||
// (which should be the href).
|
||||
var root = this.target;
|
||||
while ( root && !this.link ) {
|
||||
if ( root.tagName == "tree" ) {
|
||||
// Hit root of tree; must have clicked in empty space;
|
||||
// thus, no link.
|
||||
break;
|
||||
}
|
||||
if ( root.getAttribute( "URL" ) ) {
|
||||
// Build pseudo link object so link-related functions work.
|
||||
this.onLink = true;
|
||||
this.link = { href : root.getAttribute("URL"),
|
||||
getAttribute: function (attr) {
|
||||
if (attr == "title") {
|
||||
return root.firstChild.firstChild.getAttribute("label");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
// If element is a directory, then you can't save it.
|
||||
if ( root.getAttribute( "container" ) == "true" ) {
|
||||
this.onSaveableLink = false;
|
||||
} else {
|
||||
this.onSaveableLink = true;
|
||||
}
|
||||
} else {
|
||||
root = root.parentNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We have meta data on images.
|
||||
this.onMetaDataItem = this.onImage;
|
||||
|
||||
// See if the user clicked on MathML
|
||||
const NS_MathML = "http://www.w3.org/1998/Math/MathML";
|
||||
if ((this.target.nodeType == Node.TEXT_NODE &&
|
||||
this.target.parentNode.namespaceURI == NS_MathML)
|
||||
|| (this.target.namespaceURI == NS_MathML))
|
||||
this.onMathML = true;
|
||||
|
||||
// See if the user clicked in a frame.
|
||||
if ( this.target.ownerDocument != window._content.document ) {
|
||||
this.inFrame = true;
|
||||
}
|
||||
|
||||
// Bubble out, looking for items of interest
|
||||
var elem = this.target;
|
||||
while ( elem ) {
|
||||
if ( elem.nodeType == Node.ELEMENT_NODE ) {
|
||||
var localname = elem.localName.toUpperCase();
|
||||
|
||||
// Link?
|
||||
if ( !this.onLink &&
|
||||
( (localname === "A" && elem.href) ||
|
||||
localname === "AREA" ||
|
||||
localname === "LINK" ||
|
||||
elem.getAttributeNS( "http://www.w3.org/1999/xlink", "type") == "simple" ) ) {
|
||||
// Clicked on a link.
|
||||
this.onLink = true;
|
||||
this.onMetaDataItem = true;
|
||||
// Remember corresponding element.
|
||||
this.link = elem;
|
||||
this.onMailtoLink = this.isLinkType( "mailto:", this.link );
|
||||
// Remember if it is saveable.
|
||||
this.onSaveableLink = this.isLinkSaveable( this.link );
|
||||
}
|
||||
|
||||
// Text input?
|
||||
if ( !this.onTextInput ) {
|
||||
// Clicked on a link.
|
||||
this.onTextInput = this.isTargetATextBox(elem);
|
||||
}
|
||||
|
||||
// Metadata item?
|
||||
if ( !this.onMetaDataItem ) {
|
||||
// We currently display metadata on anything which fits
|
||||
// the below test.
|
||||
if ( ( localname === "BLOCKQUOTE" && 'cite' in elem && elem.cite) ||
|
||||
( localname === "Q" && 'cite' in elem && elem.cite) ||
|
||||
( localname === "TABLE" && 'summary' in elem && elem.summary) ||
|
||||
( ( localname === "INS" || localname === "DEL" ) &&
|
||||
( ( 'cite' in elem && elem.cite ) ||
|
||||
( 'dateTime' in elem && elem.dateTime ) ) ) ||
|
||||
( 'title' in elem && elem.title ) ||
|
||||
( 'lang' in elem && elem.lang ) ) {
|
||||
dump("On metadata item.\n");
|
||||
this.onMetaDataItem = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Background image? Don't bother if we've already found a
|
||||
// background image further down the hierarchy. Otherwise,
|
||||
// we look for the computed background-image style.
|
||||
if ( !this.hasBGImage ) {
|
||||
var bgImgUrl = this.getComputedURL( elem, "background-image" );
|
||||
if ( bgImgUrl ) {
|
||||
this.hasBGImage = true;
|
||||
this.bgImageURL = this.makeURLAbsolute( elem.baseURI,
|
||||
bgImgUrl );
|
||||
}
|
||||
}
|
||||
}
|
||||
elem = elem.parentNode;
|
||||
}
|
||||
},
|
||||
// Returns the computed style attribute for the given element.
|
||||
getComputedStyle: function( elem, prop ) {
|
||||
return elem.ownerDocument.defaultView.getComputedStyle( elem, '' ).getPropertyValue( prop );
|
||||
},
|
||||
// Returns a "url"-type computed style attribute value, with the url() stripped.
|
||||
getComputedURL: function( elem, prop ) {
|
||||
var url = elem.ownerDocument.defaultView.getComputedStyle( elem, '' ).getPropertyCSSValue( prop );
|
||||
return ( url.primitiveType == CSSPrimitiveValue.CSS_URI ) ? url.getStringValue() : null;
|
||||
},
|
||||
// Returns true iff clicked on link is saveable.
|
||||
isLinkSaveable : function ( link ) {
|
||||
// We don't do the Right Thing for news/snews yet, so turn them off
|
||||
// until we do.
|
||||
return !(this.isLinkType( "mailto:" , link ) ||
|
||||
this.isLinkType( "javascript:" , link ) ||
|
||||
this.isLinkType( "news:", link ) ||
|
||||
this.isLinkType( "snews:", link ) );
|
||||
},
|
||||
// Returns true iff clicked on link is of type given.
|
||||
isLinkType : function ( linktype, link ) {
|
||||
try {
|
||||
// Test for missing protocol property.
|
||||
if ( !link.protocol ) {
|
||||
// We must resort to testing the URL string :-(.
|
||||
var protocol;
|
||||
if ( link.href ) {
|
||||
protocol = link.href.substr( 0, linktype.length );
|
||||
} else {
|
||||
protocol = link.getAttributeNS("http://www.w3.org/1999/xlink","href");
|
||||
if ( protocol ) {
|
||||
protocol = protocol.substr( 0, linktype.length );
|
||||
}
|
||||
}
|
||||
return protocol.toLowerCase() === linktype;
|
||||
} else {
|
||||
// Presume all but javascript: urls are saveable.
|
||||
return link.protocol.toLowerCase() === linktype;
|
||||
}
|
||||
} catch (e) {
|
||||
// something was wrong with the link,
|
||||
// so we won't be able to save it anyway
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// Open linked-to URL in a new window.
|
||||
openLink : function () {
|
||||
// Determine linked-to URL.
|
||||
openNewWindowWith( this.linkURL() );
|
||||
},
|
||||
// Open linked-to URL in a new tab.
|
||||
openLinkInTab : function () {
|
||||
// Determine linked-to URL.
|
||||
openNewTabWith( this.linkURL() );
|
||||
},
|
||||
// Open frame in a new tab.
|
||||
openFrameInTab : function () {
|
||||
// Determine linked-to URL.
|
||||
openNewTabWith( this.target.ownerDocument.location.href );
|
||||
},
|
||||
// Reload clicked-in frame.
|
||||
reloadFrame : function () {
|
||||
this.target.ownerDocument.location.reload();
|
||||
},
|
||||
// Open clicked-in frame in its own window.
|
||||
openFrame : function () {
|
||||
openNewWindowWith( this.target.ownerDocument.location.href );
|
||||
},
|
||||
// Open clicked-in frame in the same window
|
||||
showOnlyThisFrame : function () {
|
||||
window.loadURI(this.target.ownerDocument.location.href);
|
||||
},
|
||||
// View Partial Source
|
||||
viewPartialSource : function ( context ) {
|
||||
var focusedWindow = document.commandDispatcher.focusedWindow;
|
||||
if (focusedWindow == window)
|
||||
focusedWindow = _content;
|
||||
var docCharset = null;
|
||||
if (focusedWindow)
|
||||
docCharset = "charset=" + focusedWindow.document.characterSet;
|
||||
|
||||
// "View Selection Source" and others such as "View MathML Source"
|
||||
// are mutually exclusive, with the precedence given to the selection
|
||||
// when there is one
|
||||
var reference = null;
|
||||
if (context == "selection")
|
||||
reference = focusedWindow.__proto__.getSelection.call(focusedWindow);
|
||||
else if (context == "mathml")
|
||||
reference = this.target;
|
||||
else
|
||||
throw "not reached";
|
||||
|
||||
var docUrl = null; // unused (and play nice for fragments generated via XSLT too)
|
||||
window.openDialog("chrome://browser/content/viewPartialSource.xul",
|
||||
"_blank", "scrollbars,resizable,chrome,dialog=no",
|
||||
docUrl, docCharset, reference, context);
|
||||
},
|
||||
// Open new "view source" window with the frame's URL.
|
||||
viewFrameSource : function () {
|
||||
BrowserViewSourceOfDocument(this.target.ownerDocument);
|
||||
},
|
||||
viewInfo : function () {
|
||||
BrowserPageInfo();
|
||||
},
|
||||
viewFrameInfo : function () {
|
||||
BrowserPageInfo(this.target.ownerDocument);
|
||||
},
|
||||
// Change current window to the URL of the image.
|
||||
viewImage : function () {
|
||||
openTopWin( this.imageURL );
|
||||
},
|
||||
// Change current window to the URL of the background image.
|
||||
viewBGImage : function () {
|
||||
openTopWin( this.bgImageURL );
|
||||
},
|
||||
setWallpaper: function() {
|
||||
var winhooks = Components.classes[ "@mozilla.org/winhooks;1" ].
|
||||
getService(Components.interfaces.nsIWindowsHooks);
|
||||
|
||||
winhooks.setImageAsWallpaper(this.target, false);
|
||||
},
|
||||
// Save URL of clicked-on frame.
|
||||
saveFrame : function () {
|
||||
saveDocument( this.target.ownerDocument );
|
||||
},
|
||||
// Save URL of clicked-on link.
|
||||
saveLink : function () {
|
||||
saveURL( this.linkURL(), this.linkText(), null, true );
|
||||
},
|
||||
// Save URL of clicked-on image.
|
||||
saveImage : function () {
|
||||
saveURL( this.imageURL, null, "SaveImageTitle", false );
|
||||
},
|
||||
toggleImageBlocking : function (aBlock) {
|
||||
var permissionmanager =
|
||||
Components.classes["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Components.interfaces.nsIPermissionManager);
|
||||
permissionmanager.add(this.imageURL, !aBlock, IMAGEPERMISSION);
|
||||
},
|
||||
isImageBlocked : function() {
|
||||
var permissionmanager =
|
||||
Components.classes["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Components.interfaces.nsIPermissionManager);
|
||||
return permissionmanager.testForBlocking(this.imageURL, IMAGEPERMISSION);
|
||||
},
|
||||
// Generate email address and put it on clipboard.
|
||||
copyEmail : function () {
|
||||
// Copy the comma-separated list of email addresses only.
|
||||
// There are other ways of embedding email addresses in a mailto:
|
||||
// link, but such complex parsing is beyond us.
|
||||
var url = this.linkURL();
|
||||
var qmark = url.indexOf( "?" );
|
||||
var addresses;
|
||||
|
||||
if ( qmark > 7 ) { // 7 == length of "mailto:"
|
||||
addresses = url.substring( 7, qmark );
|
||||
} else {
|
||||
addresses = url.substr( 7 );
|
||||
}
|
||||
|
||||
var clipboard = this.getService( "@mozilla.org/widget/clipboardhelper;1",
|
||||
Components.interfaces.nsIClipboardHelper );
|
||||
clipboard.copyString(addresses);
|
||||
},
|
||||
addBookmark : function() {
|
||||
var docshell = document.getElementById( "content" ).webNavigation;
|
||||
BookmarksUtils.addBookmark( docshell.currentURI.spec,
|
||||
docshell.document.title,
|
||||
docshell.document.charset,
|
||||
false );
|
||||
},
|
||||
addBookmarkForFrame : function() {
|
||||
var doc = this.target.ownerDocument;
|
||||
var uri = doc.location.href;
|
||||
var title = doc.title;
|
||||
if ( !title )
|
||||
title = uri;
|
||||
BookmarksUtils.addBookmark( uri,
|
||||
title,
|
||||
doc.charset,
|
||||
false );
|
||||
},
|
||||
// Open Metadata window for node
|
||||
showMetadata : function () {
|
||||
window.openDialog( "chrome://navigator/content/metadata.xul",
|
||||
"_blank",
|
||||
"scrollbars,resizable,chrome,dialog=no",
|
||||
this.target);
|
||||
},
|
||||
|
||||
///////////////
|
||||
// Utilities //
|
||||
///////////////
|
||||
|
||||
// Create instance of component given contractId and iid (as string).
|
||||
createInstance : function ( contractId, iidName ) {
|
||||
var iid = Components.interfaces[ iidName ];
|
||||
return Components.classes[ contractId ].createInstance( iid );
|
||||
},
|
||||
// Get service given contractId and iid (as string).
|
||||
getService : function ( contractId, iidName ) {
|
||||
var iid = Components.interfaces[ iidName ];
|
||||
return Components.classes[ contractId ].getService( iid );
|
||||
},
|
||||
// Show/hide one item (specified via name or the item element itself).
|
||||
showItem : function ( itemOrId, show ) {
|
||||
var item = itemOrId.constructor == String ? document.getElementById(itemOrId) : itemOrId;
|
||||
if (item)
|
||||
item.hidden = !show;
|
||||
},
|
||||
// Set given attribute of specified context-menu item. If the
|
||||
// value is null, then it removes the attribute (which works
|
||||
// nicely for the disabled attribute).
|
||||
setItemAttr : function ( id, attr, val ) {
|
||||
var elem = document.getElementById( id );
|
||||
if ( elem ) {
|
||||
if ( val == null ) {
|
||||
// null indicates attr should be removed.
|
||||
elem.removeAttribute( attr );
|
||||
} else {
|
||||
// Set attr=val.
|
||||
elem.setAttribute( attr, val );
|
||||
}
|
||||
}
|
||||
},
|
||||
// Set context menu attribute according to like attribute of another node
|
||||
// (such as a broadcaster).
|
||||
setItemAttrFromNode : function ( item_id, attr, other_id ) {
|
||||
var elem = document.getElementById( other_id );
|
||||
if ( elem && elem.getAttribute( attr ) == "true" ) {
|
||||
this.setItemAttr( item_id, attr, "true" );
|
||||
} else {
|
||||
this.setItemAttr( item_id, attr, null );
|
||||
}
|
||||
},
|
||||
// Temporary workaround for DOM api not yet implemented by XUL nodes.
|
||||
cloneNode : function ( item ) {
|
||||
// Create another element like the one we're cloning.
|
||||
var node = document.createElement( item.tagName );
|
||||
|
||||
// Copy attributes from argument item to the new one.
|
||||
var attrs = item.attributes;
|
||||
for ( var i = 0; i < attrs.length; i++ ) {
|
||||
var attr = attrs.item( i );
|
||||
node.setAttribute( attr.nodeName, attr.nodeValue );
|
||||
}
|
||||
|
||||
// Voila!
|
||||
return node;
|
||||
},
|
||||
// Generate fully-qualified URL for clicked-on link.
|
||||
linkURL : function () {
|
||||
if (this.link.href) {
|
||||
return this.link.href;
|
||||
}
|
||||
var href = this.link.getAttributeNS("http://www.w3.org/1999/xlink","href");
|
||||
if (!href || !href.match(/\S/)) {
|
||||
throw "Empty href"; // Without this we try to save as the current doc, for example, HTML case also throws if empty
|
||||
}
|
||||
href = this.makeURLAbsolute(this.link.baseURI,href);
|
||||
return href;
|
||||
},
|
||||
// Get text of link.
|
||||
linkText : function () {
|
||||
var text = gatherTextUnder( this.link );
|
||||
if (!text || !text.match(/\S/)) {
|
||||
text = this.link.getAttribute("title");
|
||||
if (!text || !text.match(/\S/)) {
|
||||
text = this.link.getAttribute("alt");
|
||||
if (!text || !text.match(/\S/)) {
|
||||
if (this.link.href) {
|
||||
text = this.link.href;
|
||||
} else {
|
||||
text = getAttributeNS("http://www.w3.org/1999/xlink", "href");
|
||||
if (text && text.match(/\S/)) {
|
||||
text = this.makeURLAbsolute(this.link.baseURI, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
//Get selected object and convert it to a string to get
|
||||
//selected text. Only use the first 15 chars.
|
||||
isTextSelection : function() {
|
||||
var result = false;
|
||||
var selection = this.searchSelected();
|
||||
|
||||
var searchSelectText;
|
||||
if (selection != "") {
|
||||
searchSelectText = selection.toString();
|
||||
if (searchSelectText.length > 15)
|
||||
searchSelectText = searchSelectText.substr(0,15) + "...";
|
||||
result = true;
|
||||
|
||||
// format "Search for <selection>" string to show in menu
|
||||
var bundle = document.getElementById("contentAreaBundle");
|
||||
searchSelectText = bundle.getFormattedString("searchText", [searchSelectText]);
|
||||
this.setItemAttr("context-searchselect", "label", searchSelectText);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
searchSelected : function() {
|
||||
var focusedWindow = document.commandDispatcher.focusedWindow;
|
||||
var searchStr = focusedWindow.__proto__.getSelection.call(focusedWindow);
|
||||
searchStr = searchStr.toString();
|
||||
searchStr = searchStr.replace( /^\s+/, "" );
|
||||
searchStr = searchStr.replace(/(\n|\r|\t)+/g, " ");
|
||||
searchStr = searchStr.replace(/\s+$/,"");
|
||||
return searchStr;
|
||||
},
|
||||
|
||||
// Determine if target <object> is an image.
|
||||
objectIsImage : function ( objElem ) {
|
||||
var result = false;
|
||||
// Get type and data attributes.
|
||||
var type = objElem.getAttribute( "type" );
|
||||
var data = objElem.getAttribute( "data" );
|
||||
// Presume any mime type of the form "image/..." is an image.
|
||||
// There must be a data= attribute with an URL, also.
|
||||
if ( type.substring( 0, 6 ) == "image/" && data && data != "" ) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
// Extract image URL from <object> tag.
|
||||
objectImageURL : function ( objElem ) {
|
||||
// Extract url from data= attribute.
|
||||
var data = objElem.getAttribute( "data" );
|
||||
// Make it absolute.
|
||||
return this.makeURLAbsolute( objElem.baseURI, data );
|
||||
},
|
||||
// Convert relative URL to absolute, using document's <base>.
|
||||
makeURLAbsolute : function ( base, url ) {
|
||||
// Construct nsIURL.
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
var baseURI = ioService.newURI(base, null, null);
|
||||
|
||||
return ioService.newURI(baseURI.resolve(url), null, null).spec;
|
||||
},
|
||||
// Parse coords= attribute and return array.
|
||||
parseCoords : function ( area ) {
|
||||
return [];
|
||||
},
|
||||
toString : function () {
|
||||
return "contextMenu.target = " + this.target + "\n" +
|
||||
"contextMenu.onImage = " + this.onImage + "\n" +
|
||||
"contextMenu.onLink = " + this.onLink + "\n" +
|
||||
"contextMenu.link = " + this.link + "\n" +
|
||||
"contextMenu.inFrame = " + this.inFrame + "\n" +
|
||||
"contextMenu.hasBGImage = " + this.hasBGImage + "\n";
|
||||
},
|
||||
isTargetATextBox : function ( node )
|
||||
{
|
||||
if (node.nodeType != Node.ELEMENT_NODE)
|
||||
return false;
|
||||
|
||||
if (node.localName.toUpperCase() == "INPUT") {
|
||||
var attrib = "";
|
||||
var type = node.getAttribute("type");
|
||||
|
||||
if (type)
|
||||
attrib = type.toUpperCase();
|
||||
|
||||
return( (attrib != "IMAGE") &&
|
||||
(attrib != "CHECKBOX") &&
|
||||
(attrib != "RADIO") &&
|
||||
(attrib != "SUBMIT") &&
|
||||
(attrib != "RESET") &&
|
||||
(attrib != "FILE") &&
|
||||
(attrib != "HIDDEN") &&
|
||||
(attrib != "RESET") &&
|
||||
(attrib != "BUTTON") );
|
||||
} else {
|
||||
return(node.localName.toUpperCase() == "TEXTAREA");
|
||||
}
|
||||
},
|
||||
|
||||
// Determines whether or not the separator with the specified ID should be
|
||||
// shown or not by determining if there are any non-hidden items between it
|
||||
// and the previous separator.
|
||||
shouldShowSeparator : function ( aSeparatorID )
|
||||
{
|
||||
var separator = document.getElementById(aSeparatorID);
|
||||
if (separator) {
|
||||
var sibling = separator.previousSibling;
|
||||
while (sibling && sibling.localName != "menuseparator") {
|
||||
if (sibling.getAttribute("hidden") != "true")
|
||||
return true;
|
||||
sibling = sibling.previousSibling;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* nsDefaultEngine : nsIObserver
|
||||
*
|
||||
*************************************************************************/
|
||||
function nsDefaultEngine()
|
||||
{
|
||||
try
|
||||
{
|
||||
var pb = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
var pbi = pb.QueryInterface(
|
||||
Components.interfaces.nsIPrefBranchInternal);
|
||||
pbi.addObserver(this.domain, this, false);
|
||||
|
||||
// reuse code by explicitly invoking initial |observe| call
|
||||
// to initialize the |icon| and |name| member variables
|
||||
this.observe(pb, "", this.domain);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
nsDefaultEngine.prototype =
|
||||
{
|
||||
name: "",
|
||||
icon: "",
|
||||
domain: "browser.search.defaultengine",
|
||||
|
||||
// nsIObserver implementation
|
||||
observe: function(aPrefBranch, aTopic, aPrefName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rdf = Components.
|
||||
classes["@mozilla.org/rdf/rdf-service;1"].
|
||||
getService(Components.interfaces.nsIRDFService);
|
||||
var ds = rdf.GetDataSource("rdf:internetsearch");
|
||||
var defaultEngine = aPrefBranch.getCharPref(aPrefName);
|
||||
var res = rdf.GetResource(defaultEngine);
|
||||
|
||||
// get engine ``pretty'' name
|
||||
const kNC_Name = rdf.GetResource(
|
||||
"http://home.netscape.com/NC-rdf#Name");
|
||||
var engineName = ds.GetTarget(res, kNC_Name, true);
|
||||
if (engineName)
|
||||
{
|
||||
this.name = engineName.QueryInterface(
|
||||
Components.interfaces.nsIRDFLiteral).Value;
|
||||
}
|
||||
|
||||
// get URL to engine vendor icon
|
||||
const kNC_Icon = rdf.GetResource(
|
||||
"http://home.netscape.com/NC-rdf#Icon");
|
||||
var iconURL = ds.GetTarget(res, kNC_Icon, true);
|
||||
if (iconURL)
|
||||
{
|
||||
this.icon = iconURL.QueryInterface(
|
||||
Components.interfaces.nsIRDFLiteral).Value;
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsClipboard.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/strres.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/x-javascript" src="chrome://browser/content/contentAreaClick.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaDD.js"/>
|
||||
|
@ -63,9 +62,7 @@
|
|||
<script type="application/x-javascript" src="chrome://global/content/charset.js"/>
|
||||
<script type="application/x-javascript" src="chrome://browser/content/bookmarks/bookmarks.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/viewZoomOverlay.js"/>
|
||||
|
||||
<script type="application/x-javascript" src="chrome://browser/content/browser.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsContextMenu.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaUtils.js"/>
|
||||
|
||||
<stringbundleset id="stringbundleset"> <!-- Overlay hook for 3rd parties. Don't remove. -->
|
||||
|
@ -74,6 +71,7 @@
|
|||
<stringbundle id="bundle_browser_region" src="chrome://navigator-region/locale/region.properties"/>
|
||||
<stringbundle id="bundle_brand_region" src="chrome://global-region/locale/region.properties"/>
|
||||
<stringbundle id="findBundle" src="chrome://global/locale/finddialog.properties"/>
|
||||
<stringbundle id="contentAreaBundle" src="chrome://communicator/locale/contentAreaCommands.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<commandset commandupdater="true"
|
||||
|
|
Загрузка…
Ссылка в новой задаче