mobile/android/components/FilePicker.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 const Ci = Components.interfaces;
michael@0 6 const Cu = Components.utils;
michael@0 7 const Cc = Components.classes;
michael@0 8
michael@0 9 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 10 Cu.import("resource://gre/modules/Services.jsm");
michael@0 11 Cu.import("resource://gre/modules/FileUtils.jsm");
michael@0 12
michael@0 13 function FilePicker() {
michael@0 14 }
michael@0 15
michael@0 16 FilePicker.prototype = {
michael@0 17 _mimeTypeFilter: 0,
michael@0 18 _extensionsFilter: "",
michael@0 19 _defaultString: "",
michael@0 20 _domWin: null,
michael@0 21 _defaultExtension: null,
michael@0 22 _displayDirectory: null,
michael@0 23 _filePath: null,
michael@0 24 _promptActive: false,
michael@0 25 _filterIndex: 0,
michael@0 26 _addToRecentDocs: false,
michael@0 27
michael@0 28 init: function(aParent, aTitle, aMode) {
michael@0 29 this._domWin = aParent;
michael@0 30 this._mode = aMode;
michael@0 31 Services.obs.addObserver(this, "FilePicker:Result", false);
michael@0 32
michael@0 33 let idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
michael@0 34 this.guid = idService.generateUUID().toString();
michael@0 35
michael@0 36 if (aMode != Ci.nsIFilePicker.modeOpen && aMode != Ci.nsIFilePicker.modeOpenMultiple)
michael@0 37 throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
michael@0 38 },
michael@0 39
michael@0 40 appendFilters: function(aFilterMask) {
michael@0 41 if (aFilterMask & Ci.nsIFilePicker.filterAudio) {
michael@0 42 this._mimeTypeFilter = "audio/*";
michael@0 43 return;
michael@0 44 }
michael@0 45
michael@0 46 if (aFilterMask & Ci.nsIFilePicker.filterImages) {
michael@0 47 this._mimeTypeFilter = "image/*";
michael@0 48 return;
michael@0 49 }
michael@0 50
michael@0 51 if (aFilterMask & Ci.nsIFilePicker.filterVideo) {
michael@0 52 this._mimeTypeFilter = "video/*";
michael@0 53 return;
michael@0 54 }
michael@0 55
michael@0 56 if (aFilterMask & Ci.nsIFilePicker.filterAll) {
michael@0 57 this._mimeTypeFilter = "*/*";
michael@0 58 return;
michael@0 59 }
michael@0 60
michael@0 61 /* From BaseFilePicker.cpp */
michael@0 62 if (aFilterMask & Ci.nsIFilePicker.filterHTML) {
michael@0 63 this.appendFilter("*.html; *.htm; *.shtml; *.xhtml");
michael@0 64 }
michael@0 65 if (aFilterMask & Ci.nsIFilePicker.filterText) {
michael@0 66 this.appendFilter("*.txt; *.text");
michael@0 67 }
michael@0 68
michael@0 69 if (aFilterMask & Ci.nsIFilePicker.filterXML) {
michael@0 70 this.appendFilter("*.xml");
michael@0 71 }
michael@0 72
michael@0 73 if (aFilterMask & Ci.nsIFilePicker.xulFilter) {
michael@0 74 this.appendFilter("*.xul");
michael@0 75 }
michael@0 76
michael@0 77 if (aFilterMask & Ci.nsIFilePicker.xulFilter) {
michael@0 78 this.appendFilter("..apps");
michael@0 79 }
michael@0 80 },
michael@0 81
michael@0 82 appendFilter: function(title, filter) {
michael@0 83 if (this._extensionsFilter)
michael@0 84 this._extensionsFilter += ", ";
michael@0 85 this._extensionsFilter += filter;
michael@0 86 },
michael@0 87
michael@0 88 get defaultString() {
michael@0 89 return this._defaultString;
michael@0 90 },
michael@0 91
michael@0 92 set defaultString(defaultString) {
michael@0 93 this._defaultString = defaultString;
michael@0 94 },
michael@0 95
michael@0 96 get defaultExtension() {
michael@0 97 return this._defaultExtension;
michael@0 98 },
michael@0 99
michael@0 100 set defaultExtension(defaultExtension) {
michael@0 101 this._defaultExtension = defaultExtension;
michael@0 102 },
michael@0 103
michael@0 104 get filterIndex() {
michael@0 105 return this._filterIndex;
michael@0 106 },
michael@0 107
michael@0 108 set filterIndex(val) {
michael@0 109 this._filterIndex = val;
michael@0 110 },
michael@0 111
michael@0 112 get displayDirectory() {
michael@0 113 return this._displayDirectory;
michael@0 114 },
michael@0 115
michael@0 116 set displayDirectory(dir) {
michael@0 117 this._displayDirectory = dir;
michael@0 118 },
michael@0 119
michael@0 120 get file() {
michael@0 121 if (!this._filePath) {
michael@0 122 return null;
michael@0 123 }
michael@0 124
michael@0 125 return new FileUtils.File(this._filePath);
michael@0 126 },
michael@0 127
michael@0 128 get fileURL() {
michael@0 129 let file = this.getFile();
michael@0 130 return Services.io.newFileURI(file);
michael@0 131 },
michael@0 132
michael@0 133 get files() {
michael@0 134 return this.getEnumerator([this.file], function(file) {
michael@0 135 return file;
michael@0 136 });
michael@0 137 },
michael@0 138
michael@0 139 get domfile() {
michael@0 140 let f = this.file;
michael@0 141 if (!f) {
michael@0 142 return null;
michael@0 143 }
michael@0 144 return File(f);
michael@0 145 },
michael@0 146
michael@0 147 get domfiles() {
michael@0 148 return this.getEnumerator([this.file], function(file) {
michael@0 149 return File(file);
michael@0 150 });
michael@0 151 },
michael@0 152
michael@0 153 get addToRecentDocs() {
michael@0 154 return this._addToRecentDocs;
michael@0 155 },
michael@0 156
michael@0 157 set addToRecentDocs(val) {
michael@0 158 this._addToRecentDocs = val;
michael@0 159 },
michael@0 160
michael@0 161 get mode() {
michael@0 162 return this._mode;
michael@0 163 },
michael@0 164
michael@0 165 show: function() {
michael@0 166 if (this._domWin) {
michael@0 167 this.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
michael@0 168 let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
michael@0 169 winUtils.enterModalState();
michael@0 170 }
michael@0 171
michael@0 172 this._promptActive = true;
michael@0 173 this._sendMessage();
michael@0 174
michael@0 175 let thread = Services.tm.currentThread;
michael@0 176 while (this._promptActive)
michael@0 177 thread.processNextEvent(true);
michael@0 178 delete this._promptActive;
michael@0 179
michael@0 180 if (this._domWin) {
michael@0 181 let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
michael@0 182 winUtils.leaveModalState();
michael@0 183 this.fireDialogEvent(this._domWin, "DOMModalDialogClosed");
michael@0 184 }
michael@0 185
michael@0 186 if (this._filePath)
michael@0 187 return Ci.nsIFilePicker.returnOK;
michael@0 188
michael@0 189 return Ci.nsIFilePicker.returnCancel;
michael@0 190 },
michael@0 191
michael@0 192 open: function(callback) {
michael@0 193 this._callback = callback;
michael@0 194 this._sendMessage();
michael@0 195 },
michael@0 196
michael@0 197 _sendMessage: function() {
michael@0 198 let msg = {
michael@0 199 type: "FilePicker:Show",
michael@0 200 guid: this.guid,
michael@0 201 };
michael@0 202
michael@0 203 // Knowing the window lets us destroy any temp files when the tab is closed
michael@0 204 // Other consumers of the file picker may have to either wait for Android
michael@0 205 // to clean up the temp dir (not guaranteed) or clean up after themselves.
michael@0 206 let win = Services.wm.getMostRecentWindow('navigator:browser');
michael@0 207 let tab = win.BrowserApp.getTabForWindow(this._domWin.top)
michael@0 208 if (tab) {
michael@0 209 msg.tabId = tab.id;
michael@0 210 }
michael@0 211
michael@0 212 if (!this._extensionsFilter && !this._mimeTypeFilter) {
michael@0 213 // If neither filters is set show anything we can.
michael@0 214 msg.mode = "mimeType";
michael@0 215 msg.mimeType = "*/*";
michael@0 216 } else if (this._extensionsFilter) {
michael@0 217 msg.mode = "extension";
michael@0 218 msg.extensions = this._extensionsFilter;
michael@0 219 } else {
michael@0 220 msg.mode = "mimeType";
michael@0 221 msg.mimeType = this._mimeTypeFilter;
michael@0 222 }
michael@0 223
michael@0 224 this.sendMessageToJava(msg);
michael@0 225 },
michael@0 226
michael@0 227 sendMessageToJava: function(aMsg) {
michael@0 228 Services.androidBridge.handleGeckoMessage(aMsg);
michael@0 229 },
michael@0 230
michael@0 231 observe: function(aSubject, aTopic, aData) {
michael@0 232 let data = JSON.parse(aData);
michael@0 233 if (data.guid != this.guid)
michael@0 234 return;
michael@0 235
michael@0 236 this._filePath = null;
michael@0 237 if (data.file)
michael@0 238 this._filePath = data.file;
michael@0 239
michael@0 240 this._promptActive = false;
michael@0 241
michael@0 242 if (this._callback) {
michael@0 243 this._callback.done(this._filePath ? Ci.nsIFilePicker.returnOK : Ci.nsIFilePicker.returnCancel);
michael@0 244 }
michael@0 245 delete this._callback;
michael@0 246 },
michael@0 247
michael@0 248 getEnumerator: function(files, mapFunction) {
michael@0 249 return {
michael@0 250 QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
michael@0 251 mFiles: files,
michael@0 252 mIndex: 0,
michael@0 253 hasMoreElements: function() {
michael@0 254 return (this.mIndex < this.mFiles.length);
michael@0 255 },
michael@0 256 getNext: function() {
michael@0 257 if (this.mIndex >= this.mFiles.length) {
michael@0 258 throw Components.results.NS_ERROR_FAILURE;
michael@0 259 }
michael@0 260 return mapFunction(this.mFiles[this.mIndex++]);
michael@0 261 }
michael@0 262 };
michael@0 263 },
michael@0 264
michael@0 265 fireDialogEvent: function(aDomWin, aEventName) {
michael@0 266 // accessing the document object can throw if this window no longer exists. See bug 789888.
michael@0 267 try {
michael@0 268 if (!aDomWin.document)
michael@0 269 return;
michael@0 270 let event = aDomWin.document.createEvent("Events");
michael@0 271 event.initEvent(aEventName, true, true);
michael@0 272 let winUtils = aDomWin.QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 273 .getInterface(Ci.nsIDOMWindowUtils);
michael@0 274 winUtils.dispatchEventToChromeOnly(aDomWin, event);
michael@0 275 } catch(ex) {
michael@0 276 }
michael@0 277 },
michael@0 278
michael@0 279 classID: Components.ID("{18a4e042-7c7c-424b-a583-354e68553a7f}"),
michael@0 280 QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker, Ci.nsIObserver])
michael@0 281 };
michael@0 282
michael@0 283 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FilePicker]);

mercurial