1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/specialpowers/content/MockFilePicker.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,236 @@ 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 +this.EXPORTED_SYMBOLS = ["MockFilePicker"]; 1.9 + 1.10 +const Cc = Components.classes; 1.11 +const Ci = Components.interfaces; 1.12 +const Cm = Components.manager; 1.13 +const Cu = Components.utils; 1.14 + 1.15 +const CONTRACT_ID = "@mozilla.org/filepicker;1"; 1.16 + 1.17 +Cu.import("resource://gre/modules/FileUtils.jsm"); 1.18 +Cu.import("resource://gre/modules/Services.jsm"); 1.19 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.20 + 1.21 +var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); 1.22 +var oldClassID, oldFactory; 1.23 +var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID(); 1.24 +var newFactory = function (window) { 1.25 + return { 1.26 + createInstance: function(aOuter, aIID) { 1.27 + if (aOuter) 1.28 + throw Components.results.NS_ERROR_NO_AGGREGATION; 1.29 + return new MockFilePickerInstance(window).QueryInterface(aIID); 1.30 + }, 1.31 + lockFactory: function(aLock) { 1.32 + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; 1.33 + }, 1.34 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]) 1.35 + }; 1.36 +} 1.37 + 1.38 +this.MockFilePicker = { 1.39 + returnOK: Ci.nsIFilePicker.returnOK, 1.40 + returnCancel: Ci.nsIFilePicker.returnCancel, 1.41 + returnReplace: Ci.nsIFilePicker.returnReplace, 1.42 + 1.43 + filterAll: Ci.nsIFilePicker.filterAll, 1.44 + filterHTML: Ci.nsIFilePicker.filterHTML, 1.45 + filterText: Ci.nsIFilePicker.filterText, 1.46 + filterImages: Ci.nsIFilePicker.filterImages, 1.47 + filterXML: Ci.nsIFilePicker.filterXML, 1.48 + filterXUL: Ci.nsIFilePicker.filterXUL, 1.49 + filterApps: Ci.nsIFilePicker.filterApps, 1.50 + filterAllowURLs: Ci.nsIFilePicker.filterAllowURLs, 1.51 + filterAudio: Ci.nsIFilePicker.filterAudio, 1.52 + filterVideo: Ci.nsIFilePicker.filterVideo, 1.53 + 1.54 + window: null, 1.55 + 1.56 + init: function(window) { 1.57 + this.window = window; 1.58 + 1.59 + this.reset(); 1.60 + this.factory = newFactory(window); 1.61 + if (!registrar.isCIDRegistered(newClassID)) { 1.62 + oldClassID = registrar.contractIDToCID(CONTRACT_ID); 1.63 + oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory); 1.64 + registrar.unregisterFactory(oldClassID, oldFactory); 1.65 + registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory); 1.66 + } 1.67 + }, 1.68 + 1.69 + reset: function() { 1.70 + this.appendFilterCallback = null; 1.71 + this.appendFiltersCallback = null; 1.72 + this.displayDirectory = null; 1.73 + this.filterIndex = 0; 1.74 + this.mode = null; 1.75 + this.returnFiles = []; 1.76 + this.returnValue = null; 1.77 + this.showCallback = null; 1.78 + this.shown = false; 1.79 + this.showing = false; 1.80 + }, 1.81 + 1.82 + cleanup: function() { 1.83 + var previousFactory = this.factory; 1.84 + this.reset(); 1.85 + this.factory = null; 1.86 + if (oldFactory) { 1.87 + registrar.unregisterFactory(newClassID, previousFactory); 1.88 + registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory); 1.89 + } 1.90 + }, 1.91 + 1.92 + useAnyFile: function() { 1.93 + var file = FileUtils.getDir("TmpD", [], false); 1.94 + file.append("testfile"); 1.95 + file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644); 1.96 + this.returnFiles = [file]; 1.97 + }, 1.98 + 1.99 + useBlobFile: function() { 1.100 + var blob = new this.window.Blob([]); 1.101 + var file = new this.window.File(blob, { name: 'helloworld.txt', type: 'plain/text' }); 1.102 + this.returnFiles = [file]; 1.103 + }, 1.104 + 1.105 + isNsIFile: function(aFile) { 1.106 + let ret = false; 1.107 + try { 1.108 + if (aFile.QueryInterface(Ci.nsIFile)) 1.109 + ret = true; 1.110 + } catch(e) {} 1.111 + 1.112 + return ret; 1.113 + } 1.114 +}; 1.115 + 1.116 +function MockFilePickerInstance(window) { 1.117 + this.window = window; 1.118 +}; 1.119 +MockFilePickerInstance.prototype = { 1.120 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]), 1.121 + init: function(aParent, aTitle, aMode) { 1.122 + MockFilePicker.mode = aMode; 1.123 + this.filterIndex = MockFilePicker.filterIndex; 1.124 + this.parent = aParent; 1.125 + }, 1.126 + appendFilter: function(aTitle, aFilter) { 1.127 + if (typeof MockFilePicker.appendFilterCallback == "function") 1.128 + MockFilePicker.appendFilterCallback(this, aTitle, aFilter); 1.129 + }, 1.130 + appendFilters: function(aFilterMask) { 1.131 + if (typeof MockFilePicker.appendFiltersCallback == "function") 1.132 + MockFilePicker.appendFiltersCallback(this, aFilterMask); 1.133 + }, 1.134 + defaultString: "", 1.135 + defaultExtension: "", 1.136 + parent: null, 1.137 + filterIndex: 0, 1.138 + displayDirectory: null, 1.139 + get file() { 1.140 + if (MockFilePicker.returnFiles.length >= 1 && 1.141 + // window.File does not implement nsIFile 1.142 + MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) { 1.143 + return MockFilePicker.returnFiles[0]; 1.144 + } 1.145 + 1.146 + return null; 1.147 + }, 1.148 + get domfile() { 1.149 + if (MockFilePicker.returnFiles.length >= 1) { 1.150 + // window.File does not implement nsIFile 1.151 + if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) { 1.152 + return MockFilePicker.returnFiles[0]; 1.153 + } 1.154 + 1.155 + let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor) 1.156 + .getInterface(Ci.nsIDOMWindowUtils); 1.157 + return utils.wrapDOMFile(MockFilePicker.returnFiles[0]); 1.158 + } 1.159 + return null; 1.160 + }, 1.161 + get fileURL() { 1.162 + if (MockFilePicker.returnFiles.length >= 1 && 1.163 + // window.File does not implement nsIFile 1.164 + MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) { 1.165 + return Services.io.newFileURI(MockFilePicker.returnFiles[0]); 1.166 + } 1.167 + 1.168 + return null; 1.169 + }, 1.170 + get files() { 1.171 + return { 1.172 + index: 0, 1.173 + QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]), 1.174 + hasMoreElements: function() { 1.175 + return this.index < MockFilePicker.returnFiles.length; 1.176 + }, 1.177 + getNext: function() { 1.178 + // window.File does not implement nsIFile 1.179 + if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) { 1.180 + return null; 1.181 + } 1.182 + return MockFilePicker.returnFiles[this.index++]; 1.183 + } 1.184 + }; 1.185 + }, 1.186 + get domfiles() { 1.187 + let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor) 1.188 + .getInterface(Ci.nsIDOMWindowUtils); 1.189 + return { 1.190 + index: 0, 1.191 + QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]), 1.192 + hasMoreElements: function() { 1.193 + return this.index < MockFilePicker.returnFiles.length; 1.194 + }, 1.195 + getNext: function() { 1.196 + // window.File does not implement nsIFile 1.197 + if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) { 1.198 + return MockFilePicker.returnFiles[this.index++]; 1.199 + } 1.200 + return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]); 1.201 + } 1.202 + }; 1.203 + }, 1.204 + show: function() { 1.205 + MockFilePicker.displayDirectory = this.displayDirectory; 1.206 + MockFilePicker.shown = true; 1.207 + if (typeof MockFilePicker.showCallback == "function") { 1.208 + var returnValue = MockFilePicker.showCallback(this); 1.209 + if (typeof returnValue != "undefined") 1.210 + return returnValue; 1.211 + } 1.212 + return MockFilePicker.returnValue; 1.213 + }, 1.214 + open: function(aFilePickerShownCallback) { 1.215 + MockFilePicker.showing = true; 1.216 + this.window.setTimeout(function() { 1.217 + let result = Components.interfaces.nsIFilePicker.returnCancel; 1.218 + try { 1.219 + result = this.show(); 1.220 + } catch(ex) { 1.221 + } 1.222 + if (aFilePickerShownCallback) { 1.223 + aFilePickerShownCallback.done(result); 1.224 + } 1.225 + }.bind(this), 0); 1.226 + } 1.227 +}; 1.228 + 1.229 +// Expose everything to content. We call reset() here so that all of the relevant 1.230 +// lazy expandos get added. 1.231 +MockFilePicker.reset(); 1.232 +function exposeAll(obj) { 1.233 + var props = {}; 1.234 + for (var prop in obj) 1.235 + props[prop] = 'rw'; 1.236 + obj.__exposedProps__ = props; 1.237 +} 1.238 +exposeAll(MockFilePicker); 1.239 +exposeAll(MockFilePickerInstance.prototype);