// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- /* 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/. */ /* * context menu command handlers */ var ContextCommands = { _picker: null, get _ellipsis() { delete this._ellipsis; this._ellipsis = "\u2026"; try { this._ellipsis = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data; } catch (ex) { } return this._ellipsis; }, get clipboard() { return Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, get docRef() { return Browser.selectedBrowser.contentWindow.document; }, /* * Context menu handlers */ // Text specific cut: function cc_cut() { let target = ContextMenuUI.popupState.target; if (!target) return; if (target.localName === "browser") { // content if (ContextMenuUI.popupState.string) { this.sendCommand("cut"); SelectionHelperUI.closeEditSession(true); } } else { // chrome target.editor.cut(); } target.focus(); }, copy: function cc_copy() { let target = ContextMenuUI.popupState.target; if (!target) return; if (target.localName == "browser") { // content if (ContextMenuUI.popupState.string) { this.sendCommand("copy"); SelectionHelperUI.closeEditSession(true); } } else { // chrome target.editor.copy(); } target.focus(); }, paste: function cc_paste() { let target = ContextMenuUI.popupState.target; if (target.localName == "browser") { // content let x = ContextMenuUI.popupState.x; let y = ContextMenuUI.popupState.y; let json = {x: x, y: y, command: "paste" }; target.messageManager.sendAsyncMessage("Browser:ContextCommand", json); SelectionHelperUI.closeEditSession(); } else { // chrome target.editor.paste(Ci.nsIClipboard.kGlobalClipboard); target.focus(); } }, pasteAndGo: function cc_pasteAndGo() { let target = ContextMenuUI.popupState.target; target.editor.selectAll(); target.editor.paste(Ci.nsIClipboard.kGlobalClipboard); BrowserUI.goToURI(); }, select: function cc_select() { SelectionHelperUI.openEditSession(ContextMenuUI.popupState.target, ContextMenuUI.popupState.xPos, ContextMenuUI.popupState.yPos); }, selectAll: function cc_selectAll() { let target = ContextMenuUI.popupState.target; if (target.localName == "browser") { // content let x = ContextMenuUI.popupState.xPos; let y = ContextMenuUI.popupState.yPos; let json = {x: x, y: y, command: "select-all" }; target.messageManager.sendAsyncMessage("Browser:ContextCommand", json); SelectionHelperUI.attachEditSession(target, x, y); } else { // chrome target.editor.selectAll(); target.focus(); } }, // called on display of the search text menu item searchTextSetup: function cc_searchTextSetup(aRichListItem, aSearchString) { let defaultURI; let defaultName; aSearchString = aSearchString.trim(); try { let defaultPB = Services.prefs.getDefaultBranch(null); const nsIPLS = Ci.nsIPrefLocalizedString; defaultName = defaultPB.getComplexValue("browser.search.defaultenginename", nsIPLS).data; let defaultEngine = Services.search.getEngineByName(defaultName); defaultURI = defaultEngine.getSubmission(aSearchString).uri.spec; } catch (ex) { Cu.reportError(ex); return false; } let displayString = aSearchString; if (displayString.length > 15) { displayString = displayString.substring(0, 15) + this._ellipsis; } // label child node let label = Services.strings .createBundle("chrome://browser/locale/browser.properties") .formatStringFromName("browser.search.contextTextSearchLabel2", [defaultName, displayString], 2); aRichListItem.childNodes[0].setAttribute("value", label); aRichListItem.setAttribute("searchString", defaultURI); return true; }, searchText: function cc_searchText(aRichListItem) { let defaultURI = aRichListItem.getAttribute("searchString"); aRichListItem.childNodes[0].setAttribute("value", ""); aRichListItem.setAttribute("searchString", ""); BrowserUI.newTab(defaultURI, Browser.selectedTab); }, // Link specific openLinkInNewTab: function cc_openLinkInNewTab() { Browser.addTab(ContextMenuUI.popupState.linkURL, false, Browser.selectedTab); ContextUI.peekTabs(); }, copyLink: function cc_copyLink() { this.clipboard.copyString(ContextMenuUI.popupState.linkURL, this.docRef); }, bookmarkLink: function cc_bookmarkLink() { let state = ContextMenuUI.popupState; let uri = Util.makeURI(state.linkURL); let title = state.linkTitle || state.linkURL; try { Bookmarks.addForURI(uri, title); } catch (e) { return; } }, // Image specific saveImageToLib: function cc_saveImageToLib() { this.saveToWinLibrary("Pict"); }, copyImage: function cc_copyImage() { // copy to clibboard this.sendCommand("copy-image-contents"); }, copyImageSrc: function cc_copyImageSrc() { this.clipboard.copyString(ContextMenuUI.popupState.mediaURL, this.docRef); }, openImageInNewTab: function cc_openImageInNewTab() { BrowserUI.newTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab); }, // Video specific saveVideoToLib: function cc_saveVideoToLib() { this.saveToWinLibrary("Vids"); }, copyVideoSrc: function cc_copyVideoSrc() { this.clipboard.copyString(ContextMenuUI.popupState.mediaURL, this.docRef); }, openVideoInNewTab: function cc_openVideoInNewTab() { BrowserUI.newTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab); }, // Bookmarks editBookmark: function cc_editBookmark() { let target = ContextMenuUI.popupState.target; target.startEditing(); }, removeBookmark: function cc_removeBookmark() { let target = ContextMenuUI.popupState.target; target.remove(); }, // App bar findInPage: function cc_findInPage() { FindHelperUI.show(); }, viewOnDesktop: function cc_viewOnDesktop() { Appbar.onViewOnDesktop(); }, /* * Utilities */ saveToWinLibrary: function cc_saveToWinLibrary(aType) { let popupState = ContextMenuUI.popupState; let browser = popupState.target; // ContentAreaUtils internalSave relies on various desktop related prefs, // values, and functionality. We want to be more direct by saving the // image to the users Windows Library. If users want to specify the // save location they can use the context menu option 'Save (type) To'. let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties); let saveLocationPath = dirSvc.get(aType, Components.interfaces.nsIFile); let fileInfo = new ContentAreaUtils.FileInfo(); ContentAreaUtils.initFileInfo(fileInfo, popupState.mediaURL, browser.documentURI.originCharset, null, null, null); let filename = ContentAreaUtils.getNormalizedLeafName(fileInfo.fileName, fileInfo.fileExt); saveLocationPath.append(filename); // Start the background save process ContentAreaUtils.internalPersist({ sourceURI : fileInfo.uri, sourceDocument : null, sourceReferrer : browser.documentURI, targetContentType : popupState.contentType, targetFile : saveLocationPath, sourceCacheKey : null, sourcePostData : null, bypassCache : false, initiatingWindow : this.docRef.defaultView }); }, sendCommand: function sendCommand(aCommand) { // Send via message manager over to ContextMenuHandler let browser = ContextMenuUI.popupState.target; browser.messageManager.sendAsyncMessage("Browser:ContextCommand", { command: aCommand }); }, /* * isAccessibleDirectory * * Test to see if the directory exists and is writable. */ isAccessibleDirectory: function isAccessibleDirectory(aDirectory) { return aDirectory && aDirectory.exists() && aDirectory.isDirectory() && aDirectory.isWritable(); }, /* * saveFileAs * * Browse for a location and then save a file to the local system using * standard download prefs. * * @param aFileUriString path to file */ saveFileAs: function saveFileAs(aPopupState) { let srcUri = null; let mediaURL = aPopupState.mediaURL; try { srcUri = Util.makeURI(mediaURL, null, null); } catch (ex) { Util.dumpLn("could not parse:", mediaURL); return; } let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); let windowTitle = Strings.browser.GetStringFromName("browserForSaveLocation"); picker.init(window, windowTitle, Ci.nsIFilePicker.modeSave); // prefered filename let fileName = mediaURL.substring(mediaURL.lastIndexOf("/") + 1); if (fileName.length) picker.defaultString = fileName; // prefered file extension let fileExtension = mediaURL.substring(mediaURL.lastIndexOf(".") + 1); if (fileExtension.length) picker.defaultExtension = fileExtension; picker.appendFilters(Ci.nsIFilePicker.filterImages); // prefered save location var dnldMgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); picker.displayDirectory = dnldMgr.userDownloadsDirectory; try { let lastDir = Services.prefs.getComplexValue("browser.download.lastDir", Ci.nsILocalFile); if (this.isAccessibleDirectory(lastDir)) picker.displayDirectory = lastDir; } catch (e) { } this._picker = picker; this._pickerUrl = mediaURL; this._pickerContentDisp = aPopupState.contentDisposition; this._contentType = aPopupState.contentType; picker.open(ContextCommands); }, /* * Filepicker callback */ done: function done(aSuccess) { let picker = this._picker; this._picker = null; if (aSuccess == Ci.nsIFilePicker.returnCancel) return; let file = picker.file; if (file == null) return; try { if (file.exists()) file.remove(false); } catch (e) {} ContentAreaUtils.internalSave(this._pickerUrl, null, null, this._pickerContentDisp, this._contentType, false, "SaveImageTitle", new AutoChosen(file, Util.makeURI(this._pickerUrl, null, null)), getBrowser().documentURI, this.docRef, true, null); var newDir = file.parent.QueryInterface(Ci.nsILocalFile); Services.prefs.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, newDir); }, }; function AutoChosen(aFileAutoChosen, aUriAutoChosen) { this.file = aFileAutoChosen; this.uri = aUriAutoChosen; }