testing/specialpowers/content/MockFilePicker.jsm

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:e6d7d53a371e
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 this.EXPORTED_SYMBOLS = ["MockFilePicker"];
6
7 const Cc = Components.classes;
8 const Ci = Components.interfaces;
9 const Cm = Components.manager;
10 const Cu = Components.utils;
11
12 const CONTRACT_ID = "@mozilla.org/filepicker;1";
13
14 Cu.import("resource://gre/modules/FileUtils.jsm");
15 Cu.import("resource://gre/modules/Services.jsm");
16 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
17
18 var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
19 var oldClassID, oldFactory;
20 var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
21 var newFactory = function (window) {
22 return {
23 createInstance: function(aOuter, aIID) {
24 if (aOuter)
25 throw Components.results.NS_ERROR_NO_AGGREGATION;
26 return new MockFilePickerInstance(window).QueryInterface(aIID);
27 },
28 lockFactory: function(aLock) {
29 throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
30 },
31 QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
32 };
33 }
34
35 this.MockFilePicker = {
36 returnOK: Ci.nsIFilePicker.returnOK,
37 returnCancel: Ci.nsIFilePicker.returnCancel,
38 returnReplace: Ci.nsIFilePicker.returnReplace,
39
40 filterAll: Ci.nsIFilePicker.filterAll,
41 filterHTML: Ci.nsIFilePicker.filterHTML,
42 filterText: Ci.nsIFilePicker.filterText,
43 filterImages: Ci.nsIFilePicker.filterImages,
44 filterXML: Ci.nsIFilePicker.filterXML,
45 filterXUL: Ci.nsIFilePicker.filterXUL,
46 filterApps: Ci.nsIFilePicker.filterApps,
47 filterAllowURLs: Ci.nsIFilePicker.filterAllowURLs,
48 filterAudio: Ci.nsIFilePicker.filterAudio,
49 filterVideo: Ci.nsIFilePicker.filterVideo,
50
51 window: null,
52
53 init: function(window) {
54 this.window = window;
55
56 this.reset();
57 this.factory = newFactory(window);
58 if (!registrar.isCIDRegistered(newClassID)) {
59 oldClassID = registrar.contractIDToCID(CONTRACT_ID);
60 oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
61 registrar.unregisterFactory(oldClassID, oldFactory);
62 registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
63 }
64 },
65
66 reset: function() {
67 this.appendFilterCallback = null;
68 this.appendFiltersCallback = null;
69 this.displayDirectory = null;
70 this.filterIndex = 0;
71 this.mode = null;
72 this.returnFiles = [];
73 this.returnValue = null;
74 this.showCallback = null;
75 this.shown = false;
76 this.showing = false;
77 },
78
79 cleanup: function() {
80 var previousFactory = this.factory;
81 this.reset();
82 this.factory = null;
83 if (oldFactory) {
84 registrar.unregisterFactory(newClassID, previousFactory);
85 registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
86 }
87 },
88
89 useAnyFile: function() {
90 var file = FileUtils.getDir("TmpD", [], false);
91 file.append("testfile");
92 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
93 this.returnFiles = [file];
94 },
95
96 useBlobFile: function() {
97 var blob = new this.window.Blob([]);
98 var file = new this.window.File(blob, { name: 'helloworld.txt', type: 'plain/text' });
99 this.returnFiles = [file];
100 },
101
102 isNsIFile: function(aFile) {
103 let ret = false;
104 try {
105 if (aFile.QueryInterface(Ci.nsIFile))
106 ret = true;
107 } catch(e) {}
108
109 return ret;
110 }
111 };
112
113 function MockFilePickerInstance(window) {
114 this.window = window;
115 };
116 MockFilePickerInstance.prototype = {
117 QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
118 init: function(aParent, aTitle, aMode) {
119 MockFilePicker.mode = aMode;
120 this.filterIndex = MockFilePicker.filterIndex;
121 this.parent = aParent;
122 },
123 appendFilter: function(aTitle, aFilter) {
124 if (typeof MockFilePicker.appendFilterCallback == "function")
125 MockFilePicker.appendFilterCallback(this, aTitle, aFilter);
126 },
127 appendFilters: function(aFilterMask) {
128 if (typeof MockFilePicker.appendFiltersCallback == "function")
129 MockFilePicker.appendFiltersCallback(this, aFilterMask);
130 },
131 defaultString: "",
132 defaultExtension: "",
133 parent: null,
134 filterIndex: 0,
135 displayDirectory: null,
136 get file() {
137 if (MockFilePicker.returnFiles.length >= 1 &&
138 // window.File does not implement nsIFile
139 MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
140 return MockFilePicker.returnFiles[0];
141 }
142
143 return null;
144 },
145 get domfile() {
146 if (MockFilePicker.returnFiles.length >= 1) {
147 // window.File does not implement nsIFile
148 if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
149 return MockFilePicker.returnFiles[0];
150 }
151
152 let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
153 .getInterface(Ci.nsIDOMWindowUtils);
154 return utils.wrapDOMFile(MockFilePicker.returnFiles[0]);
155 }
156 return null;
157 },
158 get fileURL() {
159 if (MockFilePicker.returnFiles.length >= 1 &&
160 // window.File does not implement nsIFile
161 MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
162 return Services.io.newFileURI(MockFilePicker.returnFiles[0]);
163 }
164
165 return null;
166 },
167 get files() {
168 return {
169 index: 0,
170 QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
171 hasMoreElements: function() {
172 return this.index < MockFilePicker.returnFiles.length;
173 },
174 getNext: function() {
175 // window.File does not implement nsIFile
176 if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
177 return null;
178 }
179 return MockFilePicker.returnFiles[this.index++];
180 }
181 };
182 },
183 get domfiles() {
184 let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
185 .getInterface(Ci.nsIDOMWindowUtils);
186 return {
187 index: 0,
188 QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
189 hasMoreElements: function() {
190 return this.index < MockFilePicker.returnFiles.length;
191 },
192 getNext: function() {
193 // window.File does not implement nsIFile
194 if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
195 return MockFilePicker.returnFiles[this.index++];
196 }
197 return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]);
198 }
199 };
200 },
201 show: function() {
202 MockFilePicker.displayDirectory = this.displayDirectory;
203 MockFilePicker.shown = true;
204 if (typeof MockFilePicker.showCallback == "function") {
205 var returnValue = MockFilePicker.showCallback(this);
206 if (typeof returnValue != "undefined")
207 return returnValue;
208 }
209 return MockFilePicker.returnValue;
210 },
211 open: function(aFilePickerShownCallback) {
212 MockFilePicker.showing = true;
213 this.window.setTimeout(function() {
214 let result = Components.interfaces.nsIFilePicker.returnCancel;
215 try {
216 result = this.show();
217 } catch(ex) {
218 }
219 if (aFilePickerShownCallback) {
220 aFilePickerShownCallback.done(result);
221 }
222 }.bind(this), 0);
223 }
224 };
225
226 // Expose everything to content. We call reset() here so that all of the relevant
227 // lazy expandos get added.
228 MockFilePicker.reset();
229 function exposeAll(obj) {
230 var props = {};
231 for (var prop in obj)
232 props[prop] = 'rw';
233 obj.__exposedProps__ = props;
234 }
235 exposeAll(MockFilePicker);
236 exposeAll(MockFilePickerInstance.prototype);

mercurial