summaryrefslogtreecommitdiffstats
path: root/testing/specialpowers/content/MockFilePicker.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'testing/specialpowers/content/MockFilePicker.jsm')
-rw-r--r--testing/specialpowers/content/MockFilePicker.jsm235
1 files changed, 235 insertions, 0 deletions
diff --git a/testing/specialpowers/content/MockFilePicker.jsm b/testing/specialpowers/content/MockFilePicker.jsm
new file mode 100644
index 000000000..4c93cd0e2
--- /dev/null
+++ b/testing/specialpowers/content/MockFilePicker.jsm
@@ -0,0 +1,235 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+this.EXPORTED_SYMBOLS = ["MockFilePicker"];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cm = Components.manager;
+const Cu = Components.utils;
+
+const CONTRACT_ID = "@mozilla.org/filepicker;1";
+
+Cu.import("resource://gre/modules/FileUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// Allow stuff from this scope to be accessed from non-privileged scopes. This
+// would crash if used outside of automation.
+Cu.forcePermissiveCOWs();
+
+var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+var oldClassID, oldFactory;
+var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
+var newFactory = function (window) {
+ return {
+ createInstance: function(aOuter, aIID) {
+ if (aOuter)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ return new MockFilePickerInstance(window).QueryInterface(aIID);
+ },
+ lockFactory: function(aLock) {
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
+ };
+}
+
+this.MockFilePicker = {
+ returnOK: Ci.nsIFilePicker.returnOK,
+ returnCancel: Ci.nsIFilePicker.returnCancel,
+ returnReplace: Ci.nsIFilePicker.returnReplace,
+
+ filterAll: Ci.nsIFilePicker.filterAll,
+ filterHTML: Ci.nsIFilePicker.filterHTML,
+ filterText: Ci.nsIFilePicker.filterText,
+ filterImages: Ci.nsIFilePicker.filterImages,
+ filterXML: Ci.nsIFilePicker.filterXML,
+ filterXUL: Ci.nsIFilePicker.filterXUL,
+ filterApps: Ci.nsIFilePicker.filterApps,
+ filterAllowURLs: Ci.nsIFilePicker.filterAllowURLs,
+ filterAudio: Ci.nsIFilePicker.filterAudio,
+ filterVideo: Ci.nsIFilePicker.filterVideo,
+
+ window: null,
+
+ init: function(window) {
+ this.window = window;
+
+ this.reset();
+ this.factory = newFactory(window);
+ if (!registrar.isCIDRegistered(newClassID)) {
+ oldClassID = registrar.contractIDToCID(CONTRACT_ID);
+ oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
+ registrar.unregisterFactory(oldClassID, oldFactory);
+ registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
+ }
+ },
+
+ reset: function() {
+ this.appendFilterCallback = null;
+ this.appendFiltersCallback = null;
+ this.displayDirectory = null;
+ this.filterIndex = 0;
+ this.mode = null;
+ this.returnFiles = [];
+ this.returnValue = null;
+ this.showCallback = null;
+ this.shown = false;
+ this.showing = false;
+ },
+
+ cleanup: function() {
+ var previousFactory = this.factory;
+ this.reset();
+ this.factory = null;
+ if (oldFactory) {
+ registrar.unregisterFactory(newClassID, previousFactory);
+ registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
+ }
+ },
+
+ useAnyFile: function() {
+ var file = FileUtils.getDir("TmpD", [], false);
+ file.append("testfile");
+ file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
+ this.returnFiles = [file];
+ },
+
+ useBlobFile: function() {
+ var blob = new this.window.Blob([]);
+ var file = new this.window.File([blob], 'helloworld.txt', { type: 'plain/text' });
+ this.returnFiles = [file];
+ },
+
+ useDirectory: function(aPath) {
+ var directory = new this.window.Directory(aPath);
+ this.returnFiles = [directory];
+ },
+
+ isNsIFile: function(aFile) {
+ let ret = false;
+ try {
+ if (aFile.QueryInterface(Ci.nsIFile))
+ ret = true;
+ } catch(e) {}
+
+ return ret;
+ }
+};
+
+function MockFilePickerInstance(window) {
+ this.window = window;
+};
+MockFilePickerInstance.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
+ init: function(aParent, aTitle, aMode) {
+ MockFilePicker.mode = aMode;
+ this.filterIndex = MockFilePicker.filterIndex;
+ this.parent = aParent;
+ },
+ appendFilter: function(aTitle, aFilter) {
+ if (typeof MockFilePicker.appendFilterCallback == "function")
+ MockFilePicker.appendFilterCallback(this, aTitle, aFilter);
+ },
+ appendFilters: function(aFilterMask) {
+ if (typeof MockFilePicker.appendFiltersCallback == "function")
+ MockFilePicker.appendFiltersCallback(this, aFilterMask);
+ },
+ defaultString: "",
+ defaultExtension: "",
+ parent: null,
+ filterIndex: 0,
+ displayDirectory: null,
+ get file() {
+ if (MockFilePicker.returnFiles.length >= 1 &&
+ // window.File does not implement nsIFile
+ MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+ return MockFilePicker.returnFiles[0];
+ }
+
+ return null;
+ },
+
+ // We don't support directories here.
+ get domFileOrDirectory() {
+ if (MockFilePicker.returnFiles.length >= 1) {
+ // window.File does not implement nsIFile
+ if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+ return MockFilePicker.returnFiles[0];
+ }
+
+ let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ return utils.wrapDOMFile(MockFilePicker.returnFiles[0]);
+ }
+ return null;
+ },
+ get fileURL() {
+ if (MockFilePicker.returnFiles.length >= 1 &&
+ // window.File does not implement nsIFile
+ MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+ return Services.io.newFileURI(MockFilePicker.returnFiles[0]);
+ }
+
+ return null;
+ },
+ get files() {
+ return {
+ index: 0,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
+ hasMoreElements: function() {
+ return this.index < MockFilePicker.returnFiles.length;
+ },
+ getNext: function() {
+ // window.File does not implement nsIFile
+ if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
+ return null;
+ }
+ return MockFilePicker.returnFiles[this.index++];
+ }
+ };
+ },
+ get domFileOrDirectoryEnumerator() {
+ let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ return {
+ index: 0,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
+ hasMoreElements: function() {
+ return this.index < MockFilePicker.returnFiles.length;
+ },
+ getNext: function() {
+ // window.File does not implement nsIFile
+ if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
+ return MockFilePicker.returnFiles[this.index++];
+ }
+ return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]);
+ }
+ };
+ },
+ show: function() {
+ MockFilePicker.displayDirectory = this.displayDirectory;
+ MockFilePicker.shown = true;
+ if (typeof MockFilePicker.showCallback == "function") {
+ var returnValue = MockFilePicker.showCallback(this);
+ if (typeof returnValue != "undefined")
+ return returnValue;
+ }
+ return MockFilePicker.returnValue;
+ },
+ open: function(aFilePickerShownCallback) {
+ MockFilePicker.showing = true;
+ this.window.setTimeout(function() {
+ let result = Components.interfaces.nsIFilePicker.returnCancel;
+ try {
+ result = this.show();
+ } catch(ex) {
+ }
+ if (aFilePickerShownCallback) {
+ aFilePickerShownCallback.done(result);
+ }
+ }.bind(this), 0);
+ }
+};