browser/metro/base/content/ContextCommands.js

changeset 0
6474c204b198
     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 +

mercurial