1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/components/Sidebar.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,130 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +const Ci = Components.interfaces; 1.9 +const Cc = Components.classes; 1.10 +const Cu = Components.utils; 1.11 + 1.12 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.13 +Cu.import("resource://gre/modules/Services.jsm"); 1.14 + 1.15 +const SIDEBAR_CID = Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}"); 1.16 +const SIDEBAR_CONTRACTID = "@mozilla.org/sidebar;1"; 1.17 + 1.18 +function Sidebar() { 1.19 + // Depending on if we are in the parent or child, prepare to remote 1.20 + // certain calls 1.21 + var appInfo = Cc["@mozilla.org/xre/app-info;1"]; 1.22 + if (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { 1.23 + // Parent process 1.24 + 1.25 + this.inContentProcess = false; 1.26 + 1.27 + // Used for wakeups service. FIXME: clean up with bug 593407 1.28 + this.wrappedJSObject = this; 1.29 + 1.30 + // Setup listener for child messages. We don't need to call 1.31 + // addMessageListener as the wakeup service will do that for us. 1.32 + this.receiveMessage = function(aMessage) { 1.33 + switch (aMessage.name) { 1.34 + case "Sidebar:AddSearchProvider": 1.35 + this.AddSearchProvider(aMessage.json.descriptionURL); 1.36 + } 1.37 + }; 1.38 + } else { 1.39 + // Child process 1.40 + 1.41 + this.inContentProcess = true; 1.42 + this.messageManager = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); 1.43 + } 1.44 +} 1.45 + 1.46 +Sidebar.prototype = { 1.47 + // =========================== utility code =========================== 1.48 + _validateSearchEngine: function validateSearchEngine(engineURL, iconURL) { 1.49 + try { 1.50 + // Make sure we're using HTTP, HTTPS, or FTP. 1.51 + if (! /^(https?|ftp):\/\//i.test(engineURL)) 1.52 + throw "Unsupported search engine URL"; 1.53 + 1.54 + // Make sure we're using HTTP, HTTPS, or FTP and refering to a 1.55 + // .gif/.jpg/.jpeg/.png/.ico file for the icon. 1.56 + if (iconURL && 1.57 + ! /^(https?|ftp):\/\/.+\.(gif|jpg|jpeg|png|ico)$/i.test(iconURL)) 1.58 + throw "Unsupported search icon URL."; 1.59 + } catch(ex) { 1.60 + Cu.reportError("Invalid argument passed to window.sidebar.addSearchEngine: " + ex); 1.61 + 1.62 + var searchBundle = Services.strings.createBundle("chrome://global/locale/search/search.properties"); 1.63 + var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); 1.64 + var brandName = brandBundle.GetStringFromName("brandShortName"); 1.65 + var title = searchBundle.GetStringFromName("error_invalid_engine_title"); 1.66 + var msg = searchBundle.formatStringFromName("error_invalid_engine_msg", 1.67 + [brandName], 1); 1.68 + Services.prompt.alert(null, title, msg); 1.69 + return false; 1.70 + } 1.71 + 1.72 + return true; 1.73 + }, 1.74 + 1.75 + // The suggestedTitle and suggestedCategory parameters are ignored, but remain 1.76 + // for backward compatibility. 1.77 + addSearchEngine: function addSearchEngine(engineURL, iconURL, suggestedTitle, 1.78 + suggestedCategory) { 1.79 + if (!this._validateSearchEngine(engineURL, iconURL)) 1.80 + return; 1.81 + 1.82 + // File extension for Sherlock search plugin description files 1.83 + const SHERLOCK_FILE_EXT_REGEXP = /\.src$/i; 1.84 + 1.85 + // OpenSearch files will likely be far more common than Sherlock files, and 1.86 + // have less consistent suffixes, so we assume that ".src" is a Sherlock 1.87 + // (text) file, and anything else is OpenSearch (XML). 1.88 + var dataType; 1.89 + if (SHERLOCK_FILE_EXT_REGEXP.test(engineURL)) 1.90 + dataType = Ci.nsISearchEngine.DATA_TEXT; 1.91 + else 1.92 + dataType = Ci.nsISearchEngine.DATA_XML; 1.93 + 1.94 + Services.search.addEngine(engineURL, dataType, iconURL, true); 1.95 + }, 1.96 + 1.97 + // This function exists to implement window.external.AddSearchProvider(), 1.98 + // to match other browsers' APIs. The capitalization, although nonstandard here, 1.99 + // is therefore important. 1.100 + AddSearchProvider: function AddSearchProvider(aDescriptionURL) { 1.101 + if (!this._validateSearchEngine(aDescriptionURL, "")) 1.102 + return; 1.103 + 1.104 + if (this.inContentProcess) { 1.105 + this.messageManager.sendAsyncMessage("Sidebar:AddSearchProvider", 1.106 + { descriptionURL: aDescriptionURL }); 1.107 + return; 1.108 + } 1.109 + 1.110 + const typeXML = Ci.nsISearchEngine.DATA_XML; 1.111 + Services.search.addEngine(aDescriptionURL, typeXML, "", true); 1.112 + }, 1.113 + 1.114 + // This function exists to implement window.external.IsSearchProviderInstalled(), 1.115 + // for compatibility with other browsers. It will return an integer value 1.116 + // indicating whether the given engine is installed for the current user. 1.117 + // However, it is currently stubbed out due to security/privacy concerns 1.118 + // stemming from difficulties in determining what domain issued the request. 1.119 + // See bug 340604 and 1.120 + // http://msdn.microsoft.com/en-us/library/aa342526%28VS.85%29.aspx . 1.121 + // XXX Implement this! 1.122 + IsSearchProviderInstalled: function IsSearchProviderInstalled(aSearchURL) { 1.123 + return 0; 1.124 + }, 1.125 + 1.126 + // =========================== nsISupports =========================== 1.127 + QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]), 1.128 + 1.129 + // XPCOMUtils stuff 1.130 + classID: SIDEBAR_CID, 1.131 +}; 1.132 + 1.133 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Sidebar]);