1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/base/content/ContextCommands.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,436 @@ 1.4 +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 + /* 1.10 + * context menu command handlers 1.11 + */ 1.12 + 1.13 +var ContextCommands = { 1.14 + _picker: null, 1.15 + 1.16 + get _ellipsis() { 1.17 + delete this._ellipsis; 1.18 + this._ellipsis = "\u2026"; 1.19 + try { 1.20 + this._ellipsis = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data; 1.21 + } catch (ex) { } 1.22 + return this._ellipsis; 1.23 + }, 1.24 + 1.25 + get clipboard() { 1.26 + return Cc["@mozilla.org/widget/clipboardhelper;1"] 1.27 + .getService(Ci.nsIClipboardHelper); 1.28 + }, 1.29 + 1.30 + get docRef() { 1.31 + return Browser.selectedBrowser.contentWindow.document; 1.32 + }, 1.33 + 1.34 + /* 1.35 + * Context menu handlers 1.36 + */ 1.37 + 1.38 + // Text specific 1.39 + 1.40 + cut: function cc_cut() { 1.41 + let target = ContextMenuUI.popupState.target; 1.42 + 1.43 + if (!target) { 1.44 + return; 1.45 + } 1.46 + 1.47 + if (target.localName === "browser") { 1.48 + // content 1.49 + if (ContextMenuUI.popupState.string) { 1.50 + this.sendCommand("cut"); 1.51 + 1.52 + SelectionHelperUI.closeEditSession(true); 1.53 + } 1.54 + } else { 1.55 + // chrome 1.56 + CommandUpdater.doCommand("cmd_cut"); 1.57 + } 1.58 + 1.59 + target.focus(); 1.60 + }, 1.61 + 1.62 + copy: function cc_copy() { 1.63 + let target = ContextMenuUI.popupState.target; 1.64 + 1.65 + if (!target) { 1.66 + return; 1.67 + } 1.68 + 1.69 + if (target.localName == "browser") { 1.70 + // content 1.71 + if (ContextMenuUI.popupState.string) { 1.72 + this.sendCommand("copy"); 1.73 + } 1.74 + } else if (ContextMenuUI.popupState.string) { 1.75 + this.clipboard.copyString(ContextMenuUI.popupState.string, this.docRef); 1.76 + } else { 1.77 + // chrome 1.78 + CommandUpdater.doCommand("cmd_copy"); 1.79 + } 1.80 + 1.81 + target.focus(); 1.82 + }, 1.83 + 1.84 + paste: function cc_paste() { 1.85 + let target = ContextMenuUI.popupState.target; 1.86 + 1.87 + if (!target) { 1.88 + return; 1.89 + } 1.90 + 1.91 + if (target.localName == "browser") { 1.92 + // content 1.93 + let x = ContextMenuUI.popupState.x; 1.94 + let y = ContextMenuUI.popupState.y; 1.95 + let json = {x: x, y: y, command: "paste" }; 1.96 + target.messageManager.sendAsyncMessage("Browser:ContextCommand", json); 1.97 + } else { 1.98 + // chrome 1.99 + CommandUpdater.doCommand("cmd_paste"); 1.100 + target.focus(); 1.101 + } 1.102 + SelectionHelperUI.closeEditSession(); 1.103 + }, 1.104 + 1.105 + pasteAndGo: function cc_pasteAndGo() { 1.106 + let target = ContextMenuUI.popupState.target; 1.107 + target.editor.selectAll(); 1.108 + target.editor.paste(Ci.nsIClipboard.kGlobalClipboard); 1.109 + BrowserUI.goToURI(); 1.110 + }, 1.111 + 1.112 + select: function cc_select() { 1.113 + SelectionHelperUI.openEditSession(ContextMenuUI.popupState.target, 1.114 + ContextMenuUI.popupState.xPos, 1.115 + ContextMenuUI.popupState.yPos, 1.116 + true); 1.117 + }, 1.118 + 1.119 + selectAll: function cc_selectAll() { 1.120 + let target = ContextMenuUI.popupState.target; 1.121 + if (target.localName == "browser") { 1.122 + // content 1.123 + let x = ContextMenuUI.popupState.xPos; 1.124 + let y = ContextMenuUI.popupState.yPos; 1.125 + let json = {x: x, y: y, command: "select-all" }; 1.126 + target.messageManager.sendAsyncMessage("Browser:ContextCommand", json); 1.127 + SelectionHelperUI.attachEditSession(target, x, y); 1.128 + } else { 1.129 + // chrome 1.130 + target.editor.selectAll(); 1.131 + target.focus(); 1.132 + } 1.133 + }, 1.134 + 1.135 + // called on display of the search text menu item 1.136 + searchTextSetup: function cc_searchTextSetup(aRichListItem, aSearchString) { 1.137 + let defaultURI; 1.138 + let defaultName; 1.139 + aSearchString = aSearchString.trim(); 1.140 + try { 1.141 + let defaultPB = Services.prefs.getDefaultBranch(null); 1.142 + const nsIPLS = Ci.nsIPrefLocalizedString; 1.143 + defaultName = defaultPB.getComplexValue("browser.search.defaultenginename", nsIPLS).data; 1.144 + let defaultEngine = Services.search.getEngineByName(defaultName); 1.145 + defaultURI = defaultEngine.getSubmission(aSearchString).uri.spec; 1.146 + } catch (ex) { 1.147 + Cu.reportError(ex); 1.148 + return false; 1.149 + } 1.150 + let displayString = aSearchString; 1.151 + if (displayString.length > 15) { 1.152 + displayString = displayString.substring(0, 15) + this._ellipsis; 1.153 + } 1.154 + // label child node 1.155 + let label = Services.strings 1.156 + .createBundle("chrome://browser/locale/browser.properties") 1.157 + .formatStringFromName("browser.search.contextTextSearchLabel2", 1.158 + [defaultName, displayString], 2); 1.159 + aRichListItem.childNodes[0].setAttribute("value", label); 1.160 + aRichListItem.setAttribute("searchString", defaultURI); 1.161 + return true; 1.162 + }, 1.163 + 1.164 + searchText: function cc_searchText(aRichListItem) { 1.165 + let defaultURI = aRichListItem.getAttribute("searchString"); 1.166 + aRichListItem.childNodes[0].setAttribute("value", ""); 1.167 + aRichListItem.setAttribute("searchString", ""); 1.168 + BrowserUI.addAndShowTab(defaultURI, Browser.selectedTab); 1.169 + }, 1.170 + 1.171 + // Link specific 1.172 + 1.173 + openLinkInNewTab: function cc_openLinkInNewTab() { 1.174 + let url = ContextMenuUI.popupState.linkURL; 1.175 + BrowserUI.openLinkInNewTab(url, false, Browser.selectedTab); 1.176 + }, 1.177 + 1.178 + copyLink: function cc_copyLink() { 1.179 + this.clipboard.copyString(ContextMenuUI.popupState.linkURL, 1.180 + this.docRef); 1.181 + }, 1.182 + 1.183 + bookmarkLink: function cc_bookmarkLink() { 1.184 + let state = ContextMenuUI.popupState; 1.185 + let uri = Util.makeURI(state.linkURL); 1.186 + let title = state.linkTitle || state.linkURL; 1.187 + 1.188 + try { 1.189 + Bookmarks.addForURI(uri, title); 1.190 + } catch (e) { 1.191 + return; 1.192 + } 1.193 + }, 1.194 + 1.195 + // Image specific 1.196 + 1.197 + saveImageToLib: function cc_saveImageToLib() { 1.198 + this.saveToWinLibrary("Pict"); 1.199 + }, 1.200 + 1.201 + copyImage: function cc_copyImage() { 1.202 + // copy to clibboard 1.203 + this.sendCommand("copy-image-contents"); 1.204 + }, 1.205 + 1.206 + copyImageSrc: function cc_copyImageSrc() { 1.207 + this.clipboard.copyString(ContextMenuUI.popupState.mediaURL, 1.208 + this.docRef); 1.209 + }, 1.210 + 1.211 + openImageInNewTab: function cc_openImageInNewTab() { 1.212 + BrowserUI.addAndShowTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab); 1.213 + }, 1.214 + 1.215 + // Video specific 1.216 + 1.217 + saveVideoToLib: function cc_saveVideoToLib() { 1.218 + this.saveToWinLibrary("Vids"); 1.219 + }, 1.220 + 1.221 + copyVideoSrc: function cc_copyVideoSrc() { 1.222 + this.clipboard.copyString(ContextMenuUI.popupState.mediaURL, 1.223 + this.docRef); 1.224 + }, 1.225 + 1.226 + openVideoInNewTab: function cc_openVideoInNewTab() { 1.227 + BrowserUI.addAndShowTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab); 1.228 + }, 1.229 + 1.230 + // Bookmarks 1.231 + 1.232 + editBookmark: function cc_editBookmark() { 1.233 + let target = ContextMenuUI.popupState.target; 1.234 + target.startEditing(); 1.235 + }, 1.236 + 1.237 + removeBookmark: function cc_removeBookmark() { 1.238 + let target = ContextMenuUI.popupState.target; 1.239 + target.remove(); 1.240 + }, 1.241 + 1.242 + // App bar 1.243 + 1.244 + errorConsole: function cc_errorConsole() { 1.245 + PanelUI.show("console-container"); 1.246 + }, 1.247 + 1.248 + jsShell: function cc_jsShell() { 1.249 + // XXX for debugging, this only works when running on the desktop. 1.250 + if (!Services.metro.immersive) 1.251 + window.openDialog("chrome://browser/content/shell.xul", "_blank", 1.252 + "all=no,scrollbars=yes,resizable=yes,dialog=no"); 1.253 + }, 1.254 + 1.255 + findInPage: function cc_findInPage() { 1.256 + FindHelperUI.show(); 1.257 + }, 1.258 + 1.259 + viewOnDesktop: function cc_viewOnDesktop() { 1.260 + Appbar.onViewOnDesktop(); 1.261 + }, 1.262 + 1.263 + // Checks for MS app store specific meta data, and if present opens 1.264 + // the Windows Store to the appropriate app 1.265 + openWindowsStoreLink: function cc_openWindowsStoreLink() { 1.266 + let storeLink = this.getStoreLink(); 1.267 + if (storeLink) { 1.268 + Browser.selectedBrowser.contentWindow.document.location = storeLink; 1.269 + } 1.270 + }, 1.271 + 1.272 + getStoreLink: function cc_getStoreLink() { 1.273 + let metaData = Browser.selectedBrowser.contentWindow.document.getElementsByTagName("meta"); 1.274 + let msApplicationName = metaData.namedItem("msApplication-PackageFamilyName"); 1.275 + if (msApplicationName) { 1.276 + return "ms-windows-store:PDP?PFN=" + msApplicationName.getAttribute("content"); 1.277 + } 1.278 + return null; 1.279 + }, 1.280 + 1.281 + getPageSource: function cc_getPageSource() { 1.282 + let uri = Services.io.newURI(Browser.selectedBrowser.currentURI.spec, null, null); 1.283 + if (!uri.schemeIs("view-source")) { 1.284 + return "view-source:" + Browser.selectedBrowser.currentURI.spec; 1.285 + } 1.286 + return null; 1.287 + }, 1.288 + 1.289 + viewPageSource: function cc_viewPageSource() { 1.290 + let uri = this.getPageSource(); 1.291 + if (uri) { 1.292 + BrowserUI.addAndShowTab(uri, Browser.selectedTab); 1.293 + } 1.294 + }, 1.295 + 1.296 + /* 1.297 + * Utilities 1.298 + */ 1.299 + 1.300 + saveToWinLibrary: function cc_saveToWinLibrary(aType) { 1.301 + let popupState = ContextMenuUI.popupState; 1.302 + let browser = popupState.target; 1.303 + 1.304 + // ContentAreaUtils internalSave relies on various desktop related prefs, 1.305 + // values, and functionality. We want to be more direct by saving the 1.306 + // image to the users Windows Library. If users want to specify the 1.307 + // save location they can use the context menu option 'Save (type) To'. 1.308 + 1.309 + let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] 1.310 + .getService(Components.interfaces.nsIProperties); 1.311 + let saveLocationPath = dirSvc.get(aType, Components.interfaces.nsIFile); 1.312 + 1.313 + let fileInfo = new ContentAreaUtils.FileInfo(); 1.314 + ContentAreaUtils.initFileInfo(fileInfo, popupState.mediaURL, 1.315 + browser.documentURI.originCharset, 1.316 + null, null, null); 1.317 + let filename = 1.318 + ContentAreaUtils.getNormalizedLeafName(fileInfo.fileName, fileInfo.fileExt); 1.319 + saveLocationPath.append(filename); 1.320 + 1.321 + // Start the background save process 1.322 + ContentAreaUtils.internalPersist({ 1.323 + sourceURI : fileInfo.uri, 1.324 + sourceDocument : null, 1.325 + sourceReferrer : browser.documentURI, 1.326 + targetContentType : popupState.contentType, 1.327 + targetFile : saveLocationPath, 1.328 + sourceCacheKey : null, 1.329 + sourcePostData : null, 1.330 + bypassCache : false, 1.331 + initiatingWindow : this.docRef.defaultView 1.332 + }); 1.333 + }, 1.334 + 1.335 + sendCommand: function sendCommand(aCommand) { 1.336 + // Send via message manager over to ContextMenuHandler 1.337 + let browser = ContextMenuUI.popupState.target; 1.338 + browser.messageManager.sendAsyncMessage("Browser:ContextCommand", { command: aCommand }); 1.339 + }, 1.340 + 1.341 + /* 1.342 + * isAccessibleDirectory 1.343 + * 1.344 + * Test to see if the directory exists and is writable. 1.345 + */ 1.346 + isAccessibleDirectory: function isAccessibleDirectory(aDirectory) { 1.347 + return aDirectory && aDirectory.exists() && aDirectory.isDirectory() && 1.348 + aDirectory.isWritable(); 1.349 + }, 1.350 + 1.351 + /* 1.352 + * saveFileAs 1.353 + * 1.354 + * Browse for a location and then save a file to the local system using 1.355 + * standard download prefs. 1.356 + * 1.357 + * @param aFileUriString path to file 1.358 + */ 1.359 + saveFileAs: function saveFileAs(aPopupState) { 1.360 + let srcUri = null; 1.361 + let mediaURL = aPopupState.mediaURL; 1.362 + try { 1.363 + srcUri = Util.makeURI(mediaURL, null, null); 1.364 + } catch (ex) { 1.365 + Util.dumpLn("could not parse:", mediaURL); 1.366 + return; 1.367 + } 1.368 + 1.369 + let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); 1.370 + let windowTitle = Strings.browser.GetStringFromName("browserForSaveLocation"); 1.371 + 1.372 + picker.init(window, windowTitle, Ci.nsIFilePicker.modeSave); 1.373 + 1.374 + // prefered filename 1.375 + let fileName = mediaURL.substring(mediaURL.lastIndexOf("/") + 1); 1.376 + if (fileName.length) 1.377 + picker.defaultString = fileName; 1.378 + 1.379 + // prefered file extension 1.380 + let fileExtension = mediaURL.substring(mediaURL.lastIndexOf(".") + 1); 1.381 + if (fileExtension.length) 1.382 + picker.defaultExtension = fileExtension; 1.383 + picker.appendFilters(Ci.nsIFilePicker.filterImages); 1.384 + 1.385 + // prefered save location 1.386 + Task.spawn(function() { 1.387 + let preferredDir = yield Downloads.getPreferredDownloadsDirectory(); 1.388 + picker.displayDirectory = new FileUtils.File(preferredDir); 1.389 + 1.390 + try { 1.391 + let lastDir = Services.prefs.getComplexValue("browser.download.lastDir", Ci.nsILocalFile); 1.392 + if (this.isAccessibleDirectory(lastDir)) 1.393 + picker.displayDirectory = lastDir; 1.394 + } 1.395 + catch (e) { } 1.396 + 1.397 + this._picker = picker; 1.398 + this._pickerUrl = mediaURL; 1.399 + this._pickerContentDisp = aPopupState.contentDisposition; 1.400 + this._contentType = aPopupState.contentType; 1.401 + picker.open(ContextCommands); 1.402 + }.bind(this)); 1.403 + }, 1.404 + 1.405 + /* 1.406 + * Filepicker callback 1.407 + */ 1.408 + done: function done(aSuccess) { 1.409 + let picker = this._picker; 1.410 + this._picker = null; 1.411 + 1.412 + if (aSuccess == Ci.nsIFilePicker.returnCancel) 1.413 + return; 1.414 + 1.415 + let file = picker.file; 1.416 + if (file == null) 1.417 + return; 1.418 + 1.419 + try { 1.420 + if (file.exists()) 1.421 + file.remove(false); 1.422 + } catch (e) {} 1.423 + 1.424 + ContentAreaUtils.internalSave(this._pickerUrl, null, null, 1.425 + this._pickerContentDisp, 1.426 + this._contentType, false, "SaveImageTitle", 1.427 + new AutoChosen(file, Util.makeURI(this._pickerUrl, null, null)), 1.428 + getBrowser().documentURI, this.docRef, true, null); 1.429 + 1.430 + var newDir = file.parent.QueryInterface(Ci.nsILocalFile); 1.431 + Services.prefs.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, newDir); 1.432 + }, 1.433 +}; 1.434 + 1.435 +function AutoChosen(aFileAutoChosen, aUriAutoChosen) { 1.436 + this.file = aFileAutoChosen; 1.437 + this.uri = aUriAutoChosen; 1.438 +} 1.439 +