Skip to content

Commit ca5ff74

Browse files
author
Kaustav Das Modak
committed
Release v1.0
0 parents  commit ca5ff74

File tree

5 files changed

+349
-0
lines changed

5 files changed

+349
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*~
2+
3+
# KDE directory preferences
4+
.directory

EventEmitter.min.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 Applait Technologies LLP
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Finder library for Firefox OS
2+
3+
This library is an interface to search and pick files from the `DeviceStorages` on Firefox OS devices. It provides an easy-to-use asynchronous interface for other Firefox OS apps to search for files on Firefox OS devices. The library is based on an event-based architecture, letting developers build beautiful asynchronous API for their apps.
4+
5+
The `Finder` library is best used by developers looking to pick a file from `sdcard` for their apps.
6+
7+
This library depends on [EventEmitter](https://github.com/Wolfy87/EventEmitter) by Wolfy87, included with the package.
8+
9+
## Install
10+
11+
Copy the scripts to your app's directory, e.g. in the `js` subdirectory. Load these scripts in the HTML page in this order:
12+
13+
- `EventEmitter.min.js`
14+
- `applait.finder.js`
15+
16+
```html
17+
<script type="text/javascript" src="js/EventEmitter.min.js"></script>
18+
<script type="text/javascript" src="js/applait.finder.js"></script>
19+
```
20+
21+
## Usage
22+
23+
### 1. Create an instance
24+
25+
Create an instance of `Applait.Finder`. The constructor takes an `options` object which can have the following options. All options are optional:
26+
27+
- `type` : Can be one of `sdcard`, `pictures`, `music`, `videos`. Default: `sdcard`.
28+
- `minSearchLength` : A number representing the minimum length of the search string without which search will not be triggered. Default: `3`.
29+
- `debugMode` : If set to `true`, enables the debug mode, which prints all activities by the library on the browser console. Default: `false`.
30+
31+
```js
32+
var finder = new Applait.Finder("sdcard");
33+
```
34+
35+
### 2. Trigger search
36+
37+
Trigger a search by calling `finder.search()` and passing it the search string.
38+
39+
```js
40+
finder.search(searchterm);
41+
```
42+
43+
From this point onwards, `Finder` raises events for each action.
44+
45+
The `search` method will return `null` only if the search string is smaller in length than `minSearchLength` or if no `storage` mediums are found on the device for the given storage `type`. But is not necessary because `Finder` raises an event in either case.
46+
47+
48+
### 3. Listening to events
49+
50+
To listen to events, add an event listener with a callback using `finder.events.addListener()`. Each event gets a specific set of arguments depending on the event. For example, when `search()` finds a matching file, it raises the `fileFound` event with two arguments, the `File` object and a `fileinfo` object and the storage name in which it was found:
51+
52+
```js
53+
finder.events.addListener("fileFound", function (file, fileinfo, storageName) {
54+
console.log("Found file " + fileinfo.name + " at " + fileinfo.path + " in " + storageName, file);
55+
}
56+
```
57+
58+
## List of events
59+
60+
The `search` method raises events depending on the stage and result of processing the search. When `finder.search()` is triggered, it raises the following events:
61+
62+
### fileFound
63+
64+
This event is fired each time when a file is matched during the search. It provides the following arguments:
65+
66+
- `file` - the [File](https://developer.mozilla.org/en-US/docs/Web/API/File) object of the result matched.
67+
- `fileinfo` - An object containing the name and path of the file with the following keys:
68+
- `name`: A string containing the file name and extension.
69+
- `path`: A string containing the path to the directory of the file.
70+
- `storageName` - The internal name of the storage space.
71+
72+
Example:
73+
74+
```js
75+
finder.events.addListener("fileFound", function (file, fileinfo, storageName) {
76+
// Code goes here
77+
});
78+
```
79+
80+
### searchBegin
81+
82+
This event is fired when search is started. It provides the following arguments:
83+
84+
- `needle` - The search string.
85+
86+
Example:
87+
88+
```js
89+
finder.events.addListener("searchBegin", function (needle) {
90+
// Code goes here
91+
});
92+
```
93+
94+
### storageSearchBegin
95+
96+
This event is event when a search is begun for a particular [DeviceStorage](https://developer.mozilla.org/en-US/docs/Web/API/DeviceStorage).
97+
98+
For instance, `sdcard` storage type can have multiple locations. `Finder` iterates over all available location of the provided storage type using [navigator.getDeviceStorages](https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getDeviceStorages).
99+
100+
This event provides the following arguments:
101+
102+
- `storageName` - The internal name of the storage space.
103+
- `needle` - The search string.
104+
105+
Example:
106+
107+
```js
108+
finder.events.addListener("storageSearchBegin", function (storageName, needle) {
109+
// Code goes here
110+
});
111+
```
112+
113+
### searchComplete
114+
115+
This event is fired when search has completed for a particular storage location. It provides the following arguments:
116+
117+
- `storageName` - The internal name of the storage space.
118+
- `needle` - The search string.
119+
- `filematchcount` - The number of files matched in this search.
120+
121+
Note that `searchComplete` can be fired multiple times during a single `search()` if there are multiple storage locations.
122+
123+
Example:
124+
125+
```js
126+
finder.events.addListener("searchComplete", function (storageName, needle, filematchcount) {
127+
// Code goes here
128+
});
129+
```
130+
131+
### searchCancelled
132+
133+
This event is fired when a search is cancelled. It provides the following arguments:
134+
135+
- `message` : A string describing the reason of the cancel.
136+
137+
Example:
138+
139+
```js
140+
finder.events.addListener("searchCancelled", function (message) {
141+
// Code goes here
142+
});
143+
```
144+
145+
### empty
146+
147+
This event is fired when there is no storage medium available for the provided storage type. It provides the following arguments:
148+
149+
- `needle` - The search string.
150+
151+
Example:
152+
153+
```js
154+
finder.events.addListener("empty", function (needle) {
155+
// Code goes here
156+
});
157+
```
158+
159+
### error
160+
161+
This event is fired when any error is faced by the search. It provides the following arguments:
162+
163+
- `message` : A string describing the reason of the cancel.
164+
- `error` : The error object thrown.
165+
166+
Example:
167+
168+
```js
169+
finder.events.addListener("error", function (message) {
170+
// Code goes here
171+
});
172+
```
173+
174+
## Credits and attribution
175+
176+
- [EventEmitter](https://github.com/Wolfy87/EventEmitter) by Oliver Caldwell. Used under the MIT License.

applait.finder.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* File picker and finder for device storages on Firefox OS devices
3+
*
4+
* This library provides an easy-to-use asynchronous interface for other Firefox OS apps to search for files
5+
* on Firefox OS devices. The library is based on an event-based architecture, letting developers build
6+
* beautiful asynchronous API for their apps.
7+
*
8+
* The `Finder` library is best used by developers looking to pick a file from the `sdcard` for their apps.
9+
*
10+
* This library depends on [EventEmitter](https://github.com/Wolfy87/EventEmitter) by Wolfy87, included with the
11+
* package.
12+
*
13+
* @version 1.0.0
14+
* @license The MIT License (MIT)
15+
*
16+
* Copyright (c) 2014 Applait Technologies LLP
17+
*/
18+
19+
var Applait = Applait || {};
20+
21+
/**
22+
* Core `Finder` class. Provides the constructor for applications to instantiate.
23+
*
24+
* @constructor
25+
* @param {object=} options - Default options for the `Finder` constructor. It can include any of the following
26+
* properties:
27+
*
28+
* - `type` : `{string}` : Can be one of `sdcard`, `music`, `pictures`, `videos`. Defaults to `sdcard`.
29+
* - `minSearchLength`: `{number}` : The minimum length of search string without which search will not be triggered.
30+
* Defaults to `3`.
31+
* - `debugMode`: `{boolean}` : If `true`, enables debug mode which logs all messages to the browser console. This
32+
* should be disabled in production mode to reduce memory footprint.
33+
*
34+
* @example
35+
* var finder = new Applait.Finder({ type: "sdcard", debugMode: true });
36+
*/
37+
Applait.Finder = function (options) {
38+
39+
this.options = options || {};
40+
41+
this.type = options.type || "sdcard";
42+
43+
this.minSearchLength = (options.minSearchLength && typeof options.minSearchLength === "number") ?
44+
options.minSearchLength || 3;
45+
46+
this.debugMode = (options.debugMode && options.debugMode === true) ? true : false;
47+
48+
this.storages = navigator.getDeviceStorages && navigator.getDeviceStorages(this.type);
49+
50+
this.events = new EventEmitter();
51+
52+
};
53+
54+
/**
55+
* Instantiate search
56+
*
57+
* @memberOf Applait.Finder
58+
* @param {string} needle - The string to match file names from the device storage.
59+
* @return {null} - Only if `needle` length is less than 3 characters or if no DeviceStorages are found.
60+
*/
61+
Applait.Finder.prototype.search = function (needle) {
62+
63+
var context = this,
64+
filematchcount = 0;
65+
66+
needle = needle.trim();
67+
68+
if (needle.length < context.minSearchLength) {
69+
if (context.debugMode) {
70+
console.log("Search cancelled. Less than " + context.minSearchLength + " characters search string");
71+
}
72+
context.events.emitEvent("searchCancelled", ["Search string should be at least " + context.minSearchLength
73+
+ " characters"]);
74+
return null;
75+
}
76+
77+
if (context.storages.length < 1) {
78+
if (context.debugMode) console.log("empty", needle);
79+
context.events.emitEvent("empty", [needle]);
80+
return null;
81+
}
82+
83+
if (context.debugMode) console.log("searchBegin", needle);
84+
context.events.emitEvent("searchBegin", [needle]);
85+
86+
context.storages.forEach(function (storage) {
87+
88+
var cursor = storage.enumerate();
89+
90+
if (context.debugMode) console.log("storageSearchBegin", storage.storageName, needle);
91+
context.events.emitEvent("storageSearchBegin", [storage.storageName, needle]);
92+
93+
cursor.onsuccess = function () {
94+
95+
if (this.result) {
96+
97+
var file = this.result;
98+
var fileinfo = context.splitname(file.name);
99+
100+
if (fileinfo.name.indexOf(needle) > -1) {
101+
filematchcount++;
102+
if (context.debugMode) console.log("fileFound", file, fileinfo, storage.storageName);
103+
context.events.emitEvent("fileFound", [file, fileinfo, storage.storageName]);
104+
}
105+
106+
if (!this.done) {
107+
this.continue();
108+
} else {
109+
if (context.debugMode) console.log("searchComplete", storage.storageName, needle, filematchcount);
110+
context.events.emitEvent("searchComplete", [storage.storageName, needle, filematchcount]);
111+
}
112+
} else {
113+
if (context.debugMode) console.log("searchComplete", storage.storageName, needle, filematchcount);
114+
context.events.emitEvent("searchComplete", [storage.storageName, needle, filematchcount]);
115+
}
116+
117+
};
118+
119+
cursor.onerror = function () {
120+
if (context.debugMode) console.log("Error accessing device storage '" + storage.storageName + "'", this.error);
121+
context.events.emitEvent('error', ["Error accessing device storage '" + storage.storageName + "'", this.error]);
122+
};
123+
124+
});
125+
};
126+
127+
/**
128+
* Splits full file path into basename and path to directory.
129+
*
130+
* @memberOf Applait.Finder
131+
* @param {string} filename - Filename obtained for `File.filename`
132+
* @return {object} - An object with two keys:
133+
*
134+
* - `name` - the basename of the file with extension
135+
* - `path` - path to the file's directory.
136+
*/
137+
Applait.Finder.prototype.splitname = function (filename) {
138+
filename = filename.split(/[\\/]/);
139+
140+
return { "name": filename.pop(), "path": filename.join("/") };
141+
};

0 commit comments

Comments
 (0)