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.

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

mercurial