Merge branch 'next'
diff --git a/.gitignore b/.gitignore
index 4e14638..8d7f400 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@
www/*
build_output/
pkg
+plugins
diff --git a/.jshintrc b/.jshintrc
index d8b8028..556accb 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -64,7 +64,8 @@
"sinon",
"setInterval", "clearInterval", "setTimeout", "clearTimeout",
"require", "Contact", "Position", "Coordinates", "Node",
- "OpenLayers"
+ "OpenLayers",
+ "cordova"
],
"node" : true,
diff --git a/Jakefile b/Jakefile
index 137e693..5a39f14 100644
--- a/Jakefile
+++ b/Jakefile
@@ -22,10 +22,29 @@
desc("test and lint before building (with js compression)");
task('deploy', [], require('./build/deploy'));
+// TODO: put this functionality into its own module (same with code in build/deploy).
desc("run all tests in node with an emulated dom - jake test [path,path2]");
task('test', [], function () {
- require('./build/test')(null, process.argv.length >= 4 ? process.argv[3] : null);
-});
+ var childProcess = require('child_process'),
+ env = process.env,
+ lib = process.cwd() + '/lib',
+ script = process.cwd() + '/build/scripts/runTestsInNode',
+ child;
+
+ env.NODE_PATH = lib;
+ child = childProcess.spawn(process.execPath, [script], {'env': env});
+
+ function log(data) {
+ process.stdout.write(new Buffer(data).toString('utf-8'));
+ }
+
+ child.stdout.on('data', log);
+ child.stderr.on('data', log);
+ child.on('exit', function (code) {
+ complete();
+ process.exit(code);
+ });
+}, true);
desc("boot test server for running all tests in the browser");
task('btest', [], require('./build/btest'));
diff --git a/README.md b/README.md
index 905d8cb..26ec006 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,17 @@
This will describe all the available commands for building and running the tests
+## Running as a Chrome Extension
+
+- go to the extension management page (chrome://chrome/extensions/) in chrome.
+- Ensure that you have selected the developer mode checkbox
+- click the Load Unpacked extension button
+- select the chromestore folders in the pkg/ folder.
+
+NOTE: for development you should be fine to just build with jake and refresh your browser. If
+you end up editing anything in the ext folder you will need to refresh the extension from
+the extension management page.
+
## Running Inside Other Web Browsers
Ripple is (by-design) browser agnostic, and is able to run inside any web browser (with disabled web security).
@@ -45,6 +56,8 @@
--disable-web-security
--user-data-dir=/path/to/dummy/profile
+This has only really be tested in chrome.
+
## Code Guidelines
* 4 spaces per editor tab
diff --git a/build/btest.js b/build/btest.js
index 1a8df75..438ab46 100644
--- a/build/btest.js
+++ b/build/btest.js
@@ -24,27 +24,21 @@
doc,
modules,
specs,
- openlayers,
- app = connect(
- connect.static(__dirname + "/../lib/"),
- connect.static(__dirname + "/../"),
- connect.router(function (app) {
- app.get('/', function (req, res) {
- res.writeHead(200, {
- "Cache-Control": "no-cache",
- "Content-Type": "text/html"
- });
- res.end(doc);
+ app = connect()
+ .use(connect.static(__dirname + "/../lib/"))
+ .use(connect.static(__dirname + "/../"))
+ .use('/', function (req, res) {
+ res.writeHead(200, {
+ "Cache-Control": "max-age=0",
+ "Content-Type": "text/html"
});
- })
- );
+ res.end(doc);
+ });
- //HACK: Openlayers causes weird stuff with the browser runner, so lets pop it off the list until we fix it
- openlayers = conf.thirdpartyIncludes.pop();
- if (openlayers !== "OpenLayers.js") {
- //HACK: just a safe check to make sure our hack is still valid
- console.log("HACK: we wanted to pop OpenLayers off but it looks like it wasn't the last one anymore");
- }
+ //HACK: Openlayers causes weird stuff with the browser runner, so lets remove it from the list until we fix it
+ conf.thirdpartyIncludes = conf.thirdpartyIncludes.filter(function (filename) {
+ return !filename.match(/openlayers\.js/i);
+ });
modules = pack();
diff --git a/build/build/chromestore.js b/build/build/chromestore.js
index f9441e2..7875b10 100644
--- a/build/build/chromestore.js
+++ b/build/build/chromestore.js
@@ -24,7 +24,8 @@
'cp -r ' + _c.ASSETS + "images " + _c.DEPLOY + "chromestore/ &&" +
'cp -r ' + _c.ASSETS + "themes " + _c.DEPLOY + "chromestore/ &&" +
'cp ' + _c.EXT + "chromestore/manifest.json " + _c.DEPLOY + "chromestore/manifest.json &&" +
- 'cp ' + _c.EXT + "chromestore/controllers/Background.js " + _c.DEPLOY + "chromestore/controllers/Background.js";
+ 'cp ' + _c.EXT + "chromestore/controllers/Background.js " + _c.DEPLOY + "chromestore/controllers/Background.js" +
+ 'cp ' + _c.EXT + "chromestore/views/background.html " + _c.DEPLOY + "chromestore/views/background.html";
childProcess.exec(copy, function () {
var css = _c.ASSETS + "ripple.css",
diff --git a/build/build/chromium.js b/build/build/chromium.js
index 331a725..91aac0b 100644
--- a/build/build/chromium.js
+++ b/build/build/chromium.js
@@ -22,7 +22,8 @@
var copy = 'cp -r ' + _c.EXT + "chromium " + _c.DEPLOY + " && " +
'cp -r ' + _c.ASSETS + "images " + _c.DEPLOY + "chromium/ &&" +
- 'cp -r ' + _c.ASSETS + "themes " + _c.DEPLOY + "chromium/";
+ 'cp -r ' + _c.ASSETS + "themes " + _c.DEPLOY + "chromium/" +
+ 'cp -r ' + _c.ROOT + "plugins " + _c.DEPLOY + "chromium/";
childProcess.exec(copy, function () {
var css = _c.ASSETS + "ripple.css",
diff --git a/build/deploy.js b/build/deploy.js
index 6dd68cc..6ed1e3f 100644
--- a/build/deploy.js
+++ b/build/deploy.js
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-var test = require('./test'),
- lint = require('./lint'),
+var lint = require('./lint'),
build = require('./build'),
+ childProcess = require('child_process'),
fs = require('fs'),
fail = fs.readFileSync(__dirname + "/../thirdparty/fail.txt", "utf-8");
@@ -26,6 +26,26 @@
}
}
+function test(callback) {
+ var env = process.env,
+ lib = process.cwd() + '/lib',
+ script = process.cwd() + '/build/scripts/runTestsInNode',
+ child;
+
+ env.NODE_PATH = lib;
+ child = childProcess.spawn(process.execPath, [script], {'env': env});
+
+ function log(data) {
+ process.stdout.write(new Buffer(data).toString('utf-8'));
+ }
+
+ child.stdout.on('data', log);
+ child.stderr.on('data', log);
+ child.on('exit', function (code) {
+ callback(code);
+ });
+}
+
module.exports = function () {
test(function (code) {
ok(code, "red tests");
diff --git a/build/lint.js b/build/lint.js
index 32917d1..f02b99e 100644
--- a/build/lint.js
+++ b/build/lint.js
@@ -38,7 +38,7 @@
function _lintCSS(files, done) {
var rules = JSON.parse(fs.readFileSync(__dirname + "/../.csslintrc", "utf-8")),
- options = ["--rules=" + rules, "--format=compact"];
+ options = ["--errors=" + rules, "--format=compact", "--quiet"];
_spawn('csslint', files.concat(options), done);
}
diff --git a/build/scripts/runTestsInNode b/build/scripts/runTestsInNode
new file mode 100755
index 0000000..c34ae30
--- /dev/null
+++ b/build/scripts/runTestsInNode
@@ -0,0 +1,5 @@
+// This is here for a reason.
+// This is so you can do things like `NODE_PATH=/path/to/ripple/lib node external_script`.
+// This gets around that pesky forcing of relative requires in Node (these days).
+// See the `jakefile` for how this is used in this project.
+require('./../test')();
diff --git a/build/test.js b/build/test.js
index c0a9a22..8474423 100644
--- a/build/test.js
+++ b/build/test.js
@@ -66,13 +66,11 @@
_extraMocks();
- childProcess.exec('rm -rf node_modules/ripple* && ' +
- 'cp -rf lib/ripple node_modules/ripple && ' +
- 'cp -f lib/ripple.js node_modules/ripple.js', ready);
+ ready();
});
}
-module.exports = function (done, custom) {
+module.exports = function (done) {
//HACK: this should be taken out if our pull request in jasmine is accepted.
jasmine.core.Matchers.prototype.toThrow = function (expected) {
var result = false,
@@ -108,14 +106,11 @@
};
_setupEnv(function () {
- var targets = __dirname + "/../" + (custom ? custom : "test");
+ var targets = __dirname + "/../test";
jasmine.run(targets.split(' '), function (runner) {
var failed = runner.results().failedCount === 0 ? 0 : 1;
- //Nuke everything out of node_modules since it was just in there to run the tests
- childProcess.exec('rm -rf node_modules/ripple*', function () {
- (typeof done !== "function" ? process.exit : done)(failed);
- });
+ (typeof done !== "function" ? process.exit : done)(failed);
});
});
};
diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md
index 81131a5..e21ddd8 100644
--- a/doc/CHANGELOG.md
+++ b/doc/CHANGELOG.md
@@ -1,3 +1,26 @@
+## v0.9.7 - July 19, 2012
+
+* Fixed an issue with Ripple booting on Chrome 21 dev channel
+* Webworks BB10 support: (https://github.com/blackberry/Ripple-UI/issues?milestone=11&page=1&state=closed)
+ * blackberry.app.exit
+ * device settings for software version and hardware ID
+ * support for consumer and enterprise parameters
+ * support for the swipe down event
+ * support for invoke
+* Fixed a caching issue.
+* Cleaned up browser test failures
+* updated build tooling to work in latest node
+* updated README docs for running as a plugin
+* added support for selecting the platform and version when launching from the querystring
+* Updated Cordova support for 2.0.0 (https://github.com/blackberry/Ripple-UI/issues?milestone=13&page=1&state=closed)
+ * updated the version numbers for phonegap and cordova
+ * navigator camera
+ * Media
+ * File API
+ * cordova specific event support
+ * updated and fixed support for navigator.contacts
+ * added partial support for navigator.device.capture
+
## v0.9.6.1 (HOTFIX) - June 21, 2012
* Fixed bug with Chrome Version 21.0.1180.0 dev where Ripple will not boot
diff --git a/ext/assets/index.html b/ext/assets/index.html
index b922c21..ad7a547 100644
--- a/ext/assets/index.html
+++ b/ext/assets/index.html
@@ -16,6 +16,7 @@
<!DOCTYPE html>
<html manifest="cache.manifest">
<head>
+ <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<link href="#URL_PREFIX#ripple.css" type="text/css" rel="stylesheet" />
</head>
<body>
diff --git a/ext/chromestore/controllers/Background.js b/ext/chromestore/controllers/Background.js
index 4a44c2c..39d3963 100644
--- a/ext/chromestore/controllers/Background.js
+++ b/ext/chromestore/controllers/Background.js
@@ -173,7 +173,7 @@
chrome.tabs.getSelected(null, function (tab) {
console.log("enable ==> " + tab.url);
_persistEnabled(tab.url);
- chrome.tabs.sendRequest(tab.id, {"action": "enable", "mode": "widget", "tabURL": tab.url }, function (response) {});
+ chrome.tabs.sendRequest(tab.id, {"action": "enable", "mode": "widget", "tabURL": tab.url });
});
},
@@ -194,7 +194,7 @@
localStorage["tinyhippos-enabled-uri"] = JSON.stringify(jsonObject);
- chrome.tabs.sendRequest(tab.id, {"action": "disable", "tabURL": tab.url }, function (response) {});
+ chrome.tabs.sendRequest(tab.id, {"action": "disable", "tabURL": tab.url });
});
},
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js b/ext/chromestore/views/background.html
similarity index 71%
copy from lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
copy to ext/chromestore/views/background.html
index 38aa21a..96379ac 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
+++ b/ext/chromestore/views/background.html
@@ -1,4 +1,4 @@
-/*
+<!--
* Copyright 2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,10 +12,12 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-//blackberry.invoke.BrowserArguments ( url : String , [transport : blackberry.identity.Transport ] )
-module.exports = function (url, transport) {
- return {
- url: url
- };
-};
+-->
+<html>
+ <head>
+ <script type="text/javascript" src="../controllers/jquery.js"></script>
+ <script type="text/javascript" src="../controllers/Background.js"></script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/ext/chromium/controllers/Background.js b/ext/chromium/controllers/Background.js
index 0d43bee..0b29e7f 100644
--- a/ext/chromium/controllers/Background.js
+++ b/ext/chromium/controllers/Background.js
@@ -56,6 +56,8 @@
xhr.send();
chrome.extension.onRequest.addListener(function (request, sender, sendResponse) {
+ var xhr, postData, data, plugin;
+console.log(request);
switch (request.action) {
case "isEnabled":
console.log("isEnabled? ==> " + request.tabURL);
@@ -67,16 +69,16 @@
sendResponse();
break;
case "userAgent":
- console.log("user agent ==> " + userAgent);
+ console.log("user agent ==> " + request.data);
userAgent = request.data;
break;
case "version":
sendResponse(version);
break;
case "xhr":
- var xhr = new XMLHttpRequest(),
- postData = new FormData(),
- data = JSON.parse(request.data);
+ xhr = new XMLHttpRequest();
+ postData = new FormData();
+ data = JSON.parse(request.data);
console.log("xhr ==> " + data.url);
@@ -99,8 +101,32 @@
}
});
break;
+ case "services":
+ console.log("services", request.data);
+ if (request.data === '"start"') {
+ plugin = document.getElementById("pluginRippleBD");
+ if (plugin) {
+ console.log("return from startBD", plugin.startBD(9910));
+ sendResponse();
+ }
+ }
+ else if (request.data === '"stop"') {
+ xhr = new XMLHTTPRequest();
+ try {
+ xhr.open("GET", "http://127.0.0.1:9910/ripple/shutdown", false);
+ xhr.send();
+ }
+ catch (e) {
+ console.log(e);
+ }
+ }
+ break;
+ case "lag":
+ case "network":
+ // methods to be implemented at a later date
+ break;
default:
- throw {name: "MethodNotImplemented", message: "Requested action is not supported!"};
+ throw {name: "MethodNotImplemented", message: "Requested action is not supported! "};
break;
};
});
@@ -186,7 +212,7 @@
chrome.tabs.getSelected(null, function (tab) {
console.log("enable ==> " + tab.url);
_persistEnabled(tab.url);
- chrome.tabs.sendRequest(tab.id, {"action": "enable", "mode": "widget", "tabURL": tab.url }, function (response) {});
+ chrome.tabs.sendRequest(tab.id, {"action": "enable", "mode": "widget", "tabURL": tab.url});
});
},
@@ -207,12 +233,12 @@
localStorage["tinyhippos-enabled-uri"] = JSON.stringify(jsonObject);
- chrome.tabs.sendRequest(tab.id, {"action": "disable", "tabURL": tab.url }, function (response) {});
+ chrome.tabs.sendRequest(tab.id, {"action": "disable", "tabURL": tab.url });
});
},
isEnabled: function (url, enabledURIs) {
- if (url.match(/enableripple=true/i)) {
+ if (url.match(/enableripple=/i)) {
_persistEnabled(url);
return true;
}
diff --git a/ext/chromium/controllers/Insertion.js b/ext/chromium/controllers/Insertion.js
index 5b2457e..6ccbe8a 100644
--- a/ext/chromium/controllers/Insertion.js
+++ b/ext/chromium/controllers/Insertion.js
@@ -21,16 +21,20 @@
case "enable":
break;
case "disable":
- localStorage.removeItem("tinyhippos-enabled-uri");
- uri = uri.replace(/\?enableripple\=true/, "").replace(/\&enableripple\=true/, "");
+ //HACK: ummm .... I am sorry
+ uri = uri.replace(/enableripple=[^&]*[&]?/i, "").replace(/[\?&]*$/, "");
break;
default:
throw {name: "MethodNotImplemented", message: "Requested action is not supported!"};
}
- sendResponse({});
- location.href = uri;
+ if (location.href !== uri) {
+ location.href = uri;
+ }
+ else {
+ location.reload();
+ }
});
}
diff --git a/ext/chromium/controllers/frame.js b/ext/chromium/controllers/frame.js
index b0d4289..eb3a854 100644
--- a/ext/chromium/controllers/frame.js
+++ b/ext/chromium/controllers/frame.js
@@ -1,6 +1,21 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
if (!document.getElementById("emulator-booting") && !document.getElementById("tinyhippos-injected")) {
var script = document.createElement("script");
script.id = "tinyhippos-injected";
- script.src = chrome.extension.getURL("controllers/injector.js");
+ script.innerText = 'if (window.top.require) { window.top.require("ripple/bootstrap").inject(window, document); }';
document.documentElement.appendChild(script);
}
diff --git a/ext/chromium/controllers/injector.js b/ext/chromium/controllers/injector.js
deleted file mode 100644
index 4cc51cf..0000000
--- a/ext/chromium/controllers/injector.js
+++ /dev/null
@@ -1,9 +0,0 @@
-if (window.top.require) {
- //HACK: make this work better and handle iframes in the app!
- window.top.require('ripple/bootstrap').inject(window, document);
- window.top.onbeforeunload = function () {
- if (!window.top.tinyHipposReload) {
- return "Are you sure you want to exit Ripple?";
- }
- };
-}
diff --git a/ext/chromium/manifest.json b/ext/chromium/manifest.json
index 67e1a5e..f54a673 100644
--- a/ext/chromium/manifest.json
+++ b/ext/chromium/manifest.json
@@ -2,6 +2,10 @@
"version": "",
"name": "Ripple Emulator (Beta)",
"background_page":"views/background.html",
+ "plugins": [
+ { "path": "plugins/npRippleBD.dll" },
+ { "path": "plugins/RippleBD.plugin" }
+ ],
"icons":{
"16":"images/Icon_16x16.png",
"128":"images/Icon_128x128.png",
@@ -23,7 +27,7 @@
"matches": ["http://*/*","https://*/*","file:///*"],
"all_frames": true
}],
- "permissions": ["tabs", "unlimitedStorage", "notifications", "contextMenus", "webRequest", "webRequestBlocking", "http://*/*", "https://*/*", "file:///*/*"],
+ "permissions": ["tabs", "unlimitedStorage", "notifications", "contextMenus", "webRequest", "webRequestBlocking", "<all_urls>"],
"description": "A browser based html5 mobile application development and testing tool",
"update_url": "http://developer.blackberry.com/ripple/updates.xml"
}
diff --git a/ext/chromium/views/background.html b/ext/chromium/views/background.html
index 96379ac..2794dff 100644
--- a/ext/chromium/views/background.html
+++ b/ext/chromium/views/background.html
@@ -19,5 +19,6 @@
<script type="text/javascript" src="../controllers/Background.js"></script>
</head>
<body>
+ <embed type="application/x-ripplebd" id="pluginRippleBD" hidden="true" width="0" height="0" />
</body>
</html>
diff --git a/lib/ripple.js b/lib/ripple.js
index 28b707a..602883a 100644
--- a/lib/ripple.js
+++ b/lib/ripple.js
@@ -57,6 +57,25 @@
}
});
+ window.onbeforeunload = function () {
+ if (!window.tinyHipposReload) {
+ return "Are you sure you want to exit Ripple?";
+ }
+ };
+
+ //HACK: need to find a better way to do this since it's
+ //WebWorks specific!!!
+ window.onunload = function () {
+ var bus = require('ripple/bus');
+ bus.ajax(
+ "GET",
+ "http://127.0.0.1:9910/ripple/shutdown",
+ null,
+ null,
+ null
+ );
+ };
+
jWorkflow.order(omgwtf.initialize, omgwtf)
.andThen(appcache.initialize, appcache)
.andThen(db.initialize, db)
diff --git a/lib/ripple/bootstrap.js b/lib/ripple/bootstrap.js
index 0525ee1..9c806d2 100644
--- a/lib/ripple/bootstrap.js
+++ b/lib/ripple/bootstrap.js
@@ -118,7 +118,7 @@
tinyHippos.boot(function () {
var uri = ui.registered('omnibar') ?
db.retrieve(_CURRENT_URL) || "about:blank" :
- document.documentURI.replace(/enableripple=true[&]/i, "").replace(/[\?&]$/, "");
+ document.documentURI.replace(/enableripple=[^&]*[&]?/i, "").replace(/[\?&]*$/, "");
_post(uri);
delete tinyHippos.boot;
diff --git a/lib/ripple/devices/Colt.js b/lib/ripple/devices/Colt.js
index ea664a7..e4be734 100644
--- a/lib/ripple/devices/Colt.js
+++ b/lib/ripple/devices/Colt.js
@@ -20,9 +20,10 @@
"model": "Colt",
"osName": "BlackBerry",
"uuid": "42",
- "osVersion": "10.0.4.178",
+ "osVersion": "10.0.6.99",
"firmware": "6",
"manufacturer": "Research In Motion",
+ "hardwareId": "0x8500240a",
"skin": "Colt",
diff --git a/lib/ripple/devices/NexusS.js b/lib/ripple/devices/NexusS.js
index 311c882..37be6a4 100644
--- a/lib/ripple/devices/NexusS.js
+++ b/lib/ripple/devices/NexusS.js
@@ -45,7 +45,7 @@
"ppi": 235,
"userAgent": "Mozilla/5.0 (Linux; U; Android 2.3.2; en-us; Nexus S Build/GRH78C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
"browser": ["Webkit", "Presto"],
- "platforms": ["web", "phonegap"],
+ "platforms": ["web", "phonegap", "cordova"],
"notes": {
"1": "<a href=\"http://www.google.com/nexus/#/tech-specs\" target=\"_blank\">Specs</a>"
diff --git a/lib/ripple/devices/iPad.js b/lib/ripple/devices/iPad.js
index 909b489..05ecdcd 100644
--- a/lib/ripple/devices/iPad.js
+++ b/lib/ripple/devices/iPad.js
@@ -46,7 +46,7 @@
"ppi": 132,
"userAgent": "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10",
"browser": ["Webkit"],
- "platforms": ["web", "phonegap"],
+ "platforms": ["web", "phonegap", "cordova"],
"notes": {
"1": "<a href=\"http://www.apple.com/ipad/specs/\" target=\"_blank\">Specs</a>"
diff --git a/lib/ripple/devices/iPhone3.js b/lib/ripple/devices/iPhone3.js
index fb57df9..d5dfd62 100644
--- a/lib/ripple/devices/iPhone3.js
+++ b/lib/ripple/devices/iPhone3.js
@@ -46,5 +46,5 @@
"ppi": 164.8,
"userAgent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3",
"browser": ["Webkit"],
- "platforms": ["web", "phonegap"]
+ "platforms": ["web", "phonegap", "cordova"]
};
diff --git a/lib/ripple/emulatorBridge.js b/lib/ripple/emulatorBridge.js
index a8bdea3..42e7b77 100644
--- a/lib/ripple/emulatorBridge.js
+++ b/lib/ripple/emulatorBridge.js
@@ -78,12 +78,15 @@
var marshal = function (obj, key) {
window[key] = win[key] = obj;
},
+ currentPlatform = platform.current(),
sandbox = {};
marshal(window.tinyHippos, "tinyHippos");
marshal(window.XMLHttpRequest, "XMLHttpRequest");
- platform.current().initialize(win);
+ if (currentPlatform.initialize) {
+ currentPlatform.initialize(win);
+ }
builder.build(platform.current().objects).into(sandbox);
utils.forEach(sandbox, marshal);
diff --git a/lib/ripple/platform.js b/lib/ripple/platform.js
index f22adec..3139ee1 100644
--- a/lib/ripple/platform.js
+++ b/lib/ripple/platform.js
@@ -23,13 +23,30 @@
spec = require('ripple/platform/spec'),
_self;
-function _checkForDeprecatedPlatforms(replacement) {
- if (!spec[_current.name] ||
- !spec[_current.name][_current.version] ||
- (spec[_current.name][_current.version] && !spec[_current.name][_current.version].objects)) {
- _current = replacement;
- db.saveObject("api-key", _current);
+function _getRequestedPlatform() {
+ var requestedPlatform = null,
+ enableRippleArg = utils.queryString().enableripple,
+ platform;
+
+ if (enableRippleArg) {
+ enableRippleArg = enableRippleArg.split('-');
+ platform = spec.get(enableRippleArg[0], enableRippleArg[1]);
+ if (platform) {
+ requestedPlatform = { name: platform.id, version: platform.version };
+ }
}
+
+ return requestedPlatform;
+}
+
+function _validatePlatform(platform, defaultPlatform) {
+ if (!platform ||
+ !spec[platform.name] ||
+ !spec[platform.name][platform.version] ||
+ (spec[platform.name][platform.version] && !spec[platform.name][platform.version].objects)) {
+ return defaultPlatform;
+ }
+ return platform;
}
function _getPlatform() {
@@ -39,20 +56,16 @@
_self = {
initialize: function () {
var firstAvailablePlatform = utils.map(this.getList(), function (platform) {
- return utils.map(platform, function (details, version) {
- return {name: details.id, version: version};
- })[0];
- })[0];
+ return utils.map(platform, function (details, version) {
+ return {name: details.id, version: version};
+ })[0];
+ })[0];
- _current = db.retrieveObject("api-key");
+ _current = _getRequestedPlatform() || db.retrieveObject("api-key") || firstAvailablePlatform;
+ _current = _validatePlatform(_current, firstAvailablePlatform);
+ db.saveObject("api-key", _current);
- if (_current) {
- _checkForDeprecatedPlatforms(firstAvailablePlatform);
- } else {
- _current = firstAvailablePlatform;
- }
-
- _console.prefix = _getPlatform().name;
+ _console.prefix = _current.name;
},
getList: function () {
diff --git a/lib/ripple/platform/cordova/1.6/bridge.js b/lib/ripple/platform/cordova/1.6/bridge.js
deleted file mode 100644
index 03a9e6b..0000000
--- a/lib/ripple/platform/cordova/1.6/bridge.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2011 Research In Motion Limited.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-var _prompt = require('ripple/ui/plugins/exec-dialog');
-
-module.exports = {
- exec: function (success, fail, service, action, args) {
- var emulator = {
- "Network Status": require('ripple/platform/cordova/1.6/bridge/network'),
- "NetworkStatus": require('ripple/platform/cordova/1.6/bridge/network'),
- "Device": require('ripple/platform/cordova/1.6/bridge/device'),
- "Contacts": require('ripple/platform/cordova/1.6/bridge/contacts'),
- "Accelerometer": require('ripple/platform/cordova/1.6/bridge/accelerometer'),
- "Compass": require('ripple/platform/cordova/1.6/bridge/compass'),
- "Notification": require('ripple/platform/cordova/1.6/bridge/notification')
- };
-
- try {
- emulator[service][action](success, fail, args);
- }
- catch (e) {
- console.log("missing exec:" + service + "." + action);
- console.log(args);
- console.log(e);
- console.log(e.stack);
- //TODO: this should really not log the above lines, but they are very nice for development right now
- _prompt.show(service, action, success, fail);
- }
- }
-};
diff --git a/lib/ripple/platform/cordova/1.6/spec.js b/lib/ripple/platform/cordova/1.6/spec.js
deleted file mode 100644
index 6dfccf6..0000000
--- a/lib/ripple/platform/cordova/1.6/spec.js
+++ /dev/null
@@ -1,85 +0,0 @@
-function loadWebworks(win, device) {
- var builder = require('ripple/platform/builder'),
- platform = device.id === "Playbook" || device.id === "Colt" ? "tablet" : "handset",
- webworks = require('ripple/platform/webworks.' + platform + '/2.0.0/spec');
-
- builder.build(webworks.objects).into(win);
- builder.build(webworks.objects).into(window);
-}
-
-module.exports = {
- id: "cordova",
- version: "1.6",
- name: "Apache Cordova",
- type: "platform",
-
- config: require('ripple/platform/phonegap/1.0/spec/config'),
- device: require('ripple/platform/phonegap/1.0/spec/device'),
- ui: require('ripple/platform/phonegap/1.0/spec/ui'),
- events: require('ripple/platform/phonegap/1.0/spec/events'),
-
- initialize: function (win) {
- var honeypot = require('ripple/honeypot'),
- devices = require('ripple/devices'),
- device = devices.getCurrentDevice(),
- bridge = require('ripple/platform/cordova/1.6/bridge'),
- cordova,
- get = function () {
- return cordova;
- },
- set = function (orig) {
- if (cordova) {
- return;
- }
-
- cordova = orig;
-
- cordova.define.remove("cordova/exec");
- cordova.define("cordova/exec", function (require, exports, module) {
- module.exports = bridge.exec;
- });
-
- cordova.UsePolling = true;
-
- //do nothing here as we will just call the callbacks ourselves
- cordova.define.remove("cordova/plugin/android/polling");
- cordova.define("cordova/plugin/android/polling", function (require, exports, module) {
- module.exports = function () {};
- });
-
- var builder = cordova.require('cordova/builder'),
- base = cordova.require('cordova/common');
-
- //HACK: Overwrite all the things, handles when cordova.js executes before we start booting
- builder.build(base.objects).intoAndClobber(window);
- };
-
- if (device.manufacturer === "Research In Motion") {
- loadWebworks(win, device);
- }
-
- honeypot.monitor(win, "cordova").andRun(get, set);
- win._nativeReady = true;
- },
-
- objects: {
- org: {
- children: {
- apache: {
- children: {
- cordova: {
- children: {
- Logger: {
- path: "cordova/1.6/logger"
- },
- JavaPluginManager: {
- path: "cordova/1.6/JavaPluginManager"
- }
- }
- }
- }
- }
- }
- }
- }
-};
diff --git a/lib/ripple/platform/cordova/1.6/JavaPluginManager.js b/lib/ripple/platform/cordova/2.0.0/JavaPluginManager.js
similarity index 100%
rename from lib/ripple/platform/cordova/1.6/JavaPluginManager.js
rename to lib/ripple/platform/cordova/2.0.0/JavaPluginManager.js
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js b/lib/ripple/platform/cordova/2.0.0/MediaError.js
similarity index 62%
copy from lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
copy to lib/ripple/platform/cordova/2.0.0/MediaError.js
index 38aa21a..51cebea 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
+++ b/lib/ripple/platform/cordova/2.0.0/MediaError.js
@@ -13,9 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-//blackberry.invoke.BrowserArguments ( url : String , [transport : blackberry.identity.Transport ] )
-module.exports = function (url, transport) {
- return {
- url: url
- };
+var MediaError = function (code, msg) {
+ this.code = (code !== undefined ? code : null);
+ this.message = msg || "";
};
+
+MediaError.MEDIA_ERR_NONE_ACTIVE = 0;
+MediaError.MEDIA_ERR_ABORTED = 1;
+MediaError.MEDIA_ERR_NETWORK = 2;
+MediaError.MEDIA_ERR_DECODE = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+module.exports = MediaError;
diff --git a/lib/ripple/platform/cordova/2.0.0/bridge.js b/lib/ripple/platform/cordova/2.0.0/bridge.js
new file mode 100644
index 0000000..2542452
--- /dev/null
+++ b/lib/ripple/platform/cordova/2.0.0/bridge.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _prompt = require('ripple/ui/plugins/exec-dialog');
+
+module.exports = {
+ exec: function (success, fail, service, action, args) {
+ var emulator = {
+ "App": require('ripple/platform/cordova/2.0.0/bridge/app'),
+ "Accelerometer": require('ripple/platform/cordova/2.0.0/bridge/accelerometer'),
+ "Compass": require('ripple/platform/cordova/2.0.0/bridge/compass'),
+ "Camera": require('ripple/platform/cordova/2.0.0/bridge/camera'),
+ "Capture": require('ripple/platform/cordova/2.0.0/bridge/capture'),
+ "Contacts": require('ripple/platform/cordova/2.0.0/bridge/contacts'),
+ "Debug Console": require('ripple/platform/cordova/2.0.0/bridge/console'),
+ "Device": require('ripple/platform/cordova/2.0.0/bridge/device'),
+ "File": require('ripple/platform/cordova/2.0.0/bridge/file'),
+ "Geolocation": require('ripple/platform/cordova/2.0.0/bridge/geolocation'),
+ "Media": require('ripple/platform/cordova/2.0.0/bridge/media'),
+ "Network Status": require('ripple/platform/cordova/2.0.0/bridge/network'),
+ "NetworkStatus": require('ripple/platform/cordova/2.0.0/bridge/network'),
+ "Notification": require('ripple/platform/cordova/2.0.0/bridge/notification')
+ };
+
+ try {
+ emulator[service][action](success, fail, args);
+ }
+ catch (e) {
+ console.log("missing exec:" + service + "." + action);
+ console.log(args);
+ console.log(e);
+ console.log(e.stack);
+ //TODO: this should really not log the above lines, but they are very nice for development right now
+ _prompt.show(service, action, success, fail);
+ }
+ }
+};
diff --git a/lib/ripple/platform/cordova/1.6/bridge/accelerometer.js b/lib/ripple/platform/cordova/2.0.0/bridge/accelerometer.js
similarity index 65%
rename from lib/ripple/platform/cordova/1.6/bridge/accelerometer.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/accelerometer.js
index bbfec57..434d4d0 100644
--- a/lib/ripple/platform/cordova/1.6/bridge/accelerometer.js
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/accelerometer.js
@@ -13,30 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-var utils = require('ripple/utils'),
- event = require('ripple/event'),
- _current = {x: 0, y: 0, z: 0, timestamp: (new Date()).getTime()};
+var event = require('ripple/event'),
+ _success,
+ _error,
+ _current = {x: 0, y: 0, z: 0, timestamp: (new Date()).getTime()},
+ _interval;
event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
- _current.x = accelerometerInfo.accelerationIncludingGravity.x / 9.8;
- _current.y = accelerometerInfo.accelerationIncludingGravity.y / 9.8;
- _current.z = accelerometerInfo.accelerationIncludingGravity.z / 9.8;
+ _current.x = accelerometerInfo.accelerationIncludingGravity.x;
+ _current.y = accelerometerInfo.accelerationIncludingGravity.y;
+ _current.z = accelerometerInfo.accelerationIncludingGravity.z;
_current.timestamp = (new Date()).getTime();
});
module.exports = {
- getTimeout: function (success, error, args) {
- return success && success(1);
+ start: function (success, error, args) {
+ _success = success;
+ _error = error;
+ // Possible HACK? update the timestamp of the last data to something current
+ _interval = window.setInterval(function () {
+ _current.timestamp = (new Date()).getTime();
+ _success(_current);
+ }, 50);
},
- setTimeout: function (success, error, args) {
- //do nothing
- return success && success();
- },
-
- getAcceleration: function (success, error, args) {
- // TODO: build facility to trigger onError() from emulator
- // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
- success(utils.copy(_current));
+ stop: function () {
+ _success = null;
+ _error = null;
+ window.clearInterval(_interval);
}
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js b/lib/ripple/platform/cordova/2.0.0/bridge/app.js
similarity index 75%
copy from lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
copy to lib/ripple/platform/cordova/2.0.0/bridge/app.js
index 38aa21a..ea6f86f 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/app.js
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-//blackberry.invoke.BrowserArguments ( url : String , [transport : blackberry.identity.Transport ] )
-module.exports = function (url, transport) {
- return {
- url: url
- };
+var camera = require('ripple/ui/plugins/camera'),
+ event = require('ripple/event');
+
+module.exports = {
+ show: function (success, error, args) {
+ return success && success();
+ }
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js b/lib/ripple/platform/cordova/2.0.0/bridge/camera.js
similarity index 62%
copy from lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
copy to lib/ripple/platform/cordova/2.0.0/bridge/camera.js
index 38aa21a..41b5a3e 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/camera.js
@@ -13,9 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-//blackberry.invoke.BrowserArguments ( url : String , [transport : blackberry.identity.Transport ] )
-module.exports = function (url, transport) {
- return {
- url: url
- };
+var camera = require('ripple/ui/plugins/camera'),
+ event = require('ripple/event');
+
+module.exports = {
+ takePicture: function (success, error, args) {
+ event.once("captured-image", function (uri, file) {
+ success(uri);
+ });
+ camera.show();
+ },
+ cleanup: function (success, error, args) {
+ success();
+ }
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js b/lib/ripple/platform/cordova/2.0.0/bridge/capture.js
similarity index 64%
copy from lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
copy to lib/ripple/platform/cordova/2.0.0/bridge/capture.js
index 38aa21a..54251e3 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/capture.js
@@ -13,9 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-//blackberry.invoke.BrowserArguments ( url : String , [transport : blackberry.identity.Transport ] )
-module.exports = function (url, transport) {
- return {
- url: url
- };
+
+var camera = require('ripple/ui/plugins/camera'),
+ event = require('ripple/event');
+
+module.exports = {
+ captureImage: function (success, error, args) {
+ event.once("captured-image", function (uri, file) {
+ file.fullPath = uri;
+ success([file]);
+ });
+ camera.show();
+ }
};
diff --git a/lib/ripple/platform/cordova/1.6/bridge/compass.js b/lib/ripple/platform/cordova/2.0.0/bridge/compass.js
similarity index 77%
rename from lib/ripple/platform/cordova/1.6/bridge/compass.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/compass.js
index 10c5354..63e0f2a 100644
--- a/lib/ripple/platform/cordova/1.6/bridge/compass.js
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/compass.js
@@ -16,18 +16,18 @@
var geo = require('ripple/geo');
module.exports = {
- getTimeout: function (success, error, args) {
- return success && success(1);
- },
-
- setTimeout: function (success, error, args) {
- //do nothing
- return success && success();
- },
-
getHeading: function (success, error, args) {
// TODO: build facility to trigger onError() from emulator
// see pivotal item: https://www.pivotaltracker.com/story/show/7040343
- success(geo.getPositionInfo().heading);
+ success({
+ magneticHeading: geo.getPositionInfo().heading,
+ trueHeading: geo.getPositionInfo().heading,
+ headingAccuracy: 100,
+ timestamp: new Date().getSeconds()
+ });
+ },
+
+ stopHeading: function () {
+ //do nothing
}
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js b/lib/ripple/platform/cordova/2.0.0/bridge/console.js
similarity index 76%
rename from lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/console.js
index 38aa21a..ef7aa54 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/BrowserArguments.js
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/console.js
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-//blackberry.invoke.BrowserArguments ( url : String , [transport : blackberry.identity.Transport ] )
-module.exports = function (url, transport) {
- return {
- url: url
- };
+
+module.exports = {
+ log: function (win, fail, args) {
+ console.log(args[0]);
+ }
};
diff --git a/lib/ripple/platform/cordova/1.6/bridge/contacts.js b/lib/ripple/platform/cordova/2.0.0/bridge/contacts.js
similarity index 100%
rename from lib/ripple/platform/cordova/1.6/bridge/contacts.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/contacts.js
diff --git a/lib/ripple/platform/cordova/1.6/bridge/device.js b/lib/ripple/platform/cordova/2.0.0/bridge/device.js
similarity index 100%
rename from lib/ripple/platform/cordova/1.6/bridge/device.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/device.js
diff --git a/lib/ripple/platform/cordova/2.0.0/bridge/file.js b/lib/ripple/platform/cordova/2.0.0/bridge/file.js
new file mode 100644
index 0000000..7a2d4a4
--- /dev/null
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/file.js
@@ -0,0 +1,349 @@
+// HACK: fs keeps a reference to the last-used FileSystem requested via requestFileSystem
+// this is a hack because if you keep switching between TEMPORARY vs. PERSISTENT file systems requested,
+// and run Cordova File API methods, no parameter is passed into exec specifying the underlying File System.
+// This should be fixed in Cordova!
+var fs,
+ topCordova = window.top.require('ripple/platform/cordova/2.0.0/spec'),
+ BlobBuilder = (window.BlobBuilder || window.WebKitBlobBuilder),
+ rlfsu = window.webkitResolveLocalFileSystemURL;
+
+function cleanPath(path) {
+ while (path[0] && path[0] === '/') {
+ path = path.substr(1);
+ }
+ return path;
+}
+
+module.exports = {
+ requestFileSystem: function (win, fail, args) {
+ // HACK: may not be webkit
+ var rfs = window.webkitRequestFileSystem,
+ type = args[0],
+ size = args[1];
+
+ // HACK: assume any FS requested over a gig in size will throw an error
+ if (size > (1024 * 1024 * 1024 /* gigabyte */)) {
+ if (fail) fail(FileError.QUOTA_EXCEEDED_ERR);
+ } else {
+ return rfs(type, size, function (effes) {
+ fs = effes;
+ win(effes);
+ }, fail);
+ }
+ },
+ resolveLocalFileSystemURI: function (win, fail, args) {
+ var uri = args[0],
+ fulluri = fs.root.toURL();
+
+ // HACK: iOS-specific bs right here. See lib/ios/plugin/ios/Entry.js in cordova.js for details
+ // Cordova badly needs a unified File System abstraction.
+ if (uri.indexOf("file://localhost") === 0) {
+ uri = uri.substr(16);
+ }
+ uri = cleanPath(uri);
+
+ fulluri += uri;
+
+ return rlfsu(fulluri, function (entry) {
+ if (win) win(entry);
+ }, function (error) {
+ if (fail) fail(error.code);
+ });
+ },
+ getFile: function (win, fail, args) {
+ var path = args[0],
+ filename = args[1],
+ options = args[2],
+ file = '';
+
+ path = cleanPath(path);
+ filename = cleanPath(filename);
+
+ if (path) {
+ file = path + '/';
+ }
+ file += filename;
+
+ fs.root.getFile(file, options, function (entry) {
+ if (win) win(entry);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ remove: function (win, fail, args) {
+ var file = args[0];
+ rlfsu(fs.root.toURL() + file, function (entry) {
+ entry.remove(function () {
+ if (win) win();
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, fail);
+ },
+ readEntries: function (win, fail, args) {
+ var root = fs.root.toURL(),
+ path = args[0],
+ reader;
+
+ path = cleanPath(path);
+ path = root + path;
+
+ rlfsu(path, function (entry) {
+ reader = entry.createReader();
+ reader.readEntries(function (entries) {
+ if (win) win(entries);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ getDirectory: function (win, fail, args) {
+ var path = args[0],
+ filename = args[1],
+ options = args[2],
+ file = '';
+
+ path = cleanPath(path);
+ filename = cleanPath(filename);
+
+ if (path) {
+ file = path + '/';
+ }
+ file += filename;
+
+ fs.root.getDirectory(file, options, function (entry) {
+ if (win) win(entry);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ removeRecursively: function (win, fail, args) {
+ var root = fs.root.toURL(),
+ path = args[0];
+
+ path = cleanPath(path);
+
+ rlfsu(root + path, function (dirEntry) {
+ dirEntry.removeRecursively(function () {
+ if (win) win();
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ getFileMetadata: function (win, fail, args) {
+ var path = args[0],
+ root = fs.root.toURL();
+
+ path = cleanPath(path);
+
+ rlfsu(root + path, function (entry) {
+ entry.file(function (file) {
+ if (win) win(file);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ getMetadata: function (win, fail, args) {
+ var path = args[0],
+ root = fs.root.toURL();
+
+ path = cleanPath(path);
+
+ rlfsu(root + path, function (entry) {
+ entry.getMetadata(function (data) {
+ if (win) win(data);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ getParent: function (win, fail, args) {
+ var path = args[0],
+ root = fs.root.toURL();
+
+ path = cleanPath(path);
+
+ rlfsu(root + path, function (entry) {
+ entry.getParent(function (dirEntry) {
+ if (win) win(dirEntry);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ copyTo: function (win, fail, args) {
+ var src = args[0],
+ parent = args[1],
+ name = args[2],
+ root = fs.root.toURL();
+
+ parent = cleanPath(parent);
+ src = cleanPath(src);
+
+ // get the directoryentry that we will copy TO
+ rlfsu(root + parent, function (parentDirToCopyTo) {
+ rlfsu(root + src, function (sourceDir) {
+ sourceDir.copyTo(parentDirToCopyTo, name, function (newEntry) {
+ if (win) win(newEntry);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ moveTo: function (win, fail, args) {
+ var src = args[0],
+ parent = args[1],
+ name = args[2],
+ root = fs.root.toURL();
+
+ parent = cleanPath(parent);
+ src = cleanPath(src);
+
+ // get the directoryentry that we will move TO
+ rlfsu(root + parent, function (parentDirToMoveTo) {
+ rlfsu(root + src, function (sourceDir) {
+ sourceDir.moveTo(parentDirToMoveTo, name, function (newEntry) {
+ if (win) win(newEntry);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ write: function (win, fail, args) {
+ var file = args[0],
+ text = args[1],
+ position = args[2],
+ sourcepath,
+ bb = new BlobBuilder();
+
+ // Format source path
+ sourcepath = (file.fullPath ? file.fullPath : '') + file.name;
+ sourcepath = cleanPath(sourcepath);
+
+ // Create a blob for the text to be written
+ bb.append(text);
+
+ // Get the FileEntry, create if necessary
+ fs.root.getFile(sourcepath, {create: true}, function (entry) {
+ // Create a FileWriter for this entry
+ entry.createWriter(function (writer) {
+ writer.onwriteend = function (progressEvt) {
+ if (win) win(progressEvt.total);
+ };
+ writer.onerror = function (err) {
+ if (fail) fail(err.code);
+ };
+
+ if (position && position > 0) {
+ writer.seek(position);
+ }
+ writer.write(bb.getBlob('text/plain'));
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ readAsText: function (win, fail, args) {
+ var path = args[0],
+ encoding = args[1],
+ FileReader = topCordova.nativeMethods.FileReader,
+ fr = new FileReader();
+
+ // Set up FileReader events
+ fr.onerror = function (err) {
+ if (fail) fail(err.code);
+ };
+ fr.onload = function (evt) {
+ if (win) win(evt.target.result);
+ };
+
+ path = cleanPath(path);
+
+ fs.root.getFile(path, {create: false}, function (entry) {
+ entry.file(function (blob) {
+ fr.readAsText(blob, encoding);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ readAsDataURL: function (win, fail, args) {
+ var path = args[0],
+ FileReader = topCordova.nativeMethods.FileReader,
+ fr = new FileReader();
+
+ // Set up FileReader events
+ fr.onerror = function (err) {
+ if (fail) fail(err.code);
+ };
+ fr.onload = function (evt) {
+ if (win) win(evt.target.result);
+ };
+
+ path = cleanPath(path);
+
+ fs.root.getFile(path, {create: false}, function (entry) {
+ entry.file(function (blob) {
+ fr.readAsDataURL(blob);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ },
+ truncate: function (win, fail, args) {
+ var file = args[0],
+ position = args[1],
+ sourcepath;
+
+ // Format source path
+ sourcepath = (file.fullPath ? file.fullPath : '') + file.name;
+ sourcepath = cleanPath(sourcepath);
+
+ // Get the FileEntry, create if necessary
+ fs.root.getFile(sourcepath, {create: false}, function (entry) {
+ // Create a FileWriter for this entry
+ entry.createWriter(function (writer) {
+ writer.onwriteend = function (progressEvt) {
+ if (win) win(progressEvt.target.length);
+ };
+ writer.onerror = function (err) {
+ if (fail) fail(err.code);
+ };
+
+ writer.truncate(position);
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }, function (err) {
+ if (fail) fail(err.code);
+ });
+ }
+};
diff --git a/lib/ripple/platform/cordova/2.0.0/bridge/geolocation.js b/lib/ripple/platform/cordova/2.0.0/bridge/geolocation.js
new file mode 100644
index 0000000..b6219f4
--- /dev/null
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/geolocation.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+ geo = require('ripple/geo'),
+ utils = require('ripple/utils'),
+ PositionError = require('ripple/platform/w3c/1.0/PositionError'),
+ _watches = {},
+ _current = {
+ "latitude": 43.465187,
+ "longitude": -80.522372,
+ "altitude": 100,
+ "accuracy": 150,
+ "altitudeAccuracy": 80,
+ "heading": 0,
+ "velocity": 0,
+ },
+ _error;
+
+function _getCurrentPosition(win, fail) {
+ if (geo.timeout) {
+ if (fail) {
+ var positionError = new PositionError();
+
+ positionError.code = PositionError.TIMEOUT;
+ positionError.message = "postion timed out";
+ fail(positionError);
+ }
+ }
+ else {
+ win(geo.getPositionInfo());
+ }
+}
+
+event.on("PositionInfoUpdatedEvent", function (pi) {
+ _current.latitude = pi.latitude;
+ _current.longitude = pi.longitude;
+ _current.altitude = pi.altitude;
+ _current.accuracy = pi.accuracy;
+ _current.altitudeAccuracy = pi.altitudeAccuracy;
+ _current.heading = pi.heading;
+ _current.velocity = pi.speed;
+
+ utils.forEach(_watches, function (watch) {
+ try {
+ _getCurrentPosition(watch.win, watch.fail);
+ } catch (e) {
+ console.log(e);
+ }
+ });
+});
+
+module.exports = {
+ getLocation: function (success, error, args) {
+ _getCurrentPosition(success, error);
+ },
+
+ addWatch: function (success, error, args) {
+ _watches[args[0]] = {
+ win: success,
+ fail: error
+ };
+ _getCurrentPosition(success, error);
+ },
+
+ clearWatch: function (id) {
+ delete _watches[id];
+ }
+};
diff --git a/lib/ripple/platform/cordova/2.0.0/bridge/media.js b/lib/ripple/platform/cordova/2.0.0/bridge/media.js
new file mode 100644
index 0000000..e185451
--- /dev/null
+++ b/lib/ripple/platform/cordova/2.0.0/bridge/media.js
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var audioObjects = {},
+ noop = function () {};
+
+function createAudio(id, src, error) {
+ var a = new Audio();
+ a.addEventListener("error", function (e) {
+ error(new window.MediaError(1, e.toString()));
+ });
+ a.addEventListener("durationchange", function () {
+ //HACK: I don't like this but best way for us to update the duration
+ cordova.require("cordova/plugin/Media").onStatus(id, 2, this.duration);
+ });
+ a.src = src;
+
+ return a;
+}
+
+module.exports = {
+ create: function (success, error, args) {
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ src = args[1];
+
+ error = error || noop;
+ success = success || noop;
+
+ audioObjects[id] = createAudio(id, src, error);
+ success();
+ },
+ startPlayingAudio: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (args.length === 1) {
+ error("Media source argument not found");
+ return;
+ }
+
+ if (audio) {
+ audio.pause();
+ audioObjects[id] = undefined;
+ }
+
+ audio = audioObjects[id] = createAudio(id, args[1], error);
+ audio.play();
+
+ success();
+ },
+ stopPlayingAudio: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (!audio) {
+ error("Audio Object has not been initialized");
+ return;
+ }
+
+ audio.pause();
+ audioObjects[id] = undefined;
+
+ success();
+ },
+ seekToAudio: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (!audio) {
+ error("Audio Object has not been initialized");
+ return;
+ } else if (args.length === 1) {
+ error("Media seek time argument not found");
+ return;
+ } else {
+ try {
+ audio.currentTime = args[1];
+ } catch (e) {
+ error("Error seeking audio: " + e);
+ }
+ }
+
+ success();
+ },
+ pausePlayingAudio: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (!audio) {
+ error("Audio Object has not been initialized");
+ return;
+ }
+
+ audio.pause();
+ success();
+ },
+ getCurrentPositionAudio: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (!audio) {
+ error("Audio Object has not been initialized");
+ return;
+ }
+
+ success(audio.currentTime);
+ },
+ getDuration: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (!audio) {
+ error("Audio Object has not been initialized");
+ return;
+ }
+
+ success(audio.duration);
+ },
+ startRecordingAudio: function (success, error, args) {
+ error = error || noop;
+ error("Not supported");
+ },
+ stopRecordingAudio: function (success, error, args) {
+ error = error || noop;
+ error("Not supported");
+ },
+ release: function (success, error, args) {
+ error = error || noop;
+ success = success || noop;
+ if (!args.length) {
+ error("Media Object id was not sent in arguments");
+ return;
+ }
+
+ var id = args[0],
+ audio = audioObjects[id];
+
+ if (audio) {
+ audioObjects[id] = undefined;
+ audio.src = undefined;
+ //delete audio;
+ }
+
+ success();
+ }
+};
diff --git a/lib/ripple/platform/cordova/1.6/bridge/network.js b/lib/ripple/platform/cordova/2.0.0/bridge/network.js
similarity index 100%
rename from lib/ripple/platform/cordova/1.6/bridge/network.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/network.js
diff --git a/lib/ripple/platform/cordova/1.6/bridge/notification.js b/lib/ripple/platform/cordova/2.0.0/bridge/notification.js
similarity index 100%
rename from lib/ripple/platform/cordova/1.6/bridge/notification.js
rename to lib/ripple/platform/cordova/2.0.0/bridge/notification.js
diff --git a/lib/ripple/platform/cordova/1.6/logger.js b/lib/ripple/platform/cordova/2.0.0/logger.js
similarity index 100%
rename from lib/ripple/platform/cordova/1.6/logger.js
rename to lib/ripple/platform/cordova/2.0.0/logger.js
diff --git a/lib/ripple/platform/cordova/2.0.0/spec.js b/lib/ripple/platform/cordova/2.0.0/spec.js
new file mode 100644
index 0000000..ce92f99
--- /dev/null
+++ b/lib/ripple/platform/cordova/2.0.0/spec.js
@@ -0,0 +1,107 @@
+function loadWebworks(win, device) {
+ var builder = require('ripple/platform/builder'),
+ platform = device.id === "Playbook" || device.id === "Colt" ? "tablet" : "handset",
+ webworks = require('ripple/platform/webworks.' + platform + '/2.0.0/spec');
+
+ builder.build(webworks.objects).into(win);
+ builder.build(webworks.objects).into(window);
+}
+
+module.exports = {
+ id: "cordova",
+ version: "2.0.0",
+ name: "Apache Cordova",
+ type: "platform",
+ nativeMethods: {},
+
+ config: require('ripple/platform/cordova/2.0.0/spec/config'),
+ device: require('ripple/platform/cordova/2.0.0/spec/device'),
+ ui: require('ripple/platform/cordova/2.0.0/spec/ui'),
+ events: require('ripple/platform/cordova/2.0.0/spec/events'),
+
+ initialize: function (win) {
+ var honeypot = require('ripple/honeypot'),
+ devices = require('ripple/devices'),
+ device = devices.getCurrentDevice(),
+ bridge = require('ripple/platform/cordova/2.0.0/bridge'),
+ cordova,
+ topCordova = window.top.require('ripple/platform/cordova/2.0.0/spec'),
+ get = function () {
+ return cordova;
+ },
+ set = function (orig) {
+ if (cordova) {
+ return;
+ }
+
+ cordova = orig;
+
+ cordova.define.remove("cordova/exec");
+ cordova.define("cordova/exec", function (require, exports, module) {
+ module.exports = bridge.exec;
+ });
+
+ cordova.UsePolling = true;
+
+ //do nothing here as we will just call the callbacks ourselves
+ cordova.define.remove("cordova/plugin/android/polling");
+ cordova.define("cordova/plugin/android/polling", function (require, exports, module) {
+ module.exports = function () {};
+ });
+
+ var builder = cordova.require('cordova/builder'),
+ allTheThings = window,
+ base = cordova.require('cordova/common'),
+ iosPlugin;
+
+ //HACK: Overwrite all the things, handles when cordova.js executes before we start booting
+ builder.build(base.objects).intoAndClobber(allTheThings);
+ cordova.require('cordova/channel').onNativeReady.fire();
+ // DIRTY HACK: once cordova is cleaned up, we do not
+ // need this.
+ // reference issue: https://issues.apache.org/jira/browse/CB-1013
+ try {
+ iosPlugin = cordova.require('cordova/plugin/ios/device');
+ bridge.exec(function (info) {
+ iosPlugin.setInfo(info);
+ }, null, 'Device', 'getDeviceInfo', []);
+ } catch (e) {
+ cordova.require('cordova/channel').onCordovaInfoReady.fire();
+ }
+ };
+
+ if (window.FileReader && !topCordova.nativeMethods.FileReader) {
+ topCordova.nativeMethods.FileReader = window.FileReader;
+ }
+
+ if (device.manufacturer === "Research In Motion") {
+ loadWebworks(win, device);
+ }
+
+ honeypot.monitor(win, "cordova").andRun(get, set);
+ },
+
+ objects: {
+ MediaError: {
+ path: "cordova/2.0.0/MediaError"
+ },
+ org: {
+ children: {
+ apache: {
+ children: {
+ cordova: {
+ children: {
+ Logger: {
+ path: "cordova/2.0.0/logger"
+ },
+ JavaPluginManager: {
+ path: "cordova/2.0.0/JavaPluginManager"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+};
diff --git a/lib/ripple/platform/phonegap/1.0/spec/config.js b/lib/ripple/platform/cordova/2.0.0/spec/config.js
similarity index 100%
copy from lib/ripple/platform/phonegap/1.0/spec/config.js
copy to lib/ripple/platform/cordova/2.0.0/spec/config.js
diff --git a/lib/ripple/platform/phonegap/1.0/spec/device.js b/lib/ripple/platform/cordova/2.0.0/spec/device.js
similarity index 100%
copy from lib/ripple/platform/phonegap/1.0/spec/device.js
copy to lib/ripple/platform/cordova/2.0.0/spec/device.js
diff --git a/lib/ripple/platform/cordova/2.0.0/spec/events.js b/lib/ripple/platform/cordova/2.0.0/spec/events.js
new file mode 100644
index 0000000..bca8b56
--- /dev/null
+++ b/lib/ripple/platform/cordova/2.0.0/spec/events.js
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function _fires(name, data) {
+ return function () {
+ cordova.fireDocumentEvent(name, data);
+ };
+}
+
+module.exports = {
+ "deviceready": {
+ callback: _fires("deviceready")
+ },
+ "backbutton": {
+ callback: _fires("backbutton")
+ },
+ "menubutton": {
+ callback: _fires("menubutton")
+ },
+ "pause": {
+ callback: _fires("pause")
+ },
+ "resume": {
+ callback: _fires("resume")
+ },
+ "searchbutton": {
+ callback: _fires("searchbutton")
+ },
+ "online": {
+ callback: _fires("online")
+ },
+ "offline": {
+ callback: _fires("offline")
+ }
+};
diff --git a/lib/ripple/platform/phonegap/1.0/spec/ui.js b/lib/ripple/platform/cordova/2.0.0/spec/ui.js
similarity index 100%
copy from lib/ripple/platform/phonegap/1.0/spec/ui.js
copy to lib/ripple/platform/cordova/2.0.0/spec/ui.js
diff --git a/lib/ripple/platform/phonegap/1.0/AVCodecsAttributes.js b/lib/ripple/platform/phonegap/1.0.0/AVCodecsAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/AVCodecsAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/AVCodecsAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/Acceleration.js b/lib/ripple/platform/phonegap/1.0.0/Acceleration.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/Acceleration.js
rename to lib/ripple/platform/phonegap/1.0.0/Acceleration.js
diff --git a/lib/ripple/platform/phonegap/1.0/AudioCodecAttributes.js b/lib/ripple/platform/phonegap/1.0.0/AudioCodecAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/AudioCodecAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/AudioCodecAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/AudioDeviceAttributes.js b/lib/ripple/platform/phonegap/1.0.0/AudioDeviceAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/AudioDeviceAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/AudioDeviceAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/BrailleDeviceAttributes.js b/lib/ripple/platform/phonegap/1.0.0/BrailleDeviceAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/BrailleDeviceAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/BrailleDeviceAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/CPUAttributes.js b/lib/ripple/platform/phonegap/1.0.0/CPUAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/CPUAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/CPUAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/CameraAttributes.js b/lib/ripple/platform/phonegap/1.0.0/CameraAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/CameraAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/CameraAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/Connection.js b/lib/ripple/platform/phonegap/1.0.0/Connection.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/Connection.js
rename to lib/ripple/platform/phonegap/1.0.0/Connection.js
diff --git a/lib/ripple/platform/phonegap/1.0/ConnectionAttributes.js b/lib/ripple/platform/phonegap/1.0.0/ConnectionAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ConnectionAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/ConnectionAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/Contact.js b/lib/ripple/platform/phonegap/1.0.0/Contact.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/Contact.js
rename to lib/ripple/platform/phonegap/1.0.0/Contact.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactAccount.js b/lib/ripple/platform/phonegap/1.0.0/ContactAccount.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactAccount.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactAccount.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactAddress.js b/lib/ripple/platform/phonegap/1.0.0/ContactAddress.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactAddress.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactAddress.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactError.js b/lib/ripple/platform/phonegap/1.0.0/ContactError.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactError.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactError.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactField.js b/lib/ripple/platform/phonegap/1.0.0/ContactField.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactField.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactField.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactFindOptions.js b/lib/ripple/platform/phonegap/1.0.0/ContactFindOptions.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactFindOptions.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactFindOptions.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactName.js b/lib/ripple/platform/phonegap/1.0.0/ContactName.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactName.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactName.js
diff --git a/lib/ripple/platform/phonegap/1.0/ContactOrganization.js b/lib/ripple/platform/phonegap/1.0.0/ContactOrganization.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ContactOrganization.js
rename to lib/ripple/platform/phonegap/1.0.0/ContactOrganization.js
diff --git a/lib/ripple/platform/phonegap/1.0/DisplayDeviceAttributes.js b/lib/ripple/platform/phonegap/1.0.0/DisplayDeviceAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/DisplayDeviceAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/DisplayDeviceAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/InputDevicesAttributes.js b/lib/ripple/platform/phonegap/1.0.0/InputDevicesAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/InputDevicesAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/InputDevicesAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/KeyboardAttributes.js b/lib/ripple/platform/phonegap/1.0.0/KeyboardAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/KeyboardAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/KeyboardAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/MicrophoneAttributes.js b/lib/ripple/platform/phonegap/1.0.0/MicrophoneAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/MicrophoneAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/MicrophoneAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/NetworkAttributes.js b/lib/ripple/platform/phonegap/1.0.0/NetworkAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/NetworkAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/NetworkAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/NetworkStatus.js b/lib/ripple/platform/phonegap/1.0.0/NetworkStatus.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/NetworkStatus.js
rename to lib/ripple/platform/phonegap/1.0.0/NetworkStatus.js
diff --git a/lib/ripple/platform/phonegap/1.0/OutputDevicesAttributes.js b/lib/ripple/platform/phonegap/1.0.0/OutputDevicesAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/OutputDevicesAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/OutputDevicesAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/PhoneGap.js b/lib/ripple/platform/phonegap/1.0.0/PhoneGap.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/PhoneGap.js
rename to lib/ripple/platform/phonegap/1.0.0/PhoneGap.js
diff --git a/lib/ripple/platform/phonegap/1.0/PointerAttributes.js b/lib/ripple/platform/phonegap/1.0.0/PointerAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/PointerAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/PointerAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/PowerAttributes.js b/lib/ripple/platform/phonegap/1.0.0/PowerAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/PowerAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/PowerAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/PrintingDeviceAttributes.js b/lib/ripple/platform/phonegap/1.0.0/PrintingDeviceAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/PrintingDeviceAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/PrintingDeviceAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/SensorAttributes.js b/lib/ripple/platform/phonegap/1.0.0/SensorAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/SensorAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/SensorAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/StorageUnitAttributes.js b/lib/ripple/platform/phonegap/1.0.0/StorageUnitAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/StorageUnitAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/StorageUnitAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/SystemInfoOptions.js b/lib/ripple/platform/phonegap/1.0.0/SystemInfoOptions.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/SystemInfoOptions.js
rename to lib/ripple/platform/phonegap/1.0.0/SystemInfoOptions.js
diff --git a/lib/ripple/platform/phonegap/1.0/ThermalAttributes.js b/lib/ripple/platform/phonegap/1.0.0/ThermalAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/ThermalAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/ThermalAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/VideoCodecAttributes.js b/lib/ripple/platform/phonegap/1.0.0/VideoCodecAttributes.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/VideoCodecAttributes.js
rename to lib/ripple/platform/phonegap/1.0.0/VideoCodecAttributes.js
diff --git a/lib/ripple/platform/phonegap/1.0/accelerometer.js b/lib/ripple/platform/phonegap/1.0.0/accelerometer.js
similarity index 97%
rename from lib/ripple/platform/phonegap/1.0/accelerometer.js
rename to lib/ripple/platform/phonegap/1.0.0/accelerometer.js
index f5f005c..9a433bc 100644
--- a/lib/ripple/platform/phonegap/1.0/accelerometer.js
+++ b/lib/ripple/platform/phonegap/1.0.0/accelerometer.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-var Acceleration = require('ripple/platform/phonegap/1.0/Acceleration'),
+var Acceleration = require('ripple/platform/phonegap/1.0.0/Acceleration'),
utils = require('ripple/utils'),
event = require('ripple/event'),
_accelerometerInfo = new Acceleration(),
diff --git a/lib/ripple/platform/phonegap/1.0/camera.js b/lib/ripple/platform/phonegap/1.0.0/camera.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/camera.js
rename to lib/ripple/platform/phonegap/1.0.0/camera.js
diff --git a/lib/ripple/platform/phonegap/1.0/compass.js b/lib/ripple/platform/phonegap/1.0.0/compass.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/compass.js
rename to lib/ripple/platform/phonegap/1.0.0/compass.js
diff --git a/lib/ripple/platform/phonegap/1.0/contacts.js b/lib/ripple/platform/phonegap/1.0.0/contacts.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/contacts.js
rename to lib/ripple/platform/phonegap/1.0.0/contacts.js
diff --git a/lib/ripple/platform/phonegap/1.0/device.js b/lib/ripple/platform/phonegap/1.0.0/device.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/device.js
rename to lib/ripple/platform/phonegap/1.0.0/device.js
diff --git a/lib/ripple/platform/phonegap/1.0/map.js b/lib/ripple/platform/phonegap/1.0.0/map.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/map.js
rename to lib/ripple/platform/phonegap/1.0.0/map.js
diff --git a/lib/ripple/platform/phonegap/1.0/navigator.js b/lib/ripple/platform/phonegap/1.0.0/navigator.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/navigator.js
rename to lib/ripple/platform/phonegap/1.0.0/navigator.js
diff --git a/lib/ripple/platform/phonegap/1.0/network.js b/lib/ripple/platform/phonegap/1.0.0/network.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/network.js
rename to lib/ripple/platform/phonegap/1.0.0/network.js
diff --git a/lib/ripple/platform/phonegap/1.0/notification.js b/lib/ripple/platform/phonegap/1.0.0/notification.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/notification.js
rename to lib/ripple/platform/phonegap/1.0.0/notification.js
diff --git a/lib/ripple/platform/phonegap/1.0/orientation.js b/lib/ripple/platform/phonegap/1.0.0/orientation.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/orientation.js
rename to lib/ripple/platform/phonegap/1.0.0/orientation.js
diff --git a/lib/ripple/platform/phonegap/1.0/service.js b/lib/ripple/platform/phonegap/1.0.0/service.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/service.js
rename to lib/ripple/platform/phonegap/1.0.0/service.js
diff --git a/lib/ripple/platform/phonegap/1.0/sms.js b/lib/ripple/platform/phonegap/1.0.0/sms.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/sms.js
rename to lib/ripple/platform/phonegap/1.0.0/sms.js
diff --git a/lib/ripple/platform/phonegap/1.0.0/spec.js b/lib/ripple/platform/phonegap/1.0.0/spec.js
new file mode 100644
index 0000000..37b768c
--- /dev/null
+++ b/lib/ripple/platform/phonegap/1.0.0/spec.js
@@ -0,0 +1,171 @@
+module.exports = {
+ id: "phonegap",
+ version: "1.0.0",
+ name: "PhoneGap",
+ type: "platform",
+
+ persistencePrefix: "phonegap-",
+
+ config: require('ripple/platform/phonegap/1.0.0/spec/config'),
+ device: require('ripple/platform/phonegap/1.0.0/spec/device'),
+ ui: require('ripple/platform/phonegap/1.0.0/spec/ui'),
+ events: require('ripple/platform/phonegap/1.0.0/spec/events'),
+
+ initialize: function () { },
+
+ objects: {
+ PhoneGap: {
+ path: "phonegap/1.0.0/PhoneGap"
+ },
+ Coordinates: {
+ path: "w3c/1.0/Coordinates"
+ },
+ Position: {
+ path: "w3c/1.0/Position"
+ },
+ PositionError: {
+ path: "w3c/1.0/PositionError"
+ },
+ Acceleration: {
+ path: "phonegap/1.0.0/Acceleration"
+ },
+ navigator: {
+ path: "phonegap/1.0.0/navigator",
+ children: {
+ accelerometer: {
+ path: "phonegap/1.0.0/accelerometer"
+ },
+ geolocation: {
+ path: "w3c/1.0/geolocation"
+ },
+ notification: {
+ path: "phonegap/1.0.0/notification"
+ },
+ contacts: {
+ path: "phonegap/1.0.0/contacts"
+ },
+ network: {
+ path: "phonegap/1.0.0/network"
+ },
+ camera: {
+ path: "phonegap/1.0.0/camera"
+ },
+ sms: {
+ path: "phonegap/1.0.0/sms"
+ },
+ telephony: {
+ path: "phonegap/1.0.0/telephony"
+ },
+ map: {
+ path: "phonegap/1.0.0/map"
+ },
+ orientation: {
+ path: "phonegap/1.0.0/orientation"
+ },
+ system: {
+ path: "phonegap/1.0.0/system"
+ },
+ compass: {
+ path: "phonegap/1.0.0/compass"
+ }
+ }
+ },
+ ContactError: {
+ path: "phonegap/1.0.0/ContactError"
+ },
+ Contact: {
+ path: "phonegap/1.0.0/Contact"
+ },
+ ContactName: {
+ path: "phonegap/1.0.0/ContactName"
+ },
+ ContactAccount: {
+ path: "phonegap/1.0.0/ContactAccount"
+ },
+ ContactAddress: {
+ path: "phonegap/1.0.0/ContactAddress"
+ },
+ ContactOrganization: {
+ path: "phonegap/1.0.0/ContactOrganization"
+ },
+ ContactFindOptions: {
+ path: "phonegap/1.0.0/ContactFindOptions"
+ },
+ ContactField: {
+ path: "phonegap/1.0.0/ContactField"
+ },
+ NetworkStatus: {
+ path: "phonegap/1.0.0/NetworkStatus"
+ },
+ device: {
+ path: "phonegap/1.0.0/device"
+ },
+ SystemInfoOptions: {
+ path: "phonegap/1.0.0/SystemInfoOptions"
+ },
+ PowerAttributes: {
+ path: "phonegap/1.0.0/PowerAttributes"
+ },
+ CPUAttributes: {
+ path: "phonegap/1.0.0/CPUAttributes"
+ },
+ ThermalAttributes: {
+ path: "phonegap/1.0.0/ThermalAttributes"
+ },
+ NetworkAttributes: {
+ path: "phonegap/1.0.0/NetworkAttributes"
+ },
+ Connection: {
+ path: "phonegap/1.0.0/Connection"
+ },
+ ConnectionAttributes: {
+ path: "phonegap/1.0.0/ConnectionAttributes"
+ },
+ SensorAttributes: {
+ path: "phonegap/1.0.0/SensorAttributes"
+ },
+ AVCodecsAttributes: {
+ path: "phonegap/1.0.0/AVCodecsAttributes"
+ },
+ AudioCodecAttributes: {
+ path: "phonegap/1.0.0/AudioCodecAttributes"
+ },
+ VideoCodecAttributes: {
+ path: "phonegap/1.0.0/VideoCodecAttributes"
+ },
+ StorageUnitAttributes: {
+ path: "phonegap/1.0.0/StorageUnitAttributes"
+ },
+ InputDevicesAttributes: {
+ path: "phonegap/1.0.0/InputDevicesAttributes"
+ },
+ OutputDevicesAttributes: {
+ path: "phonegap/1.0.0/OutputDevicesAttributes"
+ },
+ DisplayDeviceAttributes: {
+ path: "phonegap/1.0.0/DisplayDeviceAttributes"
+ },
+ AudioDeviceAttributes: {
+ path: "phonegap/1.0.0/AudioDeviceAttributes"
+ },
+ PrintingDeviceAttributes: {
+ path: "phonegap/1.0.0/PrintingDeviceAttributes"
+ },
+ BrailleDeviceAttributes: {
+ path: "phonegap/1.0.0/BrailleDeviceAttributes"
+ },
+ PointerAttributes: {
+ path: "phonegap/1.0.0/PointerAttributes"
+ },
+ KeyboardAttributes: {
+ path: "phonegap/1.0.0/KeyboardAttributes"
+ },
+ CameraAttributes: {
+ path: "phonegap/1.0.0/CameraAttributes"
+ },
+ MicrophoneAttributes: {
+ path: "phonegap/1.0.0/MicrophoneAttributes"
+ }
+ }
+
+};
diff --git a/lib/ripple/platform/phonegap/1.0/spec/config.js b/lib/ripple/platform/phonegap/1.0.0/spec/config.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/spec/config.js
rename to lib/ripple/platform/phonegap/1.0.0/spec/config.js
diff --git a/lib/ripple/platform/phonegap/1.0/spec/device.js b/lib/ripple/platform/phonegap/1.0.0/spec/device.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/spec/device.js
rename to lib/ripple/platform/phonegap/1.0.0/spec/device.js
diff --git a/lib/ripple/platform/phonegap/1.0/spec/events.js b/lib/ripple/platform/phonegap/1.0.0/spec/events.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/spec/events.js
rename to lib/ripple/platform/phonegap/1.0.0/spec/events.js
diff --git a/lib/ripple/platform/phonegap/1.0/spec/ui.js b/lib/ripple/platform/phonegap/1.0.0/spec/ui.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/spec/ui.js
rename to lib/ripple/platform/phonegap/1.0.0/spec/ui.js
diff --git a/lib/ripple/platform/phonegap/1.0/system.js b/lib/ripple/platform/phonegap/1.0.0/system.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/system.js
rename to lib/ripple/platform/phonegap/1.0.0/system.js
diff --git a/lib/ripple/platform/phonegap/1.0/telephony.js b/lib/ripple/platform/phonegap/1.0.0/telephony.js
similarity index 100%
rename from lib/ripple/platform/phonegap/1.0/telephony.js
rename to lib/ripple/platform/phonegap/1.0.0/telephony.js
diff --git a/lib/ripple/platform/phonegap/1.0/spec.js b/lib/ripple/platform/phonegap/1.0/spec.js
deleted file mode 100644
index 6c0abf1..0000000
--- a/lib/ripple/platform/phonegap/1.0/spec.js
+++ /dev/null
@@ -1,171 +0,0 @@
-module.exports = {
- id: "phonegap",
- version: "1.0",
- name: "PhoneGap",
- type: "platform",
-
- persistencePrefix: "phonegap-",
-
- config: require('ripple/platform/phonegap/1.0/spec/config'),
- device: require('ripple/platform/phonegap/1.0/spec/device'),
- ui: require('ripple/platform/phonegap/1.0/spec/ui'),
- events: require('ripple/platform/phonegap/1.0/spec/events'),
-
- initialize: function () { },
-
- objects: {
- PhoneGap: {
- path: "phonegap/1.0/PhoneGap"
- },
- Coordinates: {
- path: "w3c/1.0/Coordinates"
- },
- Position: {
- path: "w3c/1.0/Position"
- },
- PositionError: {
- path: "w3c/1.0/PositionError"
- },
- Acceleration: {
- path: "phonegap/1.0/Acceleration"
- },
- navigator: {
- path: "phonegap/1.0/navigator",
- children: {
- accelerometer: {
- path: "phonegap/1.0/accelerometer"
- },
- geolocation: {
- path: "w3c/1.0/geolocation"
- },
- notification: {
- path: "phonegap/1.0/notification"
- },
- contacts: {
- path: "phonegap/1.0/contacts"
- },
- network: {
- path: "phonegap/1.0/network"
- },
- camera: {
- path: "phonegap/1.0/camera"
- },
- sms: {
- path: "phonegap/1.0/sms"
- },
- telephony: {
- path: "phonegap/1.0/telephony"
- },
- map: {
- path: "phonegap/1.0/map"
- },
- orientation: {
- path: "phonegap/1.0/orientation"
- },
- system: {
- path: "phonegap/1.0/system"
- },
- compass: {
- path: "phonegap/1.0/compass"
- }
- }
- },
- ContactError: {
- path: "phonegap/1.0/ContactError"
- },
- Contact: {
- path: "phonegap/1.0/Contact"
- },
- ContactName: {
- path: "phonegap/1.0/ContactName"
- },
- ContactAccount: {
- path: "phonegap/1.0/ContactAccount"
- },
- ContactAddress: {
- path: "phonegap/1.0/ContactAddress"
- },
- ContactOrganization: {
- path: "phonegap/1.0/ContactOrganization"
- },
- ContactFindOptions: {
- path: "phonegap/1.0/ContactFindOptions"
- },
- ContactField: {
- path: "phonegap/1.0/ContactField"
- },
- NetworkStatus: {
- path: "phonegap/1.0/NetworkStatus"
- },
- device: {
- path: "phonegap/1.0/device"
- },
- SystemInfoOptions: {
- path: "phonegap/1.0/SystemInfoOptions"
- },
- PowerAttributes: {
- path: "phonegap/1.0/PowerAttributes"
- },
- CPUAttributes: {
- path: "phonegap/1.0/CPUAttributes"
- },
- ThermalAttributes: {
- path: "phonegap/1.0/ThermalAttributes"
- },
- NetworkAttributes: {
- path: "phonegap/1.0/NetworkAttributes"
- },
- Connection: {
- path: "phonegap/1.0/Connection"
- },
- ConnectionAttributes: {
- path: "phonegap/1.0/ConnectionAttributes"
- },
- SensorAttributes: {
- path: "phonegap/1.0/SensorAttributes"
- },
- AVCodecsAttributes: {
- path: "phonegap/1.0/AVCodecsAttributes"
- },
- AudioCodecAttributes: {
- path: "phonegap/1.0/AudioCodecAttributes"
- },
- VideoCodecAttributes: {
- path: "phonegap/1.0/VideoCodecAttributes"
- },
- StorageUnitAttributes: {
- path: "phonegap/1.0/StorageUnitAttributes"
- },
- InputDevicesAttributes: {
- path: "phonegap/1.0/InputDevicesAttributes"
- },
- OutputDevicesAttributes: {
- path: "phonegap/1.0/OutputDevicesAttributes"
- },
- DisplayDeviceAttributes: {
- path: "phonegap/1.0/DisplayDeviceAttributes"
- },
- AudioDeviceAttributes: {
- path: "phonegap/1.0/AudioDeviceAttributes"
- },
- PrintingDeviceAttributes: {
- path: "phonegap/1.0/PrintingDeviceAttributes"
- },
- BrailleDeviceAttributes: {
- path: "phonegap/1.0/BrailleDeviceAttributes"
- },
- PointerAttributes: {
- path: "phonegap/1.0/PointerAttributes"
- },
- KeyboardAttributes: {
- path: "phonegap/1.0/KeyboardAttributes"
- },
- CameraAttributes: {
- path: "phonegap/1.0/CameraAttributes"
- },
- MicrophoneAttributes: {
- path: "phonegap/1.0/MicrophoneAttributes"
- }
- }
-
-};
diff --git a/lib/ripple/platform/spec.js b/lib/ripple/platform/spec.js
index 7b54e64..beac662 100644
--- a/lib/ripple/platform/spec.js
+++ b/lib/ripple/platform/spec.js
@@ -14,10 +14,14 @@
* limitations under the License.
*/
module.exports = {
- "phonegap": {"1.0": require('ripple/platform/phonegap/1.0/spec')},
- "cordova": {"1.6": require('ripple/platform/cordova/1.6/spec')},
+ "phonegap": {"1.0.0": require('ripple/platform/phonegap/1.0.0/spec')},
+ "cordova": {"2.0.0": require('ripple/platform/cordova/2.0.0/spec')},
"webworks.bb10": {"1.0.0": require('ripple/platform/webworks.bb10/1.0.0/spec')},
"webworks.handset": {"2.0.0": require('ripple/platform/webworks.handset/2.0.0/spec')},
"webworks.tablet": {"2.0.0": require('ripple/platform/webworks.tablet/2.0.0/spec')},
- "web": {"default": require('ripple/platform/web/default/spec')}
+ "web": {"default": require('ripple/platform/web/default/spec')},
+ "get": function (name, version) {
+ var platform = module.exports[name] || {};
+ return (platform[version] || platform[Object.keys(platform)[0]]);
+ }
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/app.js b/lib/ripple/platform/webworks.bb10/1.0.0/app.js
index 9ec68e4..56dd91b 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/app.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/app.js
@@ -15,8 +15,15 @@
*/
var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
app = require('ripple/app'),
+ notifications = require('ripple/notifications'),
_uri = "blackberry/app/",
- _self = {};
+ _self;
+
+_self = {
+ exit: function () {
+ notifications.openNotification("normal", "blackberry.app.exit() was called, in the real world your app will exit, here... you get this notification");
+ }
+};
_self.__defineGetter__("author", function () {
return app.getInfo().author;
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/device.js b/lib/ripple/platform/webworks.bb10/1.0.0/device.js
index 04feb38..0d78821 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/device.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/device.js
@@ -16,7 +16,11 @@
var devices = require('ripple/devices'),
_self = {};
-_self.__defineGetter__("version", function () {
+_self.__defineGetter__("softwareVersion", function () {
return devices.getCurrentDevice().osVersion;
});
+
+_self.__defineGetter__("hardwareId", function () {
+ return devices.getCurrentDevice().hardwareId;
+});
module.exports = _self;
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/event.js b/lib/ripple/platform/webworks.bb10/1.0.0/event.js
index 92f7a7f..9893885 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/event.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/event.js
@@ -17,6 +17,8 @@
var event = require('ripple/event'),
settings = require('ripple/deviceSettings'),
app = require('ripple/app'),
+ cons = require('ripple/console'),
+ utils = require('ripple/utils'),
events = {
batterystatus: {
callbacks: [],
@@ -34,6 +36,14 @@
callbacks: [],
feature: 'blackberry.connection'
},
+ invoked: {
+ callbacks: [],
+ feature: 'blackberry.invoked'
+ },
+ swipedown: {
+ callbacks: [],
+ feature: 'blackberry.app'
+ },
resume: {
callbacks: [],
feature: 'blackberry.app'
@@ -80,11 +90,49 @@
_apply('connectionchange', [info]);
});
-event.on('appResume', function () {
+event.on("AppInvoke", function (invokeInfo) {
+ var invokeTargets = app.getInfo().invokeTargets;
+
+ if (!invokeTargets) {
+ cons.log("The application cannot be invoked, please add a rim:invoke-target node in config.xml");
+ return;
+ }
+
+ if (invokeTargets.some(function (target) {
+ return target.filter.some(function (filter) {
+ return (
+ (!filter.property ||
+ (filter.property && filter.property[0]["@attributes"].var === "exts" && filter.property[0]["@attributes"].value.split(",").some(function (value) {
+ return invokeInfo.extension.match(value);
+ })) ||
+ (filter.property && filter.property[0]["@attributes"].var === "uris" && filter.property[0]["@attributes"].value.split(",").some(function (value) {
+ return invokeInfo.source.match(value);
+ }))) &&
+ filter.action.some(function (action) {
+ return invokeInfo.action.match(action["#text"][0].replace("*", ""));
+ }) &&
+ filter["mime-type"].some(function (type) {
+ return invokeInfo.mimeType.match(type["#text"][0].replace("*", ""));
+ })
+ );
+ });
+ })) {
+ _apply('invoked', [invokeInfo]);
+ }
+ else {
+ cons.log("Cannot invoke application, values enter to not match values in rim:invoke-target in config.xml");
+ }
+});
+
+event.on('AppSwipeDown', function () {
+ _apply('swipedown');
+});
+
+event.on('AppResume', function () {
_apply('resume');
});
-event.on('appPause', function () {
+event.on('AppPause', function () {
_apply('pause');
});
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/invoke.js b/lib/ripple/platform/webworks.bb10/1.0.0/invoke.js
index 860a12b..f0e9a6e 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/invoke.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/invoke.js
@@ -15,60 +15,45 @@
*/
var notifications = require('ripple/notifications'),
- _self;
+ utils = require('ripple/utils'),
+ _self = {};
-_self = {
- invoke: function (appType, args) {
- var get = {};
+function _fail(onError) {
+ if (onError && typeof onError === "function") {
+ onError("invalid invocation request");
+ }
+}
- if (appType === 11) {
- if (!args) {
- get.appType = "http://";
- }
- else {
- get.appType = args.url.split("://");
+_self.invoke = function (request, onSuccess, onError) {
+ var argsString = "";
- if (get.appType.length === 1) {
- get.appType = "http://" + get.appType[0];
- }
- else if (get.appType.length === 2) {
- if (get.appType[0].indexOf("http") !== 0) {
- throw "Protocol specified in the url is not supported.";
- }
- else {
- get.appType = args.url;
- }
- }
- }
+ if (!request) { // is this check even needed?
+ _fail(onError);
+ return;
+ } else {
+ if (request.data) {
+ utils.forEach(request, function (arg, key) {
+ argsString += key + " = " + arg + "</br>";
+ });
- notifications.openNotification("normal", "Requested to launch: Browser.");
+ notifications.openNotification("normal", "Requested to invoke external application with the following arguments:</br> " +
+ argsString + "</br>");
}
else {
- throw "appType not supported";
+ _fail(onError);
+ return;
}
}
};
-_self.__defineGetter__("APP_CAMERA", function () {
- return 4;
+_self.__defineGetter__("ACTION_OPEN", function () {
+ return "bb.action.OPEN";
});
-_self.__defineGetter__("APP_MAPS", function () {
- return 5;
+_self.__defineGetter__("ACTION_VIEW", function () {
+ return "bb.action.VIEW";
});
-_self.__defineGetter__("APP_BROWSER", function () {
- return 11;
-});
-_self.__defineGetter__("APP_MUSIC", function () {
- return 13;
-});
-_self.__defineGetter__("APP_PHOTOS", function () {
- return 14;
-});
-_self.__defineGetter__("APP_VIDEOS", function () {
- return 15;
-});
-_self.__defineGetter__("APP_APPWORLD", function () {
- return 16;
+_self.__defineGetter__("ACTION_SHARE", function () {
+ return "bb.action.SHARE";
});
module.exports = _self;
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/spec.js b/lib/ripple/platform/webworks.bb10/1.0.0/spec.js
index a6ddce8..36872cd 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/spec.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/spec.js
@@ -23,7 +23,7 @@
ui: require('ripple/platform/webworks.bb10/1.0.0/spec/ui'),
device: require('ripple/platform/webworks.bb10/1.0.0/spec/device'),
- config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
+ config: require('ripple/platform/webworks.bb10/1.0.0/spec/config'),
events: require('ripple/platform/webworks.bb10/1.0.0/spec/events'),
initialize: function () {
@@ -69,13 +69,7 @@
},
invoke: {
path: "webworks.bb10/1.0.0/invoke",
- feature: "blackberry.invoke",
- children: {
- BrowserArguments: {
- path: "webworks.bb10/1.0.0/BrowserArguments",
- feature: "blackberry.invoke.BrowserArguments"
- }
- }
+ feature: "blackberry.invoke"
},
identity: {
path: "webworks.bb10/1.0.0/identity",
@@ -84,9 +78,6 @@
system: {
path: "webworks.bb10/1.0.0/system"
},
- device: {
- path: "webworks.bb10/1.0.0/device"
- },
connection: {
path: "webworks.bb10/1.0.0/connection"
},
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/spec/config.js b/lib/ripple/platform/webworks.bb10/1.0.0/spec/config.js
new file mode 100644
index 0000000..4492357
--- /dev/null
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/spec/config.js
@@ -0,0 +1,516 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils');
+
+module.exports = {
+ fileName: "config.xml",
+ validateVersion: function (config) {
+ return true;
+ },
+ extractInfo: function (config) {
+ if (!config) {
+ return null;
+ }
+
+ var widgetInfo = {},
+ widgetFeatures = config.widget.children.feature.validationResult,
+ accessUrls = config.widget.children.access.validationResult,
+ invokeTargets = config.rawJSON.widget[0]["rim:invoke-target"],
+ accessFeatures = config.widget.children.access.children.feature.validationResult,
+ toFeature = function (validationResult) {
+ return {
+ id: validationResult.attributes.id.value,
+ required: !validationResult.attributes.required || validationResult.attributes.required.value,
+ URIs: []
+ };
+ };
+
+ widgetInfo.id = config.widget.validationResult[0].attributes.id.value;
+ widgetInfo.name = config.widget.children.name.validationResult[0].value;
+ widgetInfo.icon = config.widget.children.icon.validationResult[0].attributes.src.value;
+ widgetInfo.version = config.widget.validationResult[0].attributes.version.value;
+ widgetInfo.author = config.widget.children.author.validationResult[0].value;
+ widgetInfo.authorEmail = config.widget.children.author.validationResult[0].attributes.email.value;
+ widgetInfo.authorURL = config.widget.children.author.validationResult[0].attributes.href.value;
+ widgetInfo.copyright = config.widget.children.author.validationResult[0].attributes["rim:copyright"].value;
+ widgetInfo.description = config.widget.children.description.validationResult[0].value;
+ widgetInfo.invokeTargets = invokeTargets;
+ if (config.widget.children.license.validationResult[0]) {
+ widgetInfo.license = config.widget.children.license.validationResult[0].value;
+ widgetInfo.licenseURL = config.widget.children.license.validationResult[0].attributes.href.value;
+ }
+
+ widgetInfo.features = widgetFeatures.reduce(function (features, validationResult) {
+ if (validationResult.valid) {
+ var feature = toFeature(validationResult);
+ feature.URIs.push({
+ value: utils.location().href,
+ subdomains: true
+ });
+ features = features || {};
+ features[feature.id] = feature;
+ }
+ return features;
+ }, {});
+
+ widgetInfo.features = accessUrls.map(function (access) {
+ return {
+ uri: access.attributes.uri.value,
+ subdomains: access.attributes.subdomains.value,
+ features: accessFeatures ? accessFeatures.filter(function (f) {
+ return f.node && f.node.parentNode && f.node.parentNode.attributes.uri.value === access.attributes.uri.value;
+ }) : null
+ };
+ }).reduce(function (result, access) {
+ return access.features ? access.features.reduce(function (features, validationResult) {
+ var feature = features[validationResult.attributes.id.value] || toFeature(validationResult);
+ feature.URIs.push({
+ value: access.uri,
+ subdomains: access.subdomains
+ });
+ features[feature.id] = feature;
+ return features;
+ }, result) : result;
+ }, widgetInfo.features);
+
+ return widgetInfo;
+ },
+ schema: {
+ rootElement: "widget",
+ widget: {
+ nodeName: "widget",
+ required: true,
+ occurrence: 1,
+ attributes: {
+ xmlns: {
+ attributeName: "xmlns",
+ required: true,
+ type: "list",
+ listValues: ["http://www.w3.org/ns/widgets"]
+ },
+ "xmlns:rim": {
+ attributeName: "xmlns:rim",
+ required: true,
+ type: "list",
+ listValues: ["http://www.blackberry.com/ns/widgets"]
+ },
+ "xml:lang": {
+ attributeName: "xml:lang",
+ required: false,
+ type: "iso-language"
+ },
+ id: {
+ attributeName: "id",
+ required: false,
+ type: "string"
+ },
+ version: {
+ attributeName: "version",
+ required: false,
+ type: "string"
+ },
+ "rim:header": {
+ attributeName: "rim:header",
+ required: false,
+ type: "string"
+ },
+ "rim:backButton": {
+ attributeName: "rim:backButton",
+ required: false,
+ type: "string"
+ }
+ },
+ children: {
+ name: {
+ nodeName: "name",
+ required: true,
+ occurrence: 1,
+ attributes: {
+ "xml:lang": {
+ attributeName: "xml:lang",
+ required: false,
+ type: "iso-language"
+ },
+ "its:dir": {
+ attributeName: "its:dir",
+ required: false,
+ type: "list",
+ listValues: ["rtl", "ltr", "lro", "rlo"]
+ }
+ }
+ },
+ description: {
+ nodeName: "description",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ "xml:lang": {
+ attributeName: "xml:lang",
+ required: false,
+ type: "iso-language"
+ },
+ "its:dir": {
+ attributeName: "its:dir",
+ required: false,
+ type: "list",
+ listValues: ["rtl", "ltr", "lro", "rlo"]
+ }
+ }
+ },
+ icon: {
+ nodeName: "icon",
+ required: false,
+ occurrence: 0,
+ attributes: {
+ src: {
+ attributeName: "src",
+ type: "string",
+ required: true
+ },
+ "rim:hover": {
+ attributeName: "rim:hover",
+ type: "boolean",
+ required: false
+ }
+ }
+ },
+ author: {
+ nodeName: "author",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ href: {
+ attributeName: "href",
+ type: "string",
+ required: false
+ },
+ "rim:copyright": {
+ attributeName: "rim:copyright",
+ type: "string",
+ required: false
+ },
+ email: {
+ attributeName: "email",
+ type: "string",
+ required: false
+ },
+ "xml:lang": {
+ attributeName: "xml:lang",
+ required: false,
+ type: "iso-language"
+ },
+ "its:dir": {
+ attributeName: "its:dir",
+ required: false,
+ type: "list",
+ listValues: ["rtl", "ltr", "lro", "rlo"]
+ }
+ }
+ },
+ license: {
+ nodeName: "license",
+ required: false,
+ occurrence: 1,
+ attributes : {
+ href: {
+ attributeName: "href",
+ type: "string",
+ required: false
+ },
+ "xml:lang": {
+ attributeName: "xml:lang",
+ required: false,
+ type: "iso-language"
+ },
+ "its:dir": {
+ attributeName: "its:dir",
+ required: false,
+ type: "list",
+ listValues: ["rtl", "ltr", "lro", "rlo"]
+ }
+ }
+ },
+ "rim:cache": {
+ nodeName: "rim:cache",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ disableAllCache: {
+ attributeName: "disableAllCache",
+ required: false,
+ type: "boolean"
+ },
+ aggressiveCacheAge: {
+ attributeName: "aggressiveCacheAge",
+ required: false,
+ type: "number"
+ },
+ maxCacheSizeTotal: {
+ attributeName: "maxCacheSizeTotal",
+ required: false,
+ type: "number"
+ },
+ maxCacheSizeItem: {
+ attributeName: "maxCacheSizeItem",
+ required: false,
+ type: "number"
+ }
+ }
+ },
+ access: {
+ nodeName: "access",
+ required: false,
+ occurrence: 0,
+ attributes: {
+ uri: {
+ attributeName: "uri",
+ required: true,
+ type: "string"
+ },
+ subdomains: {
+ attributeName: "subdomains",
+ required: false,
+ type: "boolean"
+ }
+ },
+ children: {
+ feature: {
+ nodeName: "feature",
+ required: false,
+ occurrence: 0,
+ attributes: {
+ id: {
+ attributeName: "id",
+ required: true,
+ //TODO: this should be a list
+ type: "string"
+ },
+ required: {
+ attributeName: "required",
+ required: false,
+ type: "boolean"
+ },
+ version: {
+ attributeName: "version",
+ required: false,
+ type: "string"
+ }
+ }
+ }
+ }
+ },
+ feature: {
+ nodeName: "feature",
+ required: false,
+ occurrence: 0,
+ attributes: {
+ id: {
+ attributeName: "id",
+ required: true,
+ //TODO: this should be a list
+ type: "string"
+ },
+ required: {
+ attributeName: "required",
+ required: false,
+ type: "boolean"
+ },
+ version: {
+ attributeName: "version",
+ required: false,
+ type: "string"
+ }
+ }
+ },
+ "rim:loadingScreen": {
+ nodeName: "rim:loadingScreen",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ backgroundColor: {
+ attributeName: "backgroundColor",
+ required: false,
+ type: "string"
+ },
+ backgroundImage: {
+ attributeName: "backgroundImage",
+ required: false,
+ type: "string"
+ },
+ foregroundImage: {
+ attributeName: "foregroundImage",
+ required: false,
+ type: "string"
+ },
+ onRemotePageLoad: {
+ attributeName: "onRemotePageLoad",
+ required: false,
+ type: "boolean"
+ },
+ onLocalPageLoad: {
+ attributeName: "onLocalPageLoad",
+ required : false,
+ type: "boolean"
+ },
+ onFirstLaunch: {
+ attributeName: "onFirstLaunch",
+ required: false,
+ type: "boolean"
+ }
+ },
+ children: {
+ "rim:transitionEffect": {
+ nodeName: "rim:transitionEffect",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ "type": {
+ attributeName: "type",
+ required: true,
+ type: "list",
+ listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"]
+ },
+ duration: {
+ attributeName: "duration",
+ required: false,
+ type: "number"
+ },
+ direction: {
+ attributeName: "direction",
+ required: false,
+ type: "list",
+ listValues: ["left", "right", "up", "down"]
+ }
+ }
+ }
+ }
+ },
+ "rim:invoke-target": {
+ nodeName: "rim:invoke-target",
+ required: false,
+ occurrence: 0,
+ attributes: {
+ id: {
+ attributeName: "id",
+ required: true,
+ type: "string"
+ }
+ },
+ children: {
+ "type": {
+ nodeName: "type",
+ required: true,
+ occurrence: 1
+ },
+ "require-source-permissions": {
+ nodeName: "require-source-permissions",
+ required: false,
+ occurence: 0
+ },
+ "filter": {
+ nodeName: "filter",
+ required: false,
+ occurence: 0,
+ children: {
+ "action": {
+ nodeName: "action",
+ required: true,
+ occurence: 0
+ },
+ "mime-type": {
+ nodeName: "mime-type",
+ required: true,
+ occurence: 0
+ },
+ "property": {
+ nodeName: "property",
+ required: false,
+ occurenc: 0,
+ attributes: {
+ "var": {
+ attributeName: "var",
+ required: false,
+ type: "string"
+ },
+ "value": {
+ attributeName: "value",
+ required: false,
+ type: "string"
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "rim:connection": {
+ nodeName: "rim:connection",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ timeout: {
+ attributeName: "timeout",
+ required: false,
+ type: "number"
+ }
+ },
+ children: {
+ id: {
+ nodeName: "id",
+ required: false,
+ occurrence: 0
+ }
+ }
+ },
+ "rim:navigation": {
+ nodeName: "rim:navigation",
+ required: false,
+ occurrence: 1,
+ attributes: {
+ mode: {
+ attributeName: "mode",
+ required: false,
+ type: "list",
+ listValues: ["focus"]
+ }
+ }
+ },
+ "content": {
+ nodeName: "content",
+ required: true,
+ occurrence: 1,
+ attributes: {
+ src: {
+ attributeName: "src",
+ required: true,
+ type: "string"
+ },
+ type: {
+ attributeName: "type",
+ required: false,
+ type: "string"
+ },
+ charset: {
+ attributeName: "charset",
+ required: false,
+ type: "string"
+ }
+ }
+ }
+ }
+ }
+ }
+};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/spec/device.js b/lib/ripple/platform/webworks.bb10/1.0.0/spec/device.js
index d1f54d5..8d32856 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/spec/device.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/spec/device.js
@@ -81,5 +81,18 @@
event.trigger("DeviceBatteryLevelChanged", [setting]);
}
}
+ },
+ "Perimiters": {
+ "perimiter": {
+ "name": "Perimiter",
+ "control": {
+ "type": "select",
+ "value": "Consumer"
+ },
+ "options": {
+ "Enterprise": "Enterprise",
+ "Consumer": "Consumer"
+ }
+ }
}
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/spec/events.js b/lib/ripple/platform/webworks.bb10/1.0.0/spec/events.js
index 80d5b09..2190b67 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/spec/events.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/spec/events.js
@@ -17,14 +17,19 @@
event = require('ripple/event');
module.exports = {
+ "blackberry.event.swipedown": {
+ callback: function () {
+ event.trigger("AppSwipeDown");
+ }
+ },
"blackberry.event.resume": {
callback: function () {
- event.trigger("appResume");
+ event.trigger("AppResume");
}
},
"blackberry.event.pause": {
callback: function () {
- event.trigger("appPause");
+ event.trigger("AppPause");
}
}
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/spec/ui.js b/lib/ripple/platform/webworks.bb10/1.0.0/spec/ui.js
index d7f2840..c19db43 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/spec/ui.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/spec/ui.js
@@ -20,6 +20,7 @@
"geoView",
"platformEvents",
"widgetConfig",
- "build"
+ "build",
+ "invoke"
]
};
diff --git a/lib/ripple/platform/webworks.bb10/1.0.0/system.js b/lib/ripple/platform/webworks.bb10/1.0.0/system.js
index 9ade778..e103ed0 100644
--- a/lib/ripple/platform/webworks.bb10/1.0.0/system.js
+++ b/lib/ripple/platform/webworks.bb10/1.0.0/system.js
@@ -53,4 +53,12 @@
return 1;
});
+_self.__defineGetter__("softwareVersion", function () {
+ return devices.getCurrentDevice().osVersion;
+});
+
+_self.__defineGetter__("hardwareId", function () {
+ return devices.getCurrentDevice().hardwareId;
+});
+
module.exports = _self;
diff --git a/lib/ripple/platform/webworks.core/2.0.0/select.js b/lib/ripple/platform/webworks.core/2.0.0/select.js
index b6a8096..504dd5f 100644
--- a/lib/ripple/platform/webworks.core/2.0.0/select.js
+++ b/lib/ripple/platform/webworks.core/2.0.0/select.js
@@ -35,7 +35,7 @@
return left >= right;
},
"REGEX": function (left, right) {
- return left.match(new RegExp(right));
+ return left && left.match(new RegExp(right));
},
"CONTAINS": function (left, right) {
return left.indexOf(right) >= 0;
diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/Contact.js b/lib/ripple/platform/webworks.handset/2.0.0/client/Contact.js
index 075e9e6..ed9d207 100644
--- a/lib/ripple/platform/webworks.handset/2.0.0/client/Contact.js
+++ b/lib/ripple/platform/webworks.handset/2.0.0/client/Contact.js
@@ -22,9 +22,9 @@
birthday: null,
categories: [],
company: null,
- email1: null,
- email2: null,
- email3: null,
+ email1: "",
+ email2: "",
+ email3: "",
faxPhone: null,
firstName: null,
homeAddress: null,
diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/appEvent.js b/lib/ripple/platform/webworks.handset/2.0.0/server/appEvent.js
index 685dad9..612bb6f 100644
--- a/lib/ripple/platform/webworks.handset/2.0.0/server/appEvent.js
+++ b/lib/ripple/platform/webworks.handset/2.0.0/server/appEvent.js
@@ -14,6 +14,7 @@
* limitations under the License.
*/
var event = require('ripple/event'),
+ notifications = require('ripple/notifications'),
_bg,
_fg,
_exit;
@@ -33,6 +34,7 @@
event.on("AppExit", function () {
var baton = _exit;
_exit = null;
+ notifications.openNotification("normal", "blackberry.app.exit() as called, in the real world your app will exit, here... you get this notification");
return baton && baton.pass({code: 1});
});
diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/server/appEvent.js b/lib/ripple/platform/webworks.tablet/2.0.0/server/appEvent.js
index 90b35c1..3a959b8 100644
--- a/lib/ripple/platform/webworks.tablet/2.0.0/server/appEvent.js
+++ b/lib/ripple/platform/webworks.tablet/2.0.0/server/appEvent.js
@@ -14,12 +14,20 @@
* limitations under the License.
*/
var event = require('ripple/event'),
+ notifications = require('ripple/notifications'),
_bg,
_fg,
_swipeDown,
_swipeStart,
_exit;
+event.on("AppExit", function () {
+ var baton = _exit;
+ _exit = null;
+ notifications.openNotification("normal", "blackberry.app.exit() as called, in the real world your app will exit, here... you get this notification");
+ return baton && baton.pass({code: 1});
+});
+
event.on("AppRequestBackground", function () {
var baton = _bg;
_bg = null;
diff --git a/lib/ripple/ui/plugins/build.js b/lib/ripple/ui/plugins/build.js
index 4f9cb71..9d2b679 100644
--- a/lib/ripple/ui/plugins/build.js
+++ b/lib/ripple/ui/plugins/build.js
@@ -14,11 +14,32 @@
* limitations under the License.
*/
var tooltip = require('ripple/ui/plugins/tooltip'),
- settings = require('ripple/ui/plugins/settings-dialog');
+ settings = require('ripple/ui/plugins/settings-dialog'),
+ bus = require('ripple/bus');
function handleBuild() {
- var node = $(this),
- action = node.attr('id').split("-")[2];
+ var node = $(this);
+
+ bus.ajax(
+ "GET",
+ "http://127.0.0.1:9910/ripple/about",
+ null,
+ function () {
+ doBuild(node);
+ },
+ function (error) {
+ if (error.code === 0 || error.code === 404) {
+ startServices(function () {
+ doBuild(node);
+ });
+ }
+ }
+ );
+
+}
+
+function doBuild(node) {
+ var action = node.attr('id').split("-")[2];
if (node.hasClass("not-ready")) {
return;
@@ -32,6 +53,16 @@
}
}
+function startServices(callBack) {
+ var action = "start";
+ bus.send("services", action, function () {
+ if (typeof callBack === "function") {
+ callBack();
+ }
+ $("#options-menu-services").show();
+ });
+}
+
module.exports = {
panel: {
domId: "build-container",
@@ -52,5 +83,7 @@
$("#options-menu-build-warning").show();
tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
}
+
+ startServices();
}
};
diff --git a/lib/ripple/ui/plugins/build/panel.html b/lib/ripple/ui/plugins/build/panel.html
index 3be2ec6..d02d266 100644
--- a/lib/ripple/ui/plugins/build/panel.html
+++ b/lib/ripple/ui/plugins/build/panel.html
@@ -21,6 +21,9 @@
</section>
</section>
<section class="info ui-widget-content ui-corner-all" style="display: none;">
+ <section id="options-menu-services" class="ui-text-fail irrelevant">
+ The Build and Deploy services are currently running at: http://127.0.0.1:9910
+ </section>
<button id="options-menu-build" class="not-ready ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
<span class="ui-button-text">Package</span>
</button>
diff --git a/lib/ripple/ui/plugins/camera.js b/lib/ripple/ui/plugins/camera.js
index e7217e0..e3a0c6d 100644
--- a/lib/ripple/ui/plugins/camera.js
+++ b/lib/ripple/ui/plugins/camera.js
@@ -14,19 +14,41 @@
* limitations under the License.
*/
-var ui = require('ripple/ui');
+var ui = require('ripple/ui'),
+ event = require('ripple/event'),
+ video = document.getElementById('camera-video'),
+ upload = document.getElementById('picture-upload'),
+ select = document.getElementById('select-file'),
+ take = document.getElementById('take-file'),
+ pic = document.getElementById("camera-image");
+
+
+select.addEventListener('click', function () {
+ upload.click();
+});
+
+upload.addEventListener('change', function () {
+ pic.src = window.webkitURL.createObjectURL(upload.files[0]);
+ take.style.display = "inline";
+});
+
+take.addEventListener('click', function () {
+ console.log("captured-image: " + pic.src);
+ event.trigger('captured-image', [pic.src, upload.files[0]]);
+ module.exports.hide();
+});
module.exports = {
show: function () {
- var video = document.getElementById('camera-video');
-
- if (navigator.webkitGetUserMedia) {
- navigator.webkitGetUserMedia("video", function (stream) {
- video.src = window.webkitURL.createObjectURL(stream);
- },
- function (err) {
- console.log(err);
- });
+ ui.showOverlay("camera-window");
+ if (pic.src) {
+ take.style.display = "inline";
}
+ else {
+ take.style.display = "none";
+ }
+ },
+ hide: function () {
+ ui.hideOverlay("camera-window");
}
};
diff --git a/lib/ripple/ui/plugins/camera/overlay.html b/lib/ripple/ui/plugins/camera/overlay.html
index 7a6899e..eb2aed7 100644
--- a/lib/ripple/ui/plugins/camera/overlay.html
+++ b/lib/ripple/ui/plugins/camera/overlay.html
@@ -14,8 +14,18 @@
* limitations under the License.
-->
<section id="camera-window" class="overlay">
- <video id="camera-video" autoplay></video>
- <button id="take-picture" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
- <span class="ui-button-text">Take a Picture</span>
- </button>
+ <section>
+ <img id="camera-image"></img>
+ </section>
+ <section>
+ <input id="picture-upload" type="file" accept="image/*" class="ui-button" style="display:none"></input>
+ <input id="video-upload" type="file" accept="video/*" class="ui-button" style="display:none"></input>
+ <input id="audio-upload" type="file" accept="audio/*" class="ui-button" style="display:none"></input>
+ <button id="select-file" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+ <span class="ui-button-text">Select a Picture</span>
+ </button>
+ <button id="take-file" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+ <span class="ui-button-text">Use Selected Picture</span>
+ </button>
+ </section>
</section>
diff --git a/lib/ripple/ui/plugins/geoView.js b/lib/ripple/ui/plugins/geoView.js
index 39ed890..495293e 100644
--- a/lib/ripple/ui/plugins/geoView.js
+++ b/lib/ripple/ui/plugins/geoView.js
@@ -210,7 +210,9 @@
}
// HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
- if (platform.current().id === 'phonegap' || platform.current().id === 'webworks') {
+ if (platform.current().id === 'phonegap' ||
+ platform.current().id === 'webworks' ||
+ platform.current().id === 'cordova') {
// make the fields visible
jQuery("#geo-cellid-container").hide();
jQuery("#geo-heading-container").show();
@@ -247,7 +249,7 @@
});
// HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
- if (platform.current().id === 'phonegap' || platform.current().id === 'webworks') {
+ if (platform.current().id === 'phonegap' || platform.current().id === 'webworks' || platform.current().id === 'cordova') {
jQuery("#" + GEO_OPTIONS.HEADING).bind("change", function () {
updateGeo();
updateHeadingValues();
diff --git a/lib/ripple/ui/plugins/invoke.js b/lib/ripple/ui/plugins/invoke.js
new file mode 100644
index 0000000..8e8c361
--- /dev/null
+++ b/lib/ripple/ui/plugins/invoke.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+ event = require('ripple/event');
+
+module.exports = {
+ panel: {
+ domId: "invoke-container",
+ collapsed: true,
+ pane: "left"
+ },
+ initialize: function () {
+ document.getElementById("invoke-send")
+ .addEventListener("click", function () {
+ var invokeInfo = {};
+
+ invokeInfo.source = document.getElementById("invoke-source-text").value;
+ invokeInfo.target = document.getElementById("invoke-target-text").value;
+ invokeInfo.action = document.getElementById("invoke-action-text").value;
+ invokeInfo.mimeType = document.getElementById("invoke-mime-type-text").value;
+ invokeInfo.extension = document.getElementById("invoke-extension-text").value;
+ invokeInfo.data = document.getElementById("invoke-data-text").value;
+ if (invokeInfo.data) {
+ invokeInfo.data = window.btoa(invokeInfo.data);
+ }
+
+ event.trigger("AppInvoke", [invokeInfo]);
+ }, false);
+ }
+};
diff --git a/lib/ripple/ui/plugins/invoke/panel.html b/lib/ripple/ui/plugins/invoke/panel.html
new file mode 100644
index 0000000..e9045b5
--- /dev/null
+++ b/lib/ripple/ui/plugins/invoke/panel.html
@@ -0,0 +1,71 @@
+<!--
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="invoke-container" class="ui-box ui-state-default ui-corner-all">
+ <section class="h2 info-header">
+ <section class="collapse-handle">Invoke</section>
+ <section class="drag-handle ui-state-default ui-corner-all ui-state-hover">
+ <span class="ui-icon ui-icon-arrow-4"></span>
+ </section>
+ </section>
+
+ <section id="invoke" class="info ui-widget-content ui-corner-all" style="display: none;">
+ <section class="invoke-info">
+ <table id="invoke-fields" class="panel-table">
+ <tr>
+ <td><label class="ui-text-label">Source</label></td>
+ <td><input class="ui-state-default ui-corner-all" id="invoke-source-text" type="text"/></td>
+ </tr>
+ <tr>
+ <td><label class="ui-text-label">Target</label></td>
+ <td><input class="ui-state-default ui-corner-all" id="invoke-target-text" type="text"/></td>
+ </tr>
+ <tr>
+ <td><label class="ui-text-label">Action</label></td>
+ <td><input class="ui-state-default ui-corner-all" id="invoke-action-text" type="text"/></td>
+ </tr>
+ <tr>
+ <td><label class="ui-text-label">mime-type</label></td>
+ <td><input class="ui-state-default ui-corner-all" id="invoke-mime-type-text" type="text"/></td>
+ </tr>
+ <tr>
+ <td><label class="ui-text-label">Extension (if Data block represents a file)</label></td>
+ <td><input class="ui-state-default ui-corner-all" id="invoke-extension-text" type="text"/></td>
+ </tr>
+ </table>
+
+ <table class="panel-table">
+ <tr>
+ <td colspan="2">
+ <label class="ui-text-label">Data (will be base64 encoded)</label>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <textarea class="ui-state-default ui-corner-all" id="invoke-data-text" rows="4" style="width: 90%;"></textarea>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">
+ <button id="invoke-send" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+ <span class="ui-button-text">Send Invoke Request</span>
+ </button>
+ </td>
+ </tr>
+ </table>
+ </section>
+ </section>
+</section>
diff --git a/lib/ripple/utils.js b/lib/ripple/utils.js
index 258fbc0..48d3fe1 100644
--- a/lib/ripple/utils.js
+++ b/lib/ripple/utils.js
@@ -145,6 +145,19 @@
return window.location;
},
+ queryString: function () {
+ // trim the leading ? and split each name=value
+ var args = this.location().search.replace(/^\?/, '').split('&');
+
+ return args.reduce(function (obj, value) {
+ if (value) {
+ value = value.toLowerCase().split("=");
+ obj[value[0]] = value[1];
+ }
+ return obj;
+ }, {});
+ },
+
extensionUrl: function () {
return document.getElementById("extension-url").innerText;
},
diff --git a/lib/ripple/widgetConfig.js b/lib/ripple/widgetConfig.js
index 0d58995..2d62e5c 100644
--- a/lib/ripple/widgetConfig.js
+++ b/lib/ripple/widgetConfig.js
@@ -381,6 +381,36 @@
}
}
+function _xmlToJson(xml) {
+ var obj = {};
+
+ if (xml.nodeType === 1) { // element
+ if (xml.attributes.length > 0) {
+ obj["@attributes"] = {};
+ utils.forEach(xml.attributes, function (attribute) {
+ obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
+ });
+ }
+ }
+ else if (xml.nodeType === 3) { // text node
+ obj = xml.nodeValue;
+ }
+
+ if (xml.hasChildNodes && xml.hasChildNodes()) {
+ utils.forEach(xml.childNodes, function (child) {
+ if (!child.nodeName) {
+ return;
+ }
+ if (!obj[child.nodeName]) {
+ obj[child.nodeName] = [];
+ }
+ obj[child.nodeName].push(_xmlToJson(child));
+ });
+ }
+
+ return obj;
+}
+
module.exports = {
validate: function (configXML) {
@@ -403,6 +433,7 @@
xmlHttp.send();
if (xmlHttp.responseXML) {
results = _validate(xmlHttp.responseXML);
+ results.rawJSON = _xmlToJson(xmlHttp.responseXML);
_process(results);
_configValidationResults = results;
}
diff --git a/package.json b/package.json
index 4554ca0..967adbf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ripple",
- "version": "0.9.6.1",
+ "version": "0.9.7",
"description": "A browser based html5 mobile application development and testing tool",
"homepage": "http://github.com/blackberry/Rippe-UI",
"author": {
@@ -14,9 +14,9 @@
"bin": { "ripple": "./bin/ripple" },
"main": "lib/index",
"dependencies": {
- "connect": "1.7.x",
+ "connect": "2.3.6",
"argsparser": "0.0.x",
- "jsdom": "0.2.4",
+ "jsdom": "0.2.14",
"jWorkflow": "*"
},
"bundledDependencies": [
diff --git a/test/integration/webworks.tablet/systemEvent.js b/test/integration/webworks.tablet/systemEvent.js
index a86fd2b..d3df7e2 100644
--- a/test/integration/webworks.tablet/systemEvent.js
+++ b/test/integration/webworks.tablet/systemEvent.js
@@ -50,20 +50,6 @@
});
describe("deviceBatteryStateChange", function () {
- it("registers and invokes onBatteryStateChange", function () {
- var listener = jasmine.createSpy();
- systemEvent.deviceBatteryStateChange(listener);
-
- _run(20, [
- function () {
- event.trigger("DeviceBatteryStateChanged", [false]);
- },
- function () {
- expect(listener).toHaveBeenCalledWith(3); // UNPLUGGED
- }
- ]);
- });
-
it("de-registers onBatterStateChange", function () {
var listener = jasmine.createSpy();
systemEvent.deviceBatteryStateChange(listener);
@@ -80,6 +66,21 @@
}
]);
});
+
+ it("registers and invokes onBatteryStateChange", function () {
+ var listener = jasmine.createSpy();
+ systemEvent.deviceBatteryStateChange(listener);
+
+ _run(20, [
+ function () {
+ event.trigger("DeviceBatteryStateChanged", [false]);
+ },
+ function () {
+ expect(listener).toHaveBeenCalledWith(3); // UNPLUGGED
+ }
+ ]);
+ });
+
});
describe("deviceBatteryLevelChange", function () {
diff --git a/test/unit/accelerometer.js b/test/unit/accelerometer.js
index f00fe01..47eddac 100644
--- a/test/unit/accelerometer.js
+++ b/test/unit/accelerometer.js
@@ -148,5 +148,4 @@
accelValues = accelerometer.getInfo(true);
expect(initialX).not.toBe(accelValues.x);
});
-
});
diff --git a/test/unit/cordova/accelerometer.js b/test/unit/cordova/accelerometer.js
new file mode 100644
index 0000000..6e79059
--- /dev/null
+++ b/test/unit/cordova/accelerometer.js
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+describe("cordova accelerometer bridge", function () {
+ var accel = require('ripple/platform/cordova/2.0.0/bridge/accelerometer'),
+ event = require('ripple/event');
+
+ beforeEach(function () {
+ spyOn(window, "setInterval").andReturn(1);
+ spyOn(window, "clearInterval");
+ });
+
+ afterEach(function () {
+ accel.stop();
+ });
+
+ describe("when starting", function () {
+ it("starts an interval", function () {
+ var s = jasmine.createSpy("success"),
+ f = jasmine.createSpy("fail");
+
+ accel.start(s, f);
+ expect(window.setInterval).toHaveBeenCalledWith(jasmine.any(Function), 50);
+ });
+
+ it("the interval function calls the success callback with the AccelerometerInfoChangedEvent", function () {
+ var s = jasmine.createSpy("success"),
+ f = jasmine.createSpy("fail");
+
+ accel.start(s, f);
+
+ event.trigger("AccelerometerInfoChangedEvent", [{
+ accelerationIncludingGravity: {
+ x: 9.8,
+ y: 9.8,
+ z: 9.8
+ }
+ }], true);
+
+ window.setInterval.mostRecentCall.args[0]();
+
+ expect(s).toHaveBeenCalledWith({
+ x: 9.8,
+ y: 9.8,
+ z: 9.8,
+ timestamp: jasmine.any(Number)
+ });
+
+ expect(f).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("when stopping", function () {
+ it("it clears the interval", function () {
+ var s = jasmine.createSpy("success"),
+ f = jasmine.createSpy("fail");
+
+ accel.start(s, f);
+ accel.stop();
+
+ expect(window.clearInterval).toHaveBeenCalledWith(1);
+ });
+ });
+});
diff --git a/test/unit/cordova/compass.js b/test/unit/cordova/compass.js
new file mode 100644
index 0000000..e5e5c3e
--- /dev/null
+++ b/test/unit/cordova/compass.js
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+describe("cordova compass bridge", function () {
+ var geo = require('ripple/geo'),
+ target = require('ripple/platform/cordova/2.0.0/bridge/compass'),
+ heading = {direction: "southish"};
+
+ beforeEach(function () {
+ spyOn(geo, "getPositionInfo").andReturn({
+ heading: heading
+ });
+ });
+
+ describe("when calling getHeading", function () {
+ it("it returns the heading from geo", function () {
+ var success = jasmine.createSpy("success");
+
+ target.getHeading(success);
+
+ expect(geo.getPositionInfo).toHaveBeenCalled();
+ expect(success).toHaveBeenCalledWith({
+ magneticHeading: heading,
+ trueHeading: heading,
+ headingAccuracy: 100,
+ timestamp: jasmine.any(Number)
+ });
+ });
+ });
+});
diff --git a/test/unit/cordova/media.js b/test/unit/cordova/media.js
new file mode 100644
index 0000000..2d3fc9c
--- /dev/null
+++ b/test/unit/cordova/media.js
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+describe("cordova media bridge object", function () {
+ var media = require('ripple/platform/cordova/2.0.0/bridge/media'),
+ audio = {
+ play: jasmine.createSpy("audio.play"),
+ pause: jasmine.createSpy("audio.pause"),
+ addEventListener: jasmine.createSpy("audio.addEventListener")
+ };
+
+ beforeEach(function () {
+ audio.play.reset();
+ global.Audio = window.Audio = jasmine.createSpy().andReturn(audio);
+ });
+
+ describe("when creating", function () {
+ it("creates an audio object for the src", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.create(success, error, ["id", "foo.mp3"]);
+
+ expect(window.Audio).toHaveBeenCalled();
+ expect(audio.src).toBe("foo.mp3");
+ expect(success).toHaveBeenCalled();
+ expect(error).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when args is empty", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.create(success, error, []);
+
+ expect(success).not.toHaveBeenCalled();
+ expect(error).toHaveBeenCalled();
+ });
+
+ it("can be called without a success callback", function () {
+ expect(function () {
+ media.create(null, null, ["1"]);
+ }).not.toThrow();
+ });
+
+ it("can be called without an error callback", function () {
+ expect(function () {
+ media.create(jasmine.createSpy(), null, ["1"]);
+ }).not.toThrow();
+ });
+
+ it("adds and event listener for error", function () {
+ media.create(null, null, ["1"]);
+ expect(audio.addEventListener).toHaveBeenCalledWith("error", jasmine.any(Function));
+ });
+
+ it("adds and event listener for durationchange", function () {
+ media.create(null, null, ["1"]);
+ expect(audio.addEventListener).toHaveBeenCalledWith("durationchange", jasmine.any(Function));
+ });
+ });
+
+ describe("when starting audio", function () {
+ it("creates an audio object", function () {
+ media.startPlayingAudio(null, null, ["a", "fred.mp3"]);
+ expect(window.Audio).toHaveBeenCalledWith();
+ expect(audio.src).toBe("fred.mp3");
+ });
+
+ it("calls play on the audio object", function () {
+ media.startPlayingAudio(null, null, ["b", "bar.mp3"]);
+ expect(audio.play).toHaveBeenCalled();
+ expect(audio.play.callCount).toBe(1);
+ });
+
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.startPlayingAudio(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when just an id arg", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.startPlayingAudio(success, error, ["larry"]);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the pause method when id exists (as well as the play method)", function () {
+ media.startPlayingAudio(null, null, ["c", "crownRoyal.mp3"]);
+ media.startPlayingAudio(null, null, ["c", "wisers.mp3"]);
+ expect(audio.pause).toHaveBeenCalled();
+ expect(audio.play).toHaveBeenCalled();
+ expect(audio.pause.callCount).toBe(1);
+ expect(audio.play.callCount).toBe(2);
+ });
+
+ it("calls the success callback when things are all rainbows and ponies", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.startPlayingAudio(success, error, ["chimay", "trios pistolues"]);
+
+ expect(success).toHaveBeenCalled();
+ expect(error).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("when stopping audio", function () {
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.stopPlayingAudio(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when it can't find the audio obj", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.stopPlayingAudio(success, error, ['lamb_burger']);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls pause on the audio object when things are 20% cooler", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.startPlayingAudio(success, error, ['milk_duds', 'yum.mp3']);
+ audio.pause.reset();
+ media.stopPlayingAudio(success, error, ['milk_duds']);
+
+ expect(audio.pause).toHaveBeenCalled();
+ });
+
+ it("calls pause on the success callback when things are 20% cooler", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.startPlayingAudio(success, error, ['nomnomnom', 'yum.mp3']);
+ audio.pause.reset();
+ media.stopPlayingAudio(success, error, ['nomnomnom']);
+
+ expect(success).toHaveBeenCalled();
+ });
+ });
+
+ describe("when seeking the audio", function () {
+ beforeEach(function () {
+ media.create(null, null, ['seek', 'until_it_sleeps.mp3']);
+ });
+
+ afterEach(function () {
+ media.stopPlayingAudio(null, null, ['seek']);
+ });
+
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.seekToAudio(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when it can't find the id", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.seekToAudio(success, error, ['hey_you_guys']);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when the seek time isn't provided", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.seekToAudio(success, error, ['seek']);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("sets the currentTime on the audio object", function () {
+ media.seekToAudio(null, null, ['seek', 12345]);
+ expect(audio.currentTime).toBe(12345);
+ });
+
+ it("calls the success callback", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.seekToAudio(success, error, ['seek', 35]);
+
+ expect(success).toHaveBeenCalled();
+ expect(error).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("when pausing audio", function () {
+ beforeEach(function () {
+ media.create(null, null, ['pause', 'hey_jude.mp3']);
+ });
+
+ afterEach(function () {
+ media.stopPlayingAudio(null, null, ['pause']);
+ });
+
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.pausePlayingAudio(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when it can't find the id", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.pausePlayingAudio(success, error, ['all along the watchtower']);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the pause method on the audio object", function () {
+ media.pausePlayingAudio(null, null, ['pause']);
+ expect(audio.pause).toHaveBeenCalled();
+ });
+
+ it("calls the success callback", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.pausePlayingAudio(success, error, ['pause']);
+
+ expect(success).toHaveBeenCalled();
+ expect(error).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("when getting the current position", function () {
+ beforeEach(function () {
+ media.create(null, null, ['position', 'space_hog.mp3']);
+ });
+
+ afterEach(function () {
+ media.stopPlayingAudio(null, null, ['position']);
+ });
+
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.getCurrentPositionAudio(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when it can't find the id", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.getCurrentPositionAudio(success, error, ['hey you guys']);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the success callback with the currentTime", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ audio.currentTime = 12;
+ media.getCurrentPositionAudio(success, error, ['position']);
+
+ expect(success).toHaveBeenCalledWith(12);
+ expect(error).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("when getting the duration", function () {
+ beforeEach(function () {
+ media.create(null, null, ['duration', 'cum_on_feel_the_noise.mp3']);
+ });
+
+ afterEach(function () {
+ media.stopPlayingAudio(null, null, ['duration']);
+ });
+
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.getDuration(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the error callback when it can't find the id", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.getDuration(success, error, ['peanuts']);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the success callback with the currentTime", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ audio.duration = 80000;
+ media.getDuration(success, error, ['duration']);
+
+ expect(success).toHaveBeenCalledWith(80000);
+ expect(error).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("when starting to record audio", function () {
+ it("can be called with no callbacks", function () {
+ expect(function () {
+ media.startRecordingAudio();
+ }).not.toThrow();
+ });
+
+ it("calls the error callback", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.startRecordingAudio(success, error, []);
+
+ expect(success).not.toHaveBeenCalled();
+ expect(error).toHaveBeenCalled();
+ });
+ });
+
+ describe("when stopping recording audio", function () {
+ it("can be called with no callbacks", function () {
+ expect(function () {
+ media.stopRecordingAudio();
+ }).not.toThrow();
+ });
+
+ it("calls the error callback", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.stopRecordingAudio(success, error, []);
+
+ expect(success).not.toHaveBeenCalled();
+ expect(error).toHaveBeenCalled();
+ });
+ });
+
+ describe("when releasing", function () {
+ beforeEach(function () {
+ media.create(null, null, ['release', 'just_beat_it.mp3']);
+ });
+
+ it("calls the error callback when no args", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.release(success, error, []);
+
+ expect(error).toHaveBeenCalled();
+ expect(success).not.toHaveBeenCalled();
+ });
+
+ it("calls the success callback when it can't find the id", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ media.release(success, error, ['rainbow dash']);
+
+ expect(success).toHaveBeenCalled();
+ expect(error).not.toHaveBeenCalled();
+ });
+
+ it("calls the success callback", function () {
+ var success = jasmine.createSpy("success"),
+ error = jasmine.createSpy("error");
+
+ audio.duration = 80000;
+ media.release(success, error, ['release']);
+
+ expect(success).toHaveBeenCalled();
+ expect(error).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/test/unit/emulatorBridge.js b/test/unit/emulatorBridge.js
index b5857a1..0b96f64 100644
--- a/test/unit/emulatorBridge.js
+++ b/test/unit/emulatorBridge.js
@@ -18,6 +18,7 @@
var emulatorBridge = require('ripple/emulatorBridge'),
platform = require('ripple/platform'),
old_gElById,
+ _currentPlatformInit,
_emulatedBody,
_emulatedHtml,
_emulatedDocument,
@@ -42,6 +43,7 @@
window.tinyHippos = {};
+ _currentPlatformInit = jasmine.createSpy('platform.current().initialize');
_emulatedViewport = document.createElement("section");
_emulatedDocument = document.createElement("section");
_emulatedHtml = document.createElement("section");
@@ -54,13 +56,16 @@
_emulatedDocument.appendChild(_emulatedHtml);
_emulatedViewport.appendChild(_emulatedDocument);
- spyOn(platform, "current").andReturn({objects: {
- foo: {a: 1},
- bar: {b: 1},
- woot: [1, 2, 3, 4, 5]
- }});
+ spyOn(platform, "current").andReturn({
+ initialize: _currentPlatformInit,
+ objects: {
+ foo: {a: 1},
+ bar: {b: 1},
+ woot: [1, 2, 3, 4, 5]
+ }
+ });
- emulatorBridge.link(_emulatedFrame);
+ emulatorBridge.link(_emulatedFrame.contentWindow);
});
afterEach(function () {
@@ -114,6 +119,10 @@
expect(window.XMLHttpRequest).toBe(_emulatedFrame.contentWindow.XMLHttpRequest);
});
+ it("initializes the current platform (if method exists)", function () {
+ expect(_currentPlatformInit).toHaveBeenCalledWith(_emulatedFrame.contentWindow);
+ });
+
it("it marshals over everything in the sandbox", function () {
expect(window.foo).toBeDefined();
expect(window.bar).toBeDefined();
diff --git a/test/unit/fs.js b/test/unit/fs.js
index 0918cc6..d26b14c 100644
--- a/test/unit/fs.js
+++ b/test/unit/fs.js
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-var fs = require('ripple/fs'),
- event = require('ripple/event'),
- utils = require('ripple/utils');
-
-xdescribe("fs", function () {
- var _resultEntries,
+describe("fs", function () {
+ var fs = require('ripple/fs'),
+ event = require('ripple/event'),
+ utils = require('ripple/utils'),
+ _resultEntries,
_dirEntry,
_baton,
_fs,
diff --git a/test/unit/phonegap/accelerometer.js b/test/unit/phonegap/accelerometer.js
index 938003a..c600458 100644
--- a/test/unit/phonegap/accelerometer.js
+++ b/test/unit/phonegap/accelerometer.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
describe("phonegap_accelerometer", function () {
- var accel = require('ripple/platform/phonegap/1.0/accelerometer'),
+ var accel = require('ripple/platform/phonegap/1.0.0/accelerometer'),
event = require('ripple/event'),
platform = require('ripple/platform');
diff --git a/test/unit/phonegap/camera.js b/test/unit/phonegap/camera.js
index ca484ac..ca6a23f 100644
--- a/test/unit/phonegap/camera.js
+++ b/test/unit/phonegap/camera.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
describe("phonegap_camera", function () {
- var camera = require('ripple/platform/phonegap/1.0/camera');
+ var camera = require('ripple/platform/phonegap/1.0.0/camera');
it("it calls the error callback ALL the time", function () {
var success = jasmine.createSpy(),
diff --git a/test/unit/phonegap/compass.js b/test/unit/phonegap/compass.js
index 784673e..a71d3e4 100644
--- a/test/unit/phonegap/compass.js
+++ b/test/unit/phonegap/compass.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
describe("phonegap_compass", function () {
- var compass = require('ripple/platform/phonegap/1.0/compass'),
+ var compass = require('ripple/platform/phonegap/1.0.0/compass'),
geo = require('ripple/geo');
it("clearWatch clears interval", function () {
diff --git a/test/unit/phonegap/contacts.js b/test/unit/phonegap/contacts.js
index 43dce76..bde3435 100644
--- a/test/unit/phonegap/contacts.js
+++ b/test/unit/phonegap/contacts.js
@@ -17,11 +17,11 @@
var db = require('ripple/db'),
event = require('ripple/event'),
utils = require('ripple/utils'),
- Contact = require('ripple/platform/phonegap/1.0/Contact'),
- ContactError = require('ripple/platform/phonegap/1.0/ContactError'),
- ContactField = require('ripple/platform/phonegap/1.0/ContactField'),
- ContactFindOptions = require('ripple/platform/phonegap/1.0/ContactFindOptions'),
- contacts = require('ripple/platform/phonegap/1.0/contacts');
+ Contact = require('ripple/platform/phonegap/1.0.0/Contact'),
+ ContactError = require('ripple/platform/phonegap/1.0.0/ContactError'),
+ ContactField = require('ripple/platform/phonegap/1.0.0/ContactField'),
+ ContactFindOptions = require('ripple/platform/phonegap/1.0.0/ContactFindOptions'),
+ contacts = require('ripple/platform/phonegap/1.0.0/contacts');
beforeEach(function () {
spyOn(window, "setTimeout").andCallFake(function (func) {
@@ -30,51 +30,51 @@
});
describe("spec", function () {
- var spec = require('ripple/platform/phonegap/1.0/spec');
+ var spec = require('ripple/platform/phonegap/1.0.0/spec');
it("includes contacts module according to proper object structure", function () {
expect(spec.objects.navigator.children.contacts.path)
- .toEqual("phonegap/1.0/contacts");
+ .toEqual("phonegap/1.0.0/contacts");
});
it("includes ContactError module according to proper object structure", function () {
expect(spec.objects.ContactError.path)
- .toEqual("phonegap/1.0/ContactError");
+ .toEqual("phonegap/1.0.0/ContactError");
});
it("includes Contact module according to proper object structure", function () {
expect(spec.objects.Contact.path)
- .toEqual("phonegap/1.0/Contact");
+ .toEqual("phonegap/1.0.0/Contact");
});
it("includes ContactName module according to proper object structure", function () {
expect(spec.objects.ContactName.path)
- .toEqual("phonegap/1.0/ContactName");
+ .toEqual("phonegap/1.0.0/ContactName");
});
it("includes ContactAccount module according to proper object structure", function () {
expect(spec.objects.ContactAccount.path)
- .toEqual("phonegap/1.0/ContactAccount");
+ .toEqual("phonegap/1.0.0/ContactAccount");
});
it("includes ContactAddress module according to proper object structure", function () {
expect(spec.objects.ContactAddress.path)
- .toEqual("phonegap/1.0/ContactAddress");
+ .toEqual("phonegap/1.0.0/ContactAddress");
});
it("includes ContactOrganization module according to proper object structure", function () {
expect(spec.objects.ContactOrganization.path)
- .toEqual("phonegap/1.0/ContactOrganization");
+ .toEqual("phonegap/1.0.0/ContactOrganization");
});
it("includes ContactFindOptions module according to proper object structure", function () {
expect(spec.objects.ContactFindOptions.path)
- .toEqual("phonegap/1.0/ContactFindOptions");
+ .toEqual("phonegap/1.0.0/ContactFindOptions");
});
it("includes ContactField module according to proper object structure", function () {
expect(spec.objects.ContactField.path)
- .toEqual("phonegap/1.0/ContactField");
+ .toEqual("phonegap/1.0.0/ContactField");
});
});
diff --git a/test/unit/phonegap/device.js b/test/unit/phonegap/device.js
index b2393b3..cdd9282 100644
--- a/test/unit/phonegap/device.js
+++ b/test/unit/phonegap/device.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
describe("phonegap_device", function () {
- var device = require('ripple/platform/phonegap/1.0/device'),
+ var device = require('ripple/platform/phonegap/1.0.0/device'),
devices = require('ripple/devices');
it("asks the device for the name", function () {
diff --git a/test/unit/phonegap/events.js b/test/unit/phonegap/events.js
index 047a425..77f7b98 100644
--- a/test/unit/phonegap/events.js
+++ b/test/unit/phonegap/events.js
@@ -1,5 +1,5 @@
describe("phonegap events", function () {
- var spec = require('ripple/platform/phonegap/1.0/spec'),
+ var spec = require('ripple/platform/phonegap/1.0.0/spec'),
emulatorBridge = require('ripple/emulatorBridge'),
events = spec.events;
diff --git a/test/unit/phonegap/navigator.js b/test/unit/phonegap/navigator.js
index 9e565e0..a2f047b 100644
--- a/test/unit/phonegap/navigator.js
+++ b/test/unit/phonegap/navigator.js
@@ -22,7 +22,7 @@
beforeEach(function () {
spyOn(devices, "getCurrentDevice").andReturn("WTF");
- navigator = require('ripple/platform/phonegap/1.0/navigator');
+ navigator = require('ripple/platform/phonegap/1.0.0/navigator');
});
it("it fires device ready and logs when tinyHippos Loaded event is raised", function () {
diff --git a/test/unit/phonegap/network.js b/test/unit/phonegap/network.js
index 8be892b..98409b6 100644
--- a/test/unit/phonegap/network.js
+++ b/test/unit/phonegap/network.js
@@ -15,7 +15,7 @@
*/
describe("phonegap_network", function () {
var deviceSettings = require('ripple/deviceSettings'),
- network = require('ripple/platform/phonegap/1.0/network');
+ network = require('ripple/platform/phonegap/1.0.0/network');
it("returns the value from deviceSettings", function () {
spyOn(deviceSettings, "retrieve").andReturn("tin_cans");
diff --git a/test/unit/phonegap/notification.js b/test/unit/phonegap/notification.js
index 51791cc..3ba7dba 100644
--- a/test/unit/phonegap/notification.js
+++ b/test/unit/phonegap/notification.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
describe("phonegap notifications", function () {
- var notification = require('ripple/platform/phonegap/1.0/notification'),
+ var notification = require('ripple/platform/phonegap/1.0.0/notification'),
goodVibrations = require('ripple/ui/plugins/goodVibrations'),
notifications = require('ripple/notifications');
diff --git a/test/unit/platform.js b/test/unit/platform.js
index 382f392..7b433ed 100644
--- a/test/unit/platform.js
+++ b/test/unit/platform.js
@@ -18,12 +18,14 @@
db = require('ripple/db'),
app = require('ripple/app'),
builder = require('ripple/platform/builder'),
+ utils = require('ripple/utils'),
event = require('ripple/event'),
_console = require('ripple/console');
beforeEach(function () {
spyOn(db, "retrieveObject");
spyOn(_console, "log");
+ spyOn(utils, "queryString").andReturn({});
spyOn(builder, "build").andReturn({
into: function () {}
});
@@ -33,9 +35,9 @@
it("getList should return correct value", function () {
var returnedPlatforms = platform.getList();
- expect(typeof returnedPlatforms["phonegap"]["1.0"].id).toEqual("string");
- expect(typeof returnedPlatforms["phonegap"]["1.0"].name).toEqual("string");
- expect(typeof returnedPlatforms["phonegap"]["1.0"].type).toEqual("string");
+ expect(typeof returnedPlatforms["phonegap"]["1.0.0"].id).toEqual("string");
+ expect(typeof returnedPlatforms["phonegap"]["1.0.0"].name).toEqual("string");
+ expect(typeof returnedPlatforms["phonegap"]["1.0.0"].type).toEqual("string");
});
describe("when changing the environment", function () {
diff --git a/test/unit/resizer.js b/test/unit/resizer.js
index 23b1922..08c8b38 100644
--- a/test/unit/resizer.js
+++ b/test/unit/resizer.js
@@ -25,7 +25,6 @@
devices = require('ripple/devices'),
event = require('ripple/event'),
db = require('ripple/db'),
- emulatorBridge = require('ripple/emulatorBridge'),
platform = require('ripple/platform'),
_console = require('ripple/console'),
resizer = require('ripple/resizer');
diff --git a/test/unit/utils.js b/test/unit/utils.js
index 7e005d5..35e3938 100644
--- a/test/unit/utils.js
+++ b/test/unit/utils.js
@@ -550,6 +550,42 @@
});
});
+ describe("queryString", function () {
+
+ it("can handle a location with no params", function () {
+ spyOn(utils, "location").andReturn({
+ search: ""
+ });
+
+ expect(utils.queryString()).toEqual({});
+ });
+
+ it("can handle a location with a single qs", function () {
+ spyOn(utils, "location").andReturn({
+ search: "?foo=bar"
+ });
+
+ expect(utils.queryString()).toEqual({foo: "bar"});
+ });
+
+ it("can handle a location with a couple of qs", function () {
+ spyOn(utils, "location").andReturn({
+ search: "?foo=bar&baz=fred"
+ });
+
+ expect(utils.queryString()).toEqual({foo: "bar", baz: "fred"});
+ });
+
+ it("lowercases the values", function () {
+ spyOn(utils, "location").andReturn({
+ search: "?YO=Momma&Is=soFat"
+ });
+
+ expect(utils.queryString()).toEqual({yo: "momma", is: "sofat"});
+
+ });
+ });
+
describe("rippleLocation", function () {
describe("properly returns the base path for ripple-ui", function () {
it("returns the base path when index.html is used", function () {
diff --git a/test/unit/webworks.bb10/event.js b/test/unit/webworks.bb10/event.js
index 805c527..966a406 100644
--- a/test/unit/webworks.bb10/event.js
+++ b/test/unit/webworks.bb10/event.js
@@ -23,7 +23,7 @@
var cb = jasmine.createSpy();
target.addEventListener("pause", cb);
- event.trigger("appPause", null, true);
+ event.trigger("AppPause", null, true);
expect(cb).toHaveBeenCalled();
});
@@ -33,7 +33,7 @@
target.addEventListener("pause", cb);
target.addEventListener("pause", cb2);
- event.trigger("appPause", null, true);
+ event.trigger("AppPause", null, true);
expect(cb).toHaveBeenCalled();
expect(cb2).toHaveBeenCalled();
});
@@ -43,7 +43,7 @@
target.addEventListener("pause", cb);
target.addEventListener("pause", cb);
- event.trigger("appPause", null, true);
+ event.trigger("AppPause", null, true);
expect(cb.callCount).toBe(1);
});
@@ -65,7 +65,7 @@
});
target.addEventListener("resume", cb);
- event.trigger("appResume", null, true);
+ event.trigger("AppResume", null, true);
expect(cb).toHaveBeenCalled();
});
@@ -91,7 +91,7 @@
target.addEventListener("pause", cb);
target.removeEventListener("pause", cb);
- event.trigger("appPause", null, true);
+ event.trigger("AppPause", null, true);
expect(cb).not.toHaveBeenCalled();
});
});
@@ -103,19 +103,19 @@
spyOn(settings, "retrieve").andReturn("22");
});
- it("triggers the pause event on appPause", function () {
+ it("triggers the pause event on AppPause", function () {
var cb = jasmine.createSpy();
target.addEventListener("pause", cb);
- event.trigger("appPause", null, true);
+ event.trigger("AppPause", null, true);
expect(cb).toHaveBeenCalled();
});
- it("triggers the resume event on appResume", function () {
+ it("triggers the resume event on AppResume", function () {
var cb = jasmine.createSpy();
target.addEventListener("resume", cb);
- event.trigger("appResume", null, true);
+ event.trigger("AppResume", null, true);
expect(cb).toHaveBeenCalled();
});
diff --git a/test/unit/webworks/fsCache.js b/test/unit/webworks/fsCache.js
index 82fb7b4..e68ab96 100644
--- a/test/unit/webworks/fsCache.js
+++ b/test/unit/webworks/fsCache.js
@@ -13,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-var fs = require('ripple/dbfs'),
- event = require('ripple/event'),
- FileProperties = require('ripple/platform/webworks.core/2.0.0/client/FileProperties'),
- bbUtils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
- cache = require('ripple/platform/webworks.core/2.0.0/fsCache');
-
describe("fsCache", function () {
- var _root = [{
+ var fs = require('ripple/dbfs'),
+ event = require('ripple/event'),
+ FileProperties = require('ripple/platform/webworks.core/2.0.0/client/FileProperties'),
+ bbUtils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
+ cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
+ _root = [{
fullPath: "/dude",
name: "dude",
isDirectory: false,
diff --git a/test/unit/webworks/select.js b/test/unit/webworks/select.js
index 37a351b..6ca3190 100644
--- a/test/unit/webworks/select.js
+++ b/test/unit/webworks/select.js
@@ -264,6 +264,13 @@
expect(result.length).toBe(1);
});
+
+ it("can handle a search where the field doesn't exist", function () {
+ var fe = new FilterExpression("bloodType", "REGEX", "^B*"),
+ result = select.from(orders).where(fe);
+
+ expect(result.length).toBe(0);
+ });
});
it("returns an empty array if left is a filter expression but right isn't", function () {
diff --git a/test/unit/widgetConfig.js b/test/unit/widgetConfig.js
index 1aee889..d01dbf7 100644
--- a/test/unit/widgetConfig.js
+++ b/test/unit/widgetConfig.js
@@ -28,7 +28,7 @@
describe("phonegap config", function () {
beforeEach(function () {
- spyOn(platform, "current").andReturn(require('ripple/platform/phonegap/1.0/spec'));
+ spyOn(platform, "current").andReturn(require('ripple/platform/phonegap/1.0.0/spec'));
});
it("validateNumberOfArguments_Throws_Exception_If_No_Arguments", function () {