diff --git a/.csslintrc b/.csslintrc new file mode 100644 index 00000000..9a5e3bb4 --- /dev/null +++ b/.csslintrc @@ -0,0 +1,17 @@ +[ + "floats", + "overqualified-elements", + "zero-units", + "universal-selector", + "import", + "font-faces", + "vendor-prefix", + "text-indent", + "gradients", + "compatible-vendor-prefixes", + "adjoining-classes", + "known-properties", + "empty-rules", + "duplicate-properties", + "display-property-grouping" +] diff --git a/.gitmodules b/.gitmodules index 28ffdbdd..43d6ba0e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = http://github.com/pivotal/jasmine.git [submodule "thirdparty/node-XMLHttpRequest"] path = thirdparty/node-XMLHttpRequest - url = http://github.com/tinyhippos/node-XMLHttpRequest.git + url = http://github.com/driverdan/node-XMLHttpRequest.git [submodule "thirdparty/browser-require"] path = thirdparty/browser-require url = https://github.com/rsms/browser-require.git diff --git a/.jshintrc b/.jshintrc index b7ed2501..dbc9827b 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,6 +1,10 @@ { "predef": [ + "stagewebview", + "FileReader", "FileWriter", + "WebKitBlobBuilder", "BlobBuilder", "webkitNotifications", + "FileError", "DOMDocument", "$", "it", "describe", "xit", "xdescribe", diff --git a/Jakefile b/Jakefile index 1cfd6c66..137e6931 100644 --- a/Jakefile +++ b/Jakefile @@ -30,7 +30,7 @@ task('test', [], function () { desc("boot test server for running all tests in the browser"); task('btest', [], require('./build/btest')); -desc("runs jshint - jake lint [path1,path2]"); +desc("runs jshint + csslint - jake lint [path1] [path2]"); task('lint', [], function () { require('./build/lint')(complete, Array.prototype.slice.call(arguments)); }, true); diff --git a/LICENSE b/LICENSE index 834eebf8..cb4dcce4 100644 --- a/LICENSE +++ b/LICENSE @@ -266,13 +266,6 @@ licensed under the MIT (MIT-LICENSE.txt) http://docs.jquery.com/UI -------------------------------------------------------- -* jQuery.Dimensions * - -Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net) -Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) -and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - ------------------------------------------------------- * jQuery Tooltip plugin * @@ -285,15 +278,6 @@ Dual licensed under the MIT and GPL licenses: http://www.opensource.org/licenses/mit-license.php http://www.gnu.org/licenses/gpl.html -------------------------------------------------------- -* Sinon * - -https://github.com/cjohansen/Sinon.JS - -Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no - -licensed under the BSD License - ------------------------------------------------------- * Math.uuid.js (v1.4) * diff --git a/build/btest.js b/build/btest.js index 3ebf5d7d..7c366845 100644 --- a/build/btest.js +++ b/build/btest.js @@ -14,19 +14,29 @@ * limitations under the License. */ module.exports = function () { - var express = require('express'), - connect = require('connect'), + var connect = require('connect'), fs = require('fs'), sys = require('sys'), utils = require('./build/utils'), libs = [], tests = [], - app = express.createServer( - connect.static(__dirname + "/../lib/"), - connect.static(__dirname + "/../") - ), html = fs.readFileSync(__dirname + "/btest/test.html", "utf-8"), - doc, modules, specs; + doc, + modules, + specs, + 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); + }); + }) + ); utils.collect(__dirname + "/../lib", libs); utils.collect(__dirname + "/../test", tests); @@ -45,11 +55,6 @@ module.exports = function () { doc = html.replace(//g, specs).replace(/"##FILES##"/g, modules); - app.get('/', function (req, res) { - res.header("Cache-Control", "no-cache"); - res.send(doc); - }); - app.listen(3000); sys.puts("Test Server running on:"); diff --git a/build/btest/test.html b/build/btest/test.html index 851862ee..05ff6a21 100644 --- a/build/btest/test.html +++ b/build/btest/test.html @@ -25,9 +25,9 @@ - - - + + + - - - @@ -83,7 +80,6 @@ - @@ -91,13 +87,6 @@ require.define('thirdparty/Math.uuid', function (require, module, exports) {}); - - -

- -

Join the Ripple Community

diff --git a/lib/ripple.js b/lib/ripple.js index 2417d28b..52aab3e4 100644 --- a/lib/ripple.js +++ b/lib/ripple.js @@ -16,23 +16,23 @@ var omgwtf = require('ripple/omgwtf'), db = require('ripple/db'), xhr = require('ripple/xhr'), - accelerometer = require('ripple/accelerometer'), geo = require('ripple/geo'), - fileSystem = require('ripple/fileSystem'), + fs = require('ripple/fs'), platform = require('ripple/platform'), - builder = require('ripple/platform/builder'), devices = require('ripple/devices'), widgetConfig = require('ripple/widgetConfig'), deviceSettings = require('ripple/deviceSettings'), ui = require('ripple/ui'), _self = { boot: function (booted) { + // techdebt (event registration timing) + require('ripple/platform/webworks.core/2.0.0/fsCache'); + jWorkflow.order(omgwtf.initialize, omgwtf) .andThen(db.initialize, db) .andThen(xhr.initialize, xhr) - .andThen(accelerometer.initialize, accelerometer) .andThen(geo.initialize, geo) - .andThen(fileSystem.initialize, fileSystem) + .andThen(fs.initialize, fs) .andThen(devices.initialize, devices) .andThen(platform.initialize, platform) .andThen(widgetConfig.initialize, widgetConfig) diff --git a/lib/ripple/accelerometer.js b/lib/ripple/accelerometer.js index 366c6418..588c1589 100644 --- a/lib/ripple/accelerometer.js +++ b/lib/ripple/accelerometer.js @@ -32,9 +32,6 @@ function _validateAccelerometerInfo(x, y, z) { } _self = { - initialize: function () { - }, - getInfo: function () { return utils.copy(_motion); }, @@ -57,7 +54,7 @@ _self = { else { _motion = { acceleration: new Acceleration(0, 0, 0), - accelerationIncludingGravity: new Acceleration(0, 0, 0), + accelerationIncludingGravity: new Acceleration(0, 0, -9.81), rotationRate: new Rotation(0, 0, 0), orientation: new Rotation(0, 0, 0), timestamp: new Date().getTime() @@ -76,7 +73,11 @@ _self = { }, shake: function (shakeXtimes) { - var id, count = 1, stopCount = shakeXtimes || 17; + var id, + count = 1, + stopCount = shakeXtimes || 17, + oldX = _motion.accelerationIncludingGravity.x; + id = setInterval(function () { var freq = 1, @@ -84,7 +85,7 @@ _self = { value = Math.round(amp * Math.sin(freq * count * (180 / Math.PI)) * 100) / 100; if (count > stopCount) { - _motion.accelerationIncludingGravity.x = 0; + _motion.accelerationIncludingGravity.x = oldX; event.trigger("AccelerometerInfoChangedEvent", [_motion]); clearInterval(id); return; diff --git a/lib/ripple/app.js b/lib/ripple/app.js index a4e3804d..e3820b3f 100644 --- a/lib/ripple/app.js +++ b/lib/ripple/app.js @@ -40,7 +40,7 @@ _self = { // TODO: WTF figure this out, platform is empty object when require at require time // could be that the new platform _getBuilder code dies when called, beforre it is initialized var spec = require('ripple/platform').current(); - if (typeof spec.config.validateVersion === "function") { + if (typeof spec.config.validateVersion === "function" && configValidationObject) { return spec.config.validateVersion(configValidationObject); } diff --git a/lib/ripple/bootstrap.js b/lib/ripple/bootstrap.js index 7e52ec94..839f7d71 100644 --- a/lib/ripple/bootstrap.js +++ b/lib/ripple/bootstrap.js @@ -14,7 +14,9 @@ * limitations under the License. */ var _bound, - _console = require('ripple/console'); + _console = require('ripple/console'), + db = require('ripple/db'), + _CURRENT_URL = "current-url"; function _bindObjects(frame) { if (!frame.contentWindow.tinyHippos) { @@ -81,7 +83,7 @@ function _post(src) { var event = require('ripple/event'), frame = _createFrame(src); - _console.log("Ripple :: Initialization Finished (Make it so.)"); + _console.log("Initialization Finished (Make it so.)"); frame.onload = function () { var bootLoader = document.querySelector("#emulator-booting"), @@ -106,6 +108,7 @@ function _post(src) { frame.onload = function () { var url = frame.contentWindow.location.href; document.getElementById("viewport-container").removeChild(frame); + event.trigger("FrameHistoryChange", [url]); _console.log("-----------------------------------------------------------"); _console.log("Pay no attention to that man behind the curtain."); _console.log("Environment Warning up again (Set main batteries to auto-fire cycle)"); @@ -120,16 +123,21 @@ function _post(src) { } function _bootstrap() { - _console.log("-----------------------------------------------------------"); - _console.log("There be dragons above here!"); + // TODO: figure this out for web and ext + //_console.log("-----------------------------------------------------------"); + //_console.log("There be dragons above here!"); _console.log("Ripple :: Environment Warming Up (Tea. Earl Gray. Hot.)"); - window.tinyHippos = require('ripple'); tinyHippos.boot(function () { - var src = document.documentURI.replace(/enableripple=true[&]/i, "").replace(/[\?&]$/, ""); - _post(src); + var ui = require('ripple/ui'), + //HACK: this seems wrong and makes babies cry + uri = ui.registered('omnibar') ? + db.retrieve(_CURRENT_URL) || "about:blank" : + document.documentURI.replace(/enableripple=true[&]/i, "").replace(/[\?&]$/, ""); + + _post(uri); delete tinyHippos.boot; }); } diff --git a/lib/ripple/config.js b/lib/ripple/config.js deleted file mode 100644 index f414e074..00000000 --- a/lib/ripple/config.js +++ /dev/null @@ -1,43 +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 exception = require('ripple/exception'), - _environmentConfiguration = { - "Production": { - "apiURL": "http://api.tinyhippos.com" - }, - - "Demo": { - "apiURL": "http://apidemo.tinyhippos.com" - }, - - "Local": { - "apiURL": "http://127.0.0.1:4567" - } - }, - _environment = "Production"; - -module.exports = { - getAPIURL: function () { - return _environmentConfiguration[_environment].apiURL; - }, - - setEnvironment: function (env) { - if (!_environmentConfiguration[env]) { - exception.raise(exception.types.Application, "No configuration found for selected environment: " + env); - } - _environment = env; - } -}; diff --git a/lib/ripple/constants.js b/lib/ripple/constants.js index 0f95f772..07dddc49 100644 --- a/lib/ripple/constants.js +++ b/lib/ripple/constants.js @@ -14,11 +14,15 @@ * limitations under the License. */ module.exports = { + "API_URL": "http://api.tinyhippos.com", + "SERVICES": { "GOOGLE_MAPS_URI": "http://maps.google.com/maps/api/staticmap?size=476x476&maptype=roadmap", "GOOGLE_MAPS_API_KEY": "ABQIAAAA-CaPZHXR-0Tzhui_h6gpjhSE_2rGlnYiB7L-ZGVwgaut5s7OYRSlBAaHCzBuZf2_23_vrCOfPxXHjA" }, + "FS_SIZE": 1024 * 1024 * 10, + "COMMON": { "APPLICATION_STATE": "ui-application-state-", "PREFIX": "tinyhippos-", @@ -40,7 +44,7 @@ module.exports = { "USER_AGENT_DEFAULT": "default", "APPLICATIONS_CONTAINER_ID": "widget-applications-content", "STORAGE_CLEAR_BUTTON_ID": "preferences-clear-button", - "CHANGE_PLATFORM_BUTTON_ID": "platform-device-update", + "CHANGE_PLATFORM_BUTTON_ID": "change-platform", "AJAX_LOADER_CONTAINER_CLASS": ".loader", "IRRELEVANT_CLASS": "irrelevant", "MULTIMEDIA_VOLUME_SLIDER_ID": "media-volume", @@ -65,7 +69,7 @@ module.exports = { "PLATFORM": { "SAVED_KEY": "api-key", "DEFAULT": { - "name": "wac", + "name": "phonegap", "version": "1.0" } }, @@ -142,10 +146,6 @@ module.exports = { "CLOSE_BUTTON_CLASS": "panel-notification-closebtn", "MESSAGE_TEXT_CONTAINER_CLASS": "panel-notification-text", "CSS_PREFIX": "panel-notification-", - "TYPES": { - "NORMAL": "normal", - "ERROR": "error" - }, "STATE_TYPES": { "OPEN": 1, "CLOSE": 2 @@ -210,34 +210,5 @@ module.exports = { "XHR": { "PROXY_DISABLED_BUTTON": "settings-xhrproxy-disabled" - }, - - "PLATFORMS": { - "WAC": { - "APPLICATIONS": [ - "ALARM", - "BROWSER", - "CALCULATOR", - "CALENDAR", - "CAMERA", - "CONTACTS", - "FILES", - "GAMES", - "MAIL", - "MEDIAPLAYER", - "MESSAGING", - "PHONECALL", - "PICTURES", - "PROG_MANAGER", - "SETTINGS", - "TASKS", - "WIDGET_MANAGER" - ], - "DEVICE": { - "WIDGET_ENGINE_NAME": "Generic", - "WIDGET_ENGINE_PROVIDER": "tinyHippos", - "WIDGET_ENGINE_VERSION": "x.x" - } - } } }; diff --git a/lib/ripple/db.js b/lib/ripple/db.js index 46fab25a..90a8962c 100644 --- a/lib/ripple/db.js +++ b/lib/ripple/db.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var self, +var _self, _db, utils = require('ripple/utils'), constants = require('ripple/constants'), @@ -101,41 +101,41 @@ function _removeAll(prefix, callback) { }); } -self = module.exports = { - save: function save(key, value, prefix, callback) { +_self = { + save: function (key, value, prefix, callback) { _save(key, value, prefix, callback); event.trigger("StorageUpdatedEvent"); }, - saveObject: function saveObject(key, obj, prefix, callback) { + saveObject: function (key, obj, prefix, callback) { _save(key, JSON.stringify(obj), prefix, callback); event.trigger("StorageUpdatedEvent"); }, - retrieve: function retrieve(key, prefix) { + retrieve: function (key, prefix) { return _retrieve(key, prefix); }, - retrieveObject: function retrieveObject(key, prefix) { + retrieveObject: function (key, prefix) { var retrievedValue = _retrieve(key, prefix); return retrievedValue ? JSON.parse(retrievedValue) : retrievedValue; }, - retrieveAll: function retrieveAll(prefix, callback) { + retrieveAll: function (prefix, callback) { return _retrieveAll(prefix, callback); }, - remove: function remove(key, prefix, callback) { + remove: function (key, prefix, callback) { event.trigger("StorageUpdatedEvent"); _remove(key, prefix, callback); }, - removeAll: function removeAll(prefix, callback) { + removeAll: function (prefix, callback) { _removeAll(prefix, callback); event.trigger("StorageUpdatedEvent"); }, - initialize: function initialize(previous, baton) { + initialize: function (previous, baton) { baton.take(); _db = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence', 2 * 1024 * 1024); @@ -155,3 +155,5 @@ self = module.exports = { }); } }; + +module.exports = _self; diff --git a/lib/ripple/devices.js b/lib/ripple/devices.js index b8bc16a1..6a85c754 100644 --- a/lib/ripple/devices.js +++ b/lib/ripple/devices.js @@ -24,7 +24,7 @@ var _self, event.on("HardwareKeyDefault", function (key) { if (key === 0 || key === "0") { //back button key - require('ripple/emulatorBridge').getWidgetWindow().history.back(); + require('ripple/emulatorBridge').window().history.back(); } }); @@ -52,9 +52,10 @@ function _currentID() { _self = module.exports = { initialize: function () { _devices = [ - "Aero", "Bold9700", "Bold9900", + "Curve9300", + "Curve9350-9360-9370", "FWVGA", "G1", "HPPre3", @@ -70,17 +71,17 @@ _self = module.exports = { "NokiaN97", "PalmPre", "PalmPre2", + "Pearl9100", "Playbook", "QVGA", - "SamsungH1", - "SamsungM1", + "Style9670", "Tattoo", - "Torch", + "Torch9800", + "Torch9810", + "Torch9860-9850", "Wave", "WQVGA", - "WVGA", - "XperiaX10", - "XperiaX10Mini" + "WVGA" ].reduce(function (hash, deviceID) { hash[deviceID] = require('ripple/devices/' + deviceID); return hash; diff --git a/lib/ripple/devices/Bold9700.js b/lib/ripple/devices/Bold9700.js index 4fe972b1..fb5aa100 100644 --- a/lib/ripple/devices/Bold9700.js +++ b/lib/ripple/devices/Bold9700.js @@ -16,9 +16,9 @@ module.exports = { "id": "Bold9700", - "name": "Blackberry Bold 9700", + "name": "BlackBerry Bold 9700", "model": "9700", - "osName": "Blackberry OS", + "osName": "BlackBerry OS", "uuid": "42", "osVersion": "6", "firmware": "6", diff --git a/lib/ripple/devices/Bold9700/skin.css b/lib/ripple/devices/Bold9700/skin.css index 4762c6cc..5dab8e5f 100644 --- a/lib/ripple/devices/Bold9700/skin.css +++ b/lib/ripple/devices/Bold9700/skin.css @@ -17,8 +17,8 @@ Bold9700 (561x1009) offset (40x181)*/ .viewport-wrapper-Bold9700 { - width:480px; - height:360px; + width: 480px; + height: 360px; border: none; } @@ -44,9 +44,11 @@ position: relative; padding: 181px 0 0 40px; width: 521px; - height:828px; + height: 828px; margin: 0 auto; border: none; -webkit-box-shadow: none; - background: url('../images/Bold9700.png') no-repeat; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Bold9700.png') no-repeat; } diff --git a/lib/ripple/devices/Bold9900.js b/lib/ripple/devices/Bold9900.js index 5ce6606e..859ad1d7 100644 --- a/lib/ripple/devices/Bold9900.js +++ b/lib/ripple/devices/Bold9900.js @@ -16,9 +16,9 @@ module.exports = { "id": "Bold9900", - "name": "Blackberry Bold 9900", + "name": "BlackBerry Bold 9900", "model": "9900", - "osName": "Blackberry OS", + "osName": "BlackBerry OS", "uuid": "42", "osVersion": "7", "firmware": "7", diff --git a/lib/ripple/devices/Bold9900/skin.css b/lib/ripple/devices/Bold9900/skin.css index a4f3e174..d0140378 100644 --- a/lib/ripple/devices/Bold9900/skin.css +++ b/lib/ripple/devices/Bold9900/skin.css @@ -17,8 +17,8 @@ Bold9900 (726x1258) offset (41x196)*/ .viewport-wrapper-Bold9900 { - width:640px; - height:480px; + width: 640px; + height: 480px; border: none; } @@ -44,9 +44,11 @@ position: relative; padding: 196px 0 0 41px; width: 685px; - height:1062px; + height: 1062px; margin: 0 auto; border: none; -webkit-box-shadow: none; - background: url('../images/Bold9900.png') no-repeat; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Bold9900.png') no-repeat; } diff --git a/lib/ripple/devices/Curve9300.js b/lib/ripple/devices/Curve9300.js new file mode 100644 index 00000000..48c46195 --- /dev/null +++ b/lib/ripple/devices/Curve9300.js @@ -0,0 +1,58 @@ +/* + * 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. + */ +module.exports = { + + "id": "Curve9300", + "name": "BlackBerry Curve 9300", + "model": "9300", + "osName": "BlackBerry OS", + "uuid": "42", + "osVersion": "6", + "firmware": "6", + "manufacturer": "Research In Motion", + + "skin": "Curve9300", + + "capabilities": [ + "location.gps", + "location.maps", + "media.audio.capture", + "media.video.capture", + "media.recording", + "storage.memorycard", + "network.bluetooth", + "network.wlan", + "network.3gpp" + ], + + "screen": { + "width": 320, + "height": 240 + }, + "viewPort": { + "portrait": { + "width": 320, + "height": 240, + "paddingTop": 0, + "paddingLeft": 0 + } + }, + + "ppi": 163, + "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+", + "browser": ["Webkit"], + "platforms": ["web", "phonegap", "webworks.handset"] +}; diff --git a/lib/ripple/devices/Curve9300/skin.css b/lib/ripple/devices/Curve9300/skin.css new file mode 100644 index 00000000..0b8308e2 --- /dev/null +++ b/lib/ripple/devices/Curve9300/skin.css @@ -0,0 +1,54 @@ +/* + * 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. + */ +/* ------------------------------> + Curve9300 (373x674) offset (27x119)*/ + +.viewport-wrapper-Curve9300 { + width: 320px; + height: 240px; + border: none; +} + +.menu-button-wrapper-Curve9300{ + position: relative; + display: inline-block; + margin: 30px 0 0 60px; + width: 60px; + height: 55px; + cursor: pointer; +} + +.back-button-wrapper-Curve9300 { + position: relative; + display: inline-block; + margin: 0 0 0 77px; + width: 60px; + height: 55px; + cursor: pointer; +} + +.device-wrapper-Curve9300 { + position: relative; + padding: 119px 0 0 27px; + width: 346px; + height: 555px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Curve9300.png') no-repeat; +} diff --git a/lib/ripple/devices/Curve9350-9360-9370.js b/lib/ripple/devices/Curve9350-9360-9370.js new file mode 100644 index 00000000..26c5aac0 --- /dev/null +++ b/lib/ripple/devices/Curve9350-9360-9370.js @@ -0,0 +1,59 @@ +/* + * 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. + */ +module.exports = { + + "id": "Curve9350-9360-9370", + "name": "BlackBerry Curve 9350/9360/9370", + "model": "9350-9360-9370", + "osName": "BlackBerry OS", + "uuid": "42", + "osVersion": "7", + "firmware": "7", + "manufacturer": "Research In Motion", + + "skin": "Curve9350-9360-9370", + + "capabilities": [ + "input.touch", + "location.gps", + "location.maps", + "media.audio.capture", + "media.video.capture", + "media.recording", + "storage.memorycard", + "network.bluetooth", + "network.wlan", + "network.3gpp" + ], + + "screen": { + "width": 480, + "height": 360 + }, + "viewPort": { + "portrait": { + "width": 480, + "height": 360, + "paddingTop": 0, + "paddingLeft": 0 + } + }, + + "ppi": 246.00, + "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9350; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1", + "browser": ["Webkit"], + "platforms": ["web", "phonegap", "webworks.handset"] +}; diff --git a/lib/ripple/devices/Curve9350-9360-9370/skin.css b/lib/ripple/devices/Curve9350-9360-9370/skin.css new file mode 100644 index 00000000..a0d7ecee --- /dev/null +++ b/lib/ripple/devices/Curve9350-9360-9370/skin.css @@ -0,0 +1,54 @@ +/* + * 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. + */ +/* ------------------------------> + Curve9350-9360-9370 (560x998) offset (42x172)*/ + +.viewport-wrapper-Curve9350-9360-9370 { + width: 480px; + height: 360px; + border: none; +} + +.menu-button-wrapper-Curve9350-9360-9370{ + position: relative; + display: inline-block; + margin: 30px 0 0 85px; + width: 100px; + height: 80px; + cursor: pointer; +} + +.back-button-wrapper-Curve9350-9360-9370 { + position: relative; + display: inline-block; + margin: 0 0 0 105px; + width: 100px; + height: 80px; + cursor: pointer; +} + +.device-wrapper-Curve9350-9360-9370 { + position: relative; + padding: 172px 0 0 42px; + width: 518px; + height: 826px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Curve9350-9360-9370.png') no-repeat; +} diff --git a/lib/ripple/devices/FWVGA.js b/lib/ripple/devices/FWVGA.js index 3ce387e5..892e0059 100644 --- a/lib/ripple/devices/FWVGA.js +++ b/lib/ripple/devices/FWVGA.js @@ -46,6 +46,6 @@ module.exports = { "browser": ["Generic"], "ppi": 96, - "platforms": ["web", "wac", "opera", "vodafone", "phonegap"], + "platforms": ["web", "phonegap"], "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2" }; diff --git a/lib/ripple/devices/G1.js b/lib/ripple/devices/G1.js index 438868dd..5e7280b1 100644 --- a/lib/ripple/devices/G1.js +++ b/lib/ripple/devices/G1.js @@ -45,7 +45,7 @@ module.exports = { "browser": ["Webkit", "Presto"], "ppi": 180.28, - "platforms": ["web", "wac", "phonegap", "vodafone"], + "platforms": ["web", "phonegap"], "userAgent": "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2", "notes": { diff --git a/lib/ripple/devices/HVGA.js b/lib/ripple/devices/HVGA.js index 4ea16863..687924fb 100644 --- a/lib/ripple/devices/HVGA.js +++ b/lib/ripple/devices/HVGA.js @@ -46,6 +46,6 @@ module.exports = { "browser": ["Generic"], "ppi": 96, - "platforms": ["web", "wac", "opera", "vodafone", "phonegap"], + "platforms": ["web", "phonegap"], "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2" }; diff --git a/lib/ripple/devices/Legend.js b/lib/ripple/devices/Legend.js index 4913fd6c..e3f716ed 100644 --- a/lib/ripple/devices/Legend.js +++ b/lib/ripple/devices/Legend.js @@ -42,29 +42,8 @@ module.exports = { } }, - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 320, - "height": 430, - "paddingTop": 50, - "paddingLeft": 0 - }, - "landscape": { - "width": 480, - "height": 270, - "paddingTop": 50, - "paddingLeft": 0 - } - } - } - } - }, - "ppi": 180.3, "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; fr-fr; HTC Legend 1.32.163.1 Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17", "browser": ["Webkit", "Presto"], - "platforms": ["web", "wac", "phonegap", "vodafone"] + "platforms": ["web", "phonegap"] }; diff --git a/lib/ripple/devices/Nexus.js b/lib/ripple/devices/Nexus.js index 48be4db5..ae72d92f 100644 --- a/lib/ripple/devices/Nexus.js +++ b/lib/ripple/devices/Nexus.js @@ -45,7 +45,7 @@ module.exports = { "ppi": 252.15, "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17", "browser": ["Webkit", "Presto"], - "platforms": ["web", "wac", "phonegap", "vodafone"], + "platforms": ["web", "phonegap"], "notes": { "1": "Specs" diff --git a/lib/ripple/devices/NokiaN97.js b/lib/ripple/devices/NokiaN97.js index bf6a7d41..9177ad49 100644 --- a/lib/ripple/devices/NokiaN97.js +++ b/lib/ripple/devices/NokiaN97.js @@ -14,7 +14,7 @@ * limitations under the License. */ module.exports = { - "id": "Nokia97", + "id": "NokiaN97", "name": "Nokia N97/5800 (touch)", "manufacturer": "Nokia", "model": "N97", @@ -42,29 +42,8 @@ module.exports = { } }, - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 360, - "height": 542, - "paddingTop": 98, - "paddingLeft": 0 - }, - "landscape": { - "width": 640, - "height": 262, - "paddingTop": 98, - "paddingLeft": 0 - } - } - } - } - }, - "ppi": 232, "browser": ["Webkit", "Presto"], "userAgent": "?", - "platforms": ["web", "wac", "vodafone", "phonegap"] + "platforms": ["web", "phonegap"] }; diff --git a/lib/ripple/devices/SamsungM1.js b/lib/ripple/devices/Pearl9100.js similarity index 51% rename from lib/ripple/devices/SamsungM1.js rename to lib/ripple/devices/Pearl9100.js index f129c190..92ed0373 100644 --- a/lib/ripple/devices/SamsungM1.js +++ b/lib/ripple/devices/Pearl9100.js @@ -14,44 +14,45 @@ * limitations under the License. */ module.exports = { - "id": "SamsungM1", - "name": "Samsung M1 (touch)", - "manufacturer": "Samsung", - "model": "M1", - "firmware": "n/a", - "osName": "LiMo", - "osVersion": "n/a", + + "id": "Pearl9100", + "name": "BlackBerry Pearl 9100", + "model": "9100", + "osName": "BlackBerry OS", + "uuid": "42", + "osVersion": "6", + "firmware": "6", + "manufacturer": "Research In Motion", + + "skin": "Pearl9100", + + "capabilities": [ + "location.gps", + "location.maps", + "media.audio.capture", + "media.video.capture", + "media.recording", + "storage.memorycard", + "network.bluetooth", + "network.wlan", + "network.3gpp" + ], "screen": { - "width": 240, + "width": 360, "height": 400 }, "viewPort": { "portrait": { - "width": 240, + "width": 360, "height": 400, "paddingTop": 0, "paddingLeft": 0 } }, - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 240, - "height": 330, - "paddingTop": 70, - "paddingLeft": 0 - } - } - } - } - }, - - "ppi": 146, + "ppi": 239, + "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9100; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+", "browser": ["Webkit"], - "userAgent": "?", - "platforms": ["web", "wac", "vodafone"] + "platforms": ["web", "phonegap", "webworks.handset"] }; diff --git a/lib/ripple/devices/Pearl9100/skin.css b/lib/ripple/devices/Pearl9100/skin.css new file mode 100644 index 00000000..4928c4e4 --- /dev/null +++ b/lib/ripple/devices/Pearl9100/skin.css @@ -0,0 +1,54 @@ +/* + * 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. + */ +/* ------------------------------> + Pearl9100 (455x969) offset (47x139)*/ + +.viewport-wrapper-Pearl9100 { + width: 360px; + height: 400px; + border: none; +} + +.menu-button-wrapper-Pearl9100{ + position: relative; + display: inline-block; + margin: 30px 0 0 65px; + width: 65px; + height: 75px; + cursor: pointer; +} + +.back-button-wrapper-Pearl9100 { + position: relative; + display: inline-block; + margin: 0 0 0 95px; + width: 65px; + height: 75px; + cursor: pointer; +} + +.device-wrapper-Pearl9100 { + position: relative; + padding: 139px 0 0 47px; + width: 408px; + height: 830px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Pearl9100.png') no-repeat; +} diff --git a/lib/ripple/devices/Playbook.js b/lib/ripple/devices/Playbook.js index c3eea0b8..8d89e830 100644 --- a/lib/ripple/devices/Playbook.js +++ b/lib/ripple/devices/Playbook.js @@ -16,9 +16,9 @@ module.exports = { "id": "Playbook", - "name": "Blackberry Playbook", + "name": "BlackBerry Playbook", "model": "Playbook", - "osName": "Blackberry Tablet OS (QNX)", + "osName": "BlackBerry Tablet OS (QNX)", "uuid": "42", "osVersion": "QNX", "firmware": "6", diff --git a/lib/ripple/devices/Playbook/skin.css b/lib/ripple/devices/Playbook/skin.css index 8feecd90..c0a96908 100644 --- a/lib/ripple/devices/Playbook/skin.css +++ b/lib/ripple/devices/Playbook/skin.css @@ -30,7 +30,9 @@ margin: 0 auto; border: none; -webkit-box-shadow: none; - background: url('../images/Playbook_landscape.png') no-repeat; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Playbook_landscape.png') no-repeat; } .viewport-wrapper-Playbook { @@ -48,5 +50,7 @@ margin: 0 auto; border: none; -webkit-box-shadow: none; - background: url('../images/Playbook.png') no-repeat; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Playbook.png') no-repeat; } diff --git a/lib/ripple/devices/QVGA.js b/lib/ripple/devices/QVGA.js index 21c7cbb7..659a6b80 100644 --- a/lib/ripple/devices/QVGA.js +++ b/lib/ripple/devices/QVGA.js @@ -44,6 +44,6 @@ module.exports = { "browser": ["Generic"], "ppi": 96, - "platforms": ["web", "wac", "opera", "vodafone", "phonegap"], + "platforms": ["web", "phonegap"], "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2" }; diff --git a/lib/ripple/devices/SamsungH1.js b/lib/ripple/devices/SamsungH1.js deleted file mode 100644 index 0ed536f5..00000000 --- a/lib/ripple/devices/SamsungH1.js +++ /dev/null @@ -1,57 +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. - */ -module.exports = { - "id": "SamsungH1", - "name": "Samsung H1 (touch)", - "manufacturer": "Samsung", - "model": "H1", - "firmware": "i8320BUIJ6", - "osName": "LiMo", - "osVersion": "n/a", - - "screen": { - "width": 480, - "height": 800 - }, - "viewPort": { - "portrait": { - "width": 480, - "height": 800, - "paddingTop": 0, - "paddingLeft": 0 - } - }, - - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 480, - "height": 684, - "paddingTop": 116, - "paddingLeft": 0 - } - } - } - } - }, - - "ppi": 265, - "browser": ["Webkit"], - "userAgent": "?", - "platforms": ["web", "wac", "vodafone"] -}; diff --git a/lib/ripple/devices/Style9670.js b/lib/ripple/devices/Style9670.js new file mode 100644 index 00000000..bad9ba4a --- /dev/null +++ b/lib/ripple/devices/Style9670.js @@ -0,0 +1,58 @@ +/* + * 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. + */ +module.exports = { + + "id": "Style9670", + "name": "BlackBerry Style 9670", + "model": "9670", + "osName": "BlackBerry OS", + "uuid": "42", + "osVersion": "6", + "firmware": "6", + "manufacturer": "Research In Motion", + + "skin": "Style9670", + + "capabilities": [ + "location.gps", + "location.maps", + "media.audio.capture", + "media.video.capture", + "media.recording", + "storage.memorycard", + "network.bluetooth", + "network.wlan", + "network.3gpp" + ], + + "screen": { + "width": 360, + "height": 400 + }, + "viewPort": { + "portrait": { + "width": 360, + "height": 400, + "paddingTop": 0, + "paddingLeft": 0 + } + }, + + "ppi": 200, + "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+", + "browser": ["Webkit"], + "platforms": ["web", "phonegap", "webworks.handset"] +}; diff --git a/lib/ripple/devices/Style9670/skin.css b/lib/ripple/devices/Style9670/skin.css new file mode 100644 index 00000000..2514ff06 --- /dev/null +++ b/lib/ripple/devices/Style9670/skin.css @@ -0,0 +1,54 @@ +/* + * 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. + */ +/* ------------------------------> + Style9670 (520x1338) offset (78x137)*/ + +.viewport-wrapper-Style9670 { + width: 360px; + height: 400px; + border: none; +} + +.menu-button-wrapper-Style9670{ + position: relative; + display: inline-block; + margin: 210px 0 0 50px; + width: 80px; + height: 100px; + cursor: pointer; +} + +.back-button-wrapper-Style9670 { + position: relative; + display: inline-block; + margin: 0 0 0 100px; + width: 80px; + height: 100px; + cursor: pointer; +} + +.device-wrapper-Style9670 { + position: relative; + padding: 137px 0 0 80px; + width: 440px; + height: 1201px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Style9670.png') no-repeat; +} diff --git a/lib/ripple/devices/Tattoo.js b/lib/ripple/devices/Tattoo.js index f37385e4..d85744bd 100644 --- a/lib/ripple/devices/Tattoo.js +++ b/lib/ripple/devices/Tattoo.js @@ -36,23 +36,8 @@ module.exports = { } }, - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 240, - "height": 283, - "paddingTop": 37, - "paddingLeft": 0 - } - } - } - } - }, - "ppi": 142.9, "userAgent": "Mozilla/5.0 (Linux; U; Android 1.6; en-us; HTC_TATTOO_A3288 Build/DRC79) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1", "browser": ["Webkit"], - "platforms": ["web", "wac", "phonegap", "vodafone"] + "platforms": ["web", "phonegap"] }; diff --git a/lib/ripple/devices/Torch.js b/lib/ripple/devices/Torch9800.js similarity index 93% rename from lib/ripple/devices/Torch.js rename to lib/ripple/devices/Torch9800.js index 9f1b1d1d..d39516cc 100644 --- a/lib/ripple/devices/Torch.js +++ b/lib/ripple/devices/Torch9800.js @@ -15,16 +15,16 @@ */ module.exports = { - "id": "Torch", - "name": "Blackberry Torch", + "id": "Torch9800", + "name": "BlackBerry Torch 9800", "model": "9800", - "osName": "Blackberry OS", + "osName": "BlackBerry OS", "uuid": "42", "osVersion": "6", "firmware": "6", "manufacturer": "Research In Motion", - "skin": "Torch", + "skin": "Torch9800", "capabilities": [ "input.touch", diff --git a/lib/ripple/devices/Torch/skin.css b/lib/ripple/devices/Torch9800/skin.css similarity index 66% rename from lib/ripple/devices/Torch/skin.css rename to lib/ripple/devices/Torch9800/skin.css index 4c870efa..32c20106 100644 --- a/lib/ripple/devices/Torch/skin.css +++ b/lib/ripple/devices/Torch9800/skin.css @@ -15,25 +15,28 @@ */ /* ------------------------------> - Torch Skin (444x779) offset (40x142)*/ -.viewport-wrapper-Torch { - width:360px; - height:480px; + Torch9800 Skin (444x779) offset (40x142)*/ + +.viewport-wrapper-Torch9800 { + width: 360px; + height: 480px; border: none; } -.device-wrapper-Torch { +.device-wrapper-Torch9800 { position: relative; padding: 142px 0 0 40px; - width:404px; - height:637px; + width: 404px; + height: 637px; margin: 0 auto; border: none; -webkit-box-shadow: none; - background: url('../images/Torch.png') no-repeat; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Torch9800.png') no-repeat; } -.menu-button-wrapper-Torch { +.menu-button-wrapper-Torch9800 { position: relative; display: inline-block; margin: 32px 0 0 75px; @@ -42,7 +45,7 @@ cursor: pointer; } -.back-button-wrapper-Torch { +.back-button-wrapper-Torch9800 { position: relative; display: inline-block; margin: 0 0 0 92px; @@ -51,38 +54,37 @@ cursor: pointer; } -.viewport-wrapper-landscape-Torch { +.viewport-wrapper-landscape-Torch9800 { margin: -99px 0 0 103px; - width:480px; - height:360px; + width: 480px; + height: 360px; border: none; } - -.device-wrapper-landscape-Torch { +.device-wrapper-landscape-Torch9800 { position: relative; padding: 142px 0 0 40px; - width:739px; - height:302px; + width: 739px; + height: 302px; margin: 0 auto; border: none; -webkit-box-shadow: none; - background: url('../images/Torch_landscape.png') no-repeat; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Torch9800_landscape.png') no-repeat; } -.menu-button-wrapper-landscape-Torch{ +.menu-button-wrapper-landscape-Torch9800{ position: relative; - display: inline-block; margin: -137px 0 0 618px; width: 55px; height: 65px; cursor: pointer; } -.back-button-wrapper-landscape-Torch { +.back-button-wrapper-landscape-Torch9800 { position: relative; - display: inline-block; - margin: -287px 0 0 618px; + margin: -212px 0 0 618px; width: 55px; height: 65px; cursor: pointer; diff --git a/lib/ripple/devices/Aero.js b/lib/ripple/devices/Torch9810.js similarity index 54% rename from lib/ripple/devices/Aero.js rename to lib/ripple/devices/Torch9810.js index f044fefa..de6eee9e 100644 --- a/lib/ripple/devices/Aero.js +++ b/lib/ripple/devices/Torch9810.js @@ -14,38 +14,52 @@ * limitations under the License. */ module.exports = { - "group": "Dell", - "id": "Areo", - "name": "Dell Aero", - "osName": "Android", - "osVersion": "1.5", - "manufacturer": "Dell", - "model": "Aero", + "id": "Torch9810", + "name": "BlackBerry Torch 9810", + "model": "9810", + "osName": "BlackBerry OS", "uuid": "42", - "firmware": "Android", + "osVersion": "7", + "firmware": "7", + "manufacturer": "Research In Motion", + + "skin": "Torch9810", + + "capabilities": [ + "input.touch", + "location.gps", + "location.maps", + "media.audio.capture", + "media.video.capture", + "media.recording", + "storage.memorycard", + "network.bluetooth", + "network.wlan", + "network.3gpp" + ], "screen": { - "width": 360, + "width": 480, "height": 640 }, "viewPort": { "portrait": { - "width": 360, + "width": 480, "height": 640, "paddingTop": 0, "paddingLeft": 0 }, "landscape": { "width": 640, - "height": 360, + "height": 480, "paddingTop": 0, "paddingLeft": 0 } }, + "ppi": 253, + "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9810; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1", "browser": ["Webkit"], - "ppi": 209.8, - "platforms": ["web"], - "userAgent": "Mozilla/5.0 (Linux; U; Android 1.5; en-us; Dell Aero Build/MASTER) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1" + "platforms": ["web", "phonegap", "webworks.handset"] }; diff --git a/lib/ripple/devices/Torch9810/skin.css b/lib/ripple/devices/Torch9810/skin.css new file mode 100644 index 00000000..68e32c00 --- /dev/null +++ b/lib/ripple/devices/Torch9810/skin.css @@ -0,0 +1,91 @@ +/* + * 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. + */ + +/* ------------------------------> + Torch9810 Skin (591x1048) offset (55x191)*/ + +.viewport-wrapper-Torch9810 { + width: 480px; + height: 640px; + border: none; +} + +.device-wrapper-Torch9810 { + position: relative; + padding: 191px 0 0 55px; + width: 536px; + height: 857px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Torch9810.png') no-repeat; +} + +.menu-button-wrapper-Torch9810 { + position: relative; + display: inline-block; + margin: 45px 0 0 100px; + width: 75px; + height: 85px; + cursor: pointer; +} + +.back-button-wrapper-Torch9810 { + position: relative; + display: inline-block; + margin: 0 0 0 118px; + width: 75px; + height: 85px; + cursor: pointer; +} + +.viewport-wrapper-landscape-Torch9810 { + width: 640px; + height: 480px; + border: none; +} + +.device-wrapper-landscape-Torch9810 { + position: relative; + padding: 55px 0 0 191px; + width: 857px; + height: 536px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Torch9810_landscape.png') no-repeat; +} + +.menu-button-wrapper-landscape-Torch9810{ + position: relative; + margin: -175px 0 0 685px; + width: 85px; + height: 75px; + cursor: pointer; +} + +.back-button-wrapper-landscape-Torch9810 { + position: relative; + margin: -272px 0 0 685px; + width: 85px; + height: 75px; + cursor: pointer; +} + diff --git a/lib/ripple/devices/Torch9860-9850.js b/lib/ripple/devices/Torch9860-9850.js new file mode 100644 index 00000000..5fc13215 --- /dev/null +++ b/lib/ripple/devices/Torch9860-9850.js @@ -0,0 +1,65 @@ +/* + * 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. + */ +module.exports = { + + "id": "Torch9860-9850", + "name": "BlackBerry Torch 9860/9850", + "model": "9860-9850", + "osName": "BlackBerry OS", + "uuid": "42", + "osVersion": "7", + "firmware": "7", + "manufacturer": "Research In Motion", + + "skin": "Torch9860-9850", + + "capabilities": [ + "input.touch", + "location.gps", + "location.maps", + "media.audio.capture", + "media.video.capture", + "media.recording", + "storage.memorycard", + "network.bluetooth", + "network.wlan", + "network.3gpp" + ], + + "screen": { + "width": 480, + "height": 800 + }, + "viewPort": { + "portrait": { + "width": 480, + "height": 800, + "paddingTop": 0, + "paddingLeft": 0 + }, + "landscape": { + "width": 800, + "height": 480, + "paddingTop": 0, + "paddingLeft": 0 + } + }, + + "ppi": 253, + "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9860; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1", + "browser": ["Webkit"], + "platforms": ["web", "phonegap", "webworks.handset"] +}; diff --git a/lib/ripple/devices/Torch9860-9850/skin.css b/lib/ripple/devices/Torch9860-9850/skin.css new file mode 100644 index 00000000..464d3499 --- /dev/null +++ b/lib/ripple/devices/Torch9860-9850/skin.css @@ -0,0 +1,92 @@ +/* + * 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. + */ + +/* ------------------------------> + Torch 9860-9850 Skin (602x1149) offset (59x159)*/ + +.viewport-wrapper-Torch9860-9850 { + width: 480px; + height: 800px; + border: none; +} + +.device-wrapper-Torch9860-9850 { + position: relative; + padding: 159px 0 0 59px; + width: 543px; + height: 990px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Torch9860-9850.png') no-repeat; +} + +.menu-button-wrapper-Torch9860-9850 { + position: relative; + display: inline-block; + margin: 40px 0 0 98px; + width: 80px; + height: 62px; + cursor: pointer; +} + +.back-button-wrapper-Torch9860-9850 { + position: relative; + display: inline-block; + margin: 0 0 0 123px; + width: 80px; + height: 62px; + cursor: pointer; +} + +.viewport-wrapper-landscape-Torch9860-9850 { + margin: -99px 0 0 103px; + width: 800px; + height: 480px; + border: none; +} + +.device-wrapper-landscape-Torch9860-9850 { + position: relative; + padding: 159px 0 0 60px; + width: 1089px; + height: 443px; + margin: 0 auto; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: url('images/Torch9860-9850_landscape.png') no-repeat; +} + +.menu-button-wrapper-landscape-Torch9860-9850 { + position: relative; + margin: -175px 0 0 940px; + width: 60px; + height: 80px; + cursor: pointer; +} + +.back-button-wrapper-landscape-Torch9860-9850 { + position: relative; + margin: -288px 0 0 940px; + width: 60px; + height: 80px; + cursor: pointer; +} + diff --git a/lib/ripple/devices/WQVGA.js b/lib/ripple/devices/WQVGA.js index ec8b46e0..9dc4df42 100644 --- a/lib/ripple/devices/WQVGA.js +++ b/lib/ripple/devices/WQVGA.js @@ -30,12 +30,12 @@ module.exports = { "viewPort": { "portrait": { "width": 240, - "height": 400, + "height": 480, "paddingTop": 0, "paddingLeft": 0 }, "landscape": { - "width": 400, + "width": 480, "height": 240, "paddingTop": 0, "paddingLeft": 0 @@ -44,6 +44,6 @@ module.exports = { "ppi": 96, "browser": ["Generic"], - "platforms": ["web", "wac", "opera", "vodafone", "phonegap"], + "platforms": ["web", "phonegap"], "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2" }; diff --git a/lib/ripple/devices/WVGA.js b/lib/ripple/devices/WVGA.js index f54d2979..43b7b6e4 100644 --- a/lib/ripple/devices/WVGA.js +++ b/lib/ripple/devices/WVGA.js @@ -44,6 +44,6 @@ module.exports = { "ppi": 96, "browser": ["Generic"], - "platforms": ["web", "wac", "opera", "vodafone", "phonegap"], + "platforms": ["web", "phonegap"], "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2" }; diff --git a/lib/ripple/devices/XperiaX10.js b/lib/ripple/devices/XperiaX10.js deleted file mode 100644 index b2d1f904..00000000 --- a/lib/ripple/devices/XperiaX10.js +++ /dev/null @@ -1,70 +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. - */ -module.exports = { - "id": "XperiaX10", - "name": "Sony Ericsson - Xperia X10", - "manufacturer": "Sony", - "model": "Xperia", - "firmware": "n/a", - "osName": "Android", - "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3", - "osVersion": "1.6", - - "screen": { - "width": 480, - "height": 854 - }, - "viewPort": { - "portrait": { - "width": 480, - "height": 854, - "paddingTop": 0, - "paddingLeft": 0 - }, - "landscape": { - "width": 854, - "height": 480, - "paddingTop": 0, - "paddingLeft": 0 - } - }, - - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 480, - "height": 787, - "paddingTop": 67, - "paddingLeft": 0 - }, - "landscape": { - "width": 854, - "height": 413, - "paddingTop": 67, - "paddingLeft": 0 - } - } - } - } - }, - - "ppi": 245, - "userAgent": "?", - "browser": ["Webkit"], - "platforms": ["web", "wac", "vodafone"] -}; diff --git a/lib/ripple/devices/XperiaX10Mini.js b/lib/ripple/devices/XperiaX10Mini.js deleted file mode 100644 index bb881267..00000000 --- a/lib/ripple/devices/XperiaX10Mini.js +++ /dev/null @@ -1,70 +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. - */ -module.exports = { - "id": "XperiaX10Mini", - "name": "Sony Ericsson - Xperia X10 mini", - "manufacturer": "Sony", - "model": "Xperia", - "firmware": "n/a", - "osName": "Android", - "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3", - "osVersion": "1.6", - - "screen": { - "width": 240, - "height": 320 - }, - "viewPort": { - "portrait": { - "width": 240, - "height": 320, - "paddingTop": 0, - "paddingLeft": 0 - }, - "landscape": { - "width": 320, - "height": 240, - "paddingTop": 0, - "paddingLeft": 0 - } - }, - - "overrides": { - "api": { - "vodafone": { - "viewPort": { - "portrait": { - "width": 240, - "height": 282, - "paddingTop": 38, - "paddingLeft": 0 - }, - "landscape": { - "width": 320, - "height": 202, - "paddingTop": 38, - "paddingLeft": 0 - } - } - } - } - }, - - "ppi": 156.9, - "userAgent": "?", - "browser": ["Webkit"], - "platforms": ["web", "wac", "vodafone"] -}; diff --git a/lib/ripple/emulatorBridge.js b/lib/ripple/emulatorBridge.js index 6704de77..3ae23418 100644 --- a/lib/ripple/emulatorBridge.js +++ b/lib/ripple/emulatorBridge.js @@ -19,6 +19,7 @@ var _isMouseDown = false, constants = require('ripple/constants'), utils = require('ripple/utils'), exception = require('ripple/exception'), + _xhr, _frame; function _getEmulatedViewportStyle(attr) { @@ -71,6 +72,9 @@ function _marshalScreen(win) { module.exports = { link: function (frame) { _frame = frame; + _xhr = frame.contentWindow.XMLHttpRequest; + + require('ripple/widgetConfig').initialize(); var marshal = function (obj, key) { window[key] = _frame.contentWindow[key] = obj; @@ -87,11 +91,16 @@ module.exports = { _marshalScreen(_frame.contentWindow); _marshalScreen(window); }, - getWidgetDocument: function () { + + document: function () { return _frame.contentDocument; }, - getWidgetWindow: function () { + window: function () { return _frame.contentWindow; + }, + + xhr: function () { + return _xhr; } }; diff --git a/lib/ripple/fileSystem.js b/lib/ripple/fileSystem.js deleted file mode 100644 index d6cc3a13..00000000 --- a/lib/ripple/fileSystem.js +++ /dev/null @@ -1,99 +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 constants = require('ripple/constants'), - db = require('ripple/db'), - exception = require('ripple/exception'), - event = require('ripple/event'), - _console = require('ripple/console'), - utils = require('ripple/utils'), - _fileSystemPaths = { - "photos": { "uri": "" }, - "videos": { "uri": "" }, - "music": { "uri": "" }, - "downloads": { "uri": "" }, - "widgethome": { "uri": "" } - }, - _fileSystemRegex = { - "photos": { "virtualPathRegex": /^\/virtual\/photos\//i }, - "videos": { "virtualPathRegex": /^\/virtual\/videos\//i }, - "music": { "virtualPathRegex": /^\/virtual\/music\//i }, - "downloads": { "virtualPathRegex": /^\/virtual\/downloads\//i }, - "widgethome": { "virtualPathRegex": /^\/virtual\/widgethome\//i } - }, - _overrides = {}; - -module.exports = { - initialize: function () { - _fileSystemPaths = db.retrieveObject(constants.FILESYSTEM.PERSISTENCE_KEY) || _fileSystemPaths; - _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1); - }, - - getURI: function getURI(origURI) { - var newURI = origURI, - found = false; - - if (_overrides[origURI]) { - return _overrides[origURI]; - } - - utils.forEach(_fileSystemPaths, function (value, key) { - if (found) { - return; - } - - var uri = value.uri.replace(/\/$/, ""); - if (origURI.match(_fileSystemRegex[key].virtualPathRegex)) { - newURI = origURI.replace(_fileSystemRegex[key].virtualPathRegex, uri + "/"); - found = true; - } - }); - - return newURI; - }, - - exists: function (path) { - try { - var scrubbedUri = this.getURI(path), - xhr = new XMLHttpRequest(); - - xhr.open("GET", scrubbedUri, false); - xhr.send(); - - //HACK: this should return maybe for 403 - return xhr.status !== 404; - } - catch (e) { - exception.handle(e); - _console.log("failed to check if [" + path + "] exists"); - return false; - } - }, - - - getFileSystemPaths: function getFileSystemPaths() { - return utils.copy(_fileSystemPaths); - }, - - updateFileSystemPaths: function updateFileSystemPaths(filePathsObject) { - _fileSystemPaths = utils.copy(filePathsObject); - _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname; - db.saveObject(constants.FILESYSTEM.PERSISTENCE_KEY, filePathsObject); - }, - - override : function (from, to) { - _overrides[from] = to; - } -}; diff --git a/lib/ripple/fs.js b/lib/ripple/fs.js new file mode 100644 index 00000000..ba30158b --- /dev/null +++ b/lib/ripple/fs.js @@ -0,0 +1,218 @@ +/* + * 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'), + constants = require('ripple/constants'), + event = require('ripple/event'), + _console = require('ripple/console'), + _self, _fs; + +function _map(array, callback) { + var map = [], i; + for (i = 0; i < array.length; i++) { + map[i] = callback(array[i], i); + } + return map; +} + +function _resolveLocalFileSystemURL(path, success, error) { + return (window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL)(path, success, error); +} + +function _blobBuilder() { + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder; + return new BlobBuilder(); +} + +function _error(e) { + var msg = ''; + + switch (e.code) { + case FileError.QUOTA_EXCEEDED_ERR: + msg = 'QUOTA_EXCEEDED_ERR'; + break; + case FileError.NOT_FOUND_ERR: + msg = 'NOT_FOUND_ERR'; + break; + case FileError.SECURITY_ERR: + msg = 'SECURITY_ERR'; + break; + case FileError.INVALID_MODIFICATION_ERR: + msg = 'INVALID_MODIFICATION_ERR'; + break; + case FileError.INVALID_STATE_ERR: + msg = 'INVALID_STATE_ERR'; + break; + default: + msg = 'Unknown Error'; + break; + } + + _console.log('FileSystem error: ' + msg); +} + +_self = { + initialize: function (prev, baton) { + try { + var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; + + if (requestFileSystem) { + baton.take(); + } + + requestFileSystem(window.TEMPORARY, constants.FS_SIZE, function (fs) { + _fs = fs; + event.trigger("FileSystemInitialized", null, true); + baton.pass(); + }, _error); + } + catch (e) { + console.log("File System Not Available"); + } + }, + + ls: function (path, success, error) { + path = path || "/"; + + _fs.root.getDirectory(path, {}, function (dirEntry) { + var dirReader = dirEntry.createReader(); + dirReader.readEntries(function (entries) { + success(_map(entries, function (entry, index) { + return entry; + })); + }, error); + }, error); + }, + + rm: function (path, success, error, options) { + options = options || {}; + + _fs.root[options.recursive ? "getDirectory" : "getFile"](path, {create: false}, function (entry) { + entry[options.recursive ? "removeRecursively" : "remove"](function () { + success(); + }, error); + }, error); + }, + + rmdir: function (path, success, error, options) { + options = options || {}; + + _fs.root.getDirectory(path, {create: false}, function (entry) { + entry.remove(function () { + success(); + }, error); + }, error); + }, + + mkdir: function (path, success, error) { + _fs.root.getDirectory(path, {create: true}, function (dirEntry) { + success(dirEntry); + }, error); + }, + + mv: function (from, to, success, error) { + var path = to.replace(/^\//, "").split("/"), + fileName = path.splice(path.length - 1, 1).toString(); + + _self.stat(from, function (entry) { + _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) { + entry.moveTo(dest, fileName, function (finalDestination) { + success(finalDestination); + }, error); + }, error); + }, error); + }, + + touch: function (path, success, error) { + _fs.root.getFile(path, {create: true}, function (fileEntry) { + success(fileEntry); + }, error); + }, + + cp: function (from, to, success, error) { + var path = to.replace(/^\//, "").split("/"), + fileName = path.splice(path.length - 1, 1).toString(); + + _self.stat(from, function (entry) { + _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) { + entry.copyTo(dest, fileName, function (finalDestination) { + success(finalDestination); + }, error); + }, error); + }, error); + }, + + stat: function (path, success, error) { + var url = "filesystem:" + utils.location().origin + "/temporary/" + path; + _resolveLocalFileSystemURL(url, function (entry) { + success(entry); + }, error); + }, + + write: function (path, contents, success, error, options) { + options = options || {}; + + function write(entry) { + entry.createWriter(function (fileWriter) { + var bb = _blobBuilder(); + + fileWriter.onwriteend = function (progressEvent) { + success(entry); + }; + fileWriter.onerror = error; + + if (options.mode === "append") { + fileWriter.seek(fileWriter.length); + } + + bb.append(contents); + fileWriter.write(bb.getBlob('text/plain')); + }, error); + } + + _self.stat(path, function (entry) { + if (options.mode === "append") { + write(entry); + } else { + _self.rm(path, function () { + _self.touch(path, write, error); + }, error); + } + }, function (e) { + if (e.code === FileError.NOT_FOUND_ERR) { + _self.touch(path, write, error); + } else { + error(e); + } + }); + }, + + read: function (path, success, error) { + _self.stat(path, function (entry) { + entry.file(function (file) { + var reader = new FileReader(); + + reader.onloadend = function (progressEvent) { + success(progressEvent.target.result); + }; + reader.onerror = error; + + reader.readAsText(file); + }, error); + }, error); + } +}; + +module.exports = _self; diff --git a/lib/ripple/notifications.js b/lib/ripple/notifications.js index 635a7a6c..ed319d5c 100644 --- a/lib/ripple/notifications.js +++ b/lib/ripple/notifications.js @@ -19,9 +19,9 @@ var constants = require('ripple/constants'), event = require('ripple/event'); function _validateAndInitNType(nType) { - nType = nType || constants.NOTIFICATIONS.TYPES.NORMAL; + nType = nType || "normal"; - if (nType !== constants.NOTIFICATIONS.TYPES.NORMAL && nType !== constants.NOTIFICATIONS.TYPES.ERROR) { + if (nType !== "normal" && nType !== "error") { exception.raise(exception.types.NotificationType, "Unknown Notification Type == " + nType + ",when dealing with Console notification."); } @@ -51,7 +51,7 @@ function _processNotification(nType, stateType, message) { case constants.NOTIFICATIONS.STATE_TYPES.OPEN: display = "display: block;"; //need to do this better. displayText = message; - if (nType === constants.NOTIFICATIONS.TYPES.ERROR) { + if (nType === "error") { displayText = "Oh Snap!\n\n" + displayText; className += " ui-state-error ui-corner-all"; notificationIcon = ''; diff --git a/lib/ripple/platform.js b/lib/ripple/platform.js index aa3d5f7a..896ab87d 100644 --- a/lib/ripple/platform.js +++ b/lib/ripple/platform.js @@ -82,7 +82,6 @@ _self = { }, changeEnvironment: function (platform, deviceId, callback) { - var save = jWorkflow.order(function (prev, baton) { baton.take(); db.saveObject(constants.PLATFORM.SAVED_KEY, platform, null, baton.pass); @@ -94,7 +93,7 @@ _self = { baton.take(); db.save(constants.ENCAPSULATOR.LAYOUT, null, null, baton.pass); }).andThen(function () { - event.trigger("PlatformChangedEvent", true); + event.trigger("PlatformChangedEvent", [], true); _console.prefix = null; _console.log("Emulator :: loading platform " + platform.name); }); diff --git a/lib/ripple/platform/builder.js b/lib/ripple/platform/builder.js index 69278393..f26dbec2 100644 --- a/lib/ripple/platform/builder.js +++ b/lib/ripple/platform/builder.js @@ -34,6 +34,9 @@ function _objectFactory(context, objects, allowed) { if (allowed(obj) || utils.count(result)) { context[key] = result; } + else { + delete context[key]; + } }); } diff --git a/lib/ripple/platform/opera/4.0/defaultStatus.js b/lib/ripple/platform/opera/4.0/defaultStatus.js deleted file mode 100644 index d2272b60..00000000 --- a/lib/ripple/platform/opera/4.0/defaultStatus.js +++ /dev/null @@ -1,16 +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. - */ -module.exports = {}; diff --git a/lib/ripple/platform/opera/4.0/moveBy.js b/lib/ripple/platform/opera/4.0/moveBy.js deleted file mode 100644 index 8cc04bb5..00000000 --- a/lib/ripple/platform/opera/4.0/moveBy.js +++ /dev/null @@ -1,20 +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 exception = require('ripple/exception'); - -module.exports = function moveBy(deltaX, deltaY) { - exception.raise(exception.types.MethodNotImplemented, "window.moveBy is not yet implemented"); -}; diff --git a/lib/ripple/platform/opera/4.0/moveTo.js b/lib/ripple/platform/opera/4.0/moveTo.js deleted file mode 100644 index 54d1e6de..00000000 --- a/lib/ripple/platform/opera/4.0/moveTo.js +++ /dev/null @@ -1,20 +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 exception = require('ripple/exception'); - -module.exports = function moveTo(posX, posY) { - exception.raise(exception.types.MethodNotImplemented, "window.moveTo is not yet implemented"); -}; diff --git a/lib/ripple/platform/opera/4.0/resizeBy.js b/lib/ripple/platform/opera/4.0/resizeBy.js deleted file mode 100644 index fd9128d6..00000000 --- a/lib/ripple/platform/opera/4.0/resizeBy.js +++ /dev/null @@ -1,20 +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 exception = require('ripple/exception'); - -module.exports = function resizeBy(deltaX, deltaY) { - exception.raise(exception.types.MethodNotImplemented, "window.resizeBy is not yet implemented"); -}; diff --git a/lib/ripple/platform/opera/4.0/resizeTo.js b/lib/ripple/platform/opera/4.0/resizeTo.js deleted file mode 100644 index 95a2d4b6..00000000 --- a/lib/ripple/platform/opera/4.0/resizeTo.js +++ /dev/null @@ -1,20 +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 exception = require('ripple/exception'); - -module.exports = function resizeTo(posX, posY) { - exception.raise(exception.types.MethodNotImplemented, "window.resizeTo is not yet implemented"); -}; diff --git a/lib/ripple/platform/opera/4.0/spec.js b/lib/ripple/platform/opera/4.0/spec.js deleted file mode 100644 index f0d5b8ea..00000000 --- a/lib/ripple/platform/opera/4.0/spec.js +++ /dev/null @@ -1,56 +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. - */ -module.exports = { - id: "opera", - version: "4.0", - name: "Opera", - type: "platform", - - persistencePrefix: "opera-", - - config: require('ripple/platform/opera/4.0/spec/config'), - device: {}, - ui: require('ripple/platform/opera/4.0/spec/ui'), - events: require('ripple/platform/opera/4.0/spec/events'), - - objects: { - navigator: { - path: "w3c/1.0/navigator" - }, - widget: { - path: "opera/4.0/widget" - }, - defaultStatus: { - path: "opera/4.0/defaultStatus" - }, - moveBy: { - path: "opera/4.0/moveBy" - }, - moveTo: { - path: "opera/4.0/moveTo" - }, - resizeBy: { - path: "opera/4.0/resizeBy" - }, - resizeTo: { - path: "opera/4.0/resizeTo" - }, - status: { - path: "opera/4.0/status" - } - } -}; - diff --git a/lib/ripple/platform/opera/4.0/spec/config.js b/lib/ripple/platform/opera/4.0/spec/config.js deleted file mode 100644 index e8a5f21b..00000000 --- a/lib/ripple/platform/opera/4.0/spec/config.js +++ /dev/null @@ -1,274 +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 constants = require('ripple/constants'); - -module.exports = { - config: "config.xml", - configSchema: { - rootElement: "widget", - widget: { - nodeName: "widget", - required: true, - occurrence: 1, - attributes: { - defaultmode: { - attributeName: "defaultmode", - required: false, - type: "listDefault", - listValues: ["widget", "application", "fullscreen"], - defaultValue: "widget" - }, - dockable: { - attributeName: "dockable", - required: false, - type: "listBoolean", - listValues: ["yes", "true", "dockable"], - defaultValue: false - }, - transparent: { - attributeName: "transparent", - required: false, - type: "listBoolean", - listValues: ["yes", "true", "transparent"], - defaultValue: false - }, - network: { - attributeName: "network", - required: false, - type: "list", - listValues: ["public", "private", "public private", "private public"] - } - }, - children: { - widgetname: { - nodeName: "widgetname", - required: true, - occurrence: 1, - type: "string" - }, - width: { - nodeName: "width", - required: false, - occurrence: 1, - type: "integer", - defaultValue: 300 - }, - height: { - nodeName: "height", - required: false, - occurrence: 1, - type: "integer", - defaultValue: 300 - }, - widgetfile: { - nodeName: "widgetfile", - required: false, - occurrence: 1, - type: "regex", - regex: constants.REGEX.URL, - helpText: "An author must not %-encode all path names.

It is recommended that authors use this element." - }, - author: { - nodeName: "author", - required: false, - occurrence: 1, - children: { - name: { - nodeName: "name", - type: "string", - occurrence: 1, - required: false - }, - organization: { - nodeName: "organization", - type: "string", - occurrence: 1, - required: false - }, - email: { - nodeName: "email", - type: "regex", - regex: constants.REGEX.EMAIL, - occurrence: 1, - required: false - }, - link: { - nodeName: "link", - type: "regex", - regex: constants.REGEX.URL, - occurrence: 1, - required: false - } - } - }, - description: { - nodeName: "description", - required: false, - occurrence: 1, - type: "string" - }, - icon: { - nodeName: "icon", - required: false, - occurrence: 0, - type: "string", - attributes: { - width: { - attributeName: "width", - type: "integer", - required: false - }, - height: { - attributeName: "height", - type: "integer", - required: false - } - } - }, - feature: { - nodeName: "feature", - required: false, - occurrence: 0, - attributes: { - name: { - attributeName: "name", - type: "string", - required: true - }, - required: { - attributeName: "required", - type: "boolean", - required: false - } - }, - children: { - param: { - nodeName: "param", - required: false, - occurrence: 0, - attributes: { - name: { - attributeName: "name", - required: true, - type: "string" - }, - value: { - attributeName: "value", - required: true, - type: "string" - } - } - } - } - }, - id: { - nodeName: "id", - required: false, - occurrence: 1, - children: { - host: { - nodeName: "host", - required: true, - occurrence: 1, - type: "regex", - regex: constants.REGEX.URL - }, - name: { - nodeName: "name", - required: true, - occurrence: 1, - type: "string" - }, - revised: { - nodeName: "revised", - required: true, - occurrence: 1, - type: "regex", - regex: constants.REGEX.WC3_DTF - } - } - }, - security: { - nodeName: "security", - required: false, - occurrence: 1, - children: { - access: { - nodeName: "access", - required: false, - occurrence: 1, - helpText: "A user agent must treat undeclared child elements of the access element to mean that an author is requesting access to the full capabilities afforded by the semantics of the missing element. An example is that if the host element is missing, the widget is requesting access to all hosts.", - children: { - protocol: { - nodeName: "protocol", - occurrence: 0, - type: "list", - listValues: ["http", "https"], - required: false - }, - host: { - nodeName: "host", - occurrence: 0, - type: "string", - required: false - }, - port: { - nodeName: "port", - occurrence: 0, - type: "listNumbers", - required: false - }, - path: { - nodeName: "path", - occurrence: 0, - type: "string", - required: false - } - } - }, - content: { - nodeName: "content", - required: false, - occurrence: 1, - attributes: { - plugin: { - attributeName: "plugin", - type: "string", - required: true, - listValues: ["yes", "no", "true", "false", "plugin"] - } - } - } - } - } - } - } - }, - extractInfo: function (configValidationObject) { - if (!configValidationObject) { - return null; - } - - var widgetInfo = {}; - - widgetInfo.id = configValidationObject.widget.children.id.children.name.validationResult[0].value || ""; - widgetInfo.name = configValidationObject.widget.children.widgetname.validationResult[0].value || ""; - widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].value || ""; - widgetInfo.preferences = {}; - - return widgetInfo; - } -}; diff --git a/lib/ripple/platform/opera/4.0/spec/events.js b/lib/ripple/platform/opera/4.0/spec/events.js deleted file mode 100644 index d20c97d7..00000000 --- a/lib/ripple/platform/opera/4.0/spec/events.js +++ /dev/null @@ -1,26 +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. - */ -module.exports = { - "contexts": { - "widget": { - "events": { - "WidgetShow": "onShow", - "WidgetHide": "onHide" - }, - "context": "widget" - } - } -}; diff --git a/lib/ripple/platform/opera/4.0/spec/ui.js b/lib/ripple/platform/opera/4.0/spec/ui.js deleted file mode 100644 index 9ee7d852..00000000 --- a/lib/ripple/platform/opera/4.0/spec/ui.js +++ /dev/null @@ -1,22 +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. - */ -module.exports = { - plugins: [ - "storage", - "widgetConfig", - "platformEvents" - ] -}; diff --git a/lib/ripple/platform/opera/4.0/status.js b/lib/ripple/platform/opera/4.0/status.js deleted file mode 100644 index d2272b60..00000000 --- a/lib/ripple/platform/opera/4.0/status.js +++ /dev/null @@ -1,16 +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. - */ -module.exports = {}; diff --git a/lib/ripple/platform/opera/4.0/widget.js b/lib/ripple/platform/opera/4.0/widget.js deleted file mode 100644 index e4817bb1..00000000 --- a/lib/ripple/platform/opera/4.0/widget.js +++ /dev/null @@ -1,130 +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 event = require('ripple/event'), - _console = require('ripple/console'), - app = require('ripple/app'), - exception = require('ripple/exception'), - notifications = require('ripple/notifications'), - utils = require('ripple/utils'), - db = require('ripple/db'), - platform = require('ripple/platform'), - _self; - -event.on("ScreenChangeDimensions", function (width, height) { - var eventToFire = document.createEvent("Event"); - _console.log("Firing resolution changed event for width: " + width + " and height: " + height); - eventToFire.height = height; - eventToFire.width = width; - eventToFire.initEvent("resolution", false, false); - window.dispatchEvent(eventToFire); -}); - -event.on("WidgetShow", function () { - if (_self.onShow) { - _self.onShow(); - } -}); - -event.on("WidgetHide", function () { - if (_self.onHide) { - _self.onHide(); - } -}); - -_self = { - // read only - originalURL: "", - identifier: "", - widgetMode: "application", - - onShow: null, - onHide: null, - - openUrl: function (url) { - window.open(url); - }, - - setPreferenceForKey: function (preference, key) { - utils.validateNumberOfArguments(1, 2, arguments.length); - utils.validateArgumentType(key, "string"); - - var msg = "", - prefix = platform.getPersistencePrefix(); - - if (app.isPreferenceReadOnly(key)) { - msg += "Cannot modify a read only preference. Preference key: " + key; - } - else { - if (preference === null) { - msg += "deleting preference " + key; - db.remove(key, prefix); - } - else { - msg += "setting preference " + key + " == " + preference; - utils.validateArgumentType(preference, "string"); - db.save(key, preference, prefix); - } - } - - _console.log(msg); - event.trigger("StorageUpdatedEvent"); - }, - - preferenceForKey: function (key) { - utils.validateNumberOfArguments(1, 1, arguments.length); - utils.validateArgumentType(key, "string"); - - var prefix = platform.getPersistencePrefix(), - value = db.retrieve(key, prefix) || undefined; - - _console.log("retrieving preference " + key + " == " + value); - - return value; - }, - - hide: function () { - exception.raise(exception.types.MethodNotImplemented, "The hide method is not yet implemented"); - }, - - show: function () { - exception.raise(exception.types.MethodNotImplemented, "The show method is not yet implemented"); - }, - - getAttention: function () { - notifications.openNotification("Hi i''m getting your attention!!!!"); - }, - - showNotification: function (message, callback) { - notifications.openNotification(message); - - if (callback) { - callback.apply(); - } - }, - - addEventListener: function (type, expression, bubbling) { - _console.log("Adding Widget Event Listener for type == " + type); - bubbling = bubbling || false; - window.addEventListener(type, expression, bubbling); - }, - - removeEventListener: function (type, listener, useCapture) { - _console.log("Removing a Widget Event Listener for type == " + type); - window.removeEventListener(type, listener, useCapture); - } -}; - -module.exports = _self; diff --git a/lib/ripple/platform/phonegap/1.0/Contact.js b/lib/ripple/platform/phonegap/1.0/Contact.js index d0844e9f..df395d84 100644 --- a/lib/ripple/platform/phonegap/1.0/Contact.js +++ b/lib/ripple/platform/phonegap/1.0/Contact.js @@ -38,54 +38,38 @@ module.exports = function ( addresses, ims, organizations, - published, - updated, birthday, - anniversary, - gender, note, - preferredUsername, photos, - tags, - relationships, - urls, - accounts, - utcOffset, - connected + categories, + urls ) { - return ({ + return { id: id || Math.uuid(undefined, 16), - displayName: displayName, - name: name, - nickname: nickname, - phoneNumbers: phoneNumbers || [], - emails: emails || [], - addresses: addresses || [], - ims: ims || [], - organizations: organizations || [], - published: published, - updated: updated, - birthday: birthday, - anniversary: anniversary, - gender: gender, - note: note, - preferredUsername: preferredUsername, - photos: photos || [], - tags: tags || [], - relationships: relationships || [], - urls: urls || [], - accounts: accounts || [], - utcOffset: utcOffset, - connected: connected, + displayName: displayName || null, + name: name || null, + nickname: nickname || null, + phoneNumbers: phoneNumbers || null, + emails: emails || null, + addresses: addresses || null, + ims: ims || null, + organizations: organizations || null, + birthday: birthday || null, + note: note || null, + photos: photos || null, + categories: categories || null, + urls: urls || null, save: function (success, error) { var _self = this, - // hackish - lastUpdated = this.updated; + lastUpdated = this.updated; // hackish + this.updated = new Date(); + if (!this.id) { this.id = Math.uuid(undefined, 16); } + event.trigger("phonegap-contact-save", [_properties(this), success, function (e) { _self.updated = lastUpdated; error(e); @@ -99,5 +83,5 @@ module.exports = function ( copy.id = null; return copy; } - }); + }; }; diff --git a/lib/ripple/platform/phonegap/1.0/ContactAddress.js b/lib/ripple/platform/phonegap/1.0/ContactAddress.js index 92c6b9b2..0144791e 100644 --- a/lib/ripple/platform/phonegap/1.0/ContactAddress.js +++ b/lib/ripple/platform/phonegap/1.0/ContactAddress.js @@ -13,13 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -module.exports = function (formatted, streetAddress, locality, region, postalCode, country) { +module.exports = function (pref, type, formatted, streetAddress, locality, region, postalCode, country, id) { return { - formatted: formatted, - streetAddress: streetAddress, - locality: locality, - region: region, - postalCode: postalCode, - country: country + pref: pref || null, + type: type || null, + formatted: formatted || null, + streetAddress: streetAddress || null, + locality: locality || null, + region: region || null, + postalCode: postalCode || null, + country: country || null, + id: id || null }; }; diff --git a/lib/ripple/platform/phonegap/1.0/ContactField.js b/lib/ripple/platform/phonegap/1.0/ContactField.js index 23cbb405..8869dde5 100644 --- a/lib/ripple/platform/phonegap/1.0/ContactField.js +++ b/lib/ripple/platform/phonegap/1.0/ContactField.js @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -module.exports = function (type, value, primary) { +module.exports = function (type, value, pref) { return { type: type, value: value, - primary: primary || false + pref: pref || false }; }; diff --git a/lib/ripple/platform/phonegap/1.0/ContactOrganization.js b/lib/ripple/platform/phonegap/1.0/ContactOrganization.js index c00fc646..c84054bb 100644 --- a/lib/ripple/platform/phonegap/1.0/ContactOrganization.js +++ b/lib/ripple/platform/phonegap/1.0/ContactOrganization.js @@ -13,16 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -module.exports = function (name, department, title, startDate, endDate, location, description) { - var org = { - name: name, - department: department, - title: title, - startDate: startDate, - endDate: endDate, - location: location, - description: description +module.exports = function (pref, type, name, dept, title) { + return { + pref: pref || null, + type: type || null, + name: name || null, + department: dept || null, + title: title || null }; - - return org; }; diff --git a/lib/ripple/platform/phonegap/1.0/FileReader.js b/lib/ripple/platform/phonegap/1.0/FileReader.js deleted file mode 100644 index 8c3dfd8b..00000000 --- a/lib/ripple/platform/phonegap/1.0/FileReader.js +++ /dev/null @@ -1,34 +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. - */ -module.exports = function () { - return { - readAsBinaryString: function () { - throw "not implemented"; - }, - readAsDataURL: function () { - throw "not implemented"; - }, - readAsText: function () { - throw "not implemented"; - }, - readAsArrayBuffer: function () { - throw "not implemented"; - }, - abort: function () { - throw "not implemented"; - } - }; -}; diff --git a/lib/ripple/platform/phonegap/1.0/FileWriter.js b/lib/ripple/platform/phonegap/1.0/FileWriter.js deleted file mode 100644 index 5ffe01d6..00000000 --- a/lib/ripple/platform/phonegap/1.0/FileWriter.js +++ /dev/null @@ -1,34 +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. - */ -module.exports = function () { - return { - write: function () { - throw "not implemented"; - }, - readAsDataURL: function () { - throw "not implemented"; - }, - seek: function () { - throw "not implemented"; - }, - truncate: function () { - throw "not implemented"; - }, - abort: function () { - throw "not implemented"; - } - }; -}; diff --git a/lib/ripple/platform/phonegap/1.0/contacts.js b/lib/ripple/platform/phonegap/1.0/contacts.js index 8db72aea..df906fc6 100644 --- a/lib/ripple/platform/phonegap/1.0/contacts.js +++ b/lib/ripple/platform/phonegap/1.0/contacts.js @@ -20,14 +20,13 @@ var Contact = require('./Contact'), utils = require('ripple/utils'), db = require('ripple/db'), event = require('ripple/event'), - _KEY = "phonegap-contacts", - _contacts, self; + self; function _error(callback, code, msg) { var e = new ContactError(); e.code = code; e.message = msg; - setTimeout(function () { + window.setTimeout(function () { callback(e); }, 1); } @@ -64,11 +63,11 @@ function _defaultContacts() { } function _getContacts() { - return _contacts || db.retrieveObject(_KEY) || _defaultContacts(); + return db.retrieveObject("phonegap-contacts") || _defaultContacts(); } -function _saveContacts() { - db.saveObject(_KEY, _contacts); +function _saveContacts(contacts) { + db.saveObject("phonegap-contacts", contacts); } function _filtered(compare, options) { @@ -90,33 +89,33 @@ function _filtered(compare, options) { } event.on("phonegap-contact-save", function (contactProperties, success, error) { - _contacts = _getContacts(); - var existsIndex = _contacts.reduce(function (result, value, index) { + var contacts = _getContacts(), + existsIndex = contacts.reduce(function (result, value, index) { return value.id === contactProperties.id ? index : result; }, -1), - contact = existsIndex >= 0 ? _contacts[existsIndex] : new Contact(); + contact = existsIndex >= 0 ? contacts[existsIndex] : new Contact(); utils.mixin(contactProperties, contact); if (existsIndex < 0) { - _contacts.push(contact); + contacts.push(contact); } - _saveContacts(); - self.find(Object.keys(contact), success, error); + _saveContacts(contacts); + success(contact); }); event.on("phonegap-contact-remove", function (id, success, error) { if (!id) { _error(error, ContactError.NOT_FOUND_ERROR, "id is falsy (" + id + ")"); } else { - _contacts = _getContacts(); - var toDelete = _contacts.reduce(function (result, current, index) { - return current.id === id ? index : result; - }, -1); + var contacts = _getContacts(), + toDelete = contacts.reduce(function (result, current, index) { + return current.id === id ? index : result; + }, -1); if (toDelete >= 0) { - _contacts.splice(toDelete, 1); - _saveContacts(); - self.find(Object.keys(new Contact()), success, error); + contacts.splice(toDelete, 1); + _saveContacts(contacts); + success(); } else { _error(error, ContactError.NOT_FOUND_ERROR, "could not find contact with id (" + id + ")"); } @@ -134,6 +133,7 @@ self = module.exports = { find: function (fields, success, error, options) { var foundContacts = [], tempContact = self.create(), + contacts = _getContacts(), errorFlag = false; options = options || {}; @@ -145,6 +145,13 @@ self = module.exports = { return; } + // handle special case of ["*"] to return all fields + if (fields.length === 1 && fields[0] === "*") { + fields = utils.map(tempContact, function (v, k) { + return k; + }); + } + fields.forEach(function (prop) { if (!(tempContact.hasOwnProperty(prop))) { errorFlag = true; @@ -161,10 +168,8 @@ self = module.exports = { return; } - _contacts = _getContacts(); - if (fields.length > 0) { - _contacts.forEach(function (contact, index) { + contacts.forEach(function (contact, index) { var newContact = utils.copy(contact); if (options && (!_filtered(contact, options) || @@ -185,7 +190,7 @@ self = module.exports = { }); } - setTimeout(function () { + window.setTimeout(function () { // TODO: don't loop over entire db just to slice the array if (options.multiple === false) { foundContacts = foundContacts.splice(0, 1); diff --git a/lib/ripple/platform/phonegap/1.0/device.js b/lib/ripple/platform/phonegap/1.0/device.js index fb89a43e..d5c5da58 100644 --- a/lib/ripple/platform/phonegap/1.0/device.js +++ b/lib/ripple/platform/phonegap/1.0/device.js @@ -14,8 +14,14 @@ * limitations under the License. */ var _self = {}, + event = require('ripple/event'), devices = require('ripple/devices'); + +event.on("HardwareKey", function (key) { + event.trigger("HardwareKeyDefault", [key]); +}); + _self.__defineGetter__("name", function () { return devices.getCurrentDevice().name; }); diff --git a/lib/ripple/platform/phonegap/1.0/file.js b/lib/ripple/platform/phonegap/1.0/file.js deleted file mode 100644 index 2022da14..00000000 --- a/lib/ripple/platform/phonegap/1.0/file.js +++ /dev/null @@ -1,23 +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. - */ -module.exports = { - read: function () { - throw "not implemented"; - }, - write: function () { - throw "not implemented"; - } -}; diff --git a/lib/ripple/platform/phonegap/1.0/navigator.js b/lib/ripple/platform/phonegap/1.0/navigator.js index 589c3a25..e6521c43 100644 --- a/lib/ripple/platform/phonegap/1.0/navigator.js +++ b/lib/ripple/platform/phonegap/1.0/navigator.js @@ -21,7 +21,7 @@ var nav = require('ripple/platform/w3c/1.0/navigator'), _self = {}; event.on("TinyHipposLoaded", function () { - var doc = emulatorBridge.getWidgetDocument(), + var doc = emulatorBridge.document(), evt = doc.createEvent("Events"); evt.initEvent("deviceready", true, true); doc.dispatchEvent(evt); diff --git a/lib/ripple/platform/phonegap/1.0/notification.js b/lib/ripple/platform/phonegap/1.0/notification.js index 47ad9bb2..dd9abe93 100644 --- a/lib/ripple/platform/phonegap/1.0/notification.js +++ b/lib/ripple/platform/phonegap/1.0/notification.js @@ -21,14 +21,14 @@ var notifications = require('ripple/notifications'), module.exports = { alert: function (message, title, buttonName) { - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, message); + notifications.openNotification("normal", message); }, beep: function (times) { for (var i = times; i > 0; i--) { _console.log("beep!"); } - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, "BEEP x " + times); + notifications.openNotification("normal", "BEEP x " + times); }, vibrate: function (milliseconds) { diff --git a/lib/ripple/platform/phonegap/1.0/spec.js b/lib/ripple/platform/phonegap/1.0/spec.js index 1c04f690..05d21228 100644 --- a/lib/ripple/platform/phonegap/1.0/spec.js +++ b/lib/ripple/platform/phonegap/1.0/spec.js @@ -9,6 +9,7 @@ module.exports = { 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'), objects: { PhoneGap: { @@ -47,9 +48,6 @@ module.exports = { camera: { path: "phonegap/1.0/camera" }, - file: { - path: "phonegap/1.0/file" - }, sms: { path: "phonegap/1.0/sms" }, @@ -165,12 +163,6 @@ module.exports = { }, MicrophoneAttributes: { path: "phonegap/1.0/MicrophoneAttributes" - }, - FileReader: { - path: "phonegap/1.0/FileReader" - }, - FileWriter: { - path: "phonegap/1.0/FileWriter" } } diff --git a/lib/ripple/platform/phonegap/1.0/spec/events.js b/lib/ripple/platform/phonegap/1.0/spec/events.js new file mode 100644 index 00000000..5724d95c --- /dev/null +++ b/lib/ripple/platform/phonegap/1.0/spec/events.js @@ -0,0 +1,34 @@ +function _fires(name, data) { + return function () { + var evt = document.createEvent("Events"); + evt.initEvent(name, true, false); + document.dispatchEvent(evt); + }; +} + +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/phonegap/1.0/spec/ui.js index 8de321a0..4ff34941 100644 --- a/lib/ripple/platform/phonegap/1.0/spec/ui.js +++ b/lib/ripple/platform/phonegap/1.0/spec/ui.js @@ -18,6 +18,7 @@ module.exports = { "accelerometer", "deviceSettings", "geoView", - "widgetConfig" + "widgetConfig", + "platformEvents" ] }; diff --git a/lib/ripple/platform/spec.js b/lib/ripple/platform/spec.js index f606beaa..e01092ec 100644 --- a/lib/ripple/platform/spec.js +++ b/lib/ripple/platform/spec.js @@ -14,11 +14,8 @@ * limitations under the License. */ module.exports = { - "wac": {"1.0": require('ripple/platform/wac/1.0/spec')}, "phonegap": {"1.0": require('ripple/platform/phonegap/1.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')}, - "opera": {"4.0": require('ripple/platform/opera/4.0/spec')}, - "vodafone": {"2.7": require('ripple/platform/vodafone/2.7/spec')} + "web": {"default": require('ripple/platform/web/default/spec')} }; diff --git a/lib/ripple/platform/vodafone/2.7/DeviceStateInfo.js b/lib/ripple/platform/vodafone/2.7/DeviceStateInfo.js deleted file mode 100644 index 3e9ea8f3..00000000 --- a/lib/ripple/platform/vodafone/2.7/DeviceStateInfo.js +++ /dev/null @@ -1,82 +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 utils = require('ripple/utils'), - exception = require('ripple/exception'), - geo = require('ripple/geo'), - deviceSettings = require('ripple/deviceSettings'), - PositionInfo = require('ripple/platform/wac/1.0/PositionInfo'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - _self; - -_self = { - // Properties - availableMemory: undefined, - language: undefined, - keypadLightOn: undefined, - backLightOn: undefined, - processorUtilizationPercent: undefined, - audioPath: undefined, - - // Methods/Callbacks - // TODO: define setter/getter and move into closure? - onPositionRetrieved: undefined, // this.onPositionRetrieved(Widget.Device.PositionInfo, method); - - requestPositionInfo: function (method) { - utils.validateNumberOfArguments(1, 1, arguments.length, - ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid number of parameters", new Exception()); - utils.validateArgumentType(method, "string", - ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid parameter", new Exception()); - - if (!(method.match(/gps|agps|cellid/))) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, - "Invalid method argument, expected (gps, agps or cellid)", new Exception()); - } - - if (typeof _self.onPositionRetrieved === "function") { - var delay = geo.delay * 1000, - timeout = geo.timeout; - window.setTimeout(function () { - var pos = PositionInfo, - errorObj = {}; - - if (timeout) { - //create - utils.forEach(pos, function (val, key) { - errorObj[key] = undefined; - }); - pos = errorObj; - } - _self.onPositionRetrieved(pos, method); - }, delay); - } - }, - - onScreenChangeDimensions: undefined, - - onFlipEvent: undefined - -}; - -_self.__defineGetter__("availableMemory", function () { - return deviceSettings.retrieveAsInt("DeviceStateInfo.availableMemory"); -}); - -_self.__defineGetter__("language", function () { - return deviceSettings.retrieve("DeviceStateInfo.language"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/vodafone/2.7/spec.js b/lib/ripple/platform/vodafone/2.7/spec.js deleted file mode 100644 index 28a84756..00000000 --- a/lib/ripple/platform/vodafone/2.7/spec.js +++ /dev/null @@ -1,140 +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. - */ -module.exports = { - - id: "vodafone", - version: "2.7", - name: "Vodafone", - type: "carrier", - - persistencePrefix: "vodafone-", - - config: require('ripple/platform/vodafone/2.7/spec/config'), - device: require('ripple/platform/vodafone/2.7/spec/device'), - ui: require('ripple/platform/vodafone/2.7/spec/ui'), - events: require('ripple/platform/vodafone/2.7/spec/events'), - - objects: { - navigator: { - path: "w3c/1.0/navigator" - }, - WidgetManager: { - path: "wac/1.0/WidgetManager" - }, - Widget: { - path: "wac/1.0/Widget", - children: { - Device: { - path: "wac/1.0/Device", - children: { - AccountInfo: { - path: "wac/1.0/AccountInfo" - }, - ApplicationTypes: { - path: "wac/1.0/ApplicationTypes" - }, - DataNetworkInfo: { - path: "wac/1.0/DataNetworkInfo", - children: { - DataNetworkConnectionTypes: { - path: "wac/1.0/DataNetworkConnectionTypes" - } - } - }, - DeviceInfo: { - path: "wac/1.0/DeviceInfo" - }, - DeviceStateInfo: { - path: "vodafone/2.7/DeviceStateInfo", - children: { - AccelerometerInfo: { - path: "wac/1.0/AccelerometerInfo" - } - } - }, - File: { - path: "wac/1.0/File" - }, - PositionInfo: { - path: "wac/1.0/PositionInfo" - }, - RadioInfo: { - path: "wac/1.0/RadioInfo", - children: { - RadioSignalSourceTypes: { - path: "wac/1.0/RadioSignalSourceTypes" - } - } - } - } - }, - ExceptionTypes: { - path: "wac/1.0/ExceptionTypes" - }, - Exception: { - path: "wac/1.0/Exception" - }, - PIM: { - path: "wac/1.0/PIM", - children: { - AddressBookItem: { - path: "wac/1.0/AddressBookItem" - }, - CalendarItem: { - path: "wac/1.0/CalendarItem" - }, - EventRecurrenceTypes: { - path: "wac/1.0/EventRecurrenceTypes" - } - } - }, - Multimedia: { - path: "wac/1.0/Multimedia", - children: { - Camera: { - path: "wac/1.0/Camera" - }, - AudioPlayer: { - path: "wac/1.0/AudioPlayer" - } - } - } - } - }, - widget: { - path: "opera/4.0/widget" - }, - defaultStatus: { - path: "opera/4.0/defaultStatus" - }, - moveBy: { - path: "opera/4.0/moveBy" - }, - moveTo: { - path: "opera/4.0/moveTo" - }, - resizeBy: { - path: "opera/4.0/resizeBy" - }, - resizeTo: { - path: "opera/4.0/resizeTo" - }, - status: { - path: "opera/4.0/status" - } - } - -}; diff --git a/lib/ripple/platform/vodafone/2.7/spec/config.js b/lib/ripple/platform/vodafone/2.7/spec/config.js deleted file mode 100644 index e2d0fdb0..00000000 --- a/lib/ripple/platform/vodafone/2.7/spec/config.js +++ /dev/null @@ -1,385 +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 constants = require('ripple/constants'), - utils = require('ripple/utils'), - platform = require('ripple/platform'), - db = require('ripple/db'); - -module.exports = { - fileName: "config.xml", - validateVersion: function (configValidationObject) { - var valid = true; - valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) || - (!configValidationObject.widget.validationResult[0].attributes["xmlns:JIL"].valid)); - - return valid; - }, - extractInfo: function (configValidationObject) { - if (!configValidationObject) { - return null; - } - - var widgetInfo = {}, - configPreferences, - preferenceName; - - widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || ""; - widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value; - widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value; - widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value; - widgetInfo.preferences = {}; - - configPreferences = configValidationObject.widget.children.preference.validationResult; - - utils.forEach(configPreferences, function (preference) { - preferenceName = preference.attributes.name.value; - if (preferenceName) { - widgetInfo.preferences[preferenceName] = { - "key": preferenceName, - "value": preference.attributes.value.value || "", - "readonly": preference.attributes.readonly.value === "true" - }; - - db.save(preferenceName, - widgetInfo.preferences[preferenceName].value, - platform.getPersistencePrefix(widgetInfo.id)); - } - }); - - return widgetInfo; - }, - schema: { - rootElement: "widget", - widget: { - nodeName: "widget", - required: true, - occurrence: 1, - helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,maximum_display_mode,update,feature,access,billing. \"widget\" element MAY have following attributes: id,version,height,width,xml:lang", - attributes: { - xmlns: { - attributeName: "xmlns", - required: true, - type: "list", - listValues: ["http://www.w3.org/ns/widgets"] - }, - "xmlns:JIL": { - attributeName: "xmlns:JIL", - required: true, - type: "list", - listValues: ["http://www.jil.org/ns/widgets1.2"] - }, - "xmlns:its": { - attributeName: "xmlns:its", - helpText: "Indicates Text Directionality can be used. According to W3C spec, this feature is at risk, therefore we don't currently validate this.", - required: false, - type: "string" - }, - id: { - attributeName: "id", - required: true, - type: "string" - }, - version: { - attributeName: "version", - helpText: "Version must be in the following format: jil-rec-version-tag = major-version \".\" minor-version [\".\" version-desc]", - required: true, - type: "regex", - regex: /^\d{1,2}\.\d{1,2}(\.[A-Za-z0-9]{1,10})?$/ - }, - height: { - attributeName: "height", - required: true, - type: "integer" - }, - width: { - attributeName: "width", - required: true, - type: "integer" - }, - viewmodes: { - attributeName: "viewmodes", - required: false, - type: "list", - listValues: ["floating", "fullscreen"] - }, - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language" - } - }, - children: { - preference: { - nodeName: "preference", - required: false, - occurrence: 0, - attributes: { - name: { - attributeName: "name", - type: "string", - required: true - }, - value: { - type: "string", - attributeName: "value", - required: false - }, - readonly: { - attributeName: "readonly", - type: "boolean", - required: false - } - } - }, - name: { - nodeName: "name", - required: false, - occurrence: 0, - type: "string", - attributes: { - "short": { - attributeName: "short", - type: "string", - required: false - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - description: { - nodeName: "description", - required: false, - occurrence: 0, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - icon: { - nodeName: "icon", - required: false, - occurrence: 0, - attributes: { - src: { - attributeName: "src", - type: "string", - required: true - }, - height: { - attributeName: "height", - required: false, - type: "integer" - }, - width: { - attributeName: "width", - required: false, - type: "integer" - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - author: { - nodeName: "author", - required: false, - occurrence: 1, - type: "string", - attributes: { - email: { - attributeName: "email", - type: "regex", - required: false, - regex: constants.REGEX.EMAIL - }, - href: { - attributeName: "href", - type: "regex", - required: false, - regex: constants.REGEX.URL - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - license: { - nodeName: "license", - required: false, - occurrence: 1, - type: "string", - attributes: { - href: { - attributeName: "href", - type: "regex", - required: false, - regex: constants.REGEX.URL - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - content: { - nodeName: "content", - required: false, - occurrence: 1, - attributes: { - src: { - attributeName: "src", - type: "string", - required: true - }, - encoding: { - attributeName: "encoding", - type: "string", - required: false - }, - type: { - attributeName: "type", - type: "string", - required: false - } - } - }, - feature: { - nodeName: "feature", - required: false, - occurrence: 0, - attributes: { - name: { - attributeName: "name", - type: "list", - required: true, - listValues: ["http://jil.org/jil/api/1.1/widget", "http://jil.org/jil/api/1.1.5/exception", - "http://jil.org/jil/api/1.1.5/exceptiontypes", "http://jil.org/jil/api/1.1/device", - "http://jil.org/jil/api/1.1/accountinfo", "http://jil.org/jil/api/1.1/deviceinfo", - "http://jil.org/jil/api/1.1.1/datanetworkinfo", "http://jil.org/jil/api/1.1/devicestateinfo", - "http://jil.org/jil/api/1.1/accelerometerinfo", "http://jil.org/jil/api/1.1/config", - "http://jil.org/jil/api/1.1.1/file", "http://jil.org/jil/api/1.1/positioninfo", - "http://jil.org/jil/api/1.1/powerinfo", "http://jil.org/jil/api/1.1.1/radioinfo", - "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes", "http://jil.org/jil/api/1.1.5/applicationtypes", - "http://jil.org/jil/api/1.1/messaging", "http://jil.org/jil/api/1.1/account", - "http://jil.org/jil/api/1.1/attachment", "http://jil.org/jil/api/1.1/message", - "http://jil.org/jil/api/1.1.4/messagefoldertypes", "http://jil.org/jil/api/1.1/messagequantities", - "http://jil.org/jil/api/1.1/messagetypes", "http://jil.org/jil/api/1.1/multimedia", - "http://jil.org/jil/api/1.1/audioplayer", "http://jil.org/jil/api/1.1.2/camera", - "http://jil.org/jil/api/1.1.2/videoplayer", "http://jil.org/jil/api/1.1.1/pim", - "http://jil.org/jil/api/1.1/addressbookitem", "http://jil.org/jil/api/1.1/calendaritem", - "http://jil.org/jil/api/1.1/eventrecurrencetypes", "http://jil.org/jil/api/1.1.1/telephony", - "http://jil.org/jil/api/1.1/callrecord", "http://jil.org/jil/api/1.1.1/callrecordtypes", - "http://jil.org/jil/api/1.1.1/widgetmanager"] - }, - required: { - attributeName: "required", - type: "boolean", - required: false - } - } - }, - "JIL:maximum_display_mode": { - nodeName: "JIL:maximum_display_mode", - required: false, - occurrence: 1, - attributes: { - height: { - attributeName: "height", - type: "integer", - required: false - }, - width: { - attributeName: "width", - type: "integer", - required: false - } - } - }, - "JIL:update": { - nodeName: "JIL:update", - required: false, - occurrence: 1, - attributes: { - href: { - attributeName: "href", - type: "regex", - required: true, - regex: constants.REGEX.URL - }, - period: { - attributeName: "period", - helpText: "Possible values for the period attribute are: 0, 1, 2, 3 meaning: every time the widget is opened in maximum display mode, every day, every week, every month; respectivly", - type: "list", - required: true, - listValues: ["0", "1", "2", "3"] - } - } - }, - "JIL:access": { - nodeName: "JIL:access", - required: false, - occurrence: 1, - attributes: { - network: { - attributeName: "network", - type: "boolean", - required: false - }, - localfs: { - attributeName: "localfs", - type: "boolean", - required: false - }, - remote_scripts: { - attributeName: "remote_scripts", - type: "boolean", - required: false - } - } - }, - "JIL:billing": { - nodeName: "JIL:billing", - required: false, - occurrence: 1, - attributes: { - required: { - attributeName: "required", - type: "boolean", - required: true - } - } - } - } - } - } -}; diff --git a/lib/ripple/platform/vodafone/2.7/spec/device.js b/lib/ripple/platform/vodafone/2.7/spec/device.js deleted file mode 100644 index fa60956a..00000000 --- a/lib/ripple/platform/vodafone/2.7/spec/device.js +++ /dev/null @@ -1,105 +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 constants = require('ripple/constants'), - event = require('ripple/event'); - -module.exports = { - "AccountInfo": { - "phoneUserUniqueId": { - "name": "User Unique Id", - "control": { - "type": "text", - "value": new Date().getTime().toString() - } - }, - "phoneOperatorName": { - "name": "Operator Name", - "control": { - "type": "text", - "value": "" - } - } - }, - "RadioInfo": { - "isRoaming": { - "name": "Is Roaming", - "control": { - "type": "checkbox", - "value": false - }, - "callback": function () { - event.trigger("RadioSignalSourceChanged"); - } - }, - "isRadioEnabled": { - "name": "Is Radio Enabled", - "control": { - "type": "checkbox", - "value": true - } - } - }, - "DeviceInfo": { - "phoneColorDepthDefault": { - "name": "Color Depth", - "control": { - "type": "number", - "value": 24 - } - } - }, - "DeviceStateInfo": { - "availableMemory": { - "name": "Available Memory", - "control": { - "type": "range", - "value": 262144, - "min": 0, - "max": 4096000 - } - }, - "language": { - "name": "Language", - "control": { - "type": "select", - "value": "eng" - }, - "options": (function () { - var i, - optionList = {}, - iterator = constants.LANG.ISO6392_LIST; - - for (i = 0; i <= iterator.length - 1; i++) { - optionList[i] = iterator[i]; - } - - return optionList; - }()) - } - }, - "DataNetworkInfo": { - "isDataNetworkConnected": { - "name": "Data Network Is Connected", - "control": { - "type": "checkbox", - "value": true - }, - "callback": function (setting) { - event.trigger("isDataNetworkConnectedChanged", [setting]); - } - } - } -}; diff --git a/lib/ripple/platform/vodafone/2.7/spec/events.js b/lib/ripple/platform/vodafone/2.7/spec/events.js deleted file mode 100644 index 67feceb6..00000000 --- a/lib/ripple/platform/vodafone/2.7/spec/events.js +++ /dev/null @@ -1,44 +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. - */ -module.exports = { - "contexts": { - "Widget": { - "events": { - "WidgetWakeup": { - name: "WidgetWakeup", - description: "onWakeup", - args: false - }, - "WidgetMaximize": { - name: "WidgetMaximize", - description: "onMaximize", - args: false - }, - "WidgetFocus": { - name: "WidgetMaximize", - description: "onFocus", - args: false - }, - "WidgetRestore": { - name: "WidgetRestore", - desription: "onRestore", - args: false - } - }, - "context": "Widget" - } - } -}; diff --git a/lib/ripple/platform/wac/1.0/AccelerometerInfo.js b/lib/ripple/platform/wac/1.0/AccelerometerInfo.js deleted file mode 100644 index f5942d00..00000000 --- a/lib/ripple/platform/wac/1.0/AccelerometerInfo.js +++ /dev/null @@ -1,31 +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 accelerometer = require('ripple/accelerometer'), - _self = {}; - -_self.__defineGetter__("xAxis", function () { - return accelerometer.getInfo().accelerationIncludingGravity.x; -}); - -_self.__defineGetter__("yAxis", function () { - return accelerometer.getInfo(true).accelerationIncludingGravity.y; -}); - -_self.__defineGetter__("zAxis", function () { - return accelerometer.getInfo(true).accelerationIncludingGravity.z; -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/Account.js b/lib/ripple/platform/wac/1.0/Account.js deleted file mode 100644 index b5130dd3..00000000 --- a/lib/ripple/platform/wac/1.0/Account.js +++ /dev/null @@ -1,32 +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 deviceSettings = require('ripple/deviceSettings'), - _self; - -_self = { - accountName: undefined, - accountId: undefined -}; - -_self.__defineGetter__("accountName", function () { - return deviceSettings.retrieve("Account.accountName"); -}); - -_self.__defineGetter__("accountId", function () { - return deviceSettings.retrieve("Account.accountId"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/AccountInfo.js b/lib/ripple/platform/wac/1.0/AccountInfo.js deleted file mode 100644 index 7ab8762c..00000000 --- a/lib/ripple/platform/wac/1.0/AccountInfo.js +++ /dev/null @@ -1,45 +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 deviceSettings = require('ripple/deviceSettings'), - _self = { - phoneUserUniqueId: undefined, - phoneMSISDN: undefined, - phoneOperatorName: undefined, - userAccountBalance: undefined, - userSubscriptionType: undefined - }; - -_self.__defineGetter__("phoneUserUniqueId", function () { - return deviceSettings.retrieve("AccountInfo.phoneUserUniqueId"); -}); - -_self.__defineGetter__("phoneMSISDN", function () { - return deviceSettings.retrieve("AccountInfo.phoneMSISDN"); -}); - -_self.__defineGetter__("phoneOperatorName", function () { - return deviceSettings.retrieve("AccountInfo.phoneOperatorName"); -}); - -_self.__defineGetter__("userAccountBalance", function () { - return deviceSettings.retrieve("AccountInfo.userAccountBalance"); -}); - -_self.__defineGetter__("userSubscriptionType", function () { - return deviceSettings.retrieve("AccountInfo.userSubscriptionType"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/AddressBookItem.js b/lib/ripple/platform/wac/1.0/AddressBookItem.js deleted file mode 100644 index 641edc9e..00000000 --- a/lib/ripple/platform/wac/1.0/AddressBookItem.js +++ /dev/null @@ -1,90 +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 utils = require('ripple/utils'), - exception = require('ripple/exception'), - db = require('ripple/db'), - constants = require('ripple/constants'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'); - -function _validateArgs(min, max, len) { - utils.validateNumberOfArguments(min, max, len, - ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception()); -} - -function _validateType(arg, argType) { - utils.validateArgumentType(arg, argType, - ExceptionTypes.INVALID_PARAMETER, "argument of wrong type provided", - new Exception()); -} - -module.exports = function () { - function _throwUnsupportedException(method) { - exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception()); - } - - this.addressBookItemId = undefined; - this.fullName = undefined; - this.mobilePhone = undefined; - this.homePhone = undefined; - this.workPhone = undefined; - this.eMail = undefined; - this.company = undefined; - this.title = undefined; - this.address = undefined; - - this.setAttributeValue = function (attribute, value) { - _validateArgs(2, 2, arguments.length); - _validateType(attribute, "string"); - this[attribute] = value; - }; - this.setAddressGroupNames = function (groups) { - _throwUnsupportedException("PIM.AddressBookItem.setAddressGroupNames"); - }; - this.getAttributeValue = function (attribute) { - _validateArgs(1, 1, arguments.length); - _validateType(attribute, "string"); - return this[attribute]; - }; - this.getAddressGroupNames = function () { - _throwUnsupportedException("PIM.AddressBookItem.getAddressGroupNames"); - }; - this.getAvailableAttributes = function () { - return utils.reduce(this, function (attributes, value, key) { - if (typeof(value) !== 'function') { - attributes.push(key); - } - return attributes; - }, []).sort(); - }; - this.update = function () { - var items = db.retrieveObject(constants.PIM.ADDRESS_LIST_KEY), - that = this, - itemIndex = items.reduce(function (current, value, i) { - return value.addressBookItemId === that.addressBookItemId ? - i : current; - }, -1); - - if (itemIndex >= 0) { - items[itemIndex] = this; - db.saveObject(constants.PIM.ADDRESS_LIST_KEY, items); - } - else { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "Address Book Item not found: " + (this.addressBookItemId || ""), new Exception()); - } - - }; -}; diff --git a/lib/ripple/platform/wac/1.0/ApplicationTypes.js b/lib/ripple/platform/wac/1.0/ApplicationTypes.js deleted file mode 100644 index 8ba17713..00000000 --- a/lib/ripple/platform/wac/1.0/ApplicationTypes.js +++ /dev/null @@ -1,26 +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 utils = require('ripple/utils'), - constants = require('ripple/constants'), - _self = {}; - -utils.forEach(constants.PLATFORMS.WAC.APPLICATIONS, function (application) { - _self.__defineGetter__(application, function () { - return application; - }); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/Attachment.js b/lib/ripple/platform/wac/1.0/Attachment.js deleted file mode 100644 index 4f947219..00000000 --- a/lib/ripple/platform/wac/1.0/Attachment.js +++ /dev/null @@ -1,20 +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. - */ -module.exports = function () { - this.fileName = ""; - this.MIMEType = ""; - this.size = 0; -}; diff --git a/lib/ripple/platform/wac/1.0/AudioPlayer.js b/lib/ripple/platform/wac/1.0/AudioPlayer.js deleted file mode 100644 index d4a80785..00000000 --- a/lib/ripple/platform/wac/1.0/AudioPlayer.js +++ /dev/null @@ -1,152 +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 constants = require('ripple/constants'), - event = require('ripple/event'), - exception = require('ripple/exception'), - utils = require('ripple/utils'), - fileSystem = require('ripple/fileSystem'), - _console = require('ripple/console'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - _self, - _state = null, - _STATES = constants.MULTIMEDIA.AUDIO_STATES, - _currentAudioFile, - _audio, _loopCount; - -event.on("MultimediaAudioStateChanged", function updateAudioState(state) { - _state = state; - if (typeof _self.onStateChange === 'function') { - _self.onStateChange.apply(_self, arguments); - } -}); - -_audio = utils.createElement("audio", { - "id": "multimedia-audio" -}); - -_audio.addEventListener('error', function () { - _console.warn("AudioPlayer encountered an error: " + _audio.error.code); - if (_audio.error.code === 4) { - _console.warn("AudioPlayer error 4 could be caused by missing codecs"); - } - _state = null; - event.trigger("MultimediaAudioStateChanged", [null], true); -}); - -_audio.addEventListener('ended', function handleAudioEnded() { - event.trigger("MultimediaAudioStateChanged", [_STATES.COMPLETED], true); - if (_loopCount > 1) { - _self.open(_currentAudioFile); - _self.play(_loopCount--); - } -}); - -document.getElementById("ui").appendChild(_audio); - -function _validateAndSet(state, validStates, callbackBeforeSuccess) { - var i, valid = false; - - for (i = 0; i < validStates.length; i++) { - if (validStates[i] === _state) { - valid = true; - } - } - - if (!valid) { - _console.warn("Attempted to initiate AudioPlayer." + state + - " in invalid state. current state: " + _state); - } else { - if (typeof(callbackBeforeSuccess) === "function") { - callbackBeforeSuccess.apply(); - } - event.trigger("MultimediaAudioStateChanged", [state], true); - } - - return valid; -} - -function _validateAudioType(fileUrl) { - var matched = fileUrl.match(/\.(\w*)$/), - type = matched ? matched[1] : ""; - - if (_audio && _audio.canPlayType("audio/" + type) === "") { - _console.warn("Attempting to load an audio that might not work in the current browser [" + fileUrl + "]"); - } -} - -_self = { - onStateChange: undefined, - - open: function (fileUrl) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open wrong number of arguments", new Exception()); - utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open invalid parameter! expected string, fileUrl: " + - fileUrl, new Exception()); - - if (fileUrl.match(/^rtsp:\/\//)) { - exception.raise(exception.types.MethodNotImplemented, "rtsp:// scheme not yet supported. sorry :("); - } - - _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () { - _validateAudioType(fileUrl); - _currentAudioFile = fileSystem.getURI(fileUrl); - _audio.setAttribute("src", _currentAudioFile); - _audio.load(); - }); - }, - - play: function (repeatTimes) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play wrong number of arguments", new Exception()); - utils.validateArgumentType(repeatTimes, "integer", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play invalid parameter! expected integer, repeatTimes: " + repeatTimes, new Exception()); - - if (repeatTimes < 0) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "value of repeatTimes must be greater than 0", new Exception()); - } - - if (repeatTimes !== 0) { - _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () { - _loopCount = repeatTimes; - _audio.play(); - }); - } - }, - - pause: function () { - _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () { - _audio.pause(); - }); - }, - - resume: function () { - _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () { - _audio.play(); - }); - }, - - stop: function () { - _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () { - try { - _audio.pause(); - _audio.currentTime = 0; - } catch (e) { - //HACK: do nothing, this could throw a dom exception 11 sometimes when playing an mp3 or before the file has loaded. - //see http://developer.palm.com/distribution/viewtopic.php?f=11&t=7568 - } - }); - } -}; - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/CalendarItem.js b/lib/ripple/platform/wac/1.0/CalendarItem.js deleted file mode 100644 index 1bbb7f2c..00000000 --- a/lib/ripple/platform/wac/1.0/CalendarItem.js +++ /dev/null @@ -1,48 +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 constants = require('ripple/constants'), - db = require('ripple/db'), - exception = require('ripple/exception'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'); - -module.exports = function () { - this.calendarItemId = undefined; - this.alarmDate = undefined; - this.eventStartTime = undefined; - this.eventEndTime = undefined; - this.eventName = undefined; - this.eventNotes = undefined; - this.alarmed = undefined; - - this.update = function () { - var events = db.retrieveObject(constants.PIM.CALENDAR_LIST_KEY) || [], - that = this, - eventIndex = events.reduce(function (match, value, i) { - return value.calendarItemId === that.calendarItemId ? - i : match; - }, -1); - - - if (eventIndex >= 0) { - events[eventIndex] = this; - db.saveObject(constants.PIM.CALENDAR_LIST_KEY, events); - } - else { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "Calendar Item not found: " + (this.calendarItemId || ""), new Exception()); - } - }; -}; diff --git a/lib/ripple/platform/wac/1.0/CallRecord.js b/lib/ripple/platform/wac/1.0/CallRecord.js deleted file mode 100644 index c6372193..00000000 --- a/lib/ripple/platform/wac/1.0/CallRecord.js +++ /dev/null @@ -1,23 +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. - */ -module.exports = function () { - this.callRecordType = undefined; - this.callRecordId = undefined; - this.callRecordAddress = undefined; - this.callRecordName = undefined; - this.durationSeconds = undefined; - this.startTime = undefined; -}; diff --git a/lib/ripple/platform/wac/1.0/CallRecordTypes.js b/lib/ripple/platform/wac/1.0/CallRecordTypes.js deleted file mode 100644 index e5d5bb26..00000000 --- a/lib/ripple/platform/wac/1.0/CallRecordTypes.js +++ /dev/null @@ -1,20 +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. - */ -module.exports = { - RECEIVED: "received", - OUTGOING: "outgoing", - MISSED: "missed" -}; diff --git a/lib/ripple/platform/wac/1.0/Camera.js b/lib/ripple/platform/wac/1.0/Camera.js deleted file mode 100644 index 0fc6fa73..00000000 --- a/lib/ripple/platform/wac/1.0/Camera.js +++ /dev/null @@ -1,146 +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 exception = require('ripple/exception'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - constants = require('ripple/constants'), - _console = require('ripple/console'), - utils = require('ripple/utils'), - notifications = require('ripple/notifications'), - _currentlySet, - _img, - _buttons, - _self, - _videoCapture; - - -function _populateWindow(domObject) { - var record = document.createElement("button"), - pause = document.createElement("button"), - stop = document.createElement("button"); - - _img = document.createElement("img"); - _img.setAttribute("id", "jil-camera-window"); - _img.setAttribute("src", document.querySelector("#extension-url").innerHTML + constants.CAMERA.WINDOW_ANIMATION); - _img.setAttribute("width", "100%"); - _currentlySet = domObject; - domObject.appendChild(_img); - - _buttons = document.createElement("div"); - _buttons.setAttribute("id", "jil-camera-window-buttons"); - _buttons.setAttribute("style", "display: none"); - - record.setAttribute("id", "jil-camera-window-buttons-record"); - record.innerHTML = "Record"; - pause.setAttribute("id", "jil-camera-window-buttons-pause"); - pause.innerHTML = "Pause"; - stop.setAttribute("id", "jil-camera-window-buttons-stop"); - stop.innerHTML = "Stop"; - stop.addEventListener("click", _self.stopVideoCapture); - - _buttons.appendChild(record); - _buttons.appendChild(pause); - _buttons.appendChild(stop); - - domObject.appendChild(_buttons); - -} - -function _verifySetWindow(method) { - if (!_img) { - exception.raise(ExceptionTypes.UNKNOWN, "Camera." + - method + " was (most likely) called before using the setWindow method.", new Exception()); - } -} - -_self = { - onCameraCaptured: undefined, //function (fileName) { } - - captureImage: function (fileName, lowRes) { - utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "captureImage invalid number of parameters", new Exception()); - utils.validateMultipleArgumentTypes([fileName, lowRes], ['string', 'boolean'], ExceptionTypes.INVALID_PARAMETER, "invalid parameter type", new Exception()); - - _verifySetWindow("captureImage"); - var msg = constants.CAMERA.WARNING_TEXT; - msg = msg.replace("{file}", fileName); - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, msg); - _console.log("simulated saved image as: " + fileName); - if (_self.onCameraCaptured) { - _self.onCameraCaptured.apply(_self, [fileName]); - } - - return fileName; - }, - setWindow: function (domObject) { - - if (_currentlySet) { - _currentlySet.removeChild(_img); - _currentlySet.removeChild(_buttons); - _currentlySet = null; - _img = null; - _buttons = null; - } - if (domObject !== null) { - _populateWindow(domObject); - } - }, - startVideoCapture: function (fileName, lowRes, maxDurationSeconds, showDefaultControls) { - _verifySetWindow("startVideoCapture"); - utils.validateNumberOfArguments(1, 4, arguments.length, ExceptionTypes.INVALID_PARAMETER, "startVideoCapture invalid number of parameters", new Exception()); - utils.validateMultipleArgumentTypes( - [fileName, lowRes, maxDurationSeconds, showDefaultControls], - ['string', 'boolean', 'integer', 'boolean'], - ExceptionTypes.INVALID_PARAMETER, - "invalid parameter type", new Exception()); - _console.log("started recording video"); - var interval = window.setTimeout(function () { - _self.stopVideoCapture(); - }, maxDurationSeconds * 1000); - - if (showDefaultControls) { - _buttons.removeAttribute("style"); - } - - _videoCapture = { - fileName: fileName, - stop: function () { - window.clearInterval(interval); - var msg = constants.CAMERA.WARNING_TEXT; - msg = msg.replace("{file}", fileName); - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, msg); - if (_self.onCameraCaptured) { - _self.onCameraCaptured.apply(_self, [fileName]); - } - } - }; - - return fileName; - }, - stopVideoCapture: function () { - utils.validateNumberOfArguments(0, 0, arguments.length, ExceptionTypes.INVALID_PARAMETER, "stopVideoCapture invalid number of parameters", new Exception()); - if (_videoCapture) { - _console.log("simulated saving a video as: " + _videoCapture.fileName); - if (_buttons) { - _buttons.setAttribute("style", "display: none"); - } - _videoCapture.stop(); - _videoCapture = null; - } - } - -}; - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/Config.js b/lib/ripple/platform/wac/1.0/Config.js deleted file mode 100644 index 4b949efe..00000000 --- a/lib/ripple/platform/wac/1.0/Config.js +++ /dev/null @@ -1,50 +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 utils = require('ripple/utils'), - notifications = require('ripple/notifications'), - constants = require('ripple/constants'), - deviceSettings = require('ripple/deviceSettings'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'), - _self = { - ringtoneVolume: undefined, - msgRingtoneVolume: undefined, - vibrationSetting: undefined, - - setDefaultRingtone: function (ringtoneUrl) { - utils.validateArgumentType(ringtoneUrl, "string", ExceptionTypes.INVALID_PARAMETER, "ringtoneUrl paramter is not a string", new Exception()); - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, "Setting default ringtone to: " + ringtoneUrl); - }, - - setAsWallpaper: function (wallpaperUrl) { - utils.validateArgumentType(wallpaperUrl, "string", ExceptionTypes.INVALID_PARAMETER, "wallpaperUrl paramter is not a string", new Exception()); - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, "Setting wallpaper to: " + wallpaperUrl); - } - }; - -_self.__defineGetter__("ringtoneVolume", function () { - return deviceSettings.retrieve("Config.ringtoneVolume"); -}); - -_self.__defineGetter__("msgRingtoneVolume", function () { - return deviceSettings.retrieve("Config.msgRingtoneVolume"); -}); - -_self.__defineGetter__("vibrationSetting", function () { - return deviceSettings.retrieve("Config.vibrationSetting"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/DataNetworkConnectionTypes.js b/lib/ripple/platform/wac/1.0/DataNetworkConnectionTypes.js deleted file mode 100644 index 1ff87a56..00000000 --- a/lib/ripple/platform/wac/1.0/DataNetworkConnectionTypes.js +++ /dev/null @@ -1,34 +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 utils = require('ripple/utils'), - _self = { - "BLUETOOTH": undefined, - "EDGE": undefined, - "EVDO": undefined, - "GPRS": undefined, - "IRDA": undefined, - "LTE": undefined, - "ONEXRTT": undefined, - "WIFI": undefined - }; - -utils.forEach(_self, function (value, property) { - _self.__defineGetter__(property, function () { - return property; - }); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/DataNetworkInfo.js b/lib/ripple/platform/wac/1.0/DataNetworkInfo.js deleted file mode 100644 index cf86d0be..00000000 --- a/lib/ripple/platform/wac/1.0/DataNetworkInfo.js +++ /dev/null @@ -1,60 +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 event = require('ripple/event'), - utils = require('ripple/utils'), - _console = require('ripple/console'), - deviceSettings = require('ripple/deviceSettings'), - DataNetworkConnectionTypes = require('ripple/platform/wac/1.0/DataNetworkConnectionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - -_self = { - isDataNetworkConnected: undefined, - networkConnectionType: undefined, - onNetworkConnectionChanged: undefined, - - getNetworkConnectionName: function (networkConnectionType) { - var foundConnectionType; - utils.validateArgumentType(networkConnectionType, "string", ExceptionTypes.INVALID_PARAMETER, "networkConnectionType is invalid, expected a string", new Exception()); - foundConnectionType = DataNetworkConnectionTypes[networkConnectionType.toUpperCase()]; - return foundConnectionType || null; - } -}; - -event.on("DataNetworkConnectionChanged", function (newConnectionName) { - var callback = _self.onNetworkConnectionChanged, - msg = "Fired onNetworkConnectionChanged with newConnectionName: " + newConnectionName; - - if (callback && typeof callback === "function") { - callback.apply(null, [newConnectionName]); - } - else { - msg += " --> BUT there was no registered callback found."; - } - - _console.log(msg); -}); - -_self.__defineGetter__("isDataNetworkConnected", function () { - return deviceSettings.retrieveAsBoolean("DataNetworkInfo.isDataNetworkConnected"); -}); - -_self.__defineGetter__("networkConnectionType", function () { - var value = deviceSettings.retrieve("DataNetworkInfo.networkConnectionType"); - return value instanceof Array ? value : [value]; -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/Device.js b/lib/ripple/platform/wac/1.0/Device.js deleted file mode 100644 index da16c3c5..00000000 --- a/lib/ripple/platform/wac/1.0/Device.js +++ /dev/null @@ -1,131 +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 constants = require('ripple/constants'), - exception = require('ripple/exception'), - _console = require('ripple/console'), - utils = require('ripple/utils'), - notifications = require('ripple/notifications'), - ApplicationTypes = require('ripple/platform/wac/1.0/ApplicationTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - _applicationTypes = { - FILES: "FILES", - MEDIAPLAYER: "MEDIAPLAYER", - PHONECALL: "PHONECALL", - PICTURES: "PICTURES" - }, - _self; - -function _throwUnsupportedException(method) { - exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception()); -} - -_self = { - // Properties - clipboardString: undefined, - widgetEngineName: undefined, - widgetEngineProvider: undefined, - widgetEngineVersion: undefined, - - // Methods - getAvailableApplications: function () { - return constants.PLATFORMS.WAC.APPLICATIONS || []; - }, - - getDirectoryFileNames: function () { - _throwUnsupportedException("Device.getDirectoryFileNames"); - }, - getFile: function () { - _throwUnsupportedException("Device.getFile"); - }, - - launchApplication: function launchApplication(application, startParameter) { - if (!application || typeof(application) !== "string") { - exception.raise(ExceptionTypes.INVALID_PARAMETER, - "Invalid argument 'application' at Device.launchApplication(): expected to be of type 'string' but was of type: " + (application ? typeof(application) : "null"), - Exception); - } - - if (startParameter && typeof(startParameter) !== "string") { - exception.raise(ExceptionTypes.INVALID_PARAMETER, - "Invalid argument 'startParameter' at Device.launchApplication(): expected to be 'string' but was : " + typeof(startParameter), - Exception); - } - - // rudimentary implementation for now - var message = "The widget has requested application: '" + application + "' to be launched. \n\n"; - - if (startParameter) { - message += "The following start parameter was sent in: " + startParameter + "\n\n"; - } - - if (_applicationTypes[application] && !startParameter) { - message += "Launching this application can also be done with an optional startParameter which was not provided" + "\n\n"; - } - - if (!ApplicationTypes[application]) { - message += "Note: the application requested is not part of the common values specified by the WAC API."; - } - - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, message); - _console.log(message); - }, - - copyFile: function () { - _throwUnsupportedException("Device.copyFile"); - }, - deleteFile: function () { - _throwUnsupportedException("Device.deleteFile"); - }, - findFiles: function () { - _throwUnsupportedException("Device.findFiles"); - }, - getFileSystemRoots: function () { - _throwUnsupportedException("Device.getFileSystemRoots"); - }, - getFileSystemSize: function () { - _throwUnsupportedException("Device.getFileSystemSize"); - }, - moveFile: function () { - _throwUnsupportedException("Device.moveFile"); - }, - onFilesFound: function () { - _throwUnsupportedException("Device.onFilesFound"); - }, - setRingtone: function () { - _throwUnsupportedException("Device.setRingtone"); - }, - - vibrate: function (duration) { - utils.validateArgumentType(duration, "number", ExceptionTypes.INVALID_PARAMETER, "duration paramter is not a number", new Exception()); - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, "Vibrating for " + duration + " second(s)."); - } - -}; - -_self.__defineGetter__("widgetEngineName", function () { - return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_NAME; -}); - -_self.__defineGetter__("widgetEngineProvider", function () { - return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_PROVIDER; -}); - -_self.__defineGetter__("widgetEngineVersion", function () { - return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_VERSION; -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/DeviceInfo.js b/lib/ripple/platform/wac/1.0/DeviceInfo.js deleted file mode 100644 index 63878bb3..00000000 --- a/lib/ripple/platform/wac/1.0/DeviceInfo.js +++ /dev/null @@ -1,79 +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 utils = require('ripple/utils'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'), - devices = require('ripple/devices'), - _self; - -_self = { - ownerInfo: undefined, // return AddressBookItem - phoneColorDepthDefault: undefined, - phoneFirmware: undefined, - phoneManufacturer: undefined, - phoneModel: undefined, - phoneOS: undefined, - phoneSoftware: undefined, - phoneScreenHeightDefault: undefined, - phoneScreenWidthDefault: undefined, - totalMemory: undefined -}; - -function _getDeviceAttribute(attr) { - var devicePointer = devices.getCurrentDevice(); - utils.forEach(attr.split("."), function (dot) { - devicePointer = devicePointer[dot]; - }); - return devicePointer; -} - -_self.__defineGetter__("phoneColorDepthDefault", function () { - return deviceSettings.retrieveAsInt("DeviceInfo.phoneColorDepthDefault"); -}); - -_self.__defineGetter__("phoneFirmware", function () { - return _getDeviceAttribute("firmware"); -}); - -_self.__defineGetter__("phoneManufacturer", function () { - return _getDeviceAttribute("manufacturer"); -}); - -_self.__defineGetter__("phoneOS", function () { - return _getDeviceAttribute("osName") + " " + _getDeviceAttribute("osVersion"); -}); - -_self.__defineGetter__("phoneModel", function () { - return _getDeviceAttribute("model"); -}); - -_self.__defineGetter__("phoneSoftware", function () { - return _getDeviceAttribute("osVersion"); -}); - -_self.__defineGetter__("phoneScreenHeightDefault", function () { - return _getDeviceAttribute("screen.height"); -}); - -_self.__defineGetter__("phoneScreenWidthDefault", function () { - return _getDeviceAttribute("screen.width"); -}); - -_self.__defineGetter__("totalMemory", function () { - return deviceSettings.retrieveAsInt("DeviceInfo.totalMemory"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/DeviceStateInfo.js b/lib/ripple/platform/wac/1.0/DeviceStateInfo.js deleted file mode 100644 index 36a3b533..00000000 --- a/lib/ripple/platform/wac/1.0/DeviceStateInfo.js +++ /dev/null @@ -1,108 +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 utils = require('ripple/utils'), - exception = require('ripple/exception'), - _console = require('ripple/console'), - geo = require('ripple/geo'), - event = require('ripple/event'), - deviceSettings = require('ripple/deviceSettings'), - PositionInfo = require('ripple/platform/wac/1.0/PositionInfo'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - _self; - -event.on("ScreenChangeDimensions", function (width, height) { - try { - if (typeof _self.onScreenChangeDimensions === 'function') { - _self.onScreenChangeDimensions(width, height); - } - _console.log("called DeviceStateInfo.onScreenChangeDimensions callback function with width = " + width + " and height = " + height); - } catch (e) { - exception.handle(e, false); - } -}); - -_self = { - availableMemory: undefined, - language: undefined, - keypadLightOn: undefined, - backLightOn: undefined, - processorUtilizationPercent: undefined, - audioPath: undefined, - - onPositionRetrieved: undefined, - - requestPositionInfo: function (method) { - utils.validateNumberOfArguments(1, 1, arguments.length, - ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid number of parameters", new Exception()); - utils.validateArgumentType(method, "string", - ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid parameter", new Exception()); - - if (!(method.match(/gps|agps|cellid/))) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, - "Invalid method, expected (gps, agps or cellid)", Exception); - } - - if (typeof _self.onPositionRetrieved === "function") { - var delay = geo.delay * 1000, - timeout = geo.timeout; - setTimeout(function () { - var pos = PositionInfo, - errorObj = {}; - - if (timeout) { - //create - utils.forEach(pos, function (val, key) { - errorObj[key] = undefined; - }); - pos = errorObj; - } - _self.onPositionRetrieved(pos, method); - }, delay); - } - }, - - onScreenChangeDimensions: undefined, - - onFlipEvent: undefined -}; - -_self.__defineGetter__("availableMemory", function () { - return deviceSettings.retrieveAsInt("DeviceStateInfo.availableMemory"); -}); - -_self.__defineGetter__("language", function () { - return deviceSettings.retrieve("DeviceStateInfo.language"); -}); - -_self.__defineGetter__("keypadLightOn", function () { - return deviceSettings.retrieveAsBoolean("DeviceStateInfo.keypadLightOn"); -}); - -_self.__defineGetter__("backLightOn", function () { - return deviceSettings.retrieveAsBoolean("DeviceStateInfo.backLightOn"); -}); - -_self.__defineGetter__("audioPath", function () { - return deviceSettings.retrieve("DeviceStateInfo.audioPath"); -}); - -_self.__defineGetter__("processorUtilizationPercent", function () { - return deviceSettings.retrieve("DeviceStateInfo.processorUtilizationPercent"); -}); - -module.exports = _self; - diff --git a/lib/ripple/platform/wac/1.0/EventRecurrenceTypes.js b/lib/ripple/platform/wac/1.0/EventRecurrenceTypes.js deleted file mode 100644 index 63217635..00000000 --- a/lib/ripple/platform/wac/1.0/EventRecurrenceTypes.js +++ /dev/null @@ -1,24 +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. - */ -module.exports = { - NOT_REPEAT: "NOT_REPEAT", - DAILY: "DAILY", - EVERY_WEEKDAY: "EVERY_WEEKDAY", - WEEKLY_ON_DAY: "WEEKLY_ON_DAY", - MONTHLY_ON_DAY: "MONTHLY_ON_DAY", - MONTHLY_ON_DAY_COUNT: "MONTHLY_ON_DAY_COUNT", - YEARLY: "YEARLY" -}; diff --git a/lib/ripple/platform/wac/1.0/Exception.js b/lib/ripple/platform/wac/1.0/Exception.js deleted file mode 100644 index d0099b7c..00000000 --- a/lib/ripple/platform/wac/1.0/Exception.js +++ /dev/null @@ -1,28 +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. - */ -module.exports = function () { - this.message = ""; - this.type = ""; - - this.toString = function () { - var result = this.type + ': "' + this.message + '"'; - - if (this.stack) { - result += "\n" + this.stack; - } - return result; - }; -}; diff --git a/lib/ripple/platform/wac/1.0/ExceptionTypes.js b/lib/ripple/platform/wac/1.0/ExceptionTypes.js deleted file mode 100644 index 559be66c..00000000 --- a/lib/ripple/platform/wac/1.0/ExceptionTypes.js +++ /dev/null @@ -1,34 +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 _self = {}; - -_self.__defineGetter__("INVALID_PARAMETER", function () { - return "invalid_parameter"; -}); - -_self.__defineGetter__("SECURITY", function () { - return "security"; -}); - -_self.__defineGetter__("UNKNOWN", function () { - return "unknown"; -}); - -_self.__defineGetter__("UNSUPPORTED", function () { - return "unsupported"; -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/File.js b/lib/ripple/platform/wac/1.0/File.js deleted file mode 100644 index af095d21..00000000 --- a/lib/ripple/platform/wac/1.0/File.js +++ /dev/null @@ -1,23 +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. - */ -module.expots = function () { - this.createDate = undefined; - this.fileName = undefined; - this.filePath = undefined; - this.fileSize = undefined; - this.isDirectory = undefined; - this.lastModifyDate = undefined; -}; diff --git a/lib/ripple/platform/wac/1.0/Message.js b/lib/ripple/platform/wac/1.0/Message.js deleted file mode 100644 index 629de8d8..00000000 --- a/lib/ripple/platform/wac/1.0/Message.js +++ /dev/null @@ -1,97 +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 exception = require('ripple/exception'), - Attachment = require('ripple/platform/wac/1.0/Attachment'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'); - -function _throwUnsupportedException(method) { - exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception()); -} - -module.exports = function () { - this.messageId = Math.uuid(undefined, 16); - this.callbackNumber = undefined; - this.destinationAddress = []; - this.isRead = undefined; - this.messagePriority = undefined; - this.messageType = undefined; - this.subject = undefined; - this.body = undefined; - this.sourceAddress = undefined; - this.validityPeriodHours = undefined; - this.time = undefined; - this.ccAddress = []; - this.bccAddress = []; - this.attachments = []; - - this.addAttachment = function (fileFullName) { - var attachment = new Attachment(); - attachment.fileName = fileFullName; - this.attachments.push(attachment); - }; - this.deleteAttachment = function (attachment) { - - for (var i = this.attachments.length - 1; i >= 0; i--) { - if (this.attachments[i].fileName === attachment.fileName) { - this.attachments.splice(i, 1); - } - } - }; - this.saveAttachment = function (fileFullName, attachment) { - _throwUnsupportedException("Widget.Messaging.Message.addAddress"); - }; - this.addAddress = function (type, address) { - - var addresses = address.split(";"); - - switch (type) { - case "destination": - this.destinationAddress = this.destinationAddress.concat(addresses); - break; - case "cc": - this.ccAddress = this.ccAddress.concat(addresses); - break; - case "bcc": - this.bccAddress = this.bccAddress.concat(addresses); - break; - } - }; - - this.deleteAddress = function (type, address) { - var addresses = address.split(";"), - filter = function (orig) { - return orig.filter(function (address) { - return !addresses.some(function (x) { - return address === x; - }); - }); - }; - - switch (type) { - case "destination": - this.destinationAddress = filter(this.destinationAddress); - break; - case "cc": - this.ccAddress = filter(this.ccAddress); - break; - case "bcc": - this.bccAddress = filter(this.bccAddress); - break; - } - }; - -}; diff --git a/lib/ripple/platform/wac/1.0/MessageFolderTypes.js b/lib/ripple/platform/wac/1.0/MessageFolderTypes.js deleted file mode 100644 index b3430384..00000000 --- a/lib/ripple/platform/wac/1.0/MessageFolderTypes.js +++ /dev/null @@ -1,21 +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. - */ -module.exports = { - DRAFTS: "drafts", - INBOX: "inbox", - OUTBOX: "outbox", - SENTBOX: "sentbox" -}; diff --git a/lib/ripple/platform/wac/1.0/MessageQuantities.js b/lib/ripple/platform/wac/1.0/MessageQuantities.js deleted file mode 100644 index 9bd1bb3c..00000000 --- a/lib/ripple/platform/wac/1.0/MessageQuantities.js +++ /dev/null @@ -1,20 +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. - */ -module.exports = { - totalMessageCnt: undefined, - totalMessageReadCnt: undefined, - totalMessageUnreadCnt: undefined -}; diff --git a/lib/ripple/platform/wac/1.0/MessageTypes.js b/lib/ripple/platform/wac/1.0/MessageTypes.js deleted file mode 100644 index 27caccb9..00000000 --- a/lib/ripple/platform/wac/1.0/MessageTypes.js +++ /dev/null @@ -1,20 +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. - */ -module.exports = { - EmailMessage: "email", - MMSMessage: "mms", - SMSMessage: "sms" -}; diff --git a/lib/ripple/platform/wac/1.0/Messaging.js b/lib/ripple/platform/wac/1.0/Messaging.js deleted file mode 100644 index 6daa5d97..00000000 --- a/lib/ripple/platform/wac/1.0/Messaging.js +++ /dev/null @@ -1,103 +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 exception = require('ripple/exception'), - utils = require('ripple/utils'), - constants = require('ripple/constants'), - notifications = require('ripple/notifications'), - _console = require('ripple/console'), - Message = require('ripple/platform/wac/1.0/Message'), - MessageTypes = require('ripple/platform/wac/1.0/MessageTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'); - -function _throwUnsupportedException(method) { - exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception()); -} - -module.exports = { - onMessageArrived: undefined, - onMessageSendingFailure: undefined, - onMessagesFound: undefined, - - createMessage: function (messageType) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "createMessage invalid number of arguments", new Exception()); - utils.validateArgumentType(messageType, "string", ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception()); - - if (!utils.some(MessageTypes, function (value) { - return value === messageType; - })) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception()); - } - - var message = new Message(); - message.messageType = messageType; - - return message; - }, - deleteMessage: function () { - _throwUnsupportedException("Messaging.deleteMessage"); - }, - getMessage: function () { - _throwUnsupportedException("Messaging.getMessage"); - }, - getMessageQuantities: function () { - _throwUnsupportedException("Messaging.getMessageQuantities"); - }, - sendMessage: function (msg) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.UNSUPPORTED, "sendMessage invalid number of arguments", new Exception()); - if (msg instanceof Message === false) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "expected a valid Message object", new Exception()); - } - - //TODO: Must be modded to fail and to then call the onMessageSendingFailure callback - var message = "Sent " + msg.messageType + " " + msg.messageId + " to " + msg.destinationAddress; - - // insert fail check here - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, message); - _console.log(message); - }, - moveMessageToFolder: function () { - _throwUnsupportedException("Messaging.moveMessageToFolder"); - }, - copyMessageToFolder: function () { - _throwUnsupportedException("Messaging.copyMessageToFolder"); - }, - createFolder: function () { - _throwUnsupportedException("Messaging.createFolder"); - }, - deleteFolder: function () { - _throwUnsupportedException("Messaging.deleteFolder"); - }, - getFolderNames: function () { - _throwUnsupportedException("Messaging.getFolderNames"); - }, - findMessages: function () { - _throwUnsupportedException("Messaging.findMessages"); - }, - getCurrentEmailAccount: function () { - _throwUnsupportedException("Messaging.getCurrentEmailAccount"); - }, - getEmailAccounts: function () { - _throwUnsupportedException("Messaging.getEmailAccounts"); - }, - setCurrentEmailAccount: function () { - _throwUnsupportedException("Messaging.setCurrentEmailAccount"); - }, - deleteEmailAccount: function () { - _throwUnsupportedException("Messaging.deleteEmailAccount"); - } - -}; diff --git a/lib/ripple/platform/wac/1.0/Multimedia.js b/lib/ripple/platform/wac/1.0/Multimedia.js deleted file mode 100644 index d247e008..00000000 --- a/lib/ripple/platform/wac/1.0/Multimedia.js +++ /dev/null @@ -1,60 +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 event = require('ripple/event'), - VideoPlayer = require('ripple/platform/wac/1.0/VideoPlayer'), - AudioPlayer = require('ripple/platform/wac/1.0/AudioPlayer'), - constants = require('ripple/constants'), - _volume = 5, - _audioState, - _videoState, - _self; - -event.on("MultimediaVolumeChanged", function updateVolume(volume) { - _volume = volume; -}); - -event.on("MultimediaAudioStateChanged", function updateAudioState(state) { - _audioState = state; -}); - -event.on("MultimediaVideoStateChanged", function updateVideoState(state) { - _videoState = state; -}); - -_self = { - - isAudioPlaying: undefined, - isVideoPlaying: undefined, - - getVolume: function () { - return _volume; - }, - - stopAll: function () { - VideoPlayer.stop(); - AudioPlayer.stop(); - } -}; - -_self.__defineGetter__("isAudioPlaying", function () { - return _audioState === constants.MULTIMEDIA.AUDIO_STATES.PLAYING; -}); - -_self.__defineGetter__("isVideoPlaying", function () { - return _videoState === "playing"; -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/PIM.js b/lib/ripple/platform/wac/1.0/PIM.js deleted file mode 100644 index 5bcd076d..00000000 --- a/lib/ripple/platform/wac/1.0/PIM.js +++ /dev/null @@ -1,281 +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 _self, - exception = require('ripple/exception'), - Exception = require('ripple/platform/wac/1.0/Exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - AddressBookItem = require('ripple/platform/wac/1.0/AddressBookItem'), - CalendarItem = require('ripple/platform/wac/1.0/CalendarItem'), - utils = require('ripple/utils'), - db = require('ripple/db'), - constants = require('ripple/constants'); - -function _throwUnsupportedException(method) { - exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception()); -} - -function _toAddressBookItem(contact) { - if (!contact) { - return null; - } - - var addressBookItem = new AddressBookItem(); - - utils.forEach(contact, function (prop, key) { - addressBookItem[key] = contact[key]; - }); - - return addressBookItem; -} - -function _toCalendarItem(item) { - if (!item) { - return null; - } - - var calendarItem = new CalendarItem(); - - utils.forEach(item, function (prop, key) { - calendarItem[key] = item[key]; - }); - - return calendarItem; -} - -function _getData(type) { - var data = db.retrieveObject(type) || []; - return data; -} - -function _saveData(type, items) { - db.saveObject(type, items); -} - -function _getContacts() { - var contacts = _getData(constants.PIM.ADDRESS_LIST_KEY), - gord, - dan, - brent, - pj, - mark; - - if (contacts.length === 0) { - - gord = new AddressBookItem(); - gord.addressBookItemId = "0"; - gord.fullName = "Gord Tanner"; - gord.eMail = "gord@tinyHippos.com"; - gord.company = "tinyHippos Inc"; - gord.title = "Code Poet"; - gord.address = "121 Charles Street W, Kitchener, Ontario, Canada"; - - dan = new AddressBookItem(); - dan.addressBookItemId = "1"; - dan.fullName = "Dan Silivestru"; - dan.eMail = "dan@tinyHippos.com"; - dan.company = "tinyHippos Inc"; - dan.title = "Co-Founder And Chief Technology Officer"; - dan.address = "121 Charles Street W, Kitchener, Ontario, Canada"; - - pj = new AddressBookItem(); - pj.addressBookItemId = "2"; - pj.fullName = "PJ Lowe"; - pj.eMail = "pj@tinyHippos.com"; - pj.company = "tinyHippos Inc"; - pj.title = "Co-Founder And Chief Operations Officer"; - pj.address = "121 Charles Street W, Kitchener, Ontario, Canada"; - - brent = new AddressBookItem(); - brent.addressBookItemId = "2"; - brent.fullName = "Brent Lintner"; - brent.eMail = "brent@tinyHippos.com"; - brent.company = "tinyHippos Inc"; - brent.title = "Co-Founder And Chief Operations Officer"; - brent.address = "121 Charles Street W, Kitchener, Ontario, Canada"; - - mark = new AddressBookItem(); - mark.addressBookItemId = "3"; - mark.fullName = "Mark McArdle"; - mark.eMail = "mark@tinyHippos.com"; - mark.company = "tinyHippos Inc"; - mark.title = "Chief Executive Officer"; - mark.address = "121 Charles Street W, Kitchener, Ontario, Canada"; - - contacts.push(gord); - contacts.push(dan); - contacts.push(pj); - contacts.push(brent); - contacts.push(mark); - - _saveData(constants.PIM.ADDRESS_LIST_KEY, contacts); - } - return contacts.map(_toAddressBookItem); -} - -function _getEvents() { - var events = _getData(constants.PIM.CALENDAR_LIST_KEY); - return events.map(_toCalendarItem); -} - -function _get(type, id, fetchIDFunc) { - var items = _getData(type); - return items.reduceRight(function (match, item) { - return fetchIDFunc(item) === id ? item : match; - }, null); -} - -function _getAddressBookID(item) { - return item.addressBookItemId; -} - -function _getCalendarID(item) { - return item.calendarItemId; -} - -function _getContact(id) { - return _toAddressBookItem(_get(constants.PIM.ADDRESS_LIST_KEY, id, _getAddressBookID)); -} - -function _getEvent(id) { - return _toCalendarItem(_get(constants.PIM.CALENDAR_LIST_KEY, id, _getCalendarID)); -} - -function _add(type, item, idProp) { - var items = _getData(type); - - if (!item[idProp]) { - item[idProp] = Math.uuid(undefined, 16); - } - - items.push(item); - _saveData(type, items); -} - -function _delete(type, id, fetchIDFunc) { - var items = _getData(type); - - _saveData(type, items.filter(function (item) { - return fetchIDFunc(item) !== id; - })); -} - -function _validateArgs(min, max, len) { - utils.validateNumberOfArguments(min, max, len, - ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception()); -} - -function _validateType(arg, argType) { - utils.validateArgumentType(arg, argType, - ExceptionTypes.INVALID_PARAMETER, "argument of wrong type provided", - new Exception()); -} - -function _validateAddressBookItem(item) { - if ((item instanceof AddressBookItem) === false) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid contact, not instance of AddressBookItem.", new Exception()); - } -} - -_self = { - addAddressBookItem: function (contact) { - _validateArgs(1, 1, arguments.length); - _validateAddressBookItem(contact); - - _add(constants.PIM.ADDRESS_LIST_KEY, contact, "addressBookItemId"); - }, - createAddressBookGroup: function (groupName) { - _throwUnsupportedException("Widget.PIM.createAddressBookGroup"); - }, - createAddressBookItem: function () { - return new AddressBookItem(); - }, - deleteAddressBookItem: function (contactid) { - _validateArgs(1, 1, arguments.length); - _validateType(contactid, "string"); - _delete(constants.PIM.ADDRESS_LIST_KEY, contactid, _getAddressBookID); - }, - deleteAddressBookGroup: function (groupName) { - _throwUnsupportedException("Widget.PIM.deleteAddressBookGroup"); - }, - getAddressBookItem: function (contactid) { - _validateArgs(1, 1, arguments.length); - _validateType(contactid, "string"); - return _getContact(contactid); - }, - getAddressBookItemsCount: function () { - _validateArgs(0, 0, arguments.length); - var items = _getContacts(); - return items.length; - }, - getAvailableAddressGroupNames: function () { - _throwUnsupportedException("Widget.PIM.getAvailableAddressGroupNames"); - }, - getAddressBookGroupMembers: function (groupName) { - _throwUnsupportedException("Widget.PIM.getAddressBookGroupMembers"); - }, - findAddressBookItems: function (comparisonContact, startInx, endInx) { - _validateArgs(3, 3, arguments.length); - utils.validateMultipleArgumentTypes([comparisonContact, startInx, endInx], ["object", "number", "number"], ExceptionTypes.INVALID_PARAMETER, "argument of wrong type provided", - new Exception()); - - if (endInx < 0) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception()); - } - - startInx = startInx < 0 ? 0 : startInx; - - var contacts = _getContacts(); - utils.find(comparisonContact, contacts, startInx, endInx, _self.onAddressBookItemsFound); - }, - - addCalendarItem: function (calendarItem) { - _validateArgs(1, 1, arguments.length); - _add(constants.PIM.CALENDAR_LIST_KEY, calendarItem, "calendarItemId"); - }, - deleteCalendarItem: function (calendarId) { - _validateArgs(1, 1, arguments.length); - _delete(constants.PIM.CALENDAR_LIST_KEY, calendarId, _getCalendarID); - }, - getCalendarItem: function (calendarId) { - _validateArgs(1, 1, arguments.length); - return _getEvent(calendarId); - }, - findCalendarItems: function (itemToMatch, startInx, endInx) { - _validateArgs(1, 3, arguments.length); - var events = _getEvents(); - utils.find(itemToMatch, events, startInx, endInx, _self.onCalendarItemsFound); - }, - getCalendarItems: function (startTime, endTime) { - var events = _getEvents(); - - return events.reduce(function (matches, event) { - if (event.eventStartTime >= startTime && event.eventStartTime <= endTime) { - matches.push(event); - } - return matches; - }, []); - }, - exportAsVCard: function (addressBookItems) { - _throwUnsupportedException("Widget.PIM.exportAsVCard"); - }, - - onAddressBookItemsFound: undefined, // function (addressBookItemsFound) { } - onCalendarItemsFound: undefined, // function (calendarItemsFound) { } - onCalendarItemAlert: undefined, // function (calendarItem) { } - onVCardExportingFinish: undefined // function (vCardFilePath) { } -}; - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/PowerInfo.js b/lib/ripple/platform/wac/1.0/PowerInfo.js deleted file mode 100644 index d2dfa857..00000000 --- a/lib/ripple/platform/wac/1.0/PowerInfo.js +++ /dev/null @@ -1,113 +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 _self, - event = require('ripple/event'), - _console = require('ripple/console'), - deviceSettings = require('ripple/deviceSettings'), - _lastPercentRemaining; - -_self = { - isCharging: undefined, - percentRemaining: undefined, - - onChargeStateChange: undefined, - onLowBattery: undefined, - onChargeLevelChange: undefined -}; - -function _getCurrentChargeState(percentRemaining, isCharging) { - var batteryState; - if (percentRemaining === 100 && isCharging) { - batteryState = "full"; - } - else if (!isCharging) { - batteryState = "discharging"; - } - else { - batteryState = "charging"; - } - return batteryState; -} - -event.on("DeviceBatteryStateChanged", function (isCharging) { - var callback = _self.onChargeStateChange, - msg = "", - batteryLevel = _self.percentRemaining, - batteryState; - - batteryState = _getCurrentChargeState(batteryLevel, isCharging); - - msg += "Fired onChargeStateChange with batteryState: " + batteryState; - - if (callback && typeof callback === "function") { - callback.apply(null, [batteryState]); - } - else { - msg += " --> BUT there was no registered callback found."; - } - - _console.log(msg); -}); - -event.on("DeviceBatteryLevelChanged", function (percentRemaining) { - - var callback = _self.onChargeLevelChange, - lowBatteryCallback = _self.onLowBattery, - msg = "Fired onChargeLevelChange with percentRemaining: " + percentRemaining; - - // blah, stupid Options returning strings - percentRemaining = parseInt(percentRemaining, 10); - - if (callback && typeof callback === "function") { - callback.apply(null, [percentRemaining]); - } - else { - msg += " --> BUT there was no registered callback found."; - } - - _console.log(msg); - - if (percentRemaining <= 10) { - - msg = "Fired onLowBattery with percentRemaining: " + percentRemaining; - - if (lowBatteryCallback && typeof lowBatteryCallback === "function") { - lowBatteryCallback.apply(null, [percentRemaining]); - } - else { - msg += " --> BUT there was no registered callback found."; - } - - _console.log(msg); - } - - if (percentRemaining === 100 || (percentRemaining < 100 && _lastPercentRemaining === 100)) { - event.trigger("DeviceBatteryStateChanged", [_self.isCharging]); - } - - _lastPercentRemaining = percentRemaining; - -}); - -_self.__defineGetter__("isCharging", function () { - return deviceSettings.retrieveAsBoolean("PowerInfo.isCharging"); -}); - -_self.__defineGetter__("percentRemaining", function () { - return deviceSettings.retrieveAsInt("PowerInfo.percentRemaining"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/RadioInfo.js b/lib/ripple/platform/wac/1.0/RadioInfo.js deleted file mode 100644 index 396f7adb..00000000 --- a/lib/ripple/platform/wac/1.0/RadioInfo.js +++ /dev/null @@ -1,61 +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 _self, - event = require('ripple/event'), - _console = require('ripple/console'), - deviceSettings = require('ripple/deviceSettings'); - -_self = { - isRoaming: undefined, - radioSignalStrengthPercent: undefined, - isRadioEnabled: undefined, - radioSignalSource: undefined, - onSignalSourceChange: undefined -}; - -event.on("RadioSignalSourceChanged", function () { - var callback = _self.onSignalSourceChange, - isRoaming = _self.isRoaming, - signalSource = _self.radioSignalSource, - msg = "Fired onSignalSourceChange. signalSource: " + signalSource + ", isRoaming: " + isRoaming; - - if (callback && typeof callback === "function") { - callback.apply(null, [signalSource, isRoaming]); - } - else { - msg += " --> BUT there was no registered callback found."; - } - - _console.log(msg); -}); - -_self.__defineGetter__("radioSignalSource", function () { - return deviceSettings.retrieve("RadioInfo.radioSignalSource"); -}); - -_self.__defineGetter__("isRoaming", function () { - return deviceSettings.retrieveAsBoolean("RadioInfo.isRoaming"); -}); - -_self.__defineGetter__("isRadioEnabled", function () { - return deviceSettings.retrieveAsBoolean("RadioInfo.isRadioEnabled"); -}); - -_self.__defineGetter__("radioSignalStrengthPercent", function () { - return deviceSettings.retrieveAsInt("RadioInfo.radioSignalStrengthPercent"); -}); - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/Telephony.js b/lib/ripple/platform/wac/1.0/Telephony.js deleted file mode 100644 index d3b366d1..00000000 --- a/lib/ripple/platform/wac/1.0/Telephony.js +++ /dev/null @@ -1,111 +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 _self, - exception = require('ripple/exception'), - utils = require('ripple/utils'), - db = require('ripple/db'), - constants = require('ripple/constants'), - Device = require('ripple/platform/wac/1.0/Device'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'); - - -function _throwUnsupportedException(method) { - exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception()); -} - -_self = { - - // Public Callbacks - onCallEvent: undefined,// function (callType, phoneNumber) { }, - onCallRecordsFound: undefined,// function (callRecords) { }; - - // Public Methods - initiateVoiceCall: function (phoneNumber) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "initiateVoiceCall invalid number of parameters", new Exception()); - //HACK: should this be hardcoded? - //I am still not even sure this is the correct behaviour - Device.launchApplication("PHONECALL", phoneNumber); - - if (_self.onCallEvent) { - //HACK: shouldn't be hardcoded - //also what should the context be? isn't spec'ed - _self.onCallEvent.apply(_self, ["outgoing", phoneNumber]); - } - }, - getCallRecordCnt: function (callRecordType) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecordCnt invalid number of parameters", new Exception()); - var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY); - - return utils.sum(calls, function (call) { - return call.callRecordType === callRecordType; - }); - }, - getCallRecord: function (callRecordType, id) { - utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecord invalid number of parameters", new Exception()); - var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY); - - return utils.map(calls, function (call) { - return call.callRecordType === callRecordType ? call : null; - }).reduce(function (match, call) { - return match || call.callRecordId === id || null; - }, null); - }, - deleteCallRecord: function (callRecordType, id) { - utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteCallRecord invalid number of parameters", new Exception()); - var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY), - indexToDelete = calls.reduce(function (result, call, index) { - return call.callRecordType === callRecordType && - call.callRecordId === id ? index : result; - }, -1); - - if (indexToDelete >= 0) { - calls.splice(indexToDelete, 1); - db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls); - } - - }, - - deleteAllCallRecords: function (callRecordType) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteAllCallRecords invalid number of parameters", new Exception()); - var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY), - indexesToDelete = calls.reduce(function (result, call, index) { - if (call.callRecordType === callRecordType) { - result.push(index); - } - return result; - }, []); - - utils.forEach(indexesToDelete, function (index) { - calls.splice(index, 1); - }); - - if (indexesToDelete.length > 0) { - db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls); - } - - }, - - findCallRecords: function (comparisonRecord, startInx, endInx) { - utils.validateNumberOfArguments(1, 3, arguments.length, ExceptionTypes.INVALID_PARAMETER, "findCallRecords invalid number of parameters", new Exception()); - var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY); - utils.find(comparisonRecord, calls, startInx, endInx, _self.onCallRecordsFound); - - } - -}; - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/VideoPlayer.js b/lib/ripple/platform/wac/1.0/VideoPlayer.js deleted file mode 100644 index c740847c..00000000 --- a/lib/ripple/platform/wac/1.0/VideoPlayer.js +++ /dev/null @@ -1,172 +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 _self, - _console = require('ripple/console'), - event = require('ripple/event'), - utils = require('ripple/utils'), - fileSystem = require('ripple/fileSystem'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'), - exception = require('ripple/exception'), - _currentlySet, - _currentVideoFile, - _state = null, - _loopCount, _video, - _STATES = { - "OPENED": "opened", - "STOPPED": "stopped", - "PAUSED": "paused", - "PLAYING": "playing", - "COMPLETED": "completed" - }; - -function _validateVideoType(fileUrl) { - var matched = fileUrl.match(/\.(\w*)$/), - maps = { - "ogv": "ogg", - "flv": "mp4" - }, - type = matched ? matched[1] : ""; - - if (_video && _video.canPlayType("video/" + (maps[type] || type)) === "") { - _console.warn("Attempting to load a video that might not work in the current browser [" + fileUrl + "]"); - } -} - -function _validateAndSet(state, validStates, callbackBeforeSuccess) { - var i, valid = false; - - for (i = 0; i < validStates.length; i++) { - if (validStates[i] === _state) { - valid = true; - } - } - - if (!valid) { - _console.warn("Attempted to initiate VideoPlayer." + state + - " in invalid state. current state: " + _state); - } else { - if (typeof(callbackBeforeSuccess) === "function") { - callbackBeforeSuccess.apply(); - } - event.trigger("MultimediaVideoStateChanged", [state], true); - } - - return valid; -} - -event.on("MultimediaVideoStateChanged", function (state) { - _state = state; - if (typeof _self.onStateChange === "function") { - _self.onStateChange.apply(_self, [state]); - } -}); - -_self = module.exports = { - onStateChange: undefined, - - open: function (fileUrl) { - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, - "VideoPlayer.open invalid number of arguments", new Exception()); - utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER, - "VideoPlayer.open expected valid fileUrl but got ->" + fileUrl, new Exception()); - - if (!_video) { - return; - } - - _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () { - _validateVideoType(fileUrl); - _currentVideoFile = fileSystem.getURI(fileUrl); - _video.setAttribute("src", _currentVideoFile); - _video.setAttribute("width", "100%"); - _video.addEventListener("ended", function () { - event.trigger("MultimediaVideoStateChanged", [_STATES.COMPLETED], true); - if (_loopCount > 1) { - _self.open(_currentVideoFile); - _self.play(_loopCount--); - } - }, false); - }); - }, - - setWindow: function (domObject) { - utils.validateNumberOfArguments(0, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, - "VideoPlayer.setWindow invalid number of arguments", new Exception()); - - if (_currentlySet) { - _currentlySet.removeChild(_video); - _currentlySet = null; - _video = null; - } - - if (domObject !== null) { - _video = utils.createElement("video", { - "id": "multimedia-video" - }); - domObject.appendChild(_video); - _currentlySet = domObject; - event.trigger("MultimediaAppVideoPlayerCreated", [_video], true); - } - }, - - play: function (repeatTimes) { - utils.validateNumberOfArguments(1, 1, arguments.length, - ExceptionTypes.INVALID_PARAMETER, "invalid number of arguments (expected one)", new Exception()); - - if (typeof repeatTimes !== "number" || repeatTimes < 0) { - exception.raise(ExceptionTypes.INVALID_PARAMETER, "VideoPlayer.play was passed an invalid number of play times: " + repeatTimes, new Exception()); - } - if (repeatTimes !== 0) { - if (!_video) { - return; - } - _loopCount = repeatTimes; - _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () { - _video.play(); - }); - } - }, - - pause: function () { - if (!_video) { - return; - } - _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () { - _video.pause(); - }); - }, - - resume: function () { - if (!_video) { - return; - } - _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () { - _video.play(); - }); - }, - - stop: function () { - if (!_video) { - return; - } - _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () { - _video.pause(); - _video.setAttribute("src", _currentVideoFile); // hack - }); - } - -}; diff --git a/lib/ripple/platform/wac/1.0/Widget.js b/lib/ripple/platform/wac/1.0/Widget.js deleted file mode 100644 index 8f31ce39..00000000 --- a/lib/ripple/platform/wac/1.0/Widget.js +++ /dev/null @@ -1,129 +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 event = require('ripple/event'), - _console = require('ripple/console'), - app = require('ripple/app'), - platform = require('ripple/platform'), - exception = require('ripple/exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'), - utils = require('ripple/utils'), - db = require('ripple/db'), - _self; - -event.on("ScreenChangeDimensions", function (height, width) { - try { - // TODO: are these per spec to call? - if (typeof app.onMaximize === 'function') { - app.onMaximize(); - } - if (typeof app.onRestore === 'function') { - app.onRestore(); - } - _console.log("called Widget.onRestore and Widget.onMaximize callback function"); - } - catch (e) { - exception.handle(e, false); - } -}); - -event.on("WidgetWakeup", function () { - if (_self.onWakeup) { - _self.onWakeup(); - } -}); - -event.on("WidgetMaximize", function () { - if (_self.onMaximize) { - _self.onMaximize(); - } -}); - -event.on("WidgetFocus", function () { - if (_self.onFocus) { - _self.onFocus(); - } -}); - -event.on("WidgetRestore", function () { - if (_self.onRestore) { - _self.onRestore(); - } -}); - -_self = { - onWakeup: undefined, - onMaximize: undefined, - onFocus: undefined, - onRestore: undefined, - - openURL: function (url) { - window.open(url); - }, - - setPreferenceForKey: function (value, key) { - - utils.validateNumberOfArguments(1, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid number of paramters", new Exception()); - utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid parameter! Key:" + - key + ", Value: " + value, new Exception()); - - var msg = "", - prefix; - if (app.isPreferenceReadOnly(key)) { - msg += "Cannot modify a read only preference. Preference key: " + key; - } - else { - prefix = platform.getPersistencePrefix(); - if (value === null) { - msg += "deleting preference " + key; - db.remove(key, prefix); - } - else { - msg += "setting preference " + key + " == " + value; - utils.validateArgumentType(value, "string", ExceptionTypes.INVALID_PARAMETER, msg, new Exception()); - db.save(key, value, prefix); - } - } - - - _console.log(msg); - - // Trigger storageUpdatedEvent - event.trigger("StorageUpdatedEvent"); - - }, - - // return value or undefined - preferenceForKey: function (key) { - - utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid number of parameters", new Exception()); - utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid paramters", new Exception()); - - var prefix = platform.getPersistencePrefix(), - value = db.retrieve(key, prefix); - - if (!value && value !== "") { - value = undefined; - } - - _console.log("retrieving preference " + key + " == " + value); - - return value; - - } -}; - -module.exports = _self; diff --git a/lib/ripple/platform/wac/1.0/WidgetManager.js b/lib/ripple/platform/wac/1.0/WidgetManager.js deleted file mode 100644 index 9453a9c2..00000000 --- a/lib/ripple/platform/wac/1.0/WidgetManager.js +++ /dev/null @@ -1,26 +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 exception = require('ripple/exception'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - Exception = require('ripple/platform/wac/1.0/Exception'); - -module.exports = { - // This method is used to check the installation status of a specific widget. - checkWidgetInstallationStatus: function () { - - exception.raise(ExceptionTypes.UNSUPPORTED, "WidgetManager.checkWidgetInstallationStatus not supported", new Exception()); - } -}; diff --git a/lib/ripple/platform/wac/1.0/spec.js b/lib/ripple/platform/wac/1.0/spec.js deleted file mode 100644 index d7c197a9..00000000 --- a/lib/ripple/platform/wac/1.0/spec.js +++ /dev/null @@ -1,147 +0,0 @@ -module.exports = { - - id: "wac", - version: "1.0", - name: "WAC", - type: "plaform", - - persistencePrefix: "wac-", - - config: require('ripple/platform/wac/1.0/spec/config'), - device: require('ripple/platform/wac/1.0/spec/device'), - ui: require('ripple/platform/wac/1.0/spec/ui'), - events: require('ripple/platform/wac/1.0/spec/events'), - - objects: { - navigator: { - path: "w3c/1.0/navigator" - }, - WidgetManager: { - path: "wac/1.0/WidgetManager" - }, - Widget: { - path: "wac/1.0/Widget", - children: { - Device: { - path: "wac/1.0/Device", - children: { - AccountInfo: { - path: "wac/1.0/AccountInfo" - }, - ApplicationTypes: { - path: "wac/1.0/ApplicationTypes" - }, - DataNetworkInfo: { - path: "wac/1.0/DataNetworkInfo", - children: { - DataNetworkConnectionTypes: { - path: "wac/1.0/DataNetworkConnectionTypes" - } - } - }, - DeviceInfo: { - path: "wac/1.0/DeviceInfo" - }, - DeviceStateInfo: { - path: "wac/1.0/DeviceStateInfo", - children: { - Config: { - path: "wac/1.0/Config" - }, - AccelerometerInfo: { - path: "wac/1.0/AccelerometerInfo" - } - } - }, - File: { - path: "wac/1.0/File" - }, - PositionInfo: { - path: "wac/1.0/PositionInfo" - }, - RadioInfo: { - path: "wac/1.0/RadioInfo", - children: { - RadioSignalSourceTypes: { - path: "wac/1.0/RadioSignalSourceTypes" - } - } - }, - PowerInfo: { - path: "wac/1.0/PowerInfo" - } - } - }, - ExceptionTypes: { - path: "wac/1.0/ExceptionTypes" - }, - Exception: { - path: "wac/1.0/Exception" - }, - Multimedia: { - path: "wac/1.0/Multimedia", - children: { - Camera: { - path: "wac/1.0/Camera" - }, - AudioPlayer: { - path: "wac/1.0/AudioPlayer" - }, - VideoPlayer: { - path: "wac/1.0/VideoPlayer" - } - } - }, - Telephony: { - path: "wac/1.0/Telephony", - children: { - CallRecord: { - path: "wac/1.0/CallRecord" - }, - CallRecordTypes: { - path: "wac/1.0/CallRecordTypes" - } - } - }, - PIM: { - path: "wac/1.0/PIM", - children: { - AddressBookItem: { - path: "wac/1.0/AddressBookItem" - }, - CalendarItem: { - path: "wac/1.0/CalendarItem" - }, - EventRecurrenceTypes: { - path: "wac/1.0/EventRecurrenceTypes" - } - } - }, - Messaging: { - path: "wac/1.0/Messaging", - children: { - Account: { - path: "wac/1.0/Account" - }, - Attachment: { - path: "wac/1.0/Attachment" - }, - Message: { - path: "wac/1.0/Message" - }, - MessageFolderTypes: { - path: "wac/1.0/MessageFolderTypes" - }, - MessageQuantities: { - path: "wac/1.0/MessageQuantities" - }, - MessageTypes: { - path: "wac/1.0/MessageTypes" - } - } - } - } - } - } - -}; diff --git a/lib/ripple/platform/wac/1.0/spec/config.js b/lib/ripple/platform/wac/1.0/spec/config.js deleted file mode 100644 index e9340196..00000000 --- a/lib/ripple/platform/wac/1.0/spec/config.js +++ /dev/null @@ -1,385 +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 platform = require('ripple/platform'), - utils = require('ripple/utils'), - db = require('ripple/db'), - constants = require('ripple/constants'); - -module.exports = { - fileName: "config.xml", - validateVersion: function (configValidationObject) { - var valid = true; - valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) || - (!configValidationObject.widget.validationResult[0].attributes["xmlns:JIL"].valid)); - - return valid; - }, - extractInfo: function (configValidationObject) { - if (!configValidationObject) { - return null; - } - - var widgetInfo = {}, - configPreferences, - preferenceName; - - widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || ""; - widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value; - widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value; - widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value; - widgetInfo.preferences = {}; - - configPreferences = configValidationObject.widget.children.preference.validationResult; - - utils.forEach(configPreferences, function (preference) { - preferenceName = preference.attributes.name.value; - if (preferenceName) { - widgetInfo.preferences[preferenceName] = { - "key": preferenceName, - "value": preference.attributes.value.value || "", - "readonly": preference.attributes.readonly.value === "true" - }; - - db.save(preferenceName, - widgetInfo.preferences[preferenceName].value, - platform.getPersistencePrefix(widgetInfo.id)); - } - }); - - return widgetInfo; - }, - schema: { - rootElement: "widget", - widget: { - nodeName: "widget", - required: true, - occurrence: 1, - helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,maximum_display_mode,update,feature,access,billing. \"widget\" element MAY have following attributes: id,version,height,width,xml:lang", - attributes: { - xmlns: { - attributeName: "xmlns", - required: true, - type: "list", - listValues: ["http://www.w3.org/ns/widgets"] - }, - "xmlns:JIL": { - attributeName: "xmlns:JIL", - required: true, - type: "list", - listValues: ["http://www.jil.org/ns/widgets1.2"] - }, - "xmlns:its": { - attributeName: "xmlns:its", - helpText: "Indicates Text Directionality can be used. According to W3C spec, this feature is at risk, therefore we don't currently validate this.", - required: false, - type: "string" - }, - id: { - attributeName: "id", - required: true, - type: "string" - }, - version: { - attributeName: "version", - helpText: "Version must be in the following format: jil-rec-version-tag = major-version \".\" minor-version [\".\" version-desc]", - required: true, - type: "regex", - regex: /^\d{1,2}\.\d{1,2}(\.[A-Za-z0-9]{1,10})?$/ - }, - height: { - attributeName: "height", - required: true, - type: "integer" - }, - width: { - attributeName: "width", - required: true, - type: "integer" - }, - viewmodes: { - attributeName: "viewmodes", - required: false, - type: "list", - listValues: ["floating", "fullscreen"] - }, - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language" - } - }, - children: { - preference: { - nodeName: "preference", - required: false, - occurrence: 0, - attributes: { - name: { - attributeName: "name", - type: "string", - required: true - }, - value: { - type: "string", - attributeName: "value", - required: false - }, - readonly: { - attributeName: "readonly", - type: "boolean", - required: false - } - } - }, - name: { - nodeName: "name", - required: false, - occurrence: 0, - type: "string", - attributes: { - "short": { - attributeName: "short", - type: "string", - required: false - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - description: { - nodeName: "description", - required: false, - occurrence: 0, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - icon: { - nodeName: "icon", - required: false, - occurrence: 0, - attributes: { - src: { - attributeName: "src", - type: "string", - required: true - }, - height: { - attributeName: "height", - required: false, - type: "integer" - }, - width: { - attributeName: "width", - required: false, - type: "integer" - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - author: { - nodeName: "author", - required: false, - occurrence: 1, - type: "string", - attributes: { - email: { - attributeName: "email", - type: "regex", - required: false, - regex: constants.REGEX.EMAIL - }, - href: { - attributeName: "href", - type: "regex", - required: false, - regex: constants.REGEX.URL - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - license: { - nodeName: "license", - required: false, - occurrence: 1, - type: "string", - attributes: { - href: { - attributeName: "href", - type: "regex", - required: false, - regex: constants.REGEX.URL - }, - "xml:lang": { - attributeName: "xml:lang", - type: "string", - required: false, - unique: true - } - } - }, - content: { - nodeName: "content", - required: false, - occurrence: 1, - attributes: { - src: { - attributeName: "src", - type: "string", - required: true - }, - encoding: { - attributeName: "encoding", - type: "string", - required: false - }, - type: { - attributeName: "type", - type: "string", - required: false - } - } - }, - feature: { - nodeName: "feature", - required: false, - occurrence: 0, - attributes: { - name: { - attributeName: "name", - type: "list", - required: true, - listValues: ["http://jil.org/jil/api/1.1/widget", "http://jil.org/jil/api/1.1.5/exception", - "http://jil.org/jil/api/1.1.5/exceptiontypes", "http://jil.org/jil/api/1.1/device", - "http://jil.org/jil/api/1.1/accountinfo", "http://jil.org/jil/api/1.1/deviceinfo", - "http://jil.org/jil/api/1.1.1/datanetworkinfo", "http://jil.org/jil/api/1.1/devicestateinfo", - "http://jil.org/jil/api/1.1/accelerometerinfo", "http://jil.org/jil/api/1.1/config", - "http://jil.org/jil/api/1.1.1/file", "http://jil.org/jil/api/1.1/positioninfo", - "http://jil.org/jil/api/1.1/powerinfo", "http://jil.org/jil/api/1.1.1/radioinfo", - "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes", "http://jil.org/jil/api/1.1.5/applicationtypes", - "http://jil.org/jil/api/1.1/messaging", "http://jil.org/jil/api/1.1/account", - "http://jil.org/jil/api/1.1/attachment", "http://jil.org/jil/api/1.1/message", - "http://jil.org/jil/api/1.1.4/messagefoldertypes", "http://jil.org/jil/api/1.1/messagequantities", - "http://jil.org/jil/api/1.1/messagetypes", "http://jil.org/jil/api/1.1/multimedia", - "http://jil.org/jil/api/1.1/audioplayer", "http://jil.org/jil/api/1.1.2/camera", - "http://jil.org/jil/api/1.1.2/videoplayer", "http://jil.org/jil/api/1.1.1/pim", - "http://jil.org/jil/api/1.1/addressbookitem", "http://jil.org/jil/api/1.1/calendaritem", - "http://jil.org/jil/api/1.1/eventrecurrencetypes", "http://jil.org/jil/api/1.1.1/telephony", - "http://jil.org/jil/api/1.1/callrecord", "http://jil.org/jil/api/1.1.1/callrecordtypes", - "http://jil.org/jil/api/1.1.1/widgetmanager"] - }, - required: { - attributeName: "required", - type: "boolean", - required: false - } - } - }, - "JIL:maximum_display_mode": { - nodeName: "JIL:maximum_display_mode", - required: false, - occurrence: 1, - attributes: { - height: { - attributeName: "height", - type: "integer", - required: false - }, - width: { - attributeName: "width", - type: "integer", - required: false - } - } - }, - "JIL:update": { - nodeName: "JIL:update", - required: false, - occurrence: 1, - attributes: { - href: { - attributeName: "href", - type: "regex", - required: true, - regex: constants.REGEX.URL - }, - period: { - attributeName: "period", - helpText: "Possible values for the period attribute are: 0, 1, 2, 3 meaning: every time the widget is opened in maximum display mode, every day, every week, every month; respectivly", - type: "list", - required: true, - listValues: ["0", "1", "2", "3"] - } - } - }, - "JIL:access": { - nodeName: "JIL:access", - required: false, - occurrence: 1, - attributes: { - network: { - attributeName: "network", - type: "boolean", - required: false - }, - localfs: { - attributeName: "localfs", - type: "boolean", - required: false - }, - remote_scripts: { - attributeName: "remote_scripts", - type: "boolean", - required: false - } - } - }, - "JIL:billing": { - nodeName: "JIL:billing", - required: false, - occurrence: 1, - attributes: { - required: { - attributeName: "required", - type: "boolean", - required: true - } - } - } - } - } - } -}; diff --git a/lib/ripple/platform/wac/1.0/spec/device.js b/lib/ripple/platform/wac/1.0/spec/device.js deleted file mode 100644 index bb258c81..00000000 --- a/lib/ripple/platform/wac/1.0/spec/device.js +++ /dev/null @@ -1,331 +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 constants = require('ripple/constants'), - event = require('ripple/event'); - -module.exports = { - "AccountInfo": { - "phoneUserUniqueId": { - "name": "User Unique Id", - "control": { - "type": "text", - "value": new Date().getTime().toString() - } - }, - "phoneMSISDN": { - "name": "MSISDN", - "control": { - "type": "text", - "value": "15199999999" - } - }, - "phoneOperatorName": { - "name": "Operator Name", - "control": { - "type": "text", - "value": "" - } - }, - "userAccountBalance": { - "name": "Account Balance", - "control": { - "type": "number", - "value": 0 - } - }, - "userSubscriptionType": { - "name": "Subscription Type", - "control": { - "type": "select", - "value": "other" - }, - "options": { - "other": "other", - "prepaid": "prepaid", - "postpaid": "postpaid" - } - } - }, - "RadioInfo": { - "isRoaming": { - "name": "Is Roaming", - "control": { - "type": "checkbox", - "value": false - }, - "callback": function () { - event.trigger("RadioSignalSourceChanged"); - } - }, - "isRadioEnabled": { - "name": "Is Radio Enabled", - "control": { - "type": "checkbox", - "value": true - } - }, - "radioSignalSource": { - "name": "Radio Signal Source", - "control": { - "type": "select", - "value": "GSM" - }, - // TODO: try not to duplicate from RadioSignalSourceTypes - "options": { - "CDMA": "cdma", - "GSM": "gsm", - "LTE": "lte", - "TDSCDMA": "tdscdma", - "WCDMA": "wcdma" - }, - "callback": function () { - event.trigger("RadioSignalSourceChanged"); - } - }, - "radioSignalStrengthPercent": { - "name": "Signal Strength %", - "control": { - "type": "select", - "value": 80 - }, - "options": (function () { - var i, - optionList = {}; - - for (i = 0; i <= 100; i++) { - optionList[i] = i; - } - - return optionList; - }()) - } - }, - "Config": { - "ringtoneVolume": { - "name": "Ringtone Volume", - "control": { - "type": "select", - "value": 10 - }, - "options": (function () { - var i, - optionList = {}; - - for (i = 0; i <= 10; i++) { - optionList[i] = i; - } - - return optionList; - }()) - }, - "msgRingtoneVolume": { - "name": "Msg Ringtone Volume", - "control": { - "type": "select", - "value": 10 - }, - "options": (function () { - var i, - optionList = {}; - - for (i = 0; i <= 10; i++) { - optionList[i] = i; - } - - return optionList; - }()) - }, - "vibrationSetting": { - "name": "Vibration", - "control": { - "type": "select", - "value": "off" - }, - "options": { - "on": "ON", - "off": "OFF" - } - } - }, - "Account": { - "accountName": { - "name": "Name", - "control": { - "type": "text", - "value": "" - } - }, - "accountId": { - "name": "Id", - "control": { - "type": "text", - "value": "" - } - } - }, - "DeviceInfo": { - "totalMemory": { - "name": "Total Memory", - "control": { - "type": "range", - "value": 262144, - "min": 0, - "max": 4096000 - } - }, - "phoneColorDepthDefault": { - "name": "Color Depth", - "control": { - "type": "number", - "value": 24 - } - } - }, - "DeviceStateInfo": { - "availableMemory": { - "name": "Available Memory", - "control": { - "type": "range", - "value": 262144, - "min": 0, - "max": 4096000 - } - }, - "keypadLightOn": { - "name": "Keypad Light On", - "control": { - "type": "checkbox", - "value": false - } - }, - "backLightOn": { - "name": "Back Light On", - "control": { - "type": "checkbox", - "value": false - } - }, - "audioPath": { - "name": "Audio Path", - "control": { - "type": "select", - "value": "receiver" - }, - "options": { - "speaker": "speaker", - "receiver": "receiver", - "earphone": "earphone" - } - }, - "processorUtilizationPercent": { - "name": "CPU Utilization %", - "control": { - "type": "select", - "value": "5" - }, - "options": (function () { - var i, - optionList = {}; - - for (i = 0; i <= 100; i++) { - optionList[i] = i; - } - - return optionList; - }()) - }, - "language": { - "name": "Language", - "control": { - "type": "select", - "value": "eng" - }, - "options": (function () { - var i, - optionList = {}, - iterator = constants.LANG.ISO6392_LIST; - - for (i = 0; i <= iterator.length; i++) { - optionList[iterator[i]] = iterator[i]; - } - - return optionList; - }()) - } - }, - "DataNetworkInfo": { - "isDataNetworkConnected": { - "name": "Data Network Is Connected", - "control": { - "type": "checkbox", - "value": true - } - }, - "networkConnectionType": { - "name": "Network Connection Type", - "control": { - "type": "select", - "value": ["GPRS"] - }, - // TODO: try not to duplicate from DataNetworkConnectionTypes - "options": { - "BLUETOOTH": "bluetooth", - "EDGE": "edge", - "EVDO": "evdo", - "GPRS": "gprs", - "IRDA": "irda", - "LTE": "lte", - "ONEXRTT": "1xrtt", - "WIFI": "wifi" - }, - "callback": function (setting) { - event.trigger("DataNetworkConnectionChanged", [setting]); - } - } - }, - "PowerInfo": { - "isCharging": { - "name": "Battery Is Charging", - "control": { - "type": "checkbox", - "value": true - }, - "callback": function (setting) { - event.trigger("DeviceBatteryStateChanged", [setting]); - } - }, - "percentRemaining": { - "name": "Battery Remaining %", - "control": { - "type": "select", - "value": 100 - }, - "options": (function () { - var i, - optionList = {}; - - for (i = 0; i <= 100; i++) { - optionList[i] = i; - } - - return optionList; - }()), - "callback": function (setting) { - event.trigger("DeviceBatteryLevelChanged", [setting]); - } - } - } -}; diff --git a/lib/ripple/platform/wac/1.0/spec/events.js b/lib/ripple/platform/wac/1.0/spec/events.js deleted file mode 100644 index 03314231..00000000 --- a/lib/ripple/platform/wac/1.0/spec/events.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - "contexts": { - "Widget": { - "events": { - "WidgetWakeup": { - name: "WidgetWakeup", - description: "onWakeup", - args: false - }, - "WidgetMaximize": { - name: "WidgetMaximize", - description: "onMaximize", - args: false - }, - "WidgetFocus": { - name: "WidgetFocus", - description: "onFocus", - args: false - }, - "WidgetRestore": { - name: "WidgetRestore", - description: "onRestore", - args: false - } - }, - "context": "Widget" - } - } -}; diff --git a/lib/ripple/platform/wac/1.0/spec/ui.js b/lib/ripple/platform/wac/1.0/spec/ui.js deleted file mode 100644 index 70792a35..00000000 --- a/lib/ripple/platform/wac/1.0/spec/ui.js +++ /dev/null @@ -1,29 +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. - */ -module.exports = { - plugins: [ - "accelerometer", - "deviceSettings", - "fileSystem", - "geoView", - "multimedia", - "audioPlayer", - "telephony", - "platformEvents", - "storage", - "widgetConfig" - ] -}; diff --git a/lib/ripple/platform/web/default/tinyHipposWeb.js b/lib/ripple/platform/web/default/device.js similarity index 80% rename from lib/ripple/platform/web/default/tinyHipposWeb.js rename to lib/ripple/platform/web/default/device.js index 1583cf07..64ece1df 100644 --- a/lib/ripple/platform/web/default/tinyHipposWeb.js +++ b/lib/ripple/platform/web/default/device.js @@ -15,11 +15,11 @@ */ window.addEventListener("load", function () { var event = require('ripple/event'); - event.on("ScreenChangeDimensions", function (height, width) { - if (typeof window.onresize === "function") { - window.onresize.apply(); - } + + event.on("HardwareKey", function (key) { + event.trigger("HardwareKeyDefault", [key]); }); + //HACK: Remove this guy from namespace since we are just hacking this in as a bootstrapper - delete window.tinyHipposWeb; + delete window.device; }); diff --git a/lib/ripple/platform/web/default/spec.js b/lib/ripple/platform/web/default/spec.js index 9eede39f..06b32450 100644 --- a/lib/ripple/platform/web/default/spec.js +++ b/lib/ripple/platform/web/default/spec.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + module.exports = { id: "web", @@ -42,8 +43,8 @@ module.exports = { } } }, - tinyHipposWeb: { - path: "web/default/tinyHipposWeb" + device: { + path: "web/default/device" } }, }; diff --git a/lib/ripple/platform/webworks.core/2.0.0/XMLHttpRequest.js b/lib/ripple/platform/webworks.core/2.0.0/XMLHttpRequest.js index 5ac033c6..34464186 100644 --- a/lib/ripple/platform/webworks.core/2.0.0/XMLHttpRequest.js +++ b/lib/ripple/platform/webworks.core/2.0.0/XMLHttpRequest.js @@ -40,7 +40,7 @@ module.exports = { state++; if (_async) { baton.take(); - setTimeout(baton.pass, 1); + window.setTimeout(baton.pass, 1); } }, setResponse = function (result) { diff --git a/lib/ripple/platform/webworks.core/2.0.0/client/FileProperties.js b/lib/ripple/platform/webworks.core/2.0.0/client/FileProperties.js new file mode 100644 index 00000000..4ae4697f --- /dev/null +++ b/lib/ripple/platform/webworks.core/2.0.0/client/FileProperties.js @@ -0,0 +1,35 @@ +/* + * 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 FileProperties(props) { + props = props || {}; + + function _get(val) { + return function () { + return props[val]; + }; + } + + this.__defineGetter__("dateCreated", _get("dateCreated")); //tablet only + this.__defineGetter__("dateModified", _get("dateModified")); + this.__defineGetter__("directory", _get("directory")); + this.__defineGetter__("fileExtension", _get("fileExtension")); + this.__defineGetter__("isHidden", _get("isHidden")); + this.__defineGetter__("isReadonly", _get("isReadonly")); //handset only + this.__defineGetter__("mimeType", _get("mimeType")); //handset only + this.__defineGetter__("size", _get("size")); +} + +module.exports = FileProperties; diff --git a/lib/ripple/platform/webworks.core/2.0.0/client/io/dir.js b/lib/ripple/platform/webworks.core/2.0.0/client/io/dir.js new file mode 100644 index 00000000..b9354461 --- /dev/null +++ b/lib/ripple/platform/webworks.core/2.0.0/client/io/dir.js @@ -0,0 +1,64 @@ +/* + * 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 transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + _uri = "blackberry/io/dir/", + FILE = "file://"; + +function _prunePrefix(path) { + return path.replace(new RegExp("^" + FILE), ''); +} + +function _addPrefix(path) { + return FILE + path; +} + +module.exports = { + createNewDir: function (path) { + transport.call(_uri + "createNewDir", { + post: {path: _prunePrefix(path)} + }); + }, + deleteDirectory: function (path, recursive) { + transport.call(_uri + "deleteDirectory", { + post: {path: _prunePrefix(path), recursive: recursive} + }); + }, + exists: function (path) { + return transport.call(_uri + "exists", { + post: {path: _prunePrefix(path)} + }); + }, + getParentDirectory: function (path) { + return _addPrefix(transport.call(_uri + "getParentDirectory", { + post: {path: _prunePrefix(path)} + })); + }, + listDirectories: function (path) { + return transport.call(_uri + "listDirectories", { + post: {path: _prunePrefix(path)} + }); + }, + listFiles: function (path) { + return transport.call(_uri + "listFiles", { + post: {path: _prunePrefix(path)} + }); + }, + rename: function (path, newName) { + transport.call(_uri + "rename", { + post: {path: _prunePrefix(path), newName: newName} + }); + } +}; diff --git a/lib/ripple/platform/webworks.core/2.0.0/client/io/file.js b/lib/ripple/platform/webworks.core/2.0.0/client/io/file.js new file mode 100644 index 00000000..303949ee --- /dev/null +++ b/lib/ripple/platform/webworks.core/2.0.0/client/io/file.js @@ -0,0 +1,86 @@ +/* + * 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 transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + _uri = "blackberry/io/file/", + FILE = "file://", + _onFileOpened; + +function _prunePrefix(path) { + return path.replace(new RegExp("^" + FILE), ''); +} + +module.exports = { + copy: function (from, to) { + transport.call(_uri + "copy", { + post: {from: _prunePrefix(from), to: _prunePrefix(to)} + }); + }, + deleteFile: function (path) { + transport.call(_uri + "deleteFile", { + post: {path: _prunePrefix(path)} + }); + }, + exists: function (path) { + return transport.call(_uri + "exists", { + post: {path: _prunePrefix(path)} + }); + }, + getFileProperties: function (path) { + var properties = transport.call(_uri + "getFileProperties", { + post: {path: _prunePrefix(path)} + }); + properties.directory = FILE + properties.directory; + return properties; + }, + open: function (path, newName) { + transport.call(_uri + "open", { + post: {path: _prunePrefix(path)} + }); + }, + readFile: function (path, onFileOpened, async) { + async = async === false ? false : true; + + var uri = _uri + "readFile", + args = { + post: {path: _prunePrefix(path), async: async} + }, + callResult; + + _onFileOpened = onFileOpened; + + if (async) { + transport.poll(uri, args, function (data, res) { + if (_onFileOpened) { + _onFileOpened(FILE + data.fullPath, data.blobData); + } + return false; + }); + } else { + callResult = transport.call(uri, args); + _onFileOpened(FILE + callResult.fullPath, callResult.blobData); + } + }, + rename: function (path, newName) { + transport.call(_uri + "rename", { + post: {path: _prunePrefix(path), newName: newName} + }); + }, + saveFile: function (path, blob) { + transport.call(_uri + "saveFile", { + post: {path: _prunePrefix(path), blob: blob} + }); + } +}; diff --git a/lib/ripple/platform/webworks.core/2.0.0/client/system.js b/lib/ripple/platform/webworks.core/2.0.0/client/system.js index 62a10a51..e1d34d53 100644 --- a/lib/ripple/platform/webworks.core/2.0.0/client/system.js +++ b/lib/ripple/platform/webworks.core/2.0.0/client/system.js @@ -36,13 +36,6 @@ _self = { isMassStorageActive: function () { return transport.call(_uri + "isMassStorageActive"); - }, - - setHomeScreenBackground: function (filePath) { - transport.call(_uri + "setHomeScreenBackground", { - get: {filePath: filePath}, - async: true - }); } }; diff --git a/lib/ripple/platform/webworks.core/2.0.0/client/utils.js b/lib/ripple/platform/webworks.core/2.0.0/client/utils.js index 577ffe42..296368c6 100644 --- a/lib/ripple/platform/webworks.core/2.0.0/client/utils.js +++ b/lib/ripple/platform/webworks.core/2.0.0/client/utils.js @@ -13,91 +13,119 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -function Utils(disp) { +var _hate = {}; + +function _blobBuilder() { + var BlobBuilder = BlobBuilder || WebKitBlobBuilder; + return new BlobBuilder(); } -Utils.prototype.parseURL = function (theUrl) { - /********START IDEA BORROWING*******/ - // parseUri 1.2.2 - // (c) Steven Levithan - // MIT License +module.exports = { + parseURL: function (theUrl) { + /********START IDEA BORROWING*******/ + // parseUri 1.2.2 + // (c) Steven Levithan + // MIT License + + function parseUri(str) { + var o = parseUri.options, + m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), + uri = {}, + i = 14; + + while (i--) { + uri[o.key[i]] = m[i] || ""; + } - function parseUri(str) { - var o = parseUri.options, - m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), - uri = {}, - i = 14; + uri[o.q.name] = {}; + uri[o.q.arrayName] = []; + uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { + if ($1) { + uri[o.q.name][$1] = $2; + uri[o.q.arrayName].push($2); + } + }); - while (i--) { - uri[o.key[i]] = m[i] || ""; + return uri; } - uri[o.q.name] = {}; - uri[o.q.arrayName] = []; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) { - uri[o.q.name][$1] = $2; - uri[o.q.arrayName].push($2); + parseUri.options = { + strictMode: false, + key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], + q: { + name: "queryKey", + arrayName: "queryArray", + parser: /(?:^|&)([^&=]*)=?([^&]*)/g + }, + parser: { + strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, + loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ + } + }; + /********END IDEA BORROWING*******/ + + parseUri.strictMode = "strict"; + var uri = parseUri(theUrl), + retVal = { + getURLParameter : function (key) { + return uri.queryKey[key]; + }, + + getURLParameterByIndex : function (index) { + return uri.queryArray[index]; + } + }; + + //Add default values for the http/https port if they weren't specified in the URL. The above parser returns undefined. We need the values + //to be compatible with the BB version of API. + if (uri["port"] === "") { + if (uri["protocol"] === "http") { + uri["port"] = "80"; + } + else if (uri["protocol"] === "https") { + uri["port"] = "443"; + } + else { + uri["port"] = "0"; } + } + + retVal.__defineGetter__("host", function () { + return uri["host"]; + }); + retVal.__defineGetter__("port", function () { + return parseInt(uri["port"], 10); }); - return uri; - } + return retVal; + }, - parseUri.options = { - strictMode: false, - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], - q: { - name: "queryKey", - arrayName: "queryArray", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } - }; - /********END IDEA BORROWING*******/ + generateUniqueId: function () { + return Math.floor(Math.random() * Number.MAX_VALUE); + }, - parseUri.strictMode = "strict"; - var uri = parseUri(theUrl), - retVal = { - getURLParameter : function (key) { - return uri.queryKey[key]; - }, + blobToString: function (blob, encoding) { + var file = new FileReader(); - getURLParameterByIndex : function (index) { - return uri.queryArray[index]; - } + file.onloadend = function () { + _hate[blob.uuid] = file.result; }; + file.readAsText(blob); + return _hate[blob.uuid]; + }, - //Add default values for the http/https port if they weren't specified in the URL. The above parser returns undefined. We need the values - //to be compatible with the BB version of API. - if (uri["port"] === "") { - if (uri["protocol"] === "http") { - uri["port"] = "80"; - } - else if (uri["protocol"] === "https") { - uri["port"] = "443"; - } - else { - uri["port"] = "0"; - } - } + stringToBlob: function (string, encoding) { + var uuid = Math.uuid(undefined, 16), + blob = _blobBuilder(), + finalBlob; - retVal.__defineGetter__("host", function () { - return uri["host"]; - }); - retVal.__defineGetter__("port", function () { - return parseInt(uri["port"], 10); - }); + _hate[uuid] = string; + blob.append(string); - return retVal; -}; + finalBlob = blob.getBlob(); + finalBlob.uuid = uuid; -Utils.prototype.generateUniqueId = function () { - return Math.floor(Math.random() * Number.MAX_VALUE); + return finalBlob; + } }; - -module.exports = new Utils(); diff --git a/lib/ripple/platform/webworks.core/2.0.0/fsCache.js b/lib/ripple/platform/webworks.core/2.0.0/fsCache.js new file mode 100644 index 00000000..04212b9a --- /dev/null +++ b/lib/ripple/platform/webworks.core/2.0.0/fsCache.js @@ -0,0 +1,328 @@ +/* + * 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 fs = require('ripple/fs'), + utils = require('ripple/utils'), + _console = require('ripple/console'), + constants = require('ripple/constants'), + event = require('ripple/event'), + bbUtils = require('ripple/platform/webworks.core/2.0.0/client/utils'), + FileProperties = require('ripple/platform/webworks.core/2.0.0/client/FileProperties'), + _cache = {}, + _self; + +event.on("FileSystemInitialized", function () { + jWorkflow.order(function (prev, baton) { + baton.take(); + fs.mkdir("/SDCard", function () { + fs.mkdir("/store", baton.pass, baton.pass); + }, baton.pass); + }).start(_self.refresh); +}); + +function _fsError(e) { + _self.refresh(); + if (e.code !== 1) { // suppress file not found error + _console.error("FileSystem error (code " + e.code + ")"); + } +} + +function _walk(path, parent) { + fs.ls(path, function (entries) { + parent.children = parent.children || {}; + + entries.forEach(function (entry) { + parent.children[entry.name] = entry; + parent.children[entry.name].properties = {}; + + if (entry.isDirectory) { + _walk(entry.fullPath, entry); + } else { + entry.file(function (file) { + utils.mixin(file, parent.children[entry.name].properties); + }); + fs.read(entry.fullPath, function (data) { + parent.children[entry.name].data = data; + }, function (e) { + console.error(e); + }); + } + }); + }, function (e) { + console.error(e); + }); +} + +function _get(path) { + return path.replace(/^\//, '').split("/").reduce(function (obj, token) { + return token === "" ? obj : (obj.children ? obj.children[token] || null : null); + }, _cache); +} + +function _getInfo(path) { + var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"), + name = parent.splice(parent.length - 1, 1).join(""), + ext = name.split("."); + + return { + name: name, + extension: ext.length > 1 ? ext[ext.length - 1] : "", + hidden: (name.length > 0 && name[0] === ".") || false, + parent: parent.join("/") || "/" + }; +} + +function _set(path, obj) { + var parent = _cache, + tokens = path.replace(/^\//, '').split("/"), + child = tokens.splice(tokens.length - 1, 1).join(""); + + tokens.forEach(function (token) { + parent = parent.children[token]; + }); + + parent.children = parent.children || {}; + obj.properties = obj.properties || {}; + parent.children[child] = obj; +} + +function _delete(path) { + var parent = _cache, + tokens = path.replace(/^\//, '').split("/"), + child = tokens.splice(tokens.length - 1, 1).join(""); + + tokens.forEach(function (token) { + parent = parent.children[token]; + }); + + delete parent.children[child]; +} + +// TODO: handle exceptions so that any respective fs command can error out +// TODO: dateCreated is always dateModified + +_self = { + refresh: function () { + _cache = {}; + _walk("/", _cache); + }, + file: { + exists: function (path) { + var entry = _get(path); + fs.stat(path, function () {}, _fsError); + return !!(entry && !entry.isDirectory); + }, + + deleteFile: function (path) { + _delete(path); + fs.rm(path, function () {}, _fsError); + }, + + copy: function (from, to) { + var fromEntry = _get(from); + + _delete(from); + _set(to, { + fullPath: to, + properties: fromEntry.properties, + data: fromEntry.data + }); + + fs.cp(from, to, function (entry) { + entry.file(function (file) { + entry.properties = entry.properties || {}; + utils.mixin(file, entry.properties); + _set(to, entry); + }); + }, _fsError); + }, + + getFileProperties: function (path) { + var entry = _get(path), + info = _getInfo(path); + + fs.stat(path, function () {}, _fsError); + + return new FileProperties({ + dateCreated: entry.properties.lastModifiedDate, + dateModified: entry.properties.lastModifiedDate, + directory: info.parent, + fileExtension: info.extension, + isHidden: info.hidden, + isReadonly: false, + mimeType: entry.properties.type, + size: entry.properties.size + }); + }, + + rename: function (path, newName) { + _self.dir.rename(path, newName); + }, + + readFile: function (path, success, async) { + var entry = _get(path); + + async = async === false ? async : true; + + if (!async) { + success(bbUtils.stringToBlob(entry.data)); + } + + fs.read(path, function (data) { + var blob = bbUtils.stringToBlob(data); + if (async) { + success(blob); + } + entry.data = data; + _set(path, entry); + }, _fsError); + }, + + saveFile: function (path, blob) { + var data = bbUtils.blobToString(blob); + + _set(path, { + lastModifiedDate: new Date(), + fullPath: path, + isDirectory: false, + properties: { + type: "", + size: blob.size + }, + data: data + }); + + fs.write(path, data, function (entry) { + entry.data = data; + entry.file(function (file) { + entry.properties = entry.properties || {}; + utils.mixin(file, entry.properties); + _set(path, entry); + }); + }, _fsError); + } + }, + dir: { + createNewDir: function (path) { + var entry = _get(path); + + if (!entry) { + _set(path, { + fullPath: path + }); + } + + fs.mkdir(path, function (entry) { + _set(path, entry); + }, _fsError); + }, + + deleteDirectory: function (path, recursive) { + _delete(path); + if (recursive) { + fs.rm(path, function () {}, _fsError, {recursive: recursive}); + } else { + fs.rmdir(path, function () {}, _fsError); + } + }, + + exists: function (path) { + var entry = _get(path); + fs.stat(path, function () {}, _fsError); + return !!(entry && entry.isDirectory); + }, + + getFreeSpaceForRoot: function (path) { + function _du(obj, size) { + utils.forEach(obj, function (child, key) { + if (child.isDirectory && child.children) { + size += _du(child.children, size); + } else if (child.properties && child.properties.size) { + size += child.properties.size; + } + }); + return size; + } + + return constants.FS_SIZE - _du(_cache.children, 0); + }, + + getParentDirectory: function (path) { + path = "/" + path.replace(/^\//, '').replace(/\/$/, ''); + + var entry = _get(path), + array = path.split("/"); + + fs.stat(path, function (entry) { + entry.getParent(function (p) {}, _fsError); + }, _fsError); + + return entry ? array.splice(0, array.length - 1).join("/") || "/" : null; + }, + + listDirectories: function (path) { + var dir = _get(path), + directories = []; + + utils.forEach(dir.children, function (item) { + if (item.isDirectory) { + directories.push(item.name); + } + }); + + fs.ls(path, function () {}, _fsError); + + return directories; + }, + + listFiles: function (path) { + var dir = _get(path), + files = []; + + utils.forEach(dir.children, function (item) { + if (!item.isDirectory) { + files.push(item.name); + } + }); + + fs.ls(path, function () {}, _fsError); + + return files; + }, + + rename: function (path, newName) { + var info = _getInfo(path), + parent = info.parent, + oldName = info.name, + from = (parent === "/" ? "" : parent) + "/" + oldName, + to = (parent === "/" ? "" : parent) + "/" + newName; + + _delete(from); + _set(to, { + fullPath: to + }); + + fs.mv(from, to, function (entry) { + _set(to, entry); + }, _fsError); + }, + + getRootDirs: function () { + return _self.dir.listDirectories("/"); + } + } +}; + +module.exports = _self; diff --git a/lib/ripple/platform/webworks.core/2.0.0/server/io/dir.js b/lib/ripple/platform/webworks.core/2.0.0/server/io/dir.js new file mode 100644 index 00000000..8831b5de --- /dev/null +++ b/lib/ripple/platform/webworks.core/2.0.0/server/io/dir.js @@ -0,0 +1,50 @@ +/* + * 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 cache = require('ripple/platform/webworks.core/2.0.0/fsCache'); + +function _packet(data) { + return { + code: 1, + data: data + }; +} + +module.exports = { + createNewDir: function (get, post, baton) { + cache.dir.createNewDir(post.path); + return _packet(); + }, + deleteDirectory: function (get, post, baton) { + cache.dir.deleteDirectory(post.path, post.recursive); + return _packet(); + }, + exists: function (get, post, baton) { + return _packet(cache.dir.exists(post.path)); + }, + getParentDirectory: function (get, post, baton) { + return _packet(cache.dir.getParentDirectory(post.path)); + }, + listDirectories: function (get, post, baton) { + return _packet(cache.dir.listDirectories(post.path)); + }, + listFiles: function (get, post, baton) { + return _packet(cache.dir.listFiles(post.path)); + }, + rename: function (get, post, baton) { + cache.dir.rename(post.path, post.newName); + return _packet(); + } +}; diff --git a/lib/ripple/platform/webworks.core/2.0.0/server/io/file.js b/lib/ripple/platform/webworks.core/2.0.0/server/io/file.js new file mode 100644 index 00000000..db603c62 --- /dev/null +++ b/lib/ripple/platform/webworks.core/2.0.0/server/io/file.js @@ -0,0 +1,80 @@ +/* + * 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 cache = require('ripple/platform/webworks.core/2.0.0/fsCache'), + constants = require('ripple/constants'), + notifications = require('ripple/notifications'); + +function _packet(data) { + return { + code: 1, + data: data + }; +} + +module.exports = { + copy: function (get, post, baton) { + cache.file.copy(post.from, post.to); + return _packet(); + }, + deleteFile: function (get, post, baton) { + cache.file.deleteFile(post.path); + return _packet(); + }, + exists: function (get, post, baton) { + return _packet(cache.file.exists(post.path)); + }, + getFileProperties: function (get, post, baton) { + return _packet(cache.file.getFileProperties(post.path)); + }, + open: function (get, post, baton) { + var msg = "Attempting to open file: " + post.path; + notifications.openNotification("normal", msg); + return _packet(cache.file.exists(post.path)); + }, + readFile: function (get, post, baton) { + var val; + + if (post.async) { + baton.take(); + } + + cache.file.readFile(post.path, function (data) { + if (post.async) { + baton.pass(_packet({ + fullPath: post.path, + blobData: data + })); + } else { + val = data; + } + }, post.async); + + if (!post.async) { + return _packet({ + fullPath: post.path, + blobData: val + }); + } + }, + rename: function (get, post, baton) { + cache.file.rename(post.path, post.newName); + return _packet(); + }, + saveFile: function (get, post, baton) { + cache.file.saveFile(post.path, post.blob); + return _packet(); + } +}; diff --git a/lib/ripple/platform/webworks.core/2.0.0/server/system.js b/lib/ripple/platform/webworks.core/2.0.0/server/system.js index b03d96eb..bdbf140a 100644 --- a/lib/ripple/platform/webworks.core/2.0.0/server/system.js +++ b/lib/ripple/platform/webworks.core/2.0.0/server/system.js @@ -62,14 +62,14 @@ _self = { setHomeScreenBackground: function (args) { var path = args.filePath, msg = "Set home screen background to " + path + "."; - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, msg); + notifications.openNotification("normal", msg); return {code: 1}; }, hasPermission: function (args) { var info = app.getInfo(), - feature = info.features[args.desiredModule]; + feature = info.features ? info.features[args.desiredModule] : null; - return {code: 1, data: _is(feature).allowedFor(utils.location().href) ? client.ALLOW : client.DENY}; + return {code: 1, data: feature === null || _is(feature).allowedFor(utils.location().href) ? client.ALLOW : client.DENY}; }, network: function () { return {code: 1, data: deviceSettings.retrieve("system.network")}; diff --git a/lib/ripple/platform/webworks.core/2.0.0/spec/config.js b/lib/ripple/platform/webworks.core/2.0.0/spec/config.js index e1d5527f..a9917d08 100644 --- a/lib/ripple/platform/webworks.core/2.0.0/spec/config.js +++ b/lib/ripple/platform/webworks.core/2.0.0/spec/config.js @@ -28,6 +28,7 @@ module.exports = { var widgetInfo = {}, widgetFeatures = config.widget.children.feature.validationResult, accessUrls = config.widget.children.access.validationResult, + accessFeatures = config.widget.children.access.children.feature.validationResult, toFeature = function (validationResult) { return { id: validationResult.attributes.id.value, @@ -67,10 +68,12 @@ module.exports = { return { uri: access.attributes.uri.value, subdomains: access.attributes.subdomains.value, - features: access.children ? access.children.feature.validationResult : [] + 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.reduce(function (features, validationResult) { + return access.features ? access.features.reduce(function (features, validationResult) { var feature = features[validationResult.attributes.id.value] || toFeature(validationResult); feature.URIs.push({ value: access.uri, @@ -78,7 +81,7 @@ module.exports = { }); features[feature.id] = feature; return features; - }, result); + }, result) : result; }, widgetInfo.features); return widgetInfo; @@ -376,7 +379,7 @@ module.exports = { attributeName: "type", required: true, type: "list", - listValues: ["slideIn", "slideOut", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"] + listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"] }, duration: { attributeName: "duration", @@ -411,6 +414,41 @@ module.exports = { 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.core/2.0.0/spec/events.js b/lib/ripple/platform/webworks.core/2.0.0/spec/events.js index 4fcd3c3f..91f09faa 100644 --- a/lib/ripple/platform/webworks.core/2.0.0/spec/events.js +++ b/lib/ripple/platform/webworks.core/2.0.0/spec/events.js @@ -13,31 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +var event = require('ripple/event'); + module.exports = { - "contexts": { - "systemEvent": { - "events": { - "CoverageChange": { - name: "CoverageChange", - description: "onCoverageChange", - args: false - }, - "HardwareKey": { - name: "HardwareKey", - description: "onHardwareKey", - args: [ - "Back", - "Menu", - "Convenience 1", - "Convenience 2", - "Start Call", - "End Call", - "Volume Down", - "Volume Up" - ] - } - }, - "context": "blackberry.system.event" + "app.event.onBackground": { + callback: function () { + event.trigger("AppRequestBackground"); + } + }, + "app.event.onForeground": { + callback: function () { + event.trigger("AppRequestForeground"); } } }; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/MenuItem.js b/lib/ripple/platform/webworks.handset/2.0.0/client/MenuItem.js index 59fb961e..d79342f5 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/MenuItem.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/MenuItem.js @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'); +var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + event = require('ripple/event'); function MenuItem(isSeparator, ordinal, caption, callback) { var _isDefault = false, @@ -35,14 +36,28 @@ function MenuItem(isSeparator, ordinal, caption, callback) { this.callback = callback; + this.__defineSetter__("id", function (i) { + id = i; + }); + + this.__defineGetter__("id", function () { + return id; + }); + this.__defineSetter__("caption", function (c) { caption = c; + event.trigger("MenuItemChanged", [this]); }); this.__defineGetter__("caption", function () { return caption; }); + this.__defineSetter__("ordinal", function (o) { + ordinal = o; + event.trigger("MenuItemChanged", [this]); + }); + this.__defineGetter__("ordinal", function () { return ordinal; }); @@ -53,6 +68,7 @@ function MenuItem(isSeparator, ordinal, caption, callback) { this.__defineSetter__("isDefault", function (d) { _isDefault = d; + event.trigger("MenuItemChanged", [this]); }); this.__defineGetter__("isDefault", function () { diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/Message.js b/lib/ripple/platform/webworks.handset/2.0.0/client/Message.js index 2efc2508..325d8dbb 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/Message.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/Message.js @@ -57,14 +57,13 @@ function Message(service) { send: function () { if (_msg.toRecipients) { if (_msg.uid === 0) { - _msg.uid = Number(Math.uuid(null, 16)); + _msg.uid = Number(Math.uuid(8, 10)); } _msg.folder = Message.FOLDER_DRAFT; _msg.status = Message.STATUS_UNKNOWN; transport.call(_uri + "send", { - get: {message: _msg}, - async: true + get: {message: _msg} }); } else { throw "message has no recipients"; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/PhoneLogs.js b/lib/ripple/platform/webworks.handset/2.0.0/client/PhoneLogs.js index 4a60db29..366ef724 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/PhoneLogs.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/PhoneLogs.js @@ -84,6 +84,9 @@ _self = { if (onCallLogReset) { poll("onCallLogReset"); } + + return !!(onCallLogAdded || onCallLogRemoved || + onCallLogUpdated || onCallLogRemoved); }, callAt: function (index, folderID) { diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/app.js b/lib/ripple/platform/webworks.handset/2.0.0/client/app.js index f576d2af..1e1fbe7d 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/app.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/app.js @@ -90,6 +90,10 @@ _self.__defineGetter__("id", function () { return transport.call(_uri + "id"); }); +_self.__defineGetter__("isForeground", function () { + return transport.call(_uri + "isForeground"); +}); + _self.__defineGetter__("license", function () { return transport.call(_uri + "license"); }); diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/audio.js b/lib/ripple/platform/webworks.handset/2.0.0/client/audio.js index c46d863b..4df539cd 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/audio.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/audio.js @@ -15,9 +15,11 @@ */ module.exports = { supportedContentTypes: function (protocol) { - return ['audio/mp3', 'audio/ogg']; + return protocol === 'rtsp' ? + ['audio/amr', 'audio/mp4', 'audio/aac'] : + ['audio/midi', 'mpeg', 'x-wav', 'amr', 'basic', 'x-gsm', 'mp4', 'aac', 'x-ms-wma', 'flac', 'ogg']; }, - supportedProtocols: function (content_type) { - return ['http', 'file', 'https']; + supportedProtocols: function (contentType) { + return ['http', 'file', 'rtsp']; } }; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/invoke.js b/lib/ripple/platform/webworks.handset/2.0.0/client/invoke.js index e6c91887..75545d78 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/invoke.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/invoke.js @@ -14,17 +14,14 @@ * limitations under the License. */ var _uri = "blackberry/invoke/invoke", - APP_TYPE = "appType", APP_URL_CAMERA = "camera://", APP_URL_CAMERA_VIDEO = "camera://video", - APP_URL_BROWSER = "http://", APP_URL_MAP = "map://", APP_URL_MUSIC = "music://", APP_URL_PHOTOS = "photos://", APP_URL_VIDEOS = "videos://", APP_URL_APPWORLD = "appworld://", APP_URL_UPDATE = "update://", - APP_TYPE_ERROR = "appType not supported", APP_BROWSER_ERROR = "Protocol specified in the url is not supported.", APP_ADDRESSBOOK_ERROR = "Invalid arguments specified", transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), @@ -46,6 +43,8 @@ _self = { throw APP_ADDRESSBOOK_ERROR; //need contact for this view } } + + get.appType = appType; break; //Bluetooth Config @@ -106,10 +105,9 @@ _self = { case 11: if (!args) { - get.appType = APP_URL_BROWSER; + get.appType = "http://"; } else { - //Only http:// works to launch the browser - if (args.url.indexOf(APP_URL_BROWSER) !== 0) { + if (args.url && !args.url.match(/^https?:\/\//)) { throw APP_BROWSER_ERROR; } get.appType = args.url; @@ -123,7 +121,7 @@ _self = { break; default: - throw APP_TYPE_ERROR; + throw "appType not supported"; } transport.call(_uri, { diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/io/dir.js b/lib/ripple/platform/webworks.handset/2.0.0/client/io/dir.js new file mode 100644 index 00000000..ec14be01 --- /dev/null +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/io/dir.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. + */ +var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'), + utils = require('ripple/utils'), + _uri = "blackberry/io/dir/", + FILE = "file://", + _self = {}; + +function _prunePrefix(path) { + return path.replace(new RegExp("^" + FILE), ''); +} + +utils.mixin({ + getFreeSpaceForRoot: function (path) { + return transport.call(_uri + "getFreeSpaceForRoot", { + post: {path: _prunePrefix(path)} + }); + }, + getRootDirs: function () { + return transport.call(_uri + "getRootDirs", {}).map(function (dir) { + return FILE + dir; + }); + } +}, _self); + +utils.mixin(dir, _self); + +module.exports = _self; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/menu.js b/lib/ripple/platform/webworks.handset/2.0.0/client/menu.js index 1b1e4e8b..83834100 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/menu.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/menu.js @@ -14,6 +14,7 @@ * limitations under the License. */ var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + MenuItem = require('ripple/platform/webworks.handset/2.0.0/client/MenuItem'), utils = require('ripple/utils'), onSelect, _items = {}, @@ -47,7 +48,12 @@ _self = { }, getMenuItems: function () { - return utils.copy(_items); + return utils.map(_items, function (item) { + var menuItem = new MenuItem(item.isSeparator, item.ordinal, item.caption, item.callback); + menuItem.id = item.id; + menuItem.isDefault = item.isDefault; + return menuItem; + }); }, hasMenuItem: function (menuItem) { @@ -66,6 +72,12 @@ _self = { }, setDefaultMenuItem: function (menuItem) { + utils.forEach(_items, function (item) { + item.isDefault = false; + }); + + _items[menuItem.id].isDefault = true; + transport.call(_uri + "setDefaultMenuItem", { get: {id: menuItem.id} }); diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/sms.js b/lib/ripple/platform/webworks.handset/2.0.0/client/sms.js index 0a2c7136..9741e1e3 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/client/sms.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/sms.js @@ -50,7 +50,14 @@ _self = { }; _self.__defineGetter__("isListeningForMessage", function () { - return !!onReceive; + return transport.call(_uri + "isListeningForMessage", {async: false}); +}); + +_self.__defineSetter__("isListeningForMessage", function (value) { + transport.call(_uri + "isListeningForMessage", { + async: false, + get: {isListeningForMessage: value} + }); }); module.exports = _self; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/client/system.js b/lib/ripple/platform/webworks.handset/2.0.0/client/system.js new file mode 100644 index 00000000..bbbf9ddd --- /dev/null +++ b/lib/ripple/platform/webworks.handset/2.0.0/client/system.js @@ -0,0 +1,32 @@ +var utils = require('ripple/utils'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + system = require('ripple/platform/webworks.core/2.0.0/client/system'), + _uri = "blackberry/system/", + _self; + +_self = { + setHomeScreenBackground: function (filePath) { + transport.call(_uri + "setHomeScreenBackground", { + get: {filePath: filePath}, + async: true + }); + }, +}; + +(function () { + // HACK: can't type check if system[key] is a function, sets off getters + // also can't use utils.mixin or forEach for the same reason + function get(i) { + return function () { + return system[i]; + }; + } + + for (var key in system) { + if (system.hasOwnProperty(key)) { + _self.__defineGetter__(key, get(key)); + } + } +}()); + +module.exports = _self; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server.js b/lib/ripple/platform/webworks.handset/2.0.0/server.js index e0033d1c..7d014aa4 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server.js @@ -48,6 +48,10 @@ module.exports = { menu: require(platform + "menu"), dialog: require(platform + "dialog") }, - phone: require(platform + "phone") + phone: require(platform + "phone"), + io: { + dir: require(platform + "io/dir"), + file: require(core + "io/file") + } } }; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/app.js b/lib/ripple/platform/webworks.handset/2.0.0/server/app.js index 2ff915e0..15952cc3 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server/app.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/app.js @@ -18,6 +18,7 @@ var event = require('ripple/event'), notifications = require('ripple/notifications'), constants = require('ripple/constants'), ui = require('ripple/ui'), + _isForeground = true, _self; _self = { @@ -48,6 +49,10 @@ _self = { return {code: 1, data: app.getInfo().description}; }, + isForeground: function () { + return {code: 1, data: _isForeground}; + }, + id: function () { return {code: 1, data: app.getInfo().id}; }, @@ -75,6 +80,7 @@ _self = { if (button) { button.addEventListener("click", _self.requestForeground); } + _isForeground = false; event.trigger("AppRequestBackground"); }); @@ -88,6 +94,7 @@ _self = { if (button) { button.removeEventListener("click", _self.requestForeground); } + _isForeground = true; event.trigger("AppRequestForeground"); }); @@ -95,18 +102,28 @@ _self = { }, setHomeScreenIcon: function (args) { - var msg = "The application set the home screen" + - (args.hover ? " hover " : " ") + - "icon to " + args.uri; + if (args.uri) { + var msg = "The application set the home screen" + + (args.hover ? " hover " : " ") + + "icon to " + args.uri; - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, msg); - return {code: 1}; + notifications.openNotification("normal", msg); + return {code: 1}; + } + else { + return {code: 0}; + } }, setHomeScreenName: function (args) { - var msg = "The application set the home screen name to " + args.text; - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, msg); - return {code: 1}; + if (args.text) { + var msg = "The application set the home screen name to " + args.text; + notifications.openNotification("normal", msg); + return {code: 1}; + } + else { + return {code: 1}; + } }, removeBannerIndicator: function () { diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/audioPlayer.js b/lib/ripple/platform/webworks.handset/2.0.0/server/audioPlayer.js index 6d24c521..464e6083 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server/audioPlayer.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/audioPlayer.js @@ -53,7 +53,7 @@ container = utils.createElement("section", { document.getElementById("ui").appendChild(container); function _errClosed(method) { - notifications.openNotification(constants.NOTIFICATIONS.TYPES.ERROR, + notifications.openNotification("error", "attempted to call " + method + " on a player that is already closed. This is a very bad thing to do :)"); return false; } diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/invoke.js b/lib/ripple/platform/webworks.handset/2.0.0/server/invoke.js index 89858f66..dfa5e493 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server/invoke.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/invoke.js @@ -15,19 +15,21 @@ */ var notifications = require('ripple/notifications'), constants = require('ripple/constants'), - type = constants.NOTIFICATIONS.TYPES.NORMAL, + type = "normal", name = { "0": "Address Book", "1": "Bluetooth Config", "2": "Calculator", "3": "Calendar", - "4": "Camera", + "camera://": "Camera", + "camera://video": "Video Camera", "map://": "Maps", "6": "Memopad", "7": "Messages", "8": "Phone", "9": "Search", "10": "Tasks", + "11": "Browser", "http://": "Browser", "12": "Java", }; @@ -35,7 +37,7 @@ var notifications = require('ripple/notifications'), module.exports = { invoke: function (opts) { var app = name[opts.appType]; - if (app === undefined && opts.appType.match(/^http/i)) { + if (app === undefined && opts.appType && opts.appType.match(/^http/i)) { app = "Browser"; } diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/io/dir.js b/lib/ripple/platform/webworks.handset/2.0.0/server/io/dir.js new file mode 100644 index 00000000..29a04b80 --- /dev/null +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/io/dir.js @@ -0,0 +1,39 @@ +/* + * 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 cache = require('ripple/platform/webworks.core/2.0.0/fsCache'), + dir = require('ripple/platform/webworks.core/2.0.0/server/io/dir'), + utils = require('ripple/utils'), + _self = {}; + +function _packet(data) { + return { + code: 1, + data: data + }; +} + +utils.mixin({ + getFreeSpaceForRoot: function (get, post, baton) { + return _packet(cache.dir.getFreeSpaceForRoot(post.path)); + }, + getRootDirs: function (get, post, baton) { + return _packet(cache.dir.getRootDirs()); + } +}, _self); + +utils.mixin(dir, _self); + +module.exports = _self; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/menu.js b/lib/ripple/platform/webworks.handset/2.0.0/server/menu.js index a2a9b620..780f8490 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server/menu.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/menu.js @@ -57,6 +57,10 @@ event.on("MenuItemSelected", function (menuItem) { return baton && baton.pass({code: 1, data: menuItem}); }); +event.on("MenuItemChanged", function (menuItem) { + _menuItems[menuItem.id] = menuItem; +}); + _self = { onSelect : function (args, post, baton) { diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/phone.js b/lib/ripple/platform/webworks.handset/2.0.0/server/phone.js index b54528b8..a955938c 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server/phone.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/phone.js @@ -85,7 +85,7 @@ event.on("PhoneEvent", function (type, callId, error) { var baton = _onPhoneEventListeners[type]; delete _onPhoneEventListeners[type]; - return baton && baton.pass({id: 1, data: {callId: callId, error: error}}); + return baton && baton.pass({code: 1, data: {callId: callId, error: error}}); }); event.on("PhoneCallLogAdded", function (log) { @@ -96,21 +96,21 @@ event.on("PhoneCallLogAdded", function (log) { _saveLogs(logs); _onCallLogAdded = null; - return baton && baton.pass({id: 1, data: log}); + return baton && baton.pass({code: 1, data: {log: log}}); }); event.on("PhoneCallLogRemoved", function (log) { // TODO: make this be the only one responsible for deletion (instead of triggering internally) var baton = _onCallLogRemoved; _onCallLogRemoved = null; - return baton && baton.pass({id: 1, data: log}); + return baton && baton.pass({code: 1, data: {log: log}}); }); event.on("PhoneCallLogUpdated", function (newLog, oldLog) { // TODO: implement way to update with just this event var baton = _onCallLogUpdated; _onCallLogUpdated = null; - return baton && baton.pass({id: 1, data: { + return baton && baton.pass({code: 1, data: { newLog: newLog, oldLog: oldLog }}); @@ -120,7 +120,7 @@ event.on("PhoneCallLogReset", function () { _saveLogs(_defaultLogs()); var baton = _onCallLogReset; _onCallLogReset = null; - return baton && baton.pass({id: 1}); + return baton && baton.pass({code: 1}); }); event.on("PhoneCallInitiated", function (call) { @@ -163,9 +163,11 @@ _self = { var logs = _getLogs(), subLog = _getLogs(get.folderID), deleted = false, - log; + type, log; - if (subLog.length > get.index && (log = subLog.splice(get.index, 1))) { + if (subLog.length > get.index && + (type = _isNormalCall(subLog[get.index]) ? "normal" : "missed") && + (log = logs[type].splice(get.index, 1))) { event.trigger("PhoneCallLogRemoved", [log]); _saveLogs(logs); deleted = true; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/server/sms.js b/lib/ripple/platform/webworks.handset/2.0.0/server/sms.js index d74f5bd4..7e7f2e01 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/server/sms.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/server/sms.js @@ -14,7 +14,7 @@ * limitations under the License. */ var _listener, - _isListeningForMessage, + _isListening = false, notifications = require('ripple/notifications'), constants = require('ripple/constants'), event = require('ripple/event'), @@ -23,12 +23,13 @@ var _listener, _self; event.on("MessageReceived", function (message) { - if (message.type !== 'sms') { + if (!_isListening || message.type !== 'sms') { return; } var baton = _onReceive; _onReceive = null; + _isListening = false; return baton && baton.pass({code: 1, data: message}); }); @@ -36,13 +37,22 @@ _self = { onReceive: function (args, post, baton) { baton.take(); _onReceive = baton; + _isListening = !!_onReceive; }, send: function (args) { var msg = "To " + args.address + ": " + args.message; - notifications.openNotification(constants.NOTIFICATIONS.TYPES.NORMAL, msg); + notifications.openNotification("normal", msg); _console.log(msg); return {code: 1}; + }, + + isListeningForMessage: function (get, post, baton) { + if (get && typeof get.isListeningForMessage === "boolean") { + _isListening = get.isListeningForMessage; + } + + return {code: 1, data: _isListening}; } }; diff --git a/lib/ripple/platform/webworks.handset/2.0.0/spec.js b/lib/ripple/platform/webworks.handset/2.0.0/spec.js index ea70580e..efdde82f 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/spec.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/spec.js @@ -21,10 +21,10 @@ module.exports = { persistencePrefix: "rim-handset-", - ui: require('ripple/platform/webworks.core/2.0.0/spec/ui'), + ui: require('ripple/platform/webworks.handset/2.0.0/spec/ui'), device: require('ripple/platform/webworks.handset/2.0.0/spec/device'), config: require('ripple/platform/webworks.core/2.0.0/spec/config'), - events: require('ripple/platform/webworks.core/2.0.0/spec/events'), + events: require('ripple/platform/webworks.handset/2.0.0/spec/events'), objects: { XMLHttpRequest: { @@ -216,7 +216,7 @@ module.exports = { } }, system: { - path: "webworks.core/2.0.0/client/system", + path: "webworks.handset/2.0.0/client/system", feature: "blackberry.system", children: { event: { @@ -267,6 +267,18 @@ module.exports = { feature: "blackberry.audio.Player" } } + }, + io: { + children: { + dir: { + path: "webworks.handset/2.0.0/client/io/dir", + feature: "blackberry.io.dir" + }, + file: { + path: "webworks.core/2.0.0/client/io/file", + feature: "blackberry.io.file" + } + } } } } diff --git a/lib/ripple/platform/webworks.handset/2.0.0/spec/device.js b/lib/ripple/platform/webworks.handset/2.0.0/spec/device.js index f6e441d5..2d7b90ec 100644 --- a/lib/ripple/platform/webworks.handset/2.0.0/spec/device.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/spec/device.js @@ -17,21 +17,21 @@ var event = require('ripple/event'); module.exports = { "transports": { - "TCPCellular": { + "TCP Cellular": { "name": "Cellular TCP", "control": { "type": "checkbox", "value": true } }, - "WAP": { + "Wap": { "name": "WAP", "control": { "type": "checkbox", "value": false } }, - "WAP2": { + "Wap 2.0": { "name": "WAP 2.0", "control": { "type": "checkbox", @@ -45,21 +45,21 @@ module.exports = { "value": true } }, - "BISB": { + "Bis B": { "name": "BIS B", "control": { "type": "checkbox", "value": true } }, - "Unite": { - "name": "Unite!", + "Unite!": { + "name": "Unite", "control": { "type": "checkbox", "value": false } }, - "TCPWifi": { + "TCP Wifi": { "name": "Wifi TCP", "control": { "type": "checkbox", diff --git a/lib/ripple/platform/wac/1.0/PositionInfo.js b/lib/ripple/platform/webworks.handset/2.0.0/spec/events.js similarity index 53% rename from lib/ripple/platform/wac/1.0/PositionInfo.js rename to lib/ripple/platform/webworks.handset/2.0.0/spec/events.js index 9cf3697f..87e02be2 100644 --- a/lib/ripple/platform/wac/1.0/PositionInfo.js +++ b/lib/ripple/platform/webworks.handset/2.0.0/spec/events.js @@ -13,24 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var geo = require('ripple/geo'), - event = require('ripple/event'), - exception = require('ripple/exception'), +var _self, utils = require('ripple/utils'), - _self = { - latitude: undefined, - longitude: undefined, - altitude: undefined, - cellID: undefined, - accuracy: undefined, - altitudeAccuracy: undefined, - timeStamp: undefined - }; + event = require('ripple/event'), + events = require('ripple/platform/webworks.core/2.0.0/spec/events'); + +_self = { + "system.event.onCoverageChange": { + callback: function () { + event.trigger("CoverageChange"); + } + }, + "system.event.onHardwareKey": { + args: [ + "Back", + "Menu", + "Convenience 1", + "Convenience 2", + "Start Call", + "End Call", + "Volume Down", + "Volume Up" + ], + callback: function (key) { + event.trigger("HardwareKey", [key]); + } + } +}; -utils.forEach(_self, function (value, property) { - _self.__defineGetter__(property, function () { - return geo.getPositionInfo()[property]; - }); -}); +utils.mixin(events, _self); module.exports = _self; diff --git a/lib/ripple/platform/webworks.core/2.0.0/spec/ui.js b/lib/ripple/platform/webworks.handset/2.0.0/spec/ui.js similarity index 100% rename from lib/ripple/platform/webworks.core/2.0.0/spec/ui.js rename to lib/ripple/platform/webworks.handset/2.0.0/spec/ui.js diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/client/appEvent.js b/lib/ripple/platform/webworks.tablet/2.0.0/client/appEvent.js index a213cbf1..05a35fd9 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/client/appEvent.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/client/appEvent.js @@ -41,11 +41,11 @@ _self = { }, onSwipeDown: function (handler) { - throw "not implemented"; + _poll("onSwipeDown", handler); }, onSwipeStart: function (handler) { - throw "not implemented"; + _poll("onSwipeStart", handler); } }; diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/client/dialog.js b/lib/ripple/platform/webworks.tablet/2.0.0/client/dialog.js index e5dfcdf2..e4add605 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/client/dialog.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/client/dialog.js @@ -40,7 +40,8 @@ _self = { async: true, get: { message: message, - buttons: choices + buttons: choices, + settings: settings } }, function (response) { if (callback) { @@ -55,7 +56,8 @@ _self = { async: true, get: { message: message, - buttons: choices + buttons: choices, + settings: settings } }, function (response) { if (callback) { @@ -85,32 +87,36 @@ _self.__defineGetter__("D_OK_CANCEL", function () { return 4; }); -_self.__defineGetter__("C_CANCEL", function () { - return -1; +_self.__defineGetter__("BOTTOM", function () { + return "bottomCenter"; }); -_self.__defineGetter__("C_OK", function () { - return 0; +_self.__defineGetter__("CENTER", function () { + return "middleCenter"; }); -_self.__defineGetter__("C_SAVE", function () { - return 1; +_self.__defineGetter__("TOP", function () { + return "topCenter"; }); -_self.__defineGetter__("C_DISCARD", function () { - return 2; +_self.__defineGetter__("SIZE_FULL", function () { + return "full"; }); -_self.__defineGetter__("C_DELETE", function () { - return 3; +_self.__defineGetter__("SIZE_LARGE", function () { + return "large"; }); -_self.__defineGetter__("C_YES", function () { - return 4; +_self.__defineGetter__("SIZE_MEDIUM", function () { + return "medium"; +}); + +_self.__defineGetter__("SIZE_SMALL", function () { + return "small"; }); -_self.__defineGetter__("C_NO", function () { - return -1; +_self.__defineGetter__("SIZE_TALL", function () { + return "tall"; }); module.exports = _self; diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/client/invoke.js b/lib/ripple/platform/webworks.tablet/2.0.0/client/invoke.js index dccd83c6..1fe76ab4 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/client/invoke.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/client/invoke.js @@ -17,7 +17,6 @@ var _uri = "blackberry/invoke/invoke", APP_TYPE = "appType", APP_URL_CAMERA = "camera://", APP_URL_CAMERA_VIDEO = "camera://video", - APP_URL_BROWSER = "http://", APP_URL_MAP = "map://", APP_URL_MUSIC = "music://", APP_URL_PHOTOS = "photos://", @@ -53,15 +52,23 @@ _self = { case 11: if (!args) { - get.appType = APP_URL_BROWSER; - } else { - //Only http:// works to launch the browser - if (args.url.indexOf(APP_URL_BROWSER) !== 0) { - throw APP_BROWSER_ERROR; - } - get.appType = args.url; + get.appType = "http://"; } + else { + get.appType = args.url.split("://"); + 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 APP_BROWSER_ERROR; + } + else { + get.appType = args.url; + } + } + } break; //Music @@ -121,8 +128,5 @@ _self.__defineGetter__("APP_VIDEOS", function () { _self.__defineGetter__("APP_APPWORLD", function () { return 16; }); -_self.__defineGetter__("APP_UPDATE", function () { - return 17; -}); module.exports = _self; diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/server.js b/lib/ripple/platform/webworks.tablet/2.0.0/server.js index 7b580f75..a893c1ce 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/server.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/server.js @@ -31,6 +31,10 @@ module.exports = { system: system, ui: { dialog: require(platform + "dialog") + }, + io: { + dir: require(core + "io/dir"), + file: require(core + "io/file") } } }; 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 16c00607..90b35c13 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 @@ -16,6 +16,8 @@ var event = require('ripple/event'), _bg, _fg, + _swipeDown, + _swipeStart, _exit; event.on("AppRequestBackground", function () { @@ -30,6 +32,18 @@ event.on("AppRequestForeground", function () { return baton && baton.pass({code: 1}); }); +event.on("AppSwipeDown", function () { + var baton = _swipeDown; + _swipeDown = null; + return baton && baton.pass({code: 1}); +}); + +event.on("AppSwipeStart", function () { + var baton = _swipeStart; + _swipeStart = null; + return baton && baton.pass({code: 1}); +}); + module.exports = { onBackground: function (get, post, baton) { baton.take(); @@ -41,5 +55,17 @@ module.exports = { baton.take(); _fg = baton; return {code: 1}; + }, + + onSwipeDown: function (get, post, baton) { + baton.take(); + _swipeDown = baton; + return {code: 1}; + }, + + onSwipeStart: function (get, post, baton) { + baton.take(); + _swipeStart = baton; + return {code: 1}; } }; diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/server/dialog.js b/lib/ripple/platform/webworks.tablet/2.0.0/server/dialog.js index c6015b19..ed4d58ee 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/server/dialog.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/server/dialog.js @@ -56,14 +56,34 @@ _self = { var container = document.getElementById(constants.COMMON.VIEWPORT_CONTAINER), height = window.getComputedStyle(container, null).getPropertyValue("height"), width = window.getComputedStyle(container, null).getPropertyValue("width"), + sizeDiv = document.getElementById("dialog-wrapper"), + positionDiv = document.getElementById("dialog-window"), + titleDiv = document.getElementById("dialog-title"), buttonsDiv = document.getElementById("dialog-buttons"), - messageDiv = document.getElementById("dialog-message"); + messageDiv = document.getElementById("dialog-message"), + position, size; if (!messageDiv || !buttonsDiv) { return; } dialog.setAttribute("style", "display:-webkit-box;height:" + height + "; width:" + width + ";"); + + position = "overlay-dialog"; + size = "overlay-dialog-wrapper"; + + if (args.settings && args.settings.position) { + position += " overlay-dialog-" + args.settings.position; + } + + if (args.settings && args.settings.size) { + size += " overlay-dialog-wrapper-" + args.settings.size; + } + + positionDiv.setAttribute("class", position); + sizeDiv.setAttribute("class", size); + + titleDiv.innerHTML = args.settings && args.settings.title ? args.settings.title : ""; messageDiv.innerHTML = args.message; isDialogVisible = true; diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/server/invoke.js b/lib/ripple/platform/webworks.tablet/2.0.0/server/invoke.js index cde3337d..a09c2c44 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/server/invoke.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/server/invoke.js @@ -15,9 +15,10 @@ */ var notifications = require('ripple/notifications'), constants = require('ripple/constants'), - type = constants.NOTIFICATIONS.TYPES.NORMAL, + type = "normal", name = { "camera://": "Camera", + "camera://video": "Video Camera", "map://": "Maps", "http://": "Browser", "music://": "Music", @@ -30,7 +31,7 @@ var notifications = require('ripple/notifications'), module.exports = { invoke: function (opts) { var app = name[opts.appType]; - if (app === undefined && opts.appType.match(/^http/i)) { + if (app === undefined && opts.appType && opts.appType.match(/^http/i)) { app = "Browser"; } diff --git a/lib/ripple/platform/webworks.tablet/2.0.0/spec.js b/lib/ripple/platform/webworks.tablet/2.0.0/spec.js index 797fac8a..631d471d 100644 --- a/lib/ripple/platform/webworks.tablet/2.0.0/spec.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/spec.js @@ -21,10 +21,10 @@ module.exports = { persistencePrefix: "rim-tablet-", - ui: require('ripple/platform/webworks.core/2.0.0/spec/ui'), + ui: require('ripple/platform/webworks.tablet/2.0.0/spec/ui'), device: require('ripple/platform/webworks.tablet/2.0.0/spec/device'), config: require('ripple/platform/webworks.core/2.0.0/spec/config'), - events: require('ripple/platform/webworks.core/2.0.0/spec/events'), + events: require('ripple/platform/webworks.tablet/2.0.0/spec/events'), objects: { XMLHttpRequest: { @@ -102,6 +102,18 @@ module.exports = { utils: { path: "webworks.core/2.0.0/client/utils", feature: "blackberry.utils" + }, + io: { + children: { + dir: { + path: "webworks.core/2.0.0/client/io/dir", + feature: "blackberry.io.dir" + }, + file: { + path: "webworks.core/2.0.0/client/io/file", + feature: "blackberry.io.file" + } + } } } } diff --git a/lib/ripple/platform/wac/1.0/RadioSignalSourceTypes.js b/lib/ripple/platform/webworks.tablet/2.0.0/spec/events.js similarity index 60% rename from lib/ripple/platform/wac/1.0/RadioSignalSourceTypes.js rename to lib/ripple/platform/webworks.tablet/2.0.0/spec/events.js index e56ae67f..cb0ae51a 100644 --- a/lib/ripple/platform/wac/1.0/RadioSignalSourceTypes.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/spec/events.js @@ -14,20 +14,23 @@ * limitations under the License. */ var _self, - utils = require('ripple/utils'); + utils = require('ripple/utils'), + event = require('ripple/event'), + events = require('ripple/platform/webworks.core/2.0.0/spec/events'); _self = { - "CDMA": undefined, - "GSM": undefined, - "LTE": undefined, - "TDSCDMA": undefined, - "WCDMA": undefined + "app.event.onSwipeDown": { + callback: function () { + event.trigger("AppSwipeDown"); + } + }, + "app.event.onSwipeStart": { + callback: function () { + event.trigger("AppSwipeStart"); + } + } }; -utils.forEach(_self, function (value, property) { - _self.__defineGetter__(property, function () { - return property; - }); -}); +utils.mixin(events, _self); module.exports = _self; diff --git a/lib/ripple/platform/vodafone/2.7/spec/ui.js b/lib/ripple/platform/webworks.tablet/2.0.0/spec/ui.js similarity index 89% rename from lib/ripple/platform/vodafone/2.7/spec/ui.js rename to lib/ripple/platform/webworks.tablet/2.0.0/spec/ui.js index de36273b..2f2d437b 100644 --- a/lib/ripple/platform/vodafone/2.7/spec/ui.js +++ b/lib/ripple/platform/webworks.tablet/2.0.0/spec/ui.js @@ -17,11 +17,7 @@ module.exports = { plugins: [ "accelerometer", "deviceSettings", - "fileSystem", "geoView", - "multimedia", - "audioPlayer", - "storage", "platformEvents", "widgetConfig" ] diff --git a/lib/ripple/touchEventEmulator.js b/lib/ripple/touchEventEmulator.js index 98bc2c9b..dd255f6d 100644 --- a/lib/ripple/touchEventEmulator.js +++ b/lib/ripple/touchEventEmulator.js @@ -17,13 +17,11 @@ var emulatorBridge = require('ripple/emulatorBridge'), utils = require('ripple/utils'), _isMouseDown, self; -function _initTouchEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, - altKey, shiftKey, metaKey, touches, targetTouches, changedTouches, scale, rotation) { - var touchEvent = emulatorBridge.getWidgetDocument().createEvent("Event"); +// NOTE: missing view, detail, touches, targetTouches, scale and rotation +function _initTouchEvent(type, canBubble, cancelable, eventData) { + var touchEvent = emulatorBridge.document().createEvent("Event"); touchEvent.initEvent(type, canBubble, cancelable); - touchEvent.altKey = altKey; - touchEvent.changedTouches = changedTouches; - + utils.mixin(eventData, touchEvent); return touchEvent; } @@ -31,7 +29,8 @@ function _raiseTouchEvent(mouseEvent) { var type = "", preventDefault = false, simulatedEvent, - touchObj; + touchObj, + eventData; switch (mouseEvent.type) { case "mousedown": @@ -61,13 +60,23 @@ function _raiseTouchEvent(mouseEvent) { pageY: mouseEvent.pageY, screenX: mouseEvent.screenX, screenY: mouseEvent.screenY, - target: mouseEvent.target + target: mouseEvent.target, + }; + + eventData = { + altKey: mouseEvent.altKey, + ctrlKey: mouseEvent.ctrlKey, + shiftKey: mouseEvent.shiftKey, + metaKey: mouseEvent.metaKey, + changedTouches: [touchObj] }; - simulatedEvent = _initTouchEvent(type, true, true, emulatorBridge.getWidgetDocument(), 1, mouseEvent.screenX, mouseEvent.screenY, - mouseEvent.clientX, mouseEvent.clientY, mouseEvent.ctrlKey, mouseEvent.altKey, mouseEvent.shiftKey, mouseEvent.metaKey, [], [], [touchObj], 1, 0); + utils.mixin(touchObj, eventData); + + simulatedEvent = _initTouchEvent(type, true, true, eventData); mouseEvent.target.dispatchEvent(simulatedEvent); + if (typeof mouseEvent.target["on" + type] === "function") { mouseEvent.target["on" + type].apply(mouseEvent.target, [simulatedEvent]); } @@ -89,12 +98,5 @@ self = module.exports = { frame.contentWindow.addEventListener("DOMContentLoaded", function () { _marshalEvents(frame.contentDocument); }); - }, - // void initTouchEvent( in DOMString type, in boolean canBubble, in boolean cancelable, in DOMWindow view, in long detail, - // in long screenX, in long screenY, in long clientX, in long clientY, in boolean ctrlKey, in boolean altKey, - // in boolean shiftKey, in boolean metaKey, in TouchList touches, in TouchList targetTouches, - // in TouchList changedTouches, in float scale, in float rotation); - initTouchEvent: function (type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, touches, targetTouches, changedTouches, scale, rotation) { - return _initTouchEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, touches, targetTouches, changedTouches, scale, rotation); } }; diff --git a/lib/ripple/ui.js b/lib/ripple/ui.js index 7b0adffc..587f8d84 100644 --- a/lib/ripple/ui.js +++ b/lib/ripple/ui.js @@ -24,6 +24,9 @@ var _self, _applicationState, _availablePanels, _systemPlugins = [ + "options", + "about-dialog", + "settings-dialog", "firstRunCheck", "devices", "goodVibrations", @@ -92,9 +95,8 @@ function _addUIPaneItemsToApplicationState(arrayObj, pane) { function _insertStyleSheets() { var uiTheme = db.retrieve("ui-theme") || require('ripple/ui/themes')[0], - GUID = new Date().getTime(), extensionURL = jQuery("#extension-url").text(), - uiThemeURL = extensionURL + "themes/" + uiTheme + "/theme.css?" + GUID, + uiThemeURL = extensionURL + "themes/" + uiTheme + "/theme.css", head = document.getElementsByTagName('head')[0]; function stylesheet(src) { @@ -106,7 +108,6 @@ function _insertStyleSheets() { } head.appendChild(stylesheet(uiThemeURL)); - head.appendChild(stylesheet(extensionURL + "styles/jquery.tooltip.css?" + GUID)); } function _initializeUI() { @@ -251,6 +252,14 @@ _self = module.exports = { return utils.copy(_systemPlugins); }, + register: function (plugin) { + _systemPlugins.push(plugin); + }, + + registered: function (plugin) { + return _systemPlugins.indexOf(plugin) >= 0; + }, + getExtensionURL: function () { return jQuery("#" + constants.COMMON.EXTENSION_URL_CONTAINER).text(); }, diff --git a/lib/ripple/ui/plugins/about-dialog.js b/lib/ripple/ui/plugins/about-dialog.js new file mode 100644 index 00000000..7ff9dbd9 --- /dev/null +++ b/lib/ripple/ui/plugins/about-dialog.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 utils = require('ripple/utils'); + +module.exports = { + initialize: function () { + $("#about-dialog").dialog({ + autoOpen: false, + position: 'center', + minWidth: '400' + }); + }, + show: function () { + //TODO: Restore this line once framework issue is resolved + //var port = window.stagewebview ? stagewebview.serverPort : "9900"; + var port = "9900"; + + $.ajax({ + url: "http://127.0.0.1:" + port + "/ripple/about", + async: true, + success: function (resp) { + $("#about-dialog-ripple-build-deploy-version").html("(v" + resp.data.version + ")"); + } + }); + + $.ajax({ + url: utils.rippleLocation() + "package.json", + async: true, + success: function (resp) { + $("#about-dialog-ripple-ui-version").html("(v" + resp.version + ")"); + } + }); + + $("#about-dialog").dialog("open"); + } +}; diff --git a/lib/ripple/ui/plugins/about-dialog/dialog.html b/lib/ripple/ui/plugins/about-dialog/dialog.html new file mode 100644 index 00000000..48ef3250 --- /dev/null +++ b/lib/ripple/ui/plugins/about-dialog/dialog.html @@ -0,0 +1,17 @@ +
+ + Ripple Mobile Emulator + (v0.9.0) +
+
    +
  • Ripple UI + (checking...) +
  • +
  • Ripple Framework + (v0.9.0) +
  • +
  • Ripple Build & Deploy + (checking...) +
  • +
+
diff --git a/lib/ripple/ui/plugins/accelerometer.js b/lib/ripple/ui/plugins/accelerometer.js index 654233e4..009d0225 100644 --- a/lib/ripple/ui/plugins/accelerometer.js +++ b/lib/ripple/ui/plugins/accelerometer.js @@ -16,13 +16,15 @@ var ui = require('ripple/ui'), Rotation = require('ripple/platform/w3c/1.0/Rotation'), Acceleration = require('ripple/platform/w3c/1.0/Acceleration'), _mouseDown, + _shiftKeyDown, _offsets = { x: 0, y: 0, - z: 0 + z: -9.81, }, _oldX, _oldY, + _oldAlphaX, _shape = // // The front side @@ -82,7 +84,8 @@ function _updateAccelerometerPanel(motion) { function _updateCanvas(a, b, g) { ThreeDee.loadMesh(_shape); g = g || 0; - ThreeDee.rotate(b, g, a); + ThreeDee.rotate(0, g, 0); + ThreeDee.rotate(b, 0, a); ThreeDee.backface(); ThreeDee.shade(); ThreeDee.zSort(); @@ -92,34 +95,68 @@ function _updateCanvas(a, b, g) { } function _createCanvas() { - var node = document.querySelector("#accelerometer-canvas"); + var node = document.querySelector("#accelerometer-canvas"), + x = 0, y = 0, z = -9.81, + alpha = 0, beta = 0, gamma = 0, + cosX, sinX, cosY, sinY, + deltaAlpha = 360; + ThreeDee.setCenter(150, 100); ThreeDee.setLight(-300, -300, 800); node.addEventListener("mousemove", function (e) { - if (_mouseDown) { + if (_mouseDown && !_shiftKeyDown) { _offsets.x = (_offsets.x + _oldX - e.offsetX) % 360; _offsets.y = (_offsets.y + _oldY - e.offsetY) % 360; - _updateCanvas(_offsets.x, _offsets.y); + alpha = alpha || 0; + + // enforce gamma in [-90,90] as per w3c spec + gamma = -_offsets.x; + if (gamma < -90) { + gamma = -90; + } + if (gamma > 90) { + gamma = 90; + } + + // enforce beta in [-180,180] as per w3c spec + beta = -_offsets.y % 360; + if (beta < -180) { + beta += 360; + } + else if (beta >= 180) { + beta -= 360; + } + + cosX = Math.cos((gamma) * (Math.PI / 180)); + sinX = Math.sin((gamma) * (Math.PI / 180)); + cosY = Math.cos((beta) * (Math.PI / 180)); + sinY = Math.sin((beta) * (Math.PI / 180)); + x = 9.81 * cosY * sinX; + y = -9.81 * sinY; + z = -9.81 * cosY * cosX; - var cosX = Math.cos((_offsets.x) * (Math.PI / 180)), - sinX = Math.sin((_offsets.x) * (Math.PI / 180)), - cosY = Math.cos((_offsets.y) * (Math.PI / 180)), - sinY = Math.sin((_offsets.y) * (Math.PI / 180)); + } + else if (_mouseDown && _shiftKeyDown) { + deltaAlpha = (deltaAlpha - (_oldAlphaX - e.offsetX) * 2.5) % 360; + alpha = (360 - deltaAlpha) % 360; + } - accelerometer.setInfo({ - x: sinX * 9.81, - z: -cosX * cosY * 9.81, - y: sinY * cosX * 9.81, - alpha: (-_offsets.x + 360) % 360, - beta: -_offsets.y % 90, - gamma: 0 //gamma radiation is dangerous, stay away - }); + _oldX = e.offsetX; + _oldY = e.offsetY; + _oldAlphaX = e.offsetX; + + _updateCanvas(deltaAlpha, -beta, gamma); + accelerometer.setInfo({ + x: x, + y: y, + z: z, + alpha: alpha, + beta: beta, + gamma: gamma + }); - _oldX = e.offsetX; - _oldY = e.offsetY; - } }); node.addEventListener("mousedown", function (e) { @@ -132,6 +169,24 @@ function _createCanvas() { _mouseDown = false; }); + document.addEventListener("mouseup", function (e) { + //Catch mouseup events that fire when outside canvas bounds + _mouseDown = false; + }); + + document.addEventListener("keydown", function (e) { + if (e.keyCode === 16) { // Shift Key + _oldAlphaX = _oldX; + _shiftKeyDown = true; + } + }); + + document.addEventListener("keyup", function (e) { + if (e.keyCode === 16) { // Shift Key + _shiftKeyDown = false; + } + }); + return node; } @@ -144,10 +199,11 @@ function _resetAccelerometer() { _updateCanvas(0, 0); _oldX = 0; _oldY = 0; + _oldAlphaX = 0; _offsets = { x: 0, y: 0, - z: 0 + z: -9.81, }; accelerometer.setInfo({ acceleration: new Acceleration(0, 0, 0), diff --git a/lib/ripple/ui/plugins/accelerometer/panel.html b/lib/ripple/ui/plugins/accelerometer/panel.html index 15de712c..4abba1e4 100644 --- a/lib/ripple/ui/plugins/accelerometer/panel.html +++ b/lib/ripple/ui/plugins/accelerometer/panel.html @@ -25,6 +25,14 @@ + + + diff --git a/lib/ripple/ui/plugins/audioPlayer.js b/lib/ripple/ui/plugins/audioPlayer.js deleted file mode 100644 index 2460a536..00000000 --- a/lib/ripple/ui/plugins/audioPlayer.js +++ /dev/null @@ -1,44 +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 event = require('ripple/event'), - constants = require('ripple/constants'), - audioObj = document.getElementById("multimedia-audio"), - audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID); - -module.exports = { - initialize: function () { - var audioObj = document.getElementById("multimedia-audio"), - audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID); - - if (audioObj) { - event.on("MultimediaVolumeChanged", function (volume) { - audioObj.volume = parseFloat(volume / 10); - }); - - audioObj.addEventListener("timeupdate", function () { - var s = parseInt(audioObj.currentTime % 60, 10), - m = parseInt((audioObj.currentTime / 60) % 60, 10); - - audioProgress.innerText = ((m > 9) ? m : "0" + m) + ':' + ((s > 9) ? s : "0" + s); - }, false); - - event.on("MultimediaAudioStateChanged", function (state) { - document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_STATE_FIELD_ID).innerText = state; - document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_FILE_FIELD_ID).innerText = audioObj.getAttribute("src"); - }); - } - } -}; diff --git a/lib/ripple/ui/plugins/dialog/overlay.html b/lib/ripple/ui/plugins/dialog/overlay.html index 551e3541..9cefd7e5 100644 --- a/lib/ripple/ui/plugins/dialog/overlay.html +++ b/lib/ripple/ui/plugins/dialog/overlay.html @@ -14,10 +14,11 @@ * limitations under the License. -->
-
-
-
-
+
+
+
+
+
diff --git a/lib/ripple/ui/plugins/fileSystem.js b/lib/ripple/ui/plugins/fileSystem.js deleted file mode 100644 index 75a628c8..00000000 --- a/lib/ripple/ui/plugins/fileSystem.js +++ /dev/null @@ -1,37 +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 utils = require('ripple/utils'), - constants = require('ripple/constants'), - fileSystem = require('ripple/fileSystem'), - fileSystemPaths = fileSystem.getFileSystemPaths(); - -module.exports = { - panel: { - domId: "filsystem-container", - collapsed: true, - pane: "left" - }, - initialize: function () { - var fileSystemPaths = fileSystem.getFileSystemPaths(); - - utils.forEach(fileSystemPaths, function (value, key) { - utils.bindAutoSaveEvent(jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val(value.uri), function () { - value.uri = jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val(); - fileSystem.updateFileSystemPaths(fileSystemPaths); - }); - }); - } -}; diff --git a/lib/ripple/ui/plugins/fileSystem/panel.html b/lib/ripple/ui/plugins/fileSystem/panel.html deleted file mode 100644 index c1db8b90..00000000 --- a/lib/ripple/ui/plugins/fileSystem/panel.html +++ /dev/null @@ -1,52 +0,0 @@ - -
-
-
File System
-
- -
-
- -
+ + Click and drag with the mouse to manipulate the device.
+ Hold the Shift key to modify 'alpha' +
+
m / s^2
- - - - - - - - - - - - - - - - -
- - diff --git a/lib/ripple/ui/plugins/information.js b/lib/ripple/ui/plugins/information.js index 7c1d6f4c..13d409cf 100644 --- a/lib/ripple/ui/plugins/information.js +++ b/lib/ripple/ui/plugins/information.js @@ -32,7 +32,7 @@ function _updateInformationView() { infoList.push('
'); if (widgetInfo.icon) { - infoList.push('
widget icon
'); + infoList.push('
widget icon
'); } if (widgetInfo.name) { infoList.push('
' + widgetInfo.name + '
'); @@ -70,7 +70,8 @@ function _updateBanner(icon, count) { iconImg = document.getElementById("information-banner-icon"), countSpan = document.getElementById("information-banner-count"); - if (count > 0) { + if (icon && (count === undefined || count > 0)) { + count = count || ""; jQuery("#" + constants.COMMON.INFO_SECTION).show(); jQuery(bannerSection).fadeToggle(1000); jQuery(bannerSection).fadeIn(1000); @@ -79,8 +80,12 @@ function _updateBanner(icon, count) { jQuery(bannerSection).fadeOut(1000); } - iconImg.src = icon; - countSpan.innerHTML = count; + iconImg.src = utils.appLocation() + icon; + if (icon.indexOf("http") === 0) { + iconImg.src = icon; + } + + countSpan.innerHTML = count > 99 ? "99+" : count; } module.exports = { diff --git a/lib/ripple/ui/plugins/messaging/panel.html b/lib/ripple/ui/plugins/messaging/panel.html index 7db4b5bf..d19e606a 100644 --- a/lib/ripple/ui/plugins/messaging/panel.html +++ b/lib/ripple/ui/plugins/messaging/panel.html @@ -33,7 +33,7 @@ diff --git a/lib/ripple/ui/plugins/multimedia.js b/lib/ripple/ui/plugins/multimedia.js deleted file mode 100644 index e48a71c4..00000000 --- a/lib/ripple/ui/plugins/multimedia.js +++ /dev/null @@ -1,46 +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 constants = require('ripple/constants'), - event = require('ripple/event'), - volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID), - volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID); - -module.exports = { - panel: { - domId: "multimedia-container", - collapsed: true, - pane: "left" - }, - initialize: function () { - var volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID), - volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID); - - event.on("MultimediaVolumeChanged", function (volume) { - volumeField.innerText = volume > 9 ? volume : "0" + volume; - if (volume.value !== volume) { - volume.value = volume; - } - }); - - volume.addEventListener('change', function () { - event.trigger("MultimediaVolumeChanged", [this.value], true); - }, false); - - event.on("MultimediaAudioStateChanged", function updateIsAudioPlaying(state) { - document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PLAYING_FIELD_ID).innerHTML = state === constants.MULTIMEDIA.AUDIO_STATES.PLAYING; - }); - } -}; diff --git a/lib/ripple/ui/plugins/multimedia/panel.html b/lib/ripple/ui/plugins/multimedia/panel.html deleted file mode 100644 index 9488c6d0..00000000 --- a/lib/ripple/ui/plugins/multimedia/panel.html +++ /dev/null @@ -1,78 +0,0 @@ - -
-
-
Multimedia
-
- -
-
-
- +
- - - - - - - - - - - - -
false
false
- 05 - -
- -

Audio Player

- - - - - - - - - - - - - - -
- -

Video Player

- - - - - - - - - - - - - - -
- - diff --git a/lib/ripple/ui/plugins/omnibar.js b/lib/ripple/ui/plugins/omnibar.js new file mode 100644 index 00000000..4f1a4c2f --- /dev/null +++ b/lib/ripple/ui/plugins/omnibar.js @@ -0,0 +1,116 @@ +/* + * 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 emulatorBridge = require('ripple/emulatorBridge'), + db = require('ripple/db'), + event = require('ripple/event'); + +function _omnibar() { + return document.querySelector(".omni-bar input"); +} + +function _persist(url) { + db.save("current-url", url); +} + +function _persistRoot(url) { + db.save("root-url", url); +} + +function _currentURL() { + return db.retrieve("current-url") || "about:blank"; +} + +function _rootURL() { + return db.retrieve("root-url") || "about:blank"; +} + +function _back() { + emulatorBridge.window().history.back(); +} + +function _forward() { + emulatorBridge.window().history.forward(); +} + +function _reload() { + emulatorBridge.window().location.reload(); +} + +event.on("FrameHistoryChange", function (url) { + _omnibar().value = url; + _persist(url); +}); + +module.exports = { + initialize: function (prev, baton) { + var omnibar = _omnibar(); + + jQuery(".logo, .beta, .left, .right, .left-panel-collapse, .right-panel-collapse").css({ + "marginTop": "35px" + }); + + jQuery("#settings-xhr-proxy").parent().parent().hide(); + + $(".omni-bar").show(); + + omnibar.value = _currentURL(); + + omnibar.addEventListener("keydown", function (event) { + if (event.keyCode === '13' || event.keyCode === 13) { // enter + //default the protocal if not provided + omnibar.value = omnibar.value.indexOf("://") < 0 ? "http://" + omnibar.value : omnibar.value; + _persist(omnibar.value); + _persistRoot(omnibar.value); + emulatorBridge.window().location.assign(omnibar.value); + } + }); + + window.addEventListener("keydown", function (event) { + var hasMetaOrAltPressed = (event.metaKey || event.ctrlKey), + key = parseInt(event.keyCode, 10); + + if (key === 37 && hasMetaOrAltPressed) { // cmd/ctrl + left arrow + event.preventDefault(); + _back(); + } + + if (key === 39 && hasMetaOrAltPressed) { // cmd/ctrl + right arrow + event.preventDefault(); + _forward(); + } + + if (key === 82 && hasMetaOrAltPressed) { // cmd/ctrl + r + event.preventDefault(); + _reload(); + } + + if (key === 116) { // F5 + event.preventDefault(); + _reload(); + } + }); + + document.getElementById("history-back").addEventListener("click", _back); + document.getElementById("history-forward").addEventListener("click", _forward); + document.getElementById("history-reload").addEventListener("click", _reload); + }, + currentURL: function () { + return _currentURL(); + }, + rootURL: function () { + return _rootURL(); + } +}; diff --git a/lib/ripple/ui/plugins/options.js b/lib/ripple/ui/plugins/options.js new file mode 100644 index 00000000..f263b73e --- /dev/null +++ b/lib/ripple/ui/plugins/options.js @@ -0,0 +1,72 @@ +/* + * 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 wrench = document.getElementById('options-button'), + about = require('ripple/ui/plugins/about-dialog'), + settings = require('ripple/ui/plugins/settings-dialog'), + hide, + show; + +show = function () { + $("#options-window").show(); + $("#options-menu").show(); + wrench.onclick = hide; +}; + +hide = function () { + $("#options-window").hide(); + $("#options-menu").effect("fade", {}, 300); + wrench.onclick = show; +}; + +module.exports = { + initialize: function () { + $("#options-menu").menu().hide(); + $("#options-menu").bind("click", function (event) { + var target = $("#" + event.target.parentElement.id), + action; + + if (target.hasClass("not-ready")) { + return; + } + + switch (target.attr("id")) { + case "options-menu-build": + case "options-menu-launch": + case "options-menu-sign": + action = target.attr("id").split("-")[2]; + if (!settings.can(action)) { + settings.show(action); + } + else { + settings.perform(action); + } + break; + case "options-menu-about": + about.show(); + break; + case "options-menu-settings": + settings.show(); + break; + default: + break; + } + hide(); + }); + + $("#options-window").click(hide); + hide(); + } +}; diff --git a/lib/ripple/ui/plugins/platform.js b/lib/ripple/ui/plugins/platform.js index f689540f..a2525165 100644 --- a/lib/ripple/ui/plugins/platform.js +++ b/lib/ripple/ui/plugins/platform.js @@ -57,6 +57,19 @@ function _updatePlatformDeviceSelect(platformID, currentDeviceKey) { } } +function changePlatformOrDevice() { + var platformId = jQuery("#platform-select").val(), + version = jQuery("#version-select").val(), + device = jQuery("#device-select").val(); + + platform.changeEnvironment({ + "name": platformId, + "version": version + }, device, function () { + location.assign(location.href); + }); +} + module.exports = { panel: { domId: "platforms-container", @@ -96,18 +109,6 @@ module.exports = { }); }); - function changePlatformOrDevice() { - var platformId = jQuery("#platform-select").val(), - version = jQuery("#version-select").val(), - device = jQuery("#device-select").val(); - - platform.changeEnvironment({ - "name": platformId, - "version": version - }, device, function () { - location.assign(location.href); - }); - } jQuery("#change-platform").bind("click", changePlatformOrDevice); jQuery("#device-select").bind("change", changePlatformOrDevice); @@ -121,15 +122,15 @@ module.exports = { if (currentPlatform && version.id === currentPlatform) { platformNode.selected = true; - } - if (currentVersion && currentVersion === versionNumber) { - versionNode = utils.createElement("option", { - "innerText": versionNumber, - "value": versionNumber - }); - versionNode.selected = true; - versionSelect.appendChild(versionNode); + if (currentVersion && currentVersion === versionNumber) { + versionNode = utils.createElement("option", { + "innerText": versionNumber, + "value": versionNumber + }); + versionNode.selected = true; + versionSelect.appendChild(versionNode); + } } platformSelect.appendChild(platformNode); diff --git a/lib/ripple/ui/plugins/platformEvents.js b/lib/ripple/ui/plugins/platformEvents.js index 4c03ad21..a68c2241 100644 --- a/lib/ripple/ui/plugins/platformEvents.js +++ b/lib/ripple/ui/plugins/platformEvents.js @@ -21,99 +21,57 @@ var _console = require('ripple/console'), module.exports = { panel: { - domId: "events-container", + domId: "platform-events-container", collapsed: true, pane: "right" }, initialize: function () { - var eventContainer = document.getElementById("event-container"), - // TODO: modify to platform.getPlatformEvents() - spec = platform.current(), - eventSelect, eventArgs, events, fireEventButton; + var eventSelect = document.getElementById("platform-events-select"), + spec = platform.current(); if (!spec.events) { return; } - utils.forEach(spec.events.contexts, function (eventContext, name) { - - eventSelect = utils.createElement("select", { - "id": "events-select-" + name, - "class": "ui-state-default ui-corner-all" - }); - - eventArgs = utils.createElement("select", { - id: "events-args-" + name, - "class": "ui-state-default ui-corner-all" - }); - - events = eventContext.events; - - utils.forEach(events, function (event) { - eventSelect.appendChild(utils.createElement("option", { - "innerText": event.description, - "value": event.name - })); - }); - - fireEventButton = utils.createElement("button", { - "id": "event-button-" + name, - "class": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" - }); - - fireEventButton.appendChild(utils.createElement("span", { - "class": "ui-button-text", - "innerText": "Fire Event" + utils.forEach(spec.events, function (method, name) { + eventSelect.appendChild(utils.createElement("option", { + "innerText": name, + "value": name })); + }); - eventContainer.appendChild(utils.createElement("p", { - "innerText": "Context = " + eventContext.context - })); - eventContainer.appendChild(eventSelect); - eventContainer.appendChild(eventArgs); - eventContainer.appendChild(utils.createElement("br")); - eventContainer.appendChild(fireEventButton); - - jQuery(eventArgs).hide(); - - jQuery(fireEventButton).click(function () { - var select = jQuery("#" + eventSelect.id)[0], - args = []; - - if (events[select.value].args) { - args.push(eventArgs.value); - } - _console.log("fired event => " + eventContext.context + "." + select.children[select.selectedIndex].innerText); - try { - event.trigger(select.value, args); - } - catch (e) { - exception.throwMaskedException(e); - } - }); - - jQuery(eventSelect).change(function () { - var args = jQuery(eventArgs); + jQuery("#platform-events-fire").click(function () { + var eventName = document.getElementById("platform-events-select").value, + args = spec.events[eventName].args ? document.getElementById("platform-events-args").value : null, + callback = spec.events[eventName].callback; - args.empty(); + _console.log("fired event => " + eventName); - if (events[this.value].args) { + try { + callback(args); + } catch (e) { + exception.throwMaskedException(e); + } + }); - utils.forEach(events[this.value].args, function (arg, index) { - eventArgs.appendChild(utils.createElement("option", { - innerText: arg, - value: index - })); - }); + jQuery(eventSelect).change(function () { + var argsSelect = jQuery("#platform-events-args"), + args = spec.events[this.value].args; - args.show(); - } - else { - args.hide(); - } + argsSelect.empty(); - }); + if (args) { + utils.forEach(spec.events[this.value].args, function (arg, index) { + argsSelect.append(utils.createElement("option", { + innerText: arg, + value: index + })); + }); + argsSelect.show(); + } else { + argsSelect.hide(); + } }); } }; diff --git a/lib/ripple/ui/plugins/platformEvents/panel.html b/lib/ripple/ui/plugins/platformEvents/panel.html index 559450a4..65887e6a 100644 --- a/lib/ripple/ui/plugins/platformEvents/panel.html +++ b/lib/ripple/ui/plugins/platformEvents/panel.html @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. --> -
+
Events
@@ -21,7 +21,13 @@
- diff --git a/lib/ripple/ui/plugins/push/panel.html b/lib/ripple/ui/plugins/push/panel.html index 03b43538..851c2815 100644 --- a/lib/ripple/ui/plugins/push/panel.html +++ b/lib/ripple/ui/plugins/push/panel.html @@ -33,7 +33,7 @@ diff --git a/lib/ripple/ui/plugins/security.js b/lib/ripple/ui/plugins/security.js deleted file mode 100644 index e9bf0ef6..00000000 --- a/lib/ripple/ui/plugins/security.js +++ /dev/null @@ -1,44 +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 constants = require('ripple/constants'), - db = require('ripple/db'); - -function _saveAndReload(key, value) { - jWorkflow.order(function (prev, baton) { - baton.take(); - db.save(key, value, null, baton.pass); - }).start(function () { - location.assign(location.href); - }); -} - -module.exports = { - panel: { - domId: "security-container", - collapsed: true, - pane: "right" - }, - initialize: function () { - var securityLevel = db.retrieve(constants.COMMON.SECURITY_LEVEL) || "trusted", - select = jQuery("#security-level-select"); - - select.val(securityLevel); - - select.change(function () { - _saveAndReload(constants.COMMON.SECURITY_LEVEL, select.val()); - }); - } -}; diff --git a/lib/ripple/ui/plugins/security/panel.html b/lib/ripple/ui/plugins/security/panel.html deleted file mode 100644 index 86baf5fc..00000000 --- a/lib/ripple/ui/plugins/security/panel.html +++ /dev/null @@ -1,35 +0,0 @@ - -
-
-
Security
-
- -
-
- - -
diff --git a/lib/ripple/ui/plugins/settings-dialog.js b/lib/ripple/ui/plugins/settings-dialog.js new file mode 100644 index 00000000..105e54ea --- /dev/null +++ b/lib/ripple/ui/plugins/settings-dialog.js @@ -0,0 +1,413 @@ +/* + * 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 db = require('ripple/db'), + utils = require('ripple/utils'), + platform = require('ripple/platform'), + notifications = require('ripple/notifications'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + required = { + build: { + "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName"], + "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName"] + }, + sign: { + "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "csk_password", "p12_password", "bundle_number"], + "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "signingPassword"] + }, + launch: { + "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "device", "devicePassword"], + "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "simulator"] + } + }, + _settings = { + get: function () { + var settings = db.retrieveObject("build-settings", platform.getPersistencePrefix()) || {}; + //Always set debug to true + settings.debug = true; + return settings; + }, + save: function (settings) { + db.saveObject("build-settings", settings, platform.getPersistencePrefix()); + } + }, + //TODO: Restore this line once framework issue is resolved + //port = window.stagewebview ? stagewebview.serverPort : "9900", + port = "9900", + host = "http://127.0.0.1:" + port + "/ripple", + progressContainer = jQuery("#options-progress"), + progressInterval, + _passwordFields = [ + "signingPassword", + "devicePassword", + "csk_password", + "p12_password" + ], + _passwords = {}, + _self; + +function missing(settings, action) { + return required[action][platform.current().id].filter(function (field) { + return !settings.hasOwnProperty(field); + }); +} + +function _isPasswordField(id) { + var match = typeof id === "string" && new RegExp("^" + id + "$", "i"); + return match && utils.some(_passwordFields, function (name) { + return match.test(name); + }); +} + +function table(action) { + var _table = $("
- +
"), + _row = { + row: function (item, desc, opts) { + var id = "settings-field-" + item.toLowerCase(), + input = "", + save = function () { + var s = _settings.get(), + v = $("#" + id).val(), + val = opts.type === "number" ? parseInt(v, 10) : v; + + if (val) { + (_isPasswordField(item) ? _passwords : s)[item] = val; + } + else { + delete s[item]; + } + _settings.save(s); + }, + row; + + opts = opts || { type: "text" }; + + switch (opts.type) { + case "select": + input = ""; + break; + } + + row = $("" + + "" + + "" + + ""); + + row.appendTo(_table); + + //bind save handlers to the row + utils.bindAutoSaveEvent(row.find("#" + id).change(save), save); + + return _row; + }, + appendTo: function (id) { + var fs = $("
" + action + "
"); + + $(_table).appendTo(fs); + fs.appendTo($(id)); + } + }; + + return _row; +} + +function create() { + var build = table('build'), + sign = table('sign'), + launch = table('launch'); + + build + .row("sdk", "SDK Path") + .row("projectPath", "Project Root") + .row("projectName", "Archive Name") + .row("outputPath", "Output Folder") + .appendTo("#settings-tabs-build"); + + if (platform.current().id === "webworks.handset") { + sign.row("signingPassword", "Password", { + type: "password" + }); + + launch.row("simulator", "Simulator", { + type: "select" + }); + + launch.row("simulatorstatus", "Simulator", { + type: "span", + text: "Searching for simulators ..." + }); + } + else if (platform.current().id === "webworks.tablet") { + sign.row("csk_password", "CSK Password", { + type: "password" + }); + sign.row("p12_password", "P12 Password", { + type: "password" + }); + sign.row("bundle_number", "Bundle Number", { + type: "number" + }); + + launch.row("device", "Playbook IP"); + launch.row("devicePassword", "Playbook Password", { + type: "password" + }); + } + + sign.appendTo("#settings-tabs-build"); + launch.appendTo("#settings-tabs-build"); + + $("#settings-field-simulator").parent().parent().hide(); +} + +function populate(settings) { + var fill = function (action, prop) { + $("#settings-field-" + prop.toLowerCase()).val( + _isPasswordField(prop) ? _passwords[prop] : settings[prop] + ); + }; + + fill("build", "sdk"); + fill("build", "projectPath"); + fill("build", "outputPath"); + fill("build", "projectName"); + + fill("sign", "signingPassword"); + fill("sign", "csk_password"); + fill("sign", "p12_password"); + fill("sign", "bundle_number"); + + fill("launch", "simulator"); + fill("launch", "device"); + fill("launch", "devicePassword"); +} + +function url(action) { + var target = ""; + + switch (platform.current().id) { + case "webworks.tablet": + target = "tablet"; + break; + case "webworks.handset": + target = "smartphone"; + break; + } + + return host + "/" + action + "/" + target; +} + +function enable(action) { + $("#options-menu-" + action).removeClass("not-ready"); + if (action === "launch") { + $("#settings-field-simulatorstatus").parent().parent().hide(); + $("#settings-field-simulator").parent().parent().show(); + } +} + +function disable(action) { + $("#options-menu-" + action).addClass("not-ready"); + if (action === "launch") { + $("#settings-field-simulatorstatus").parent().parent().show(); + $("#settings-field-simulator").parent().parent().hide(); + } +} + +function getSimulators() { + if (!_settings.get().sdk) { + $("#settings-field-simulatorstatus").text(""); + disable("launch"); + return; + } + + $.ajax({ + url: host + "/simulators", + type: "GET", + async: true, + data: _settings.get(), // assume no passwords here + success: function (resp) { + var sims = resp.data.simulators; + + $("#settings-field-simulator").empty(); + if (sims.length > 0) { + $(resp.data.simulators.map(function (sim) { + return ""; + }).join()).appendTo("#settings-field-simulator"); + + enable("launch"); + } + else { + disable("launch"); + $("#settings-field-simulatorstatus").text("No simulators found :("); + } + }, + error: function () { + disable("launch"); + $("#settings-field-simulatorstatus").text("Error attempting to get simulators :("); + } + }); +} + +function _startProgress() { + if (progressInterval) { + window.clearInterval(progressInterval); + } + progressInterval = window.setInterval(function () { + if (progressContainer.html().length === 5) { + progressContainer.html("."); + } + else { + progressContainer.html(progressContainer.html() + "."); + } + }, 250); +} + +function _endProgress() { + window.clearInterval(progressInterval); + progressInterval = null; + progressContainer.html(""); +} + + +_self = { + initialize: function () { + $("#settings-dialog").dialog({ + autoOpen: false, + modal: true, + width: 700, + title: "Settings", + position: 'center' + }).hide(); + + $("#settings-tabs").tabs(); + $("#settings-action").button(); + + create(); + + if (platform.current().id === "webworks.handset") { + enable("build"); + enable("sign"); + enable("settings"); + + getSimulators(); + $("#settings-field-sdk").change(getSimulators); + } + else if (platform.current().id === "webworks.tablet") { + enable("build"); + enable("sign"); + enable("launch"); + enable("settings"); + } + }, + + can: function (action) { + var settings = {}; + + utils.mixin(_settings.get(), settings); + utils.mixin(_passwords, settings); + + return missing(settings, action).length === 0; + }, + + show: function (action) { + var settings = {}; + + utils.mixin(_settings.get(), settings); + utils.mixin(_passwords, settings); + + populate(settings); + + $("#settings-dialog").dialog("open"); + $("#settings-action").button("option", "label", action || "")[action ? "show" : "hide"](); + + if (action) { + missing(settings, action).forEach(function (field) { + $("#settings-field-" + field.toLowerCase()).effect("highlight", {color: "red"}, 1500); + }); + + $("#settings-action").unbind("click").click(function () { + if (_self.can(action)) { + _self.perform(action); + $("#settings-dialog").dialog("close"); + } + else { + _self.show(action); + } + }); + } + }, + + perform: function (action) { + var settings = _settings.get(), + data = {}, + poll = function (resp) { + var notifications = require("ripple/notifications"); + + if (resp && resp.code !== 0) { + notifications.openNotification("error", "Build request failed with message: " + resp.msg); + _endProgress(); + } + else { + if (resp && resp.data.status === "building") { + setTimeout(function () { + $.ajax({ + url: host + "/build_status/" + resp.data.id, + type: "GET", + async: true, + success: poll, + error: function (error, errorText) { + notifications.openNotification("error", "Build request failed with message: " + errorText); + _endProgress(); + } + }); + }, 500); + } + else { + if (action.match(/sign/)) { + settings["bundle_number"] = $("#settings-field-bundle_number").val(parseInt($("#settings-field-bundle_number").val(), 10) + 1).val(); + _settings.save(settings); + } + notifications.openNotification("normal", "Build succeded!"); + _endProgress(); + } + } + }; + + utils.mixin(settings, data); + utils.mixin(_passwords, data); + + $.ajax({ + url: url(action), + type: "POST", + data: data, + async: true, + success: function (msg) { + _startProgress(); + poll(msg); + }, + error: function (xhr, errorText) { + notifications.openNotification("error", "Build request failed with message: " + errorText); + } + }); + } +}; + +module.exports = _self; diff --git a/lib/ripple/ui/plugins/settings-dialog/dialog.html b/lib/ripple/ui/plugins/settings-dialog/dialog.html new file mode 100644 index 00000000..3944a92e --- /dev/null +++ b/lib/ripple/ui/plugins/settings-dialog/dialog.html @@ -0,0 +1,10 @@ +
+
+ +
+
+
+ +
diff --git a/lib/ripple/ui/plugins/storage.js b/lib/ripple/ui/plugins/storage.js deleted file mode 100644 index c3d8f6e9..00000000 --- a/lib/ripple/ui/plugins/storage.js +++ /dev/null @@ -1,74 +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 constants = require('ripple/constants'), - event = require('ripple/event'), - platform = require('ripple/platform'), - utils = require('ripple/utils'), - app = require('ripple/app'), - db = require('ripple/db'); - -function _updatePreferencesView() { - var node = document.getElementById(constants.COMMON.STORAGE_TABLE_BODY_CLASS), - countTitle = document.getElementById(constants.COMMON.STORAGE_COUNT_CONTAINER_ID); - - // TODO: convert to appendChild - if (node) { - db.retrieveAll(platform.getPersistencePrefix(), function (results) { - var str = "", - counter = 0; - - utils.forEach(results, function (value, key) { - // TODO: based of current platform - if (app.isPreferenceReadOnly(key)) { - str += ''; - } else { - str += ''; - } - str += '"; - counter ++; - }); - - node.innerHTML = str; - countTitle.innerHTML = counter.toString(); - - if (counter === 0) { - jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).addClass(constants.CSS_PREFIX.IRRELEVANT); - } - else { - jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).removeClass(constants.CSS_PREFIX.IRRELEVANT); - } - }); - } -} - -module.exports = { - panel: { - domId: "preferences", - collapsed: true, - pane: "left" - }, - initialize: function () { - jQuery("#preferences-clear-button").bind("click", function () { - db.removeAll(platform.getPersistencePrefix()); - }); - - event.on("StorageUpdatedEvent", function () { - _updatePreferencesView(); - }); - - _updatePreferencesView(); - } -}; diff --git a/lib/ripple/ui/plugins/storage/panel.html b/lib/ripple/ui/plugins/storage/panel.html deleted file mode 100644 index d5929360..00000000 --- a/lib/ripple/ui/plugins/storage/panel.html +++ /dev/null @@ -1,38 +0,0 @@ - -
-
-
Storage
-
- -
-
- -
" + input + "
' + key + '' + value + "
- - -
- -
- Total:  - (read-only preference colour)
- - -
-
diff --git a/lib/ripple/ui/plugins/telephony.js b/lib/ripple/ui/plugins/telephony.js deleted file mode 100644 index c55b35a9..00000000 --- a/lib/ripple/ui/plugins/telephony.js +++ /dev/null @@ -1,124 +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 constants = require('ripple/constants'), - db = require('ripple/db'), - utils = require('ripple/utils'), - _console = require('ripple/console'), - _optionTemplate = "", - _textTemplate = ""; - -function _addRow(calltype, number, name) { - var row = "", - option = function (key) { - return _optionTemplate.replace("[key]", key) - .replace("[selected]", calltype === key ? "selected" : "") - .replace("[value]", key.charAt(0).toUpperCase() + key.slice(1)); - }, - text = function (key, value) { - return _textTemplate.replace("[key]", key) - .replace("[value]", value); - }; - - calltype = calltype || "missed"; - number = number || ""; - name = name || ""; - - row += text("number", number); - row += text("name", name); - row += ""; - row += ""; - row += ''; - row += ""; - row += ""; - - if (jQuery("#calls-list-body tr").length > 0) { - jQuery("#calls-list-body tr:last").after(row); - } - else { - jQuery("#calls-list-body").append(row); - } - - jQuery("#calls-list-body tr:last button").bind("click", function () { - - var calltype = jQuery(this).next().val(), - number = jQuery(this).parent().parent().prev().find(".call-number").val(); - - _console.log("called Widget.Telephony.onCallEvent function [" + calltype + "," + number + "]"); - - if (Widget.Telephony.onCallEvent) { - Widget.Telephony.onCallEvent(calltype, number); - } - }); -} - -function _initializeTelephonyView() { - - var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY); - - utils.forEach(calls, function (call) { - _addRow(call.callRecordType, call.callRecordAddress, call.callRecordName); - }); -} - -function _createCall(index, row) { - var call = new Widget.Telephony.CallRecord(); - - call.callRecordId = index; - call.callRecordType = row.find(".calltype-select").val(); - call.callRecordAddress = row.find(".call-number").val(); - call.callRecordName = row.find(".call-name").val(); - call.startTime = new Date(); - call.durationSeconds = 60; - - return call; -} - -module.exports = { - panel: { - domId: "telephony", - collapsed: true, - pane: "right" - }, - initialize: function () { - jQuery("#calls-new-button").bind("click", function () { - _addRow(); - }); - - jQuery("#calls-save-button").bind("click", function () { - var calls = []; - - jQuery("#calls-list-body tr.call-details").each(function (index) { - var row = jQuery(this), - call = _createCall(index, row); - - if (call.callRecordAddress && call.callRecordName) { - calls.push(call); - } - else { - row.next().remove(); - row.remove(); - } - }); - - db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls); - }); - } -}; diff --git a/lib/ripple/ui/plugins/telephony/panel.html b/lib/ripple/ui/plugins/telephony/panel.html deleted file mode 100644 index 8c8dfcc9..00000000 --- a/lib/ripple/ui/plugins/telephony/panel.html +++ /dev/null @@ -1,44 +0,0 @@ - -
-
-
Telephony
-
- -
-
- - -
diff --git a/lib/ripple/ui/plugins/widgetConfig.js b/lib/ripple/ui/plugins/widgetConfig.js index 53400139..53e163b7 100644 --- a/lib/ripple/ui/plugins/widgetConfig.js +++ b/lib/ripple/ui/plugins/widgetConfig.js @@ -158,6 +158,7 @@ function _initializeConfigResultsView(results) { var rootNode, accordionContainer = document.getElementById("widget-config"); + accordionContainer.innerHTML = ""; if (!results) { accordionContainer.appendChild(utils.createElement("div", { "class": "config-accordion-node-title " + constants.CONFIG.SUCCESS_CSS["false"], @@ -181,7 +182,7 @@ function _initializeConfigResultsView(results) { stop = false; } }); - jQuery("#widget-config").accordion({ + jQuery("#widget-config").accordion("destroy").accordion({ header: "> div > h3", autoHeight: false }); @@ -191,6 +192,10 @@ function _initializeConfigResultsView(results) { } } +event.on("FrameHistoryChange", function (url) { + module.exports.initialize(); +}); + module.exports = { panel: { domId: "config-container", diff --git a/lib/ripple/utils.js b/lib/ripple/utils.js index f2fcbf65..b26c2d02 100644 --- a/lib/ripple/utils.js +++ b/lib/ripple/utils.js @@ -145,6 +145,46 @@ self = module.exports = { return window.location; }, + appLocation: function () { + if (require('ripple/ui').registered("omnibar")) { + var path = require('ripple/ui/plugins/omnibar').rootURL().replace(/\/$/, ""), + parts; + + if ((parts = path.match(/^((http[s]?|ftp):\/\/)(.+\/)?([^\/].+)$/i)) !== null && parts.length === 5) { + if (parts[4] === "about:blank") { + path = ""; + } + else if (parts[3]) { + path = parts[1] + parts[3]; + if (parts[4].indexOf(".") === -1) { + path += parts[4] + "/"; + } + } + else { + path = parts[1] + parts[4] + "/"; + } + } + else { + path = ""; + } + return path; + } + return self.rippleLocation(); + }, + + rippleLocation: function () { + var loc = self.location(), + parts = loc.pathname.replace(/\/$/, "").split("/"), + base = ""; + + if (parts[parts.length - 1].indexOf(".") !== -1) { + parts = parts.splice(0, parts.length - 1); + } + base = parts.join("/"); + + return loc.protocol + "//" + loc.hostname + base + "/"; + }, + arrayContains: function (array, obj) { var i = array.length; while (i--) { @@ -370,7 +410,7 @@ self = module.exports = { copy: function (obj) { var i, - newObj = (obj instanceof Array) ? [] : {}; + newObj = jQuery.isArray(obj) ? [] : {}; if (typeof obj === 'number' || typeof obj === 'string' || @@ -381,8 +421,11 @@ self = module.exports = { } if (obj instanceof Date) { - newObj = new Date(obj); - return newObj; + return new Date(obj); + } + + if (obj instanceof RegExp) { + return new RegExp(obj); } for (i in obj) { diff --git a/lib/ripple/widgetConfig.js b/lib/ripple/widgetConfig.js index 5334a012..0d58995a 100644 --- a/lib/ripple/widgetConfig.js +++ b/lib/ripple/widgetConfig.js @@ -26,11 +26,11 @@ var exception = require('ripple/exception'), }, _configValidationResults = null; -function _failNodeValidation(node, message, value) { +function _failNodeValidation(schemaNode, message, value, node) { var validationResult = utils.copy(_validationResult); - if (!node.validationResult) { - node.validationResult = []; + if (!schemaNode.validationResult) { + schemaNode.validationResult = []; } validationResult.valid = false; if (value) { @@ -39,9 +39,10 @@ function _failNodeValidation(node, message, value) { else { delete(validationResult.value); } - validationResult.message = node.nodeName + message; + validationResult.message = schemaNode.nodeName + message; + validationResult.node = node; - node.validationResult.push(validationResult); + schemaNode.validationResult.push(validationResult); } function _createEmptyNodeValidation(node) { @@ -162,13 +163,14 @@ function _validateValue(valueToTest, schemaNode) { return failMessage; } -function _passNodeValidation(node, value) { +function _passNodeValidation(schemaNode, value, node) { var validationResult = utils.copy(_validationResult); - if (!node.validationResult) { - node.validationResult = []; + if (!schemaNode.validationResult) { + schemaNode.validationResult = []; } validationResult.valid = true; + validationResult.node = node; if (value) { validationResult.value = value; } @@ -177,7 +179,7 @@ function _passNodeValidation(node, value) { } delete(validationResult.message); - node.validationResult.push(validationResult); + schemaNode.validationResult.push(validationResult); } function _validateNodeValue(schemaNode, node) { @@ -189,11 +191,11 @@ function _validateNodeValue(schemaNode, node) { failMessage = _validateValue(valueToTest, schemaNode); if (failMessage !== "") { - _failNodeValidation(schemaNode, failMessage, valueToTest); + _failNodeValidation(schemaNode, failMessage, valueToTest, node); return; } } - _passNodeValidation(schemaNode, valueToTest); + _passNodeValidation(schemaNode, valueToTest, node); } function _failNodeAttributeValidation(node, attribute, message, value) { @@ -317,7 +319,7 @@ function _validateNode(schemaNode, parentNode) { if (children.length === 0) { if (schemaNode.required) { - _failNodeValidation(schemaNode, " node expected, but not found", null); + _failNodeValidation(schemaNode, " node expected, but not found", null, null); } else { _createEmptyNodeValidation(schemaNode); @@ -326,10 +328,11 @@ function _validateNode(schemaNode, parentNode) { utils.forEach(children, function (child) { if (schemaNode.occurrence !== 0 && schemaNode.occurrence < children.length) { - _failNodeValidation(schemaNode, " node: more then " + schemaNode.occurrence + " node(s) found", null); + _failNodeValidation(schemaNode, " node: more then " + schemaNode.occurrence + " node(s) found", null, child); } else { - _validateNodeValue(schemaNode, child.childNodes[0]); + _validateNodeValue(schemaNode, child.childNodes[0] || child); + _validateNodeAttributes(schemaNode, child, children); } @@ -395,21 +398,26 @@ module.exports = { return; } - xmlHttp.open("GET", fileName, false); - xmlHttp.send(); - if (xmlHttp.responseXML) { - try { + try { + xmlHttp.open("GET", utils.appLocation() + fileName, false); + xmlHttp.send(); + if (xmlHttp.responseXML) { results = _validate(xmlHttp.responseXML); _process(results); _configValidationResults = results; } - catch (e) { - exception.handle(e); + else { + _process(); + _configValidationResults = null; + require('ripple/ui/plugins/widgetConfig').initialize(); } } + catch (e) { + exception.handle(e); + } }, getValidationResults: function () { - return utils.copy(_configValidationResults); + return _configValidationResults; } }; diff --git a/lib/ripple/xhr.js b/lib/ripple/xhr.js index 717ee2ac..befcd200 100644 --- a/lib/ripple/xhr.js +++ b/lib/ripple/xhr.js @@ -15,6 +15,7 @@ */ var constants = require('ripple/constants'), utils = require('ripple/utils'), + ui = require('ripple/ui'), helpers = require('ripple/xhr/helpers'), XHR = window.XMLHttpRequest; @@ -22,7 +23,7 @@ module.exports = { initialize: function (previous, baton) { window.XMLHttpRequest = require('ripple/xhr/base'); - if (helpers.proxyEnabled()) { + if (helpers.proxyEnabled() && !ui.registered("omnibar")) { var isFileScheme = utils.location().protocol.match(/^file:/); window.XMLHttpRequest = require(isFileScheme ? 'ripple/xhr/jsonp' : 'ripple/xhr/cors'); } diff --git a/lib/ripple/xhr/base.js b/lib/ripple/xhr/base.js index 15cbf23d..97d94c24 100644 --- a/lib/ripple/xhr/base.js +++ b/lib/ripple/xhr/base.js @@ -51,7 +51,8 @@ function _writeable(obj) { } function _XMLHttpRequest() { - return _writeable(new XHR()); + var Xhr = require('ripple/emulatorBridge').xhr() || XHR; + return _writeable(new Xhr()); } module.exports = _XMLHttpRequest; diff --git a/lib/ripple/xhr/cors.js b/lib/ripple/xhr/cors.js index e07bb87f..c25c3ad7 100644 --- a/lib/ripple/xhr/cors.js +++ b/lib/ripple/xhr/cors.js @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var config = require('ripple/config'), - fileSystem = require('ripple/fileSystem'), - helpers = require('ripple/xhr/helpers'), +var helpers = require('ripple/xhr/helpers'), + constants = require('ripple/constants'), _console = require('ripple/console'), XHR = require('ripple/xhr/base'); @@ -34,11 +33,8 @@ function _XMLHttpRequest() { }; xhr.open = function (method, url, async, user, password) { - var scrubbedUrl = fileSystem.getURI(url); - if (!helpers.isLocalRequest(url)) { - url = config.getAPIURL() + - "/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(scrubbedUrl); + url = constants.API_URL + "/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url); } origMethods.open.apply(xhr, Array.prototype.slice.call(arguments)); diff --git a/lib/ripple/xhr/jsonp.js b/lib/ripple/xhr/jsonp.js index b1cdac81..d6f658d5 100644 --- a/lib/ripple/xhr/jsonp.js +++ b/lib/ripple/xhr/jsonp.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var config = require('ripple/config'), +var constants = require('ripple/constants'), exception = require('ripple/exception'), utils = require('ripple/utils'), helpers = require('ripple/xhr/helpers'), @@ -126,8 +126,7 @@ function _XMLHttpRequest() { }; _jxhr.onerror = xhr.onerror; - _jxhr.open(method, config.getAPIURL() + - "/jsonp_xhr_proxy?callback=?&tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url)); + _jxhr.open(method, constants.API_URL + "/jsonp_xhr_proxy?callback=?&tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url)); } }; diff --git a/package.json b/package.json index 4bbe8d7d..5846020e 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "ripple", - "version": "0.6.3", + "version": "0.9.0", "description": "A browser based html5 mobile application development and testing tool", - "homepage": "http://github.com/blackberry/ripple", + "homepage": "http://github.com/blackberry/Rippe-UI", "author": { "name": "Research In Motion", - "url": "http://github.com/blackberry/ripple" + "url": "http://github.com/blackberry/Ripple-UI" }, "licenses": [{ "type": "Apache 2.0", @@ -13,9 +13,19 @@ }], "bin": { "ripple": "./bin/ripple" }, "main": "lib/index", + "dependencies": { + "connect": "1.7.x", + "argsparser": "0.0.x", + "jsdom": "0.2.4", + "jasmine-node": "1.0.7", + "jWorkflow": "*" + }, + "bundledDependencies": [ + "connect", + "argsparser" + ], "files": [ - "www", - "thirdparty", + "pkg/web", "node_modules", "README.md", "LICENSE", diff --git a/test/assets/config/config.xml b/test/assets/config/config.xml index aeb96406..d1473204 100644 --- a/test/assets/config/config.xml +++ b/test/assets/config/config.xml @@ -1,23 +1,29 @@ - - - - - - - - - - ConfigTest - This is my first Widget. - Example license Copyright (c) 2008. - myname + + + PhoneGap: Getting Started + + + A template for getting started with PhoneGap development and build.phonegap.com + + + + Ripple UI + + + + + + + + + + + + + diff --git a/test/assets/config/config_no_widet_node.xml b/test/assets/config/config_no_widget_node.xml similarity index 100% rename from test/assets/config/config_no_widet_node.xml rename to test/assets/config/config_no_widget_node.xml diff --git a/test/assets/config/config_with_missing_attributes.xml b/test/assets/config/config_with_missing_attributes.xml index ff9489ce..fedf3bf0 100644 --- a/test/assets/config/config_with_missing_attributes.xml +++ b/test/assets/config/config_with_missing_attributes.xml @@ -1,18 +1,29 @@ - - - - - - - foo - - - ConfigTest - This is my first Widget. - Example license Copyright (c) 2008. - myname + + + PhoneGap: Getting Started + + + A template for getting started with PhoneGap development and build.phonegap.com + + + + Ripple UI + + + + + + + + + + + + + diff --git a/test/assets/media/short_video.ogv b/test/assets/media/short_video.ogv deleted file mode 100644 index 69954a24..00000000 Binary files a/test/assets/media/short_video.ogv and /dev/null differ diff --git a/test/unit/accelerometer.js b/test/unit/accelerometer.js index afebf9da..f00fe017 100644 --- a/test/unit/accelerometer.js +++ b/test/unit/accelerometer.js @@ -14,13 +14,10 @@ * limitations under the License. */ describe("accelerometer", function () { - var accelerometer = require('ripple/accelerometer'), Rotation = require('ripple/platform/w3c/1.0/Rotation'), Acceleration = require('ripple/platform/w3c/1.0/Acceleration'), event = require('ripple/event'), - sinon = require('sinon'), - s, db = require('ripple/db'), MOCK_POSITIONINFO = { x: 4, @@ -31,14 +28,6 @@ describe("accelerometer", function () { gamma: 90 }; - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - it("test getInfo should return a valid set of values", function () { var info = accelerometer.getInfo(); @@ -54,7 +43,8 @@ describe("accelerometer", function () { }); it("setInfo should update successfully", function () { - s.stub(db, "saveObject"); + spyOn(db, "saveObject"); + accelerometer.setInfo({ x: MOCK_POSITIONINFO.x, y: MOCK_POSITIONINFO.y, @@ -69,7 +59,7 @@ describe("accelerometer", function () { }); it("should fire DeviceMotionEvent when setInfo is called", function () { - s.stub(db, "saveObject"); + spyOn(db, "saveObject"); spyOn(event, "trigger"); accelerometer.setInfo({ @@ -91,7 +81,7 @@ describe("accelerometer", function () { }); it("should fire DeviceMotionEvent when setInfo is called", function () { - s.stub(db, "saveObject"); + spyOn(db, "saveObject"); spyOn(event, "trigger"); accelerometer.setInfo({ @@ -113,7 +103,7 @@ describe("accelerometer", function () { }); it("should fire DeviceOrientationEvent when setInfo is called", function () { - s.stub(db, "saveObject"); + spyOn(db, "saveObject"); spyOn(event, "trigger"); accelerometer.setInfo({ @@ -135,7 +125,7 @@ describe("accelerometer", function () { }); it("test should return a valid cached object when specified", function () { - s.stub(db, "saveObject"); + spyOn(db, "saveObject"); accelerometer.setInfo(8, 8, 8); var info = accelerometer.getInfo(true); @@ -146,8 +136,8 @@ describe("accelerometer", function () { }); it("test shake should update cached x value", function () { - s.stub(db, "saveObject"); - s.stub(event, "trigger"); + spyOn(db, "saveObject"); + spyOn(event, "trigger"); spyOn(global, "setInterval").andCallFake(function (callback) { callback(); }); diff --git a/test/unit/db.js b/test/unit/db.js index a4bb3af5..127c9592 100644 --- a/test/unit/db.js +++ b/test/unit/db.js @@ -39,7 +39,6 @@ describe("db", function () { return self; }; jWorkflow.order(db.initialize, db).start(); - waits(1); }); afterEach(function () { diff --git a/test/unit/devices.js b/test/unit/devices.js index 41c6d9fd..5b572454 100644 --- a/test/unit/devices.js +++ b/test/unit/devices.js @@ -23,7 +23,7 @@ describe("devices", function () { beforeEach(function () { spyOn(db, "retrieveObject"); spyOn(db, "saveObject"); - spyOn(platform, "current").andReturn({id: "wac", version: "1.0"}); + spyOn(platform, "current").andReturn({id: "phonegap", version: "1.0"}); devices.initialize(); }); @@ -62,7 +62,7 @@ describe("devices", function () { back: jasmine.createSpy("window.history.back") } }; - spyOn(emulatorBridge, "getWidgetWindow").andReturn(_window); + spyOn(emulatorBridge, "window").andReturn(_window); }); it("calls history.back when the key is 0", function () { diff --git a/test/unit/emulatorBridge.js b/test/unit/emulatorBridge.js index d4d98516..76d144e2 100644 --- a/test/unit/emulatorBridge.js +++ b/test/unit/emulatorBridge.js @@ -15,12 +15,9 @@ */ // TODO: make more modular (be able to boot one module at a time) describeBrowser("emulator_bridge", function () { - var emulatorBridge = require('ripple/emulatorBridge'), - sinon = require('sinon'), constants = require('ripple/constants'), platform = require('ripple/platform'), - s, old_gElById, _emulatedBody, _emulatedHtml, @@ -33,8 +30,6 @@ describeBrowser("emulator_bridge", function () { }; beforeEach(function () { - s = sinon.sandbox.create(); - // TODO: hackish stub for now old_gElById = document.getElementById; document.getElementById = function (id) { @@ -70,7 +65,6 @@ describeBrowser("emulator_bridge", function () { }); afterEach(function () { - s.verifyAndRestore(); delete window.tinyHippos; _emulatedViewport = null; _emulatedBody = null; diff --git a/test/unit/exception.js b/test/unit/exception.js index 81cc9e96..f3d68e22 100644 --- a/test/unit/exception.js +++ b/test/unit/exception.js @@ -14,146 +14,142 @@ * limitations under the License. */ describe("exception", function () { - var exception = require('ripple/exception'), - _console = require('ripple/console'), - s, sinon = require('sinon'); - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); + _console = require('ripple/console'); + + describe("handle", function () { + it("throws exception if wrong number of arguments", function () { + spyOn(_console, "error"); + expect(function () { + exception.handle("1", "2", "3"); + }).toThrow(); + expect(_console.error).toHaveBeenCalled(); + }); + + it("logs to console", function () { + spyOn(_console, "error"); + try { + throw {name: "TestExceptionType"}; + } catch (e) { + exception.handle(e); + expect(_console.error.callCount).toBe(1); + } + }); - it("handle throws exception if wrong number of arguments", function () { - spyOn(_console, "error"); - expect(function () { - exception.handle("1", "2", "3"); - }).toThrow(); - expect(_console.error).toHaveBeenCalled(); + it("logs to console and rethrows exception", function () { + spyOn(_console, "error"); + try { + throw {name: "TestExceptionType"}; + } catch (e) { + try { + exception.handle(e, true); + } + catch (other_e) { + expect(_console.error.callCount).toBe(1); + return; + } + throw "Exception was expected, none was thrown"; + } + }); }); - it("handle logs to console", function () { - s.mock(_console).expects("error").once(); - try { - throw {name: "TestExceptionType"}; - } catch (e) { - exception.handle(e); - } - }); + describe("throwException", function () { + it("throws existing object exception", function () { + var obj = { + "test": "test property" + }; - it("handle logs to console and rethrows exception", function () { - s.mock(_console).expects("error").once(); - try { - throw {name: "TestExceptionType"}; - } catch (e) { try { - exception.handle(e, true); - } - catch (other_e) { + exception.raise("TestException", "test message", obj); + } catch (e) { + expect(e.test).toEqual(obj.test); + expect(e.name).toEqual("TestException"); + expect(e.message).toEqual("test message"); return; } + throw "Exception was expected, none was thrown"; - } - }); + }); - it("throwException throws existing object exception", function () { - var obj = { - "test": "test property" - }; - - try { - exception.raise("TestException", "test message", obj); - } catch (e) { - expect(e.test).toEqual(obj.test); - expect(e.name).toEqual("TestException"); - expect(e.message).toEqual("test message"); - return; - } - - throw "Exception was expected, none was thrown"; - }); + it("throws exception with both name and type properties the same", function () { + try { + exception.raise("TestException", "test message"); + } catch (e) { + expect(e.name).toEqual("TestException", e.name); + expect(e.type, "TestException"); + expect(e.message).toEqual("test message"); + return; + } - it("throwException throws exception with both name and type properties the same", function () { - try { - exception.raise("TestException", "test message"); - } catch (e) { - expect(e.name).toEqual("TestException", e.name); - expect(e.type, "TestException"); - expect(e.message).toEqual("test message"); - return; - } - - throw "Exception was expected, none was thrown"; - }); + throw "Exception was expected, none was thrown"; + }); - it("throwException throws exception if invalid arguments", function () { - try { - exception.raise(1, {}); - } catch (e) { - return; - } - throw "Exception was expected, none was thrown"; - }); + it("throws exception if invalid arguments", function () { + try { + exception.raise(1, {}); + } catch (e) { + return; + } + throw "Exception was expected, none was thrown"; + }); - it("throwException throws exception if invalid argument", function () { - try { - exception.raise(1); - } catch (e) { - return; - } + it("throws exception if invalid argument", function () { + try { + exception.raise(1); + } catch (e) { + return; + } - throw "Exception was expected, none was thrown"; - }); + throw "Exception was expected, none was thrown"; + }); - it("throwException throws correct exception type with no message", function () { - try { - exception.raise("TestExceptionType"); - } catch (e) { - expect(e.name).toEqual("TestExceptionType"); - return; - } - throw "Exception was expected, none was thrown"; - }); + it("throws correct exception type with no message", function () { + try { + exception.raise("TestExceptionType"); + } catch (e) { + expect(e.name).toEqual("TestExceptionType"); + return; + } + throw "Exception was expected, none was thrown"; + }); - it("throwException throws correct exception type with message", function () { - try { - exception.raise("TestExceptionType", "test exception was thrown"); - } catch (e) { - expect(e.message).toEqual("test exception was thrown"); - return; - } + it("throws correct exception type with message", function () { + try { + exception.raise("TestExceptionType", "test exception was thrown"); + } catch (e) { + expect(e.message).toEqual("test exception was thrown"); + return; + } - throw "Exception was expected, none was thrown"; + throw "Exception was expected, none was thrown"; + }); }); - it("throwMaskedException throws custom exception", function () { - s.mock(_console).expects("error").once(); - - try { - exception.throwMaskedException("TestExceptionType", "test message"); - } catch (e) { - expect(e.name).toEqual(exception.types.tinyHipposMaskedException); - expect(e.message).toEqual("tinyhippos terminated your script due to exception"); - return; - } + describe("throwMaskedException", function () { + it("throws custom exception", function () { + spyOn(_console, "error"); - throw "Exception was expected, none was thrown"; - }); - - it("throwMaskedException throws custom exception with custom message", function () { - s.mock(_console).expects("error").once(); + try { + exception.throwMaskedException("TestExceptionType", "test message"); + throw "Exception was expected, none was thrown"; + } catch (e) { + expect(_console.error.callCount).toBe(1); + expect(e.name).toEqual(exception.types.tinyHipposMaskedException); + expect(e.message).toEqual("tinyhippos terminated your script due to exception"); + } + }); - try { - exception.throwMaskedException("TestExceptionType"); - } catch (e) { - expect(e.name).toEqual(exception.types.tinyHipposMaskedException); - expect(typeof e.message).toEqual("string"); - return; - } + it("throws custom exception with custom message", function () { + spyOn(_console, "error"); - throw "Exception was expected, none was thrown"; + try { + exception.throwMaskedException("TestExceptionType"); + throw "Exception was expected, none was thrown"; + } catch (e) { + expect(_console.error.callCount).toBe(1); + expect(e.name).toEqual(exception.types.tinyHipposMaskedException); + expect(typeof e.message).toEqual("string"); + } + }); }); }); diff --git a/test/unit/fileSystem.js b/test/unit/fileSystem.js deleted file mode 100644 index bee8183f..00000000 --- a/test/unit/fileSystem.js +++ /dev/null @@ -1,81 +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. - */ -describe("file_system", function () { - - // TODO: make this more modular and not use itself - // TODO: add tests for getURI exceptions - // TODO: getFileSystemPaths returns a copied object - - var fileSystem = require('ripple/fileSystem'), - db = require('ripple/db'), - sinon = require('sinon'), - s, oldXHR, - xhrResult = 200; - - beforeEach(function () { - s = sinon.sandbox.create(); - s.stub(db, "saveObject"); - s.stub(db, "retrieveObject"); - - oldXHR = global.XMLHttpRequest = window.XMLHttpRequest; - - global.XMLHttpRequest = window.XMLHttpRequest = function () { - return { - open: function () { - }, - send: function () { - }, - status: xhrResult - }; - }; - - var defaultFileSystemPaths = fileSystem.getFileSystemPaths(); - defaultFileSystemPaths.photos.uri = "http://127.0.0.1"; - fileSystem.updateFileSystemPaths(defaultFileSystemPaths); - }); - - afterEach(function () { - s.verifyAndRestore(); - global.XMLHttpRequest = window.XMLHttpRequest = oldXHR; - }); - - it("getURI replaces photos virtual directory0", function () { - var newURI = fileSystem.getURI("/virtual/photos/path.jpg"); - expect(newURI).toEqual("http://127.0.0.1/path.jpg"); - }); - - it("getURI replaces photos virtual directory1", function () { - var newURI = fileSystem.getURI("/virTUal/photos/path.jpg"); - expect(newURI).toEqual("http://127.0.0.1/path.jpg"); - }); - - it("exists returns false if the file doesn't exist", function () { - xhrResult = 404; - expect(fileSystem.exists("/virtual/photos/missing.jpg")).toEqual(false); - }); - - it("exists returns true if the file does exist", function () { - xhrResult = 200; - expect(fileSystem.exists("/virtual/photos/dontPanic.png")).toEqual(true); - }); - - it("it can provide an overload for a file", function () { - var file = "http://127.0.0.1/ripple/solution/extension/chromium/images/dontPanic.png"; - fileSystem.override("virtual/photos/foo.png", file); - expect(fileSystem.getURI("virtual/photos/foo.png")).toEqual(file); - }); - -}); diff --git a/test/unit/fs.js b/test/unit/fs.js new file mode 100644 index 00000000..e29e0940 --- /dev/null +++ b/test/unit/fs.js @@ -0,0 +1,608 @@ +/* + * 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 fs = require('ripple/fs'), + event = require('ripple/event'), + utils = require('ripple/utils'); + +describe("fs", function () { + var _resultEntries, + _dirEntry, + _baton, + _fs, + _oldLocation, + _domain = "http://127.0.0.1:3000"; + + beforeEach(function () { + _baton = { + take: jasmine.createSpy("baton.take"), + pass: jasmine.createSpy("baton.pass") + }; + + _dirEntry = { + createReader: function () { + return { + readEntries: function (success, error) { + success(_resultEntries); + } + }; + } + }; + + _fs = { + root: { + getDirectory: function (path, options, success, error) { + success(_dirEntry); + } + } + }; + + window.TEMPORARY = 0; + window.PERSISTENT = 1; + window.webkitRequestFileSystem = window.requestFileSystem = function (persistenceMethod, fsSize, success, failure) { + success(_fs); + }; + + window.webkitResolveLocalFileSystemURL = window.resolveLocalFileSystemURL = function (url, success, failure) {}; + + window.WebKitBlobBuilder = window.BlobBuilder = function () {}; + window.FileReader = global.FileReader = function () {}; + window.FileError = global.FileError = {NOT_FOUND_ERR: 1}; + + spyOn(event, "trigger"); + + _oldLocation = utils.location; + utils.location = function () { + return { + origin: _domain + }; + }; + + fs.initialize(null, _baton); + }); + + afterEach(function () { + delete window.TEMPORARY; + delete window.PERSISTENT; + delete window.requestFileSystem; + delete window.webkitRequestFileSystem; + delete window.resolveLocalFileSystemURL; + delete window.webkitResolveLocalFileSystemURL; + delete window.WebKitBlobBuilder; + delete window.BlobBuilder; + delete window.FileReader; + delete global.FileReader; + utils.location = _oldLocation; + }); + + describe("initialize", function () { + it("uses requestFileSystem", function () { + spyOn(window, "requestFileSystem"); + fs.initialize(null, _baton); + + expect(window.requestFileSystem.argsForCall[0][0]).toEqual(window.TEMPORARY); + expect(window.requestFileSystem.argsForCall[0][1]).toEqual(10 * 1024 * 1024); + }); + + it("takes and passes the baton", function () { + spyOn(window, "requestFileSystem"); + fs.initialize(null, _baton); + + expect(_baton.take).toHaveBeenCalled(); + expect(_baton.pass).toHaveBeenCalled(); + }); + + it("triggers FileSystemIntialized", function () { + spyOn(window, "requestFileSystem"); + fs.initialize(null, _baton); + + expect(event.trigger).toHaveBeenCalledWith("FileSystemInitialized", null, true); + }); + + it("uses webkitRequestFileSystem when requestFileSystem is not present", function () { + delete window.requestFileSystem; + spyOn(window, "webkitRequestFileSystem"); + fs.initialize(null, _baton); + + expect(window.webkitRequestFileSystem.argsForCall[0][0]).toEqual(window.TEMPORARY); + expect(window.webkitRequestFileSystem.argsForCall[0][1]).toEqual(10 * 1024 * 1024); + }); + }); + + describe("mkdir", function () { + it("creates a directory off of root", function () { + var error = jasmine.createSpy(), + success = jasmine.createSpy(); + + _fs.root.getDirectory = function (path, options, success, error) { + success(_resultEntries[0]); + }; + + spyOn(_fs.root, "getDirectory").andCallThrough(); + + _resultEntries = [ + {fullPath: "whatev", isDirectory: true} + ]; + + fs.mkdir("whatev", success, error); + + expect(_fs.root.getDirectory.argsForCall[0][0]).toEqual("whatev"); + expect(_fs.root.getDirectory.argsForCall[0][1]).toEqual({create: true}); + expect(typeof _fs.root.getDirectory.argsForCall[0][2]).toEqual("function"); + expect(_fs.root.getDirectory.argsForCall[0][3]).toEqual(error); + expect(success).toHaveBeenCalledWith(_resultEntries[0]); + expect(error).not.toHaveBeenCalled(); + }); + }); + + describe("touch", function () { + it("creates a file off of root", function () { + var error = jasmine.createSpy(), + success = jasmine.createSpy(); + + _fs.root.getFile = function (path, options, success, error) { + success(_resultEntries[0]); + }; + + spyOn(_fs.root, "getFile").andCallThrough(); + + _resultEntries = [ + {fullPath: "er", isDirectory: false} + ]; + + fs.touch("er", success, error); + + expect(_fs.root.getFile.argsForCall[0][0]).toEqual("er"); + expect(_fs.root.getFile.argsForCall[0][1]).toEqual({create: true}); + expect(typeof _fs.root.getFile.argsForCall[0][2]).toEqual("function"); + expect(_fs.root.getFile.argsForCall[0][3]).toEqual(error); + expect(success).toHaveBeenCalledWith(_resultEntries[0]); + expect(error).not.toHaveBeenCalled(); + }); + }); + + describe("ls", function () { + it("defaults to '/' for a null path", function () { + _fs.root.getDirectory = jasmine.createSpy(); + fs.ls(null); + expect(_fs.root.getDirectory.argsForCall[0][0]).toEqual("/"); + }); + + it("returns a list of items in the root", function () { + var error = jasmine.createSpy(); + + _resultEntries = [ + {name: "dude", isDirectory: true}, + {name: "sweet.js", isDirectory: false} + ]; + + fs.ls("/", function (entries) { + expect(entries[0]).toEqual(_resultEntries[0]); + expect(entries[1]).toEqual(_resultEntries[1]); + }, error); + + expect(error).not.toHaveBeenCalled(); + }); + + it("calls error callback when path does not exist", function () { + var success = jasmine.createSpy(), + FileError = { + code: 5, + ENCODING_ERR: 5 + }; + + _dirEntry.createReader = function () { + return { + readEntries: function (success, error) { + error(FileError); + } + }; + }; + + fs.ls("/foo", success, function (error) { + expect(error).toEqual(FileError); + }); + + expect(success).not.toHaveBeenCalled(); + }); + }); + + describe("rm", function () { + it("removes a file from the root", function () { + var error = jasmine.createSpy(), + remove = jasmine.createSpy().andCallFake(function (callback) { + callback(); + }), + success = jasmine.createSpy(); + + _fs.root.getFile = function (path, options, success, error) { + success(_resultEntries[0]); + }; + + spyOn(_fs.root, "getFile").andCallThrough(); + + _resultEntries = [ + {fullPath: "/foo", isDirectory: false, remove: remove} + ]; + + fs.rm("/foo", success, error); + + expect(_fs.root.getFile.argsForCall[0][0]).toEqual("/foo"); + expect(_fs.root.getFile.argsForCall[0][1]).toEqual({create: false}); + expect(typeof _fs.root.getFile.argsForCall[0][2]).toEqual("function"); + expect(_fs.root.getFile.argsForCall[0][3]).toEqual(error); + expect(success).toHaveBeenCalled(); + expect(typeof remove.argsForCall[0][0]).toEqual("function"); + expect(remove.argsForCall[0][1]).toEqual(error); + expect(error).not.toHaveBeenCalled(); + }); + + it("removes a directory recursively", function () { + var error = jasmine.createSpy(), + removeRecursively = jasmine.createSpy().andCallFake(function (callback) { + callback(); + }), + success = jasmine.createSpy(); + + _fs.root.getDirectory = function (path, options, success, error) { + success(_resultEntries[0]); + }; + + spyOn(_fs.root, "getDirectory").andCallThrough(); + + _resultEntries = [ + {fullPath: "/foo", isDirectory: true, removeRecursively: removeRecursively} + ]; + + fs.rm("/foo", success, error, {recursive: true}); + + expect(_fs.root.getDirectory.argsForCall[0][0]).toEqual("/foo"); + expect(_fs.root.getDirectory.argsForCall[0][1]).toEqual({create: false}); + expect(typeof _fs.root.getDirectory.argsForCall[0][2]).toEqual("function"); + expect(_fs.root.getDirectory.argsForCall[0][3]).toEqual(error); + expect(success).toHaveBeenCalled(); + expect(typeof removeRecursively.argsForCall[0][0]).toEqual("function"); + expect(removeRecursively.argsForCall[0][1]).toEqual(error); + expect(error).not.toHaveBeenCalled(); + }); + }); + + describe("rmdir", function () { + it("removes a directory", function () { + var error = jasmine.createSpy(), + remove = jasmine.createSpy().andCallFake(function (callback) { + callback(); + }), + success = jasmine.createSpy(); + + _fs.root.getDirectory = function (path, options, success, error) { + success(_resultEntries[0]); + }; + + spyOn(_fs.root, "getDirectory").andCallThrough(); + + _resultEntries = [ + {fullPath: "/foo", isDirectory: true, remove: remove} + ]; + + fs.rmdir("/foo", success, error); + + expect(_fs.root.getDirectory.argsForCall[0][0]).toEqual("/foo"); + expect(_fs.root.getDirectory.argsForCall[0][1]).toEqual({create: false}); + expect(typeof _fs.root.getDirectory.argsForCall[0][2]).toEqual("function"); + expect(_fs.root.getDirectory.argsForCall[0][3]).toEqual(error); + expect(success).toHaveBeenCalled(); + expect(typeof remove.argsForCall[0][0]).toEqual("function"); + expect(remove.argsForCall[0][1]).toEqual(error); + expect(error).not.toHaveBeenCalled(); + }); + }); + + describe("stat", function () { + it("retrieves the status of a file", function () { + var entry = { + fullPath: "/bob", + isDirectory: false + }, + error = jasmine.createSpy(), + success = jasmine.createSpy(); + + spyOn(window, "resolveLocalFileSystemURL").andCallFake(function (url, success, error) { + success(entry); + }); + + fs.stat("/bob", success, error); + + expect(window.resolveLocalFileSystemURL.argsForCall[0][0]) + .toEqual("filesystem:" + _domain + "/temporary//bob"); + expect(typeof window.resolveLocalFileSystemURL.argsForCall[0][1]).toEqual("function"); + expect(window.resolveLocalFileSystemURL.argsForCall[0][2]).toEqual(error); + expect(success).toHaveBeenCalledWith(entry); + }); + }); + + describe("mv", function () { + it("can move a file from one location to another", function () { + var movedEntry = { + fullPath: "/bar", + isDirectory: false + }, + fromEntry = { + fullPath: "/foo", + isDirectory: false, + moveTo: jasmine.createSpy().andCallFake(function (dest, fileName, callback) { + callback(movedEntry); + }) + }, + rootEntry = { + fullPath: "/", + isDirectory: true + }, + error = jasmine.createSpy(), + success = jasmine.createSpy(), + from = "/foo", + to = "/bar"; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + success(path.match(/^\/$/) ? rootEntry : fromEntry); + }); + + fs.mv(from, to, success, error); + + expect(fromEntry.moveTo.argsForCall[0][0]).toEqual(rootEntry); + expect(fromEntry.moveTo.argsForCall[0][1]).toEqual("bar"); + expect(fromEntry.moveTo.argsForCall[0][3]).toEqual(error); + expect(fs.stat.argsForCall[0][2]).toEqual(error); + expect(fs.stat.argsForCall[1][2]).toEqual(error); + expect(success).toHaveBeenCalledWith(movedEntry); + }); + }); + + describe("cp", function () { + it("can copy a file from one location to another", function () { + var copiedEntry = { + fullPath: "/bar", + isDirectory: false + }, + fromEntry = { + fullPath: "/foo", + isDirectory: false, + copyTo: jasmine.createSpy().andCallFake(function (dest, fileName, callback) { + callback(copiedEntry); + }) + }, + rootEntry = { + fullPath: "/", + isDirectory: true + }, + error = jasmine.createSpy(), + success = jasmine.createSpy(), + from = "/foo", + to = "/bar"; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + success(path.match(/^\/$/) ? rootEntry : fromEntry); + }); + + fs.cp(from, to, success, error); + + expect(fromEntry.copyTo.argsForCall[0][0]).toEqual(rootEntry); + expect(fromEntry.copyTo.argsForCall[0][1]).toEqual("bar"); + expect(fromEntry.copyTo.argsForCall[0][3]).toEqual(error); + expect(fs.stat.argsForCall[0][2]).toEqual(error); + expect(fs.stat.argsForCall[1][2]).toEqual(error); + expect(success).toHaveBeenCalledWith(copiedEntry); + }); + }); + + describe("write", function () { + it("overwrites an existing file by default", function () { + var path = "some/path", + contents = "file data", + error = jasmine.createSpy(), + success = jasmine.createSpy(), + fileWriterInstance = { + onwriteend: null, + onerror: null, + write: jasmine.createSpy() + }, + progressEvent = { + target: fileWriterInstance + }, + fileEntry = { + fullPath: "some/path", + isDirectory: false, + createWriter: jasmine.createSpy().andCallFake(function (callback) { + callback(fileWriterInstance); + }) + }, + txt = "plain text blob", + blobInstance = { + append: jasmine.createSpy(), + getBlob: jasmine.createSpy().andReturn(txt) + }; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + success(fileEntry); + }); + + spyOn(fs, "touch").andCallFake(function (path, success, error) { + success(fileEntry); + }); + + spyOn(fs, "rm").andCallFake(function (path, success, error) { + success(); + }); + + spyOn(window, "BlobBuilder").andReturn(blobInstance); + + fs.write(path, contents, success, error); + + fileWriterInstance.onwriteend(progressEvent); + + expect(fs.rm.callCount).toBe(1); + expect(fs.rm.argsForCall[0][2]).toEqual(error); + expect(fs.touch.callCount).toBe(1); + expect(fs.touch.argsForCall[0][0]).toEqual(path); + expect(fs.touch.argsForCall[0][2]).toEqual(error); + + expect(success).toHaveBeenCalledWith(fileEntry); + expect(fileWriterInstance.onerror).toBe(error); + expect(fileEntry.createWriter.callCount).toBe(1); + expect(fileEntry.createWriter.argsForCall[0][1]).toBe(error); + expect(blobInstance.append).toHaveBeenCalledWith(contents); + expect(fileWriterInstance.write).toHaveBeenCalledWith(txt); + }); + + it("creates the file if it does not exist", function () { + var path = "some/path", + contents = "file data", + error = jasmine.createSpy(), + success = jasmine.createSpy(), + txt = "plain text blob", + blobInstance = { + append: jasmine.createSpy(), + getBlob: jasmine.createSpy().andReturn(txt) + }; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + error({code: 1}); + }); + + spyOn(fs, "touch"); + spyOn(fs, "rm"); + spyOn(window, "BlobBuilder").andReturn(blobInstance); + + fs.write(path, contents, success, error); + + expect(fs.touch.callCount).toBe(1); + expect(fs.touch.argsForCall[0][0]).toEqual(path); + expect(fs.touch.argsForCall[0][2]).toEqual(error); + }); + + it("invokes error when file does exit", function () { + var path = "some/path", + contents = "file data", + error = jasmine.createSpy(), + success = jasmine.createSpy(), + txt = "plain text blob", + blobInstance = { + append: jasmine.createSpy(), + getBlob: jasmine.createSpy().andReturn(txt) + }; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + error({code: 2}); + }); + + spyOn(fs, "touch"); + spyOn(fs, "rm"); + spyOn(window, "BlobBuilder").andReturn(blobInstance); + + fs.write(path, contents, success, error); + + expect(fs.touch).not.toHaveBeenCalled(); + }); + + describe("when options.append", function () { + it("appends to an existing file", function () { + var path = "some/path", + contents = "file data", + error = jasmine.createSpy(), + success = jasmine.createSpy(), + options = { + mode: "append" + }, + fileWriterInstance = { + onwriteend: null, + onerror: null, + length: 5, + write: jasmine.createSpy(), + seek: jasmine.createSpy() + }, + fileEntry = { + fullPath: "some/path", + isDirectory: false, + createWriter: jasmine.createSpy().andCallFake(function (callback) { + callback(fileWriterInstance); + }) + }, + txt = "plain text blob", + blobInstance = { + append: jasmine.createSpy(), + getBlob: jasmine.createSpy().andReturn(txt) + }; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + success(fileEntry); + }); + + spyOn(fs, "touch").andCallFake(function (path, success, error) { + success(fileEntry); + }); + + spyOn(fs, "rm").andCallFake(function (path, success, error) { + success(); + }); + + spyOn(window, "BlobBuilder").andReturn(blobInstance); + + fs.write(path, contents, success, error, options); + + expect(fileWriterInstance.seek).toHaveBeenCalledWith(fileWriterInstance.length); + }); + }); + }); + + describe("read", function () { + it("returns contents of a file", function () { + var path = "a/file", + error = jasmine.createSpy(), + success = jasmine.createSpy(), + fileInstance = jasmine.createSpy(), + fileReaderInstance = { + onloadend: null, + result: "file data", + readAsText: jasmine.createSpy() + }, + progressEvent = { + target: fileReaderInstance + }, + fileEntry = { + fullPath: "a/file", + isDirectory: false, + file: jasmine.createSpy().andCallFake(function (callback) { + callback(fileInstance); + }) + }; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + success(fileEntry); + }); + + spyOn(global, "FileReader").andReturn(fileReaderInstance); + + fs.read(path, success, error); + + fileReaderInstance.onloadend(progressEvent); + + expect(fileReaderInstance.readAsText).toHaveBeenCalledWith(fileInstance); + expect(success).toHaveBeenCalledWith(fileReaderInstance.result); + expect(fileReaderInstance.onerror).toBe(error); + expect(fileEntry.file.argsForCall[0][1]).toBe(error); + expect(fs.stat.argsForCall[0][2]).toBe(error); + }); + }); +}); diff --git a/test/unit/geo.js b/test/unit/geo.js index ddc5dd7e..ecfef95b 100644 --- a/test/unit/geo.js +++ b/test/unit/geo.js @@ -16,71 +16,67 @@ describe("geo", function () { var geo = require('ripple/geo'), db = require('ripple/db'), - event = require('ripple/event'), - sinon = require('sinon'), - s; + event = require('ripple/event'); - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); + describe("getPositionInfo", function () { + it("returns valid values", function () { + var positionInfo = geo.getPositionInfo(); - it("getPositionInfo returns valid values", function () { - var positionInfo = geo.getPositionInfo(); + expect(typeof positionInfo).toEqual("object"); + expect(typeof positionInfo.latitude).toEqual("number"); + expect(typeof positionInfo.longitude).toEqual("number"); + expect(typeof positionInfo.altitude).toEqual("number"); + expect(typeof positionInfo.accuracy).toEqual("number"); + expect(typeof positionInfo.altitudeAccuracy).toEqual("number"); + expect(typeof positionInfo.heading).toEqual("number"); + expect(typeof positionInfo.speed).toEqual("number"); + expect(typeof positionInfo.cellID).toEqual("number"); + expect(positionInfo.timeStamp instanceof Date).toEqual(true); + }); - expect(typeof positionInfo).toEqual("object"); - expect(typeof positionInfo.latitude).toEqual("number"); - expect(typeof positionInfo.longitude).toEqual("number"); - expect(typeof positionInfo.altitude).toEqual("number"); - expect(typeof positionInfo.accuracy).toEqual("number"); - expect(typeof positionInfo.altitudeAccuracy).toEqual("number"); - expect(typeof positionInfo.heading).toEqual("number"); - expect(typeof positionInfo.speed).toEqual("number"); - expect(typeof positionInfo.cellID).toEqual("number"); - expect(positionInfo.timeStamp instanceof Date).toEqual(true); + it("'s internal position info object is immutable", function () { + var positionInfo = geo.getPositionInfo(), + immutablePositionInfo; + positionInfo.altitude = 1; + immutablePositionInfo = geo.getPositionInfo(); + expect(positionInfo.altitude).not.toEqual(immutablePositionInfo.altitude); + }); }); - it("getPositionInfo's internal position info object is immutable", function () { - var positionInfo = geo.getPositionInfo(), - immutablePositionInfo; - positionInfo.altitude = 1; - immutablePositionInfo = geo.getPositionInfo(); - expect(positionInfo.altitude).not.toEqual(immutablePositionInfo.altitude); - }); + describe("updatePositionInfo", function () { + it("throws exception when invalid input", function () { + var positionInfo = { + latitude: "12", + longitude: false, + altitudeAccuracy: true, + cellID: 62, + timeStamp: "dfdgfdgfdgfdgf" + }; - it("updatePositionInfo throws exception when invalid input", function () { - var positionInfo = { - latitude: "12", - longitude: false, - altitudeAccuracy: true, - cellID: 62, - timeStamp: "dfdgfdgfdgfdgf" - }; + expect(function () { + geo.updatePositionInfo(positionInfo); + }).toThrow(); + }); - expect(function () { - geo.updatePositionInfo(positionInfo); - }).toThrow(); - }); + it("updates successfully", function () { + var positionInfo = { + latitude: 11, + longitude: 21, + altitude: 31, + accuracy: 41, + altitudeAccuracy: 51, + heading: 0, + speed: 0, + cellID: 61, + timeStamp: new Date() + }; - it("updatePositionInfo updates successfully", function () { - var positionInfo = { - latitude: 11, - longitude: 21, - altitude: 31, - accuracy: 41, - altitudeAccuracy: 51, - heading: 0, - speed: 0, - cellID: 61, - timeStamp: new Date() - }; + spyOn(db, "saveObject"); + spyOn(event, "trigger"); - s.mock(db).expects("saveObject").once(); - s.stub(event, "trigger"); + geo.updatePositionInfo(positionInfo, 4, true); - geo.updatePositionInfo(positionInfo, 4, true); + expect(db.saveObject.callCount).toBe(1); + }); }); }); diff --git a/test/unit/notifications.js b/test/unit/notifications.js index 13acae6a..e1de6a17 100644 --- a/test/unit/notifications.js +++ b/test/unit/notifications.js @@ -62,7 +62,7 @@ describe("notifications", function () { }); it("openNotification_throws_no_exception_when_valid_command", function () { - var nType = constants.NOTIFICATIONS.TYPES.NORMAL, + var nType = "normal", msg = "some type of notification"; expect(function () { notifications.closeNotification(nType, msg); @@ -70,7 +70,7 @@ describe("notifications", function () { }); it("openNotification_updates_dom_objects_properly_when_opening_normal_notification", function () { - var nType = constants.NOTIFICATIONS.TYPES.NORMAL, + var nType = "normal", msg = "some type of notification", box, msgBox; @@ -84,13 +84,14 @@ describe("notifications", function () { }); it("closeNotification_updates_dom_objects_properly_when_closing_normal_notification", function () { - notifications.closeNotification(constants.NOTIFICATIONS.TYPES.NORMAL); + notifications.closeNotification("normal"); + var box = document.getElementById(constants.NOTIFICATIONS.MAIN_CONTAINER_CLASS); expect(box.getAttribute("style")).toEqual("display: none;"); }); it("openNotification_updates_dom_objects_properly_when_opening_error_notification", function () { - var nType = constants.NOTIFICATIONS.TYPES.ERROR, + var nType = "error", msg = "type of notification", box, msgBox; @@ -104,7 +105,8 @@ describe("notifications", function () { }); it("closeNotification_updates_dom_objects_properly_when_closing_error_notification", function () { - notifications.closeNotification(constants.NOTIFICATIONS.TYPES.ERROR); + notifications.closeNotification("error"); + var box = document.getElementById(constants.NOTIFICATIONS.MAIN_CONTAINER_CLASS); expect(box.getAttribute("style")).toEqual("display: none;"); }); diff --git a/test/unit/opera/widget.js b/test/unit/opera/widget.js deleted file mode 100644 index 0c3e81b5..00000000 --- a/test/unit/opera/widget.js +++ /dev/null @@ -1,84 +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. - */ -describe("opera_widget", function () { - - var widget = require('ripple/platform/opera/4.0/widget'), - platform = require('ripple/platform'), - _console = require('ripple/console'), - db = require('ripple/db'), - sinon = require('sinon'), - s; - - beforeEach(function () { - spyOn(platform, "current").andReturn({name: "foo"}); - spyOn(_console, "log"); - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - // -------- addEventListener - - it("addEventListener is available and works", function () { - expect(function () { - widget.addEventListener("resolution", function _resolutionEventTest() {}, false); - }).not.toThrow(); - }); - - // -------- removeEventListener - - it("removeEventListener is available and works", function () { - expect(function () { - widget.removeEventListener("resolution", function _resolutionEventTest() {}, false); - }).not.toThrow(); - }); - - // --------- resolution event - - it("resolution event should fire when screen changes dimension with proper args", function () { - function myEvent() {} - s.mock(window).expects("addEventListener").once().withExactArgs("resolution", myEvent, false); - widget.addEventListener("resolution", myEvent); - }); - - // -------- setPreferenceForKey - - it("setPreferenceForKey returns undefined when key is not found", function () { - spyOn(platform, "getPersistencePrefix").andReturn(""); - spyOn(db, "retrieve"); - expect(widget.preferenceForKey("nonexistentkey")).toEqual(undefined); - }); - - it("setPreferenceForKey saves a key", function () { - spyOn(platform, "getPersistencePrefix").andReturn(""); - s.stub(db, "retrieve").returns("p value"); - s.mock(db).expects("save").once().withArgs("pstring", "p value"); - widget.setPreferenceForKey("p value", "pstring"); - expect(widget.preferenceForKey("pstring")).toEqual("p value"); - }); - - it("setPreferenceForKey removes a key", function () { - spyOn(platform, "getPersistencePrefix").andReturn(""); - s.stub(db, "retrieve"); - s.stub(db, "save"); - s.mock(db).expects("remove").once().withArgs("removes_key"); - widget.setPreferenceForKey("test", "removes_key"); - widget.setPreferenceForKey(null, "removes_key"); - }); - -}); diff --git a/test/unit/phonegap/accelerometer.js b/test/unit/phonegap/accelerometer.js index 22b5b0d1..938003af 100644 --- a/test/unit/phonegap/accelerometer.js +++ b/test/unit/phonegap/accelerometer.js @@ -32,7 +32,7 @@ describe("phonegap_accelerometer", function () { }); // TODO: why does this fail when not run atomicly - xit("accelleration info is updated on AccelerometerInfoChangedEvent", function () { + xit("acceleration info is updated on AccelerometerInfoChangedEvent", function () { event.trigger("AccelerometerInfoChangedEvent", [{ x: 9.8, y: 9.8, diff --git a/test/unit/phonegap/contacts.js b/test/unit/phonegap/contacts.js index ed13ac97..43dce76e 100644 --- a/test/unit/phonegap/contacts.js +++ b/test/unit/phonegap/contacts.js @@ -14,34 +14,19 @@ * limitations under the License. */ describe("phonegap_contacts", function () { - var s, - _contactDB = [], - sinon = require('sinon'), - db = require('ripple/db'), + 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'); - function _propertyCount(obj) { - var prop, count = 0; - for (prop in obj) { - if (Object.prototype.hasOwnProperty.call(obj, prop)) { - count++; - } - } - return count; - } - beforeEach(function () { - s = sinon.sandbox.create(); - spyOn(db, "retrieveObject").andReturn(_contactDB); - }); - - afterEach(function () { - s.verifyAndRestore(); - _contactDB.splice(0, _contactDB.length); + spyOn(window, "setTimeout").andCallFake(function (func) { + func(); + }); }); describe("spec", function () { @@ -135,7 +120,6 @@ describe("phonegap_contacts", function () { describe("find", function () { it("calls error callback when no contact fields given", function () { - waits(1); contacts.find(null, function () {}, function (error) { expect(typeof error).toEqual("object"); expect(error.message).toEqual("missing contact fields array"); @@ -144,14 +128,12 @@ describe("phonegap_contacts", function () { }); it("returns empty array of contacts when given empty contact fields array", function () { - waits(1); contacts.find([], function (items) { expect(items.length, 0, "expected empty array"); }); }); it("calls error callback when only non-existent contact fields given", function () { - waits(1); contacts.find(["dude"], function () {}, function (error) { expect(typeof error).toEqual("object"); expect(typeof error.message).toEqual("string"); @@ -160,7 +142,6 @@ describe("phonegap_contacts", function () { }); it("calls error callback when some non-existent contact fields given", function () { - waits(1); contacts.find(["displayName", "sweet"], function () {}, function (error) { expect(typeof error).toEqual("object"); expect(typeof error.message).toEqual("string"); @@ -169,7 +150,6 @@ describe("phonegap_contacts", function () { }); it("calls error callback when no success callback given", function () { - waits(1); contacts.find(["displayName"], undefined, function (error) { expect(typeof error).toEqual("object"); expect(typeof error.message).toEqual("string"); @@ -178,7 +158,6 @@ describe("phonegap_contacts", function () { }); it("returns array in success callback", function () { - waits(1); contacts.find(["displayName"], function (items) { expect(typeof items).toEqual("object"); expect(typeof items.length).toEqual("number"); @@ -190,9 +169,8 @@ describe("phonegap_contacts", function () { data[0].displayName = "dave"; data[1].displayName = "rob"; - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["displayName"], function (items) { expect(items.length).toEqual(2); expect(items[0].displayName).toEqual("dave"); @@ -207,9 +185,8 @@ describe("phonegap_contacts", function () { emails = data[0].emails = new ContactField("dave", "dave@test.com", true); data[0].id = "daveID"; - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["emails"], function (items) { expect(items[0].id).toEqual("daveID"); }); @@ -222,21 +199,20 @@ describe("phonegap_contacts", function () { emails = data[0].emails = new ContactField("dave", "dave@test.com", true); data[0].id = "daveID"; - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["emails"], function (items) { expect(items[0].id).toEqual("daveID"); expect(items[0].emails).toEqual(emails); expect(typeof items[0].save).toEqual("function"); expect(typeof items[0].clone).toEqual("function"); expect(typeof items[0].remove).toEqual("function"); - expect(_propertyCount(items[0])).toEqual(5); + expect(utils.count(items[0])).toEqual(5); }); }); it("returns default contacts when none persisted", function () { - waits(1); + spyOn(db, "retrieveObject").andReturn(null); contacts.find(["name", "displayName", "emails"], function (items) { var i; expect(items.length, 5, "expected five default contacts"); @@ -244,26 +220,36 @@ describe("phonegap_contacts", function () { expect(typeof items[i].id).toEqual("string"); expect(typeof items[i].emails).toEqual("object"); expect(typeof items[i].displayName).toEqual("string"); - expect(_propertyCount(items[i])).toEqual(7); + expect(utils.count(items[i])).toEqual(7); } }); }); + it("returns all the fields when given a fields array of ['*']", function () { + var error = jasmine.createSpy("error callback"); + + spyOn(db, "retrieveObject").andReturn(null); + + contacts.find(["*"], function (items) { + expect(utils.count(items[0])).toBe(17); + }, error); + }); + it("can find contacts based on the filter findOption", function () { var contact = contacts.create({"name": "The Sheldon Cooper"}), data = [contact, new Contact(), new Contact()], - options = new ContactFindOptions(); + options = new ContactFindOptions(), + error = jasmine.createSpy(); options.filter = "sheldon"; - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["name", "displayName", "addresses"], function (items) { expect(items.length).toEqual(1); expect(items[0].id).toEqual(contact.id); expect(items[0].name).toEqual(contact.name); - }, s.mock().never(), options); + }, error, options); }); it("can find contacts based on the filter findOption (with objects)", function () { @@ -272,52 +258,53 @@ describe("phonegap_contacts", function () { "emails": [new ContactField("personal", "sheldon@email.com", true)] }), data = [contact, new Contact(), new Contact()], - options = new ContactFindOptions(); + options = new ContactFindOptions(), + error = jasmine.createSpy(); - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); options.filter = "sheldon@email.com"; - waits(1); contacts.find(["name", "emails"], function (items) { expect(items.length).toEqual(1); expect(items[0].id).toEqual(contact.id); expect(items[0].name).toEqual(contact.name); expect(items[0].emails).toEqual(contact.emails); - }, s.mock().never(), options); + }, error, options); }); it("should return multiple contacts when findOptions.multiple is true", function () { var options = new ContactFindOptions(), - data = [new Contact(), new Contact(), new Contact()]; + data = [new Contact(), new Contact(), new Contact()], + error = jasmine.createSpy(); options.multiple = true; - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["displayName"], function (items) { expect(items.length).toEqual(3); - }, s.mock().never(), options); + }, error, options); }); it("should return only one contact when findOptions.multiple is false", function () { var options = new ContactFindOptions(), - data = [new Contact(), new Contact()]; + data = [new Contact(), new Contact()], + error = jasmine.createSpy(); - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["name"], function (items) { expect(items.length).toEqual(1); - }, s.mock().never(), options); + }, error, options); }); it("can limit amount of contacts returned by last updated (findOptions)", function () { var options = new ContactFindOptions(), newContact = new Contact(), oldContact = new Contact(), - data = [newContact, oldContact]; + data = [newContact, oldContact], + error = jasmine.createSpy(); oldContact.updated = new Date(2010, 0, 1); newContact.updated = new Date(2010, 8, 20); @@ -325,151 +312,148 @@ describe("phonegap_contacts", function () { options.updatedSince = new Date(2010, 4, 20); options.multiple = true; - _contactDB.splice.apply(_contactDB, [0, data.length].concat(data)); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contacts.find(["name"], function (items) { expect(1, items.length, "expected only one contact"); expect(newContact.id, items[0].id, "expected only one contact"); - }, s.mock().never(), options); + }, error, options); }); }); - describe("save", function () { - it("can save itself", function () { - var contact = contacts.create({"name": "claude"}); + describe("when saving", function () { - // hmm, not 100% assertive - s.mock(db) - .expects("saveObject").once() - .withArgs("phonegap-contacts"); + describe("the Contact object", function () { - _contactDB.splice.apply(_contactDB, [0, 1]); + beforeEach(function () { + spyOn(event, "trigger"); + }); - waits(1); - contact.save(function (items) { - expect(items.length).toEqual(1); - expect(items[0].id).toEqual(contact.id); - expect(items[0].name).toEqual(contact.name); - }, s.mock().never()); - }); + it("sets id to uuid if falsy", function () { + var contact = contacts.create({ + "name": "dan", + "id": null + }); - it("sets id to uuid if falsy", function () { - var contact = contacts.create({ - "name": "dan", - "id": null + spyOn(Math, "uuid").andReturn(420); + contact.save(jasmine.createSpy(), jasmine.createSpy()); + expect(contact.id).toBe(420); }); - // hmm, not 100% assertive - s.mock(db) - .expects("saveObject").once() - .withArgs("phonegap-contacts"); - - waits(1); - contact.save(function (items) { - expect(items.length).toEqual(1); - expect(typeof items[0].id).toEqual("string"); - }, s.mock().never()); - }); + it("doesn't set the uuid if truthy", function () { + var contact = contacts.create({ + "name": "dan", + "id": null + }); - it("updates last updated property", function () { - var contact = contacts.create({"name": "frank"}), - then = new Date(); + spyOn(Math, "uuid").andReturn(420); + contact.save(jasmine.createSpy(), jasmine.createSpy()); + expect(contact.id).toBe(420); + }); - // hmm, not 100% assertive - s.mock(db) - .expects("saveObject").once() - .withArgs("phonegap-contacts"); + it("raises the phonegap-contact-save event", function () { + var contact = contacts.create({"name": "claude"}); + contact.save(jasmine.createSpy(), jasmine.createSpy()); + expect(event.trigger).toHaveBeenCalledWith("phonegap-contact-save", [ + jasmine.any(Object), + jasmine.any(Function), + jasmine.any(Function) + ]); + }); - waits(1); - contact.save(function (items) { - expect(items.length).toEqual(1); - expect(items[0].updated >= then).toEqual(true); - }, s.mock().never()); - }); + it("sets the updated property", function () { + var contact = contacts.create({name: "Peter Pan"}); + contact.save(jasmine.createSpy(), jasmine.createSpy()); + expect(contact.updated).toBeDefined(); + }); - it("does not update last updated property when error", function () { - var lastUpdated = new Date(2010, 11, 28), - contact = contacts.create({ - "id": null, - "name": "ricardo", - "updated": lastUpdated - }); + it("reverts the last updated property on error", function () { - // hmm, not 100% assertive - s.mock(db) - .expects("saveObject").once() - .withArgs("phonegap-contacts"); + var contact = contacts.create({name: "Tom", updated: "w00t"}); - _contactDB.splice.apply(_contactDB, [0, 1, contact]); + contact.save(function () { }, function () { + expect(contact.updated).toBe("w00t"); + }); - waits(1); - contact.save(undefined, function (error) { - expect(contact.updated.getTime()).toEqual(lastUpdated.getTime()); + //execute the error callback via hackery and magic + event.trigger.argsForCall[0][1][2](); }); }); - it("updates an existing contact if a contact with the same id already exists", function () { - var contact = contacts.create({ - "name": "rob", - "id": "some_id_yo" - }); + describe("the contacts module", function () { + it("saves a new contact", function () { + var contact = contacts.create({ + "name": "rob", + "id": "some_id_yo" + }), + error = jasmine.createSpy(); - s.mock(db) - .expects("saveObject").once() - .withArgs("phonegap-contacts", [contact]); + spyOn(db, "saveObject"); + spyOn(db, "retrieveObject").andReturn([]); - _contactDB.splice.apply(_contactDB, [0, 1, contact]); + event.trigger("phonegap-contact-save", [contact, function (item) { + expect(db.saveObject).toHaveBeenCalledWith("phonegap-contacts", [contact]); + }, error], true); + }); - waits(1); - contact.save(function (items) { - expect(items.length).toEqual(1); - expect(items[0].id).toEqual(contact.id); - expect(items[0].name).toEqual(contact.name); - }, s.mock().never()); + it("updates an existing contact if a contact with the same id already exists", function () { + var contact = contacts.create({ + "name": "rob", + "id": "some_id_yo" + }), + error = jasmine.createSpy(); + + spyOn(db, "saveObject"); + spyOn(db, "retrieveObject").andReturn([contact]); + + event.trigger("phonegap-contact-save", [contact, function (item) { + expect(item.id).toEqual(contact.id); + expect(item.name).toEqual(contact.name); + expect(db.saveObject).toHaveBeenCalledWith("phonegap-contacts", [contact]); + }, error], true); + }); }); }); describe("remove", function () { it("can remove itself", function () { - var contact = contacts.create({"name": "michelle"}); + var contact = contacts.create({"name": "michelle"}), + data = [contact], + error = jasmine.createSpy(); contact.id = "some_awesome_id"; - s.mock(db) - .expects("saveObject").once() - .withArgs("phonegap-contacts", []); - - _contactDB.splice.apply(_contactDB, [0, 1, contact]); + spyOn(db, "saveObject"); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); - contact.remove(function (items) { - expect(0, items.length, "expected only one contact"); - }, s.mock().never()); + contact.remove(function () { + expect(data.length).toBe(0); + expect(db.saveObject).toHaveBeenCalledWith("phonegap-contacts", []); + }, error); }); - it("calling remove on a contact with a null id should return NOT_FOUND_ERROR", function () { - var contact = contacts.create({"id": null, "name": "fabio"}); + it("returns a NOT_FOUND_ERROR when calling remove on a contact with a null id", function () { + var contact = contacts.create({"id": null, "name": "fabio"}), + data = [contact]; - s.mock(db).expects("saveObject").never(); - _contactDB.splice.apply(_contactDB, [0, 1, new Contact()]); + spyOn(db, "saveObject"); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contact.remove(function () {}, function (error) { expect(typeof error).toEqual("object"); expect(typeof error.message).toEqual("string"); expect(error.code).toEqual(ContactError.NOT_FOUND_ERROR); }); + }); it("calling remove on a non-existent contact id should return NOT_FOUND_ERROR", function () { - var contact = contacts.create({"name": "fabio"}); - - s.mock(db).expects("saveObject").never(); + var contact = contacts.create({"name": "fabio"}), + data = [contact]; - _contactDB.splice.apply(_contactDB, [0, 1, new Contact()]); + spyOn(db, "saveObject"); + spyOn(db, "retrieveObject").andReturn(data); - waits(1); contact.remove(function () {}, function (error) { expect(typeof error).toEqual("object"); expect(typeof error.message).toEqual("string"); diff --git a/test/unit/phonegap/events.js b/test/unit/phonegap/events.js new file mode 100644 index 00000000..266855e7 --- /dev/null +++ b/test/unit/phonegap/events.js @@ -0,0 +1,73 @@ +describe("phonegap events", function () { + var spec = require('ripple/platform/phonegap/1.0/spec'), + events = spec.events; + + function _expectsEventToFire(name) { + var evt = {initEvent: jasmine.createSpy()}; + + spyOn(document, "createEvent").andReturn(evt); + spyOn(document, "dispatchEvent"); + + events[name].callback(); + + expect(document.createEvent).toHaveBeenCalledWith("Events"); + expect(evt.initEvent).toHaveBeenCalledWith(name, true, false); + expect(document.dispatchEvent).toHaveBeenCalledWith(evt); + } + + describe("spec/ui", function () { + it("includes the platformEvents ui plugin", function () { + expect(spec.ui.plugins.some(function (plugin) { + return plugin === "platformEvents"; + })).toBe(true); + }); + }); + + describe("deviceready", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("deviceready"); + }); + }); + + describe("backbutton", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("backbutton"); + }); + }); + + describe("menubutton", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("menubutton"); + }); + }); + + describe("pause", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("pause"); + }); + }); + + describe("resume", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("resume"); + }); + }); + + describe("searchbutton", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("searchbutton"); + }); + }); + + describe("online", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("online"); + }); + }); + + describe("offline", function () { + it("fires respective event off the document", function () { + _expectsEventToFire("offline"); + }); + }); +}); diff --git a/test/unit/phonegap/navigator.js b/test/unit/phonegap/navigator.js index 8338df5f..9e565e0f 100644 --- a/test/unit/phonegap/navigator.js +++ b/test/unit/phonegap/navigator.js @@ -26,7 +26,7 @@ describe("phonegap_navigator", function () { }); it("it fires device ready and logs when tinyHippos Loaded event is raised", function () { - spyOn(emulatorBridge, "getWidgetDocument").andReturn(document); + spyOn(emulatorBridge, "document").andReturn(document); spyOn(document, "dispatchEvent"); spyOn(_console, "log"); diff --git a/test/unit/phonegap/notification.js b/test/unit/phonegap/notification.js index add1798b..51791cc9 100644 --- a/test/unit/phonegap/notification.js +++ b/test/unit/phonegap/notification.js @@ -13,33 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -describe("phonegap_notifications", function () { - var s, - sinon = require('sinon'), - notification = require('ripple/platform/phonegap/1.0/notification'), +describe("phonegap notifications", function () { + var notification = require('ripple/platform/phonegap/1.0/notification'), goodVibrations = require('ripple/ui/plugins/goodVibrations'), - constants = require('ripple/constants'), notifications = require('ripple/notifications'); beforeEach(function () { spyOn(console, "log"); - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); }); it("it calls into the UI to vibrate the device", function () { - s.mock(goodVibrations).expects("vibrateDevice").withExactArgs(500).once(); + spyOn(goodVibrations, "vibrateDevice"); notification.vibrate(500); + expect(goodVibrations.vibrateDevice).toHaveBeenCalledWith(500); }); it("it opens a notification with the supplied message", function () { - s.mock(notifications).expects("openNotification") - .withExactArgs(constants.NOTIFICATIONS.TYPES.NORMAL, - "His name was Robert Paulson").once(); - + spyOn(notifications, "openNotification"); notification.alert("His name was Robert Paulson"); + expect(notifications.openNotification).toHaveBeenCalledWith("normal", + "His name was Robert Paulson"); }); }); diff --git a/test/unit/platform.builder.js b/test/unit/platform.builder.js index 8969bbed..5b94f47c 100644 --- a/test/unit/platform.builder.js +++ b/test/unit/platform.builder.js @@ -14,22 +14,14 @@ * limitations under the License. */ describeBrowser("platform builder", function () { - var sinon = require('sinon'), - builder = require('ripple/platform/builder'), - app = require('ripple/app'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); + var builder = require('ripple/platform/builder'), + app = require('ripple/app'); it("it requires in the module for the path", function () { - var target = {}; - require.define('ripple/platform/xmen/1.0/cyclops', s.mock().once()); + var target = {}, + cb = jasmine.createSpy(); + + require.define('ripple/platform/xmen/1.0/cyclops', cb); builder.build({ test: { @@ -42,11 +34,14 @@ describeBrowser("platform builder", function () { }); it("it creates the children", function () { - var target = {}; + var target = {}, + cb0 = jasmine.createSpy(), + cb1 = jasmine.createSpy(), + cb2 = jasmine.createSpy(); - require.define('ripple/platform/xmen/1.0/magneto', s.mock().once()); - require.define('ripple/platform/xmen/1.0/scarletWitch', s.mock().once()); - require.define('ripple/platform/xmen/1.0/quicksilver', s.mock().once()); + require.define('ripple/platform/xmen/1.0/magneto', cb0); + require.define('ripple/platform/xmen/1.0/scarletWitch', cb1); + require.define('ripple/platform/xmen/1.0/quicksilver', cb2); builder.build({ magneto: { @@ -64,6 +59,9 @@ describeBrowser("platform builder", function () { expect(target.magneto.scarletWitch).toBeDefined(); expect(target.magneto.quicksilver).toBeDefined(); + expect(cb0).toHaveBeenCalled(); + expect(cb1).toHaveBeenCalled(); + expect(cb2).toHaveBeenCalled(); delete require.modules['ripple/platform/xmen/1.0/magneto']; delete require.modules['ripple/platform/xmen/1.0/scarletWitch']; diff --git a/test/unit/platform.js b/test/unit/platform.js index e5e63c17..382f3922 100644 --- a/test/unit/platform.js +++ b/test/unit/platform.js @@ -33,9 +33,9 @@ describe("platform", function () { it("getList should return correct value", function () { var returnedPlatforms = platform.getList(); - expect(typeof returnedPlatforms["wac"]["1.0"].id).toEqual("string"); - expect(typeof returnedPlatforms["wac"]["1.0"].name).toEqual("string"); - expect(typeof returnedPlatforms["wac"]["1.0"].type).toEqual("string"); + 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"); }); describe("when changing the environment", function () { @@ -80,7 +80,7 @@ describe("platform", function () { it("triggers the platform changed event", function () { platform.changeEnvironment(platformSpec, deviceId, function () { - expect(event.trigger).toHaveBeenCalledWith("PlatformChangedEvent", true); + expect(event.trigger).toHaveBeenCalledWith("PlatformChangedEvent", [], true); }); }); }); diff --git a/test/unit/resizer.js b/test/unit/resizer.js index 805a4068..d9880f5a 100644 --- a/test/unit/resizer.js +++ b/test/unit/resizer.js @@ -14,9 +14,7 @@ * limitations under the License. */ describe("resizer", function () { - - var sinon = require('sinon'), - s, _old_gElById, + var _old_gElById, _uiDomNode, _old_document_querySelector, _emulatedBody, @@ -50,8 +48,6 @@ describe("resizer", function () { } }; - s = sinon.sandbox.create(); - _uiDomNode = document.createElement("section"); _old_document_querySelector = document.querySelector; @@ -72,7 +68,6 @@ describe("resizer", function () { }); afterEach(function () { - s.verifyAndRestore(); document.querySelector = _old_document_querySelector; _uiDomNode = null; _emulatedDevice = null; @@ -99,7 +94,7 @@ describe("resizer", function () { }); it("resize resizes device properly", function () { - s.mock(db).expects("retrieve").once().returns(null); + spyOn(db, "retrieve").andReturn(null); var w, h; @@ -108,25 +103,20 @@ describe("resizer", function () { w = _emulatedViewport.style.width; h = _emulatedViewport.style.height; + expect(db.retrieve.callCount).toBe(1); expect(iPhone3.viewPort.portrait.width).toBe(parseInt(w, 10)); expect(iPhone3.viewPort.portrait.height).toBe(parseInt(h, 10)); }); - it("resize should NOT invoke window.onresized", function () { - s.mock(db).expects("retrieve").once().returns(null); - - window.onresize = s.mock().never(); - - resizer.resize(iPhone3); - - delete window.onresize; - }); - it("resize should trigger ScreenChangeDimensions", function () { - s.mock(db).expects("retrieve").once().returns(null); - s.mock(event).expects("trigger").once().withExactArgs("ScreenChangeDimensions", [320, 480]); + spyOn(db, "retrieve").andReturn(null); + spyOn(event, "trigger").andReturn(null); resizer.resize(iPhone3); + + expect(db.retrieve.callCount).toBe(1); + expect(event.trigger.callCount).toBe(1); + expect(event.trigger).toHaveBeenCalledWith("ScreenChangeDimensions", [320, 480]); waits(1); }); diff --git a/test/unit/utils.js b/test/unit/utils.js index bf2d9ac2..e050f5fb 100644 --- a/test/unit/utils.js +++ b/test/unit/utils.js @@ -138,7 +138,7 @@ describe("utils", function () { it("createElement_Creates_Div_With_Style_Attribute", function () { var node = utils.createElement("div", {"style": "color:black;"}); expect(node.nodeName).toEqual("DIV"); - expect(node.getAttribute("style")).toMatch(/color:black;/); + expect(node.getAttribute("style")).toMatch(/color:\s?black;/); }); it("HtmlElements_Works", function () { @@ -436,6 +436,11 @@ describe("utils", function () { expect(utils.copy(date).getTime()).toEqual(date.getTime()); }); + it("Copy_copies_a_regex_properly", function () { + var regex = /a/; + expect(utils.copy(regex) instanceof RegExp).toBe(true); + }); + it("Copy_makes_an_actual_copy_of_an_integer", function () { var num = 1, num2 = utils.copy(num); @@ -464,6 +469,15 @@ describe("utils", function () { expect(date).not.toEqual(date2); }); + it("Copy_makes_an_actual_copy_of_a_regex", function () { + + var regex = /a/, + regex2 = utils.copy(regex); + + regex.woo = "hoo"; + expect(regex2.woo).not.toBe("hoo"); + }); + it("Copy_makes_an_actual_copy_of_an_object_literal", function () { var obj = { test: "hello world", @@ -481,4 +495,104 @@ describe("utils", function () { it("can copy undefined and return undefined", function () { expect(utils.copy(undefined)).toBe(undefined); }); + + describe("appLocation", function () { + var omnibar = require('ripple/ui/plugins/omnibar'), + ui = require('ripple/ui'); + + describe("properly parses the omnibar url", function () { + beforeEach(function () { + spyOn(ui, "registered").andReturn(true); + }); + + it("with a trailing slash", function () { + spyOn(omnibar, "rootURL").andReturn("http://127.0.0.1/UI/"); + expect(utils.appLocation()).toBe("http://127.0.0.1/UI/"); + }); + + it("without a trailing slash", function () { + spyOn(omnibar, "rootURL").andReturn("http://127.0.0.1/UI"); + expect(utils.appLocation()).toBe("http://127.0.0.1/UI/"); + }); + + it("with a specific file", function () { + spyOn(omnibar, "rootURL").andReturn("http://127.0.0.1/UI/yui.html"); + expect(utils.appLocation()).toBe("http://127.0.0.1/UI/"); + }); + + it("with a subdomain", function () { + spyOn(omnibar, "rootURL").andReturn("http://rippledemo.tinyhippos.com/"); + expect(utils.appLocation()).toBe("http://rippledemo.tinyhippos.com/"); + }); + + it("with simple domain", function () { + spyOn(omnibar, "rootURL").andReturn("http://rim.com"); + expect(utils.appLocation()).toBe("http://rim.com/"); + }); + + it("with simple domain", function () { + spyOn(omnibar, "rootURL").andReturn("http://rim.com"); + expect(utils.appLocation()).toBe("http://rim.com/"); + }); + + it("and returns an empty string when about:blank ", function () { + spyOn(omnibar, "rootURL").andReturn("http://about:blank"); + expect(utils.appLocation()).toBe(""); + }); + }); + + describe("when omnibar is disabled", function () { + it("returns the window.location", function () { + spyOn(ui, "registered").andReturn(false); + spyOn(utils, "rippleLocation").andReturn("http://www.rim.com"); + expect(utils.appLocation()).toBe("http://www.rim.com"); + }); + }); + }); + + describe("rippleLocation", function () { + describe("properly returns the base path for ripple-ui", function () { + it("returns the base path when index.html is used", function () { + spyOn(utils, "location").andReturn({ + href: "http://127.0.0.1/ripple/index.html", + protocol: "http:", + hostname: "127.0.0.1", + pathname: "/ripple/index.html" + }); + expect(utils.rippleLocation()).toBe("http://127.0.0.1/ripple/"); + }); + + it("returns the base path when index.html is not specified", function () { + spyOn(utils, "location").andReturn({ + href: "http://127.0.0.1/ripple/", + protocol: "http:", + hostname: "127.0.0.1", + pathname: "/ripple/" + }); + expect(utils.rippleLocation()).toBe("http://127.0.0.1/ripple/"); + }); + + it("returns the base path when no trailing forward slash exists", function () { + spyOn(utils, "location").andReturn({ + href: "http://127.0.0.1/ripple", + protocol: "http:", + hostname: "127.0.0.1", + pathname: "/ripple" + }); + expect(utils.rippleLocation()).toBe("http://127.0.0.1/ripple/"); + }); + + it("returns the base path when hosted in multiple subdirectories", function () { + spyOn(utils, "location").andReturn({ + href: "http://127.0.0.1/i/will/put/ripple/here/", + protocol: "http:", + hostname: "127.0.0.1", + pathname: "/i/will/put/ripple/here/" + }); + expect(utils.rippleLocation()).toBe("http://127.0.0.1/i/will/put/ripple/here/"); + }); + }); + + }); + }); diff --git a/test/unit/vodafone/DeviceStateInfo.js b/test/unit/vodafone/DeviceStateInfo.js deleted file mode 100644 index 43841182..00000000 --- a/test/unit/vodafone/DeviceStateInfo.js +++ /dev/null @@ -1,121 +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. - */ -describe("vodafone_DeviceStateInfo", function () { - var DeviceStateInfo = require('ripple/platform/vodafone/2.7/DeviceStateInfo'), - sinon = require('sinon'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'), - event = require('ripple/event'), - _console = require('ripple/console'), - s; - - beforeEach(function () { - spyOn(_console, "log"); - s = sinon.sandbox.create(); - spyOn(platform, "current").andReturn({ - name: "default", - device: { - DeviceStateInfo: { - language: { control: { value: "en" } }, - availableMemory: {control: {value: 256}} - } - } - }); - - deviceSettings.initialize(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - describe("language", function () { - it("should return the default control value", function () { - expect(DeviceStateInfo.language).toEqual("en"); - }); - - it("should return the current 'persisted' device's language", function () { - deviceSettings.register("DeviceStateInfo.language", "fr"); - var value = DeviceStateInfo.language; - expect(value).toEqual("fr"); - }); - }); - - describe("availableMemory", function () { - it("should return the current device's available memory", function () { - var value = DeviceStateInfo.availableMemory; - expect(value).toBeGreaterThan(0); - }); - - it("should return the current 'persisted' device's available memory", function () { - deviceSettings.register("DeviceStateInfo.availableMemory", 66666); - var value = DeviceStateInfo.availableMemory; - expect(value).toEqual(66666); - }); - }); - - describe("requestPositionInfo", function () { - it("validates argument length", function () { - expect(function () { - DeviceStateInfo.requestPositionInfo(); - }).toThrow(); - }); - - it("validates argument", function () { - expect(function () { - DeviceStateInfo.requestPositionInfo("abcdef"); - }).toThrow(); - }); - - it("accepts expected argument", function () { - expect(function () { - DeviceStateInfo.requestPositionInfo(""); - DeviceStateInfo.requestPositionInfo("gps"); - }).toThrow(); - }); - - it("onPositionRetrieved is called with empty positionInfo when time out", function () { - runs(function () { - var geo = require('ripple/geo'), - utils = require('ripple/utils'), - origTimeout = geo.timeout; - - geo.timeout = true; - - DeviceStateInfo.onPositionRetrieved = function (pos) { - expect(pos).toBeDefined(); - - utils.forEach(pos, function (prop) { - expect(prop).not.toBeDefined(); - }); - }; - - DeviceStateInfo.requestPositionInfo("gps"); - geo.timeout = origTimeout; - }); - }); - - it("onScreenChangeDimensions should not fire when the screen changes dimensions", function () { - DeviceStateInfo.onScreenChangeDimensions = jasmine.createSpy(); - event.trigger("ScreenChangeDimensions", [480, 800]); - waits(1); - runs(function () { - expect(DeviceStateInfo.onScreenChangeDimensions).not.toHaveBeenCalled(); - DeviceStateInfo.onScreenChangeDimensions = null; - }); - }); - }); -}); diff --git a/test/unit/wac/AccelerometerInfo.js b/test/unit/wac/AccelerometerInfo.js deleted file mode 100644 index dba5301e..00000000 --- a/test/unit/wac/AccelerometerInfo.js +++ /dev/null @@ -1,29 +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. - */ -describe("wac_Accelerometer", function () { - // TODO: fix some of these things, should just be mocking Accelerometer - var AccelerometerInfo = require('ripple/platform/wac/1.0/AccelerometerInfo'); - - it("returns x,y,z coordinates on poll", function () { - var x = AccelerometerInfo.xAxis, - y = AccelerometerInfo.yAxis, - z = AccelerometerInfo.zAxis; - - expect(typeof x).toEqual("number"); - expect(typeof y).toEqual("number"); - expect(typeof z).toEqual("number"); - }); -}); diff --git a/test/unit/wac/Account.js b/test/unit/wac/Account.js deleted file mode 100644 index 118832a9..00000000 --- a/test/unit/wac/Account.js +++ /dev/null @@ -1,51 +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. - */ -describe("wac_Account", function () { - var Account = require('ripple/platform/wac/1.0/Account'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'); - - beforeEach(function () { - spyOn(platform, "current").andReturn({ - name: "whatup", - device: { - "Account": { - "accountName": {control: {value: "somename"}}, - "accountId": {control: {value: "someid"}} - } - } - }); - }); - - it("accountName should return default control value", function () { - expect(Account.accountName).toEqual("somename"); - }); - - it("accountName should return a persisted string value", function () { - // not very testy - deviceSettings.register("Account.accountName", "bigmac"); - expect(Account.accountName).toEqual("bigmac"); - }); - - it("accountId should return default control value", function () { - expect(Account.accountId).toEqual("someid"); - }); - - it("accountId should return a persisted string value", function () { - deviceSettings.register("Account.accountId", "whatup"); - expect(Account.accountId).toEqual("whatup"); - }); -}); diff --git a/test/unit/wac/AccountInfo.js b/test/unit/wac/AccountInfo.js deleted file mode 100644 index 92eb4aea..00000000 --- a/test/unit/wac/AccountInfo.js +++ /dev/null @@ -1,80 +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. - */ -describe("wac_AccountInfo", function () { - var AccountInfo = require('ripple/platform/wac/1.0/AccountInfo'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'); - - beforeEach(function () { - spyOn(platform, "current").andReturn({ - device: { - "AccountInfo": { - "phoneUserUniqueId": {control: {value: "id"}}, - "phoneMSISDN": {control: {value: "id"}}, - "phoneOperatorName": {control: {value: "none"}}, - "userSubscriptionType": {control: {value: "prepaid"}}, - "userAccountBalance": {control: {value: 5466}} - } - } - }); - }); - - it("phoneUserUniqueId should return default control", function () { - expect(AccountInfo.phoneUserUniqueId).toEqual("id"); - }); - - it("phoneUserUniqueId should return a persisted value", function () { - // not very testy - deviceSettings.register("AccountInfo.phoneUserUniqueId", "dude"); - expect(AccountInfo.phoneUserUniqueId).toEqual("dude"); - }); - - it("phoneMSISDN should return default control", function () { - expect(AccountInfo.phoneMSISDN).toEqual("id"); - }); - - it("phoneMSISDN should return a persisted value", function () { - deviceSettings.register("AccountInfo.phoneMSISDN", "MSISDN"); - expect(AccountInfo.phoneMSISDN).toEqual("MSISDN"); - }); - - it("phoneOperatorName should return a default control", function () { - expect(AccountInfo.phoneOperatorName).toEqual("none"); - }); - - it("phoneOperatorName should return a persisted value", function () { - deviceSettings.register("AccountInfo.phoneOperatorName", "your face"); - expect(AccountInfo.phoneOperatorName).toEqual("your face"); - }); - - it("userSubscriptionType should return a default control", function () { - expect(AccountInfo.userSubscriptionType).toEqual("prepaid"); - }); - - it("userSubscriptionType should return a persisted value", function () { - deviceSettings.register("AccountInfo.userSubscriptionType", "burlesque"); - expect(AccountInfo.userSubscriptionType).toEqual("burlesque"); - }); - - it("userAccountBalance should return a default control", function () { - expect(AccountInfo.userAccountBalance).toEqual(5466); - }); - - it("userAccountBalance should return a persisted value", function () { - deviceSettings.register("AccountInfo.userAccountBalance", 5555); - expect(AccountInfo.userAccountBalance).toEqual(5555); - }); -}); diff --git a/test/unit/wac/AddressBookItem.js b/test/unit/wac/AddressBookItem.js deleted file mode 100644 index febc5cb6..00000000 --- a/test/unit/wac/AddressBookItem.js +++ /dev/null @@ -1,202 +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. - */ -describe("wac_AddressBookItem", function () { - var AddressBookItem = require('ripple/platform/wac/1.0/AddressBookItem'), - db = require('ripple/db'), - constants = require('ripple/constants'), - sinon = require('sinon'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("we can create an address book item", function () { - expect(new AddressBookItem()).toBeTruthy(); - }); - - it("it is an instance of addressbook item", function () { - expect(new AddressBookItem() instanceof AddressBookItem).toEqual(true); - }); - - it("can set the value of a known attribute", function () { - var target = new AddressBookItem(); - target.setAttributeValue("title", "Overlord"); - expect(target.title).toEqual("Overlord"); - }); - - it("we can set the value of an unknown attribute", function () { - var target = new AddressBookItem(); - target.setAttributeValue("turnOns", "cheetos"); - expect(target.turnOns).toEqual("cheetos"); - }); - - it("it returns undefined for an attribute that doesn't exist", function () { - var target = new AddressBookItem(); - expect(target.turnOffs).toEqual(undefined); - }); - - it("we can get the value of a known attribute", function () { - var target = new AddressBookItem(); - target.fullName = "James Howlett"; - expect(target.getAttributeValue("fullName")).toEqual("James Howlett"); - }); - - it("we can get the value of an unknown attribute", function () { - var target = new AddressBookItem(); - target.fooodOrder = "wonton soup"; - expect(target.getAttributeValue("fooodOrder")).toEqual("wonton soup"); - }); - - it("getAttributeValue validates number of params(none)", function () { - expect(function () { - var target = new AddressBookItem(); - target.getAttributeValue(); - }).toThrow(); - }); - - it("getAttributeValue validates number of params(to many)", function () { - expect(function () { - var target = new AddressBookItem(); - target.getAttributeValue("foo", "bar"); - }).toThrow(); - }); - - it("getAttributeValue validates param, wrong type", function () { - expect(function () { - var target = new AddressBookItem(); - target.getAttributeValue({}); - }).toThrow(); - }); - - it("setAttributeValue validates number of params(none)", function () { - expect(function () { - var target = new AddressBookItem(); - target.setAttributeValue(); - }).toThrow(); - }); - - it("setAttributeValue validates number of params(to many)", function () { - expect(function () { - var target = new AddressBookItem(); - target.setAttributeValue("foo", "bar", 1); - }).toThrow(); - }); - - it("setAttributeValue validates param, wrong type", function () { - expect(function () { - var target = new AddressBookItem(); - target.setAttributeValue({}, "woot"); - }).toThrow(); - }); - - it("get available attributes returns default list", function () { - var target = new AddressBookItem(); - expect(target.getAvailableAttributes()).toEqual([ - "addressBookItemId", - "fullName", - "mobilePhone", - "homePhone", - "workPhone", - "eMail", - "company", - "title", - "address" - ].sort()); - }); - - it("get available attributes returns added params", function () { - var target = new AddressBookItem(); - target.setAttributeValue("woo", "hoo"); - expect(target.getAvailableAttributes()).toEqual([ - "addressBookItemId", - "fullName", - "woo", - "mobilePhone", - "homePhone", - "workPhone", - "eMail", - "company", - "title", - "address" - ].sort()); - }); - - it("get address group names throws an exception", function () { - var target = new AddressBookItem(); - expect(function () { - target.getAddressGroupNames(target); - }).toThrow(); - }); - - it("set address group names throws an exception", function () { - var target = new AddressBookItem(); - expect(function () { - target.setAddressGroupNames(target); - }).toThrow(); - }); - - it("calling update saves the item", function () { - var items = [ - new AddressBookItem(), - new AddressBookItem(), - new AddressBookItem() - ], - target = new AddressBookItem(); - - items[0].addressBookItemId = "1"; - items[1].addressBookItemId = "2"; - items[2].addressBookItemId = "3"; - - s.stub(db, "retrieveObject").returns(items); - - target.addressBookItemId = "2"; - target.title = "1984"; - - s.mock(db).expects("saveObject").withExactArgs( - constants.PIM.ADDRESS_LIST_KEY, [items[0], target, items[2]]).once(); - - target.update(); - }); - - it("calling update on an item that doesn't exist throws an exception", function () { - var items = [ - new AddressBookItem(), - new AddressBookItem(), - new AddressBookItem() - ], - target = new AddressBookItem(); - - items[0].addressBookItemId = "1"; - items[1].addressBookItemId = "2"; - items[2].addressBookItemId = "3"; - - s.stub(db, "retrieveObject").returns(items); - - target.addressBookItemId = "4"; - target.title = "1984"; - - s.mock(db).expects("saveObject").never(); - - expect(function () { - target.update(target); - }).toThrow(); - }); -}); diff --git a/test/unit/wac/AudioPlayer.js b/test/unit/wac/AudioPlayer.js deleted file mode 100644 index f4e57f1e..00000000 --- a/test/unit/wac/AudioPlayer.js +++ /dev/null @@ -1,293 +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. - */ -describe("wac_AudioPlayer", function () { - var platform = require('ripple/platform'), - event = require('ripple/event'), - _console = require('ripple/console'), - fileSystem = require('ripple/fileSystem'), - AudioPlayer = require('ripple/platform/wac/1.0/AudioPlayer'), - sinon = require('sinon'), - s, - audioNode = document.getElementById("multimedia-audio"), - AUDIO_FILE = "../../audio.mp3"; - - beforeEach(function () { - s = sinon.sandbox.create(); - spyOn(platform, "current").andReturn({name: "default"}); - - audioNode.canPlayType = function () { - return "probably"; - }; - - // think jsdom does not have special methods like play on audio - audioNode.play = function () {}; - audioNode.pause = function () {}; - audioNode.stop = function () {}; - audioNode.load = function () {}; - - //just hack this out since we don't need the functionality for our tests - audioNode.addEventListener = function () {}; - }); - - afterEach(function () { - s.verifyAndRestore(); - //HACK: this is a hack in that we want to reset the state between tests. - AudioPlayer.onStateChange = null; - event.trigger("MultimediaAudioStateChanged", [null], true); - }); - - // -------- open - - it("open throws invalid param when given invalid fileUrl", function () { - expect(function () { - AudioPlayer.open(false); - }).toThrow(); - }); - - it("open throws invalid param when given invalid number of arguments", function () { - expect(function () { - AudioPlayer.open(); - }).toThrow(); - }); - - it("open throws method not implemented when opening rtsp scheme", function () { - expect(function () { - AudioPlayer.open("rtsp://some/file.mp3"); - }).toThrow(); - }); - - it("open sets audio tag src attribute", function () { - s.mock(audioNode).expects("load").once(); - AudioPlayer.open(AUDIO_FILE); - expect(audioNode.getAttribute("src")).toEqual(AUDIO_FILE); - }); - - it("open washes file url for virtual direcories", function () { - s.mock(fileSystem).expects("getURI").once().withExactArgs(AUDIO_FILE).returns(AUDIO_FILE); - AudioPlayer.open(AUDIO_FILE); - }); - - // ------- invalid state checks - // TODO: this could be a lot more tight (test every state case) - - it("open warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.open(AUDIO_FILE); - }); - - it("play warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - s.mock(audioNode).expects("play").never(); - AudioPlayer.play(1); - }); - - it("pause warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - AudioPlayer.open(AUDIO_FILE); - s.mock(audioNode).expects("pause").never(); - AudioPlayer.pause(); - }); - - it("resume warns to console when called from invalid state", function () { - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - s.mock(audioNode).expects("play").never(); - s.mock(_console).expects("warn").once(); - AudioPlayer.resume(); - }); - - it("stop warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - AudioPlayer.open(AUDIO_FILE); - s.mock(audioNode).expects("pause").never(); - AudioPlayer.stop(); - }); - - // -------- play - - it("play throws invalid param when given invalid number of plays (negative integer)", function () { - expect(function () { - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(-7); - }).toThrow(); - }); - - it("play throws invalid param when given invalid number of plays (boolean)", function () { - expect(function () { - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(false); - }).toThrow(); - }); - - it("play throws invalid param when given invalid number of plays (string)", function () { - expect(function () { - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play("what up dawg"); - }).toThrow(); - }); - - it("play throws invalid param when given invalid number of arguments", function () { - expect(function () { - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1, 2); - }).toThrow(); - - expect(function () { - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(); - }).toThrow(); - }); - - // -------- integration - - it("play initiates play on audio tag", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - s.mock(audioNode).expects("play").once(); - AudioPlayer.play(1); - }); - - it("pause initiates pause on audio tag", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - s.mock(audioNode).expects("pause").once(); - AudioPlayer.pause(); - }); - - it("resume initiates pause on audio tag", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.pause(); - s.mock(audioNode).expects("play").once(); - AudioPlayer.resume(); - }); - - it("stop initiates pause on audio tag", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - s.mock(audioNode).expects("pause").once(); - AudioPlayer.stop(); - }); - - it("open triggers state change event", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.onStateChange = s.mock().once().withExactArgs("opened"); - AudioPlayer.open(AUDIO_FILE); - }); - - it("play triggers state change event", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.onStateChange = s.mock().once().withExactArgs("playing"); - AudioPlayer.play(1); - }); - - it("play does not trigger state change event when give 0 number of play times", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.onStateChange = s.mock().never(); - AudioPlayer.play(0); - }); - - it("pause triggers state change event", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.onStateChange = s.mock().once().withExactArgs("paused"); - AudioPlayer.pause(); - }); - - it("resume triggers state change event", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.pause(); - - AudioPlayer.onStateChange = s.mock().once().withExactArgs("playing"); - AudioPlayer.resume(); - }); - - it("stop triggers state change event", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.pause(); - AudioPlayer.resume(); - - AudioPlayer.onStateChange = s.mock().once().withExactArgs("stopped"); - AudioPlayer.stop(); - }); - - // TODO: mock fire ended event and mock onStateChange - //"test triggers completed state change event when audio ends": function () {}, - - it("object flow executes without any invalid state warnings", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.pause(); - AudioPlayer.resume(); - AudioPlayer.stop(); - }); - - it("object flow is reusable", function () { - s.mock(_console).expects("warn").never(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.pause(); - AudioPlayer.resume(); - AudioPlayer.stop(); - - AudioPlayer.open(AUDIO_FILE); - AudioPlayer.play(1); - AudioPlayer.pause(); - AudioPlayer.resume(); - AudioPlayer.stop(); - }); - - // -------- codec/container handling - - it("open should warn when given unsupported codecs/containers", function () { - s.mock(_console).expects("warn").atLeast(1); - audioNode.canPlayType = function () { - return ""; - }; - AudioPlayer.open("audio.dude"); - }); - - // possibly useless since canPlayType is mocked - it("open should not raise notification when given supported codecs/containers (flv)", function () { - s.mock(_console).expects("warn").never(); - AudioPlayer.open("audio.mp3"); - }); -}); diff --git a/test/unit/wac/CalendarItem.js b/test/unit/wac/CalendarItem.js deleted file mode 100644 index a3cbb33d..00000000 --- a/test/unit/wac/CalendarItem.js +++ /dev/null @@ -1,87 +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. - */ -describe("wac_CalendarItem", function () { - var CalendarItem = require('ripple/platform/wac/1.0/CalendarItem'), - db = require('ripple/db'), - constants = require('ripple/constants'), - sinon = require('sinon'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("can create a CalendarItem", function () { - expect(new CalendarItem()).not.toEqual(null); - }); - - it("it is an instance of CalendarItem", function () { - expect(new CalendarItem() instanceof CalendarItem).toEqual(true); - }); - - describe("update", function () { - it("saves the item", function () { - var items = [ - new CalendarItem(), - new CalendarItem(), - new CalendarItem() - ], - target = new CalendarItem(); - - items[0].calendarItemId = "1"; - items[1].calendarItemId = "2"; - items[2].calendarItemId = "3"; - - s.stub(db, "retrieveObject").returns(items); - - target.calendarItemId = "2"; - target.eventNotes = "It puts the lotion in the basket"; - - s.mock(db).expects("saveObject").withExactArgs( - constants.PIM.CALENDAR_LIST_KEY, [items[0], target, items[2]]).once(); - - target.update(); - }); - - it("calling update on an item that doesn't exist throws an exception", function () { - var items = [ - new CalendarItem(), - new CalendarItem(), - new CalendarItem() - ], - target = new CalendarItem(); - - items[0].calendarItemId = "1"; - items[1].calendarItemId = "2"; - items[2].calendarItemId = "3"; - - s.stub(db, "retrieveObject").returns(items); - - target.calendarItemId = "4"; - target.eventNotes = "or else it gets the hose again"; - - s.mock(db).expects("saveObject").never(); - - expect(function () { - target.update(target); - }).toThrow(); - }); - }); -}); diff --git a/test/unit/wac/Camera.js b/test/unit/wac/Camera.js deleted file mode 100644 index 47dc8f41..00000000 --- a/test/unit/wac/Camera.js +++ /dev/null @@ -1,186 +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. - */ -describe("wac_Camera", function () { - - var camera = require('ripple/platform/wac/1.0/Camera'), - platform = require('ripple/platform'), - notifications = require('ripple/notifications'), - utils = require('ripple/utils'), - fileSystem = require('ripple/fileSystem'), - _console = require('ripple/console'), - domNode, - sinon = require('sinon'), - s; - - beforeEach(function () { - spyOn(_console, "log"); - s = sinon.sandbox.create(); - domNode = document.createElement("div"); - domNode.innerHTML = ""; - spyOn(platform, "current").andReturn({name: "default"}); - - document.querySelector = function (sel) { - return document.createElement("div"); - }; - camera.setWindow(domNode); - }); - - afterEach(function () { - s.verifyAndRestore(); - camera.onCameraCaptured = null; - }); - - it("setWindow does not throw invalid param exception when given null", function () { - expect(function () { - camera.setWindow(null); - }).not.toThrow(); - }); - - it("setWindow sets a img and a button div inside a dom object", function () { - expect(domNode.childNodes.length).toEqual(2); - var imageNode = domNode.childNodes[0], - buttonNode = domNode.childNodes[1]; - expect("img").toEqual(imageNode.tagName.toLowerCase(), "expected img tag name"); - expect("div").toEqual(buttonNode.tagName.toLowerCase(), "expected div tag name"); - }); - - it("setWindow only sets one img in the dom object", function () { - camera.setWindow(domNode); - expect(domNode.childNodes.length).toEqual(2); - }); - - it("setWindow dissociates canvas from a set dom object", function () { - camera.setWindow(null); - expect(domNode.childNodes.length).toEqual(0); - }); - - it("it throws an exception when no file name provided", function () { - expect(camera.captureImage).toThrow(); - }); - - it("when capturing an image it shows a notification", function () { - s.mock(fileSystem).expects("override").never(); - s.mock(notifications).expects("openNotification").once(); - camera.captureImage("foo.png", false); - }); - - it("when capturing an image it raises the onCameraCaptured event", function () { - s.stub(notifications, "openNotification"); - camera.onCameraCaptured = s.mock().withExactArgs("foo.png").once(); - camera.captureImage("foo.png", false); - }); - - it("it returns the path of the saved image", function () { - s.stub(notifications, "openNotification"); - camera.onCameraCaptured = s.mock().withExactArgs("foo.png").once(); - var path = camera.captureImage("foo.png", false); - - expect("foo.png").toEqual(path); - }); - - it("we can call start video capture and it fires the onCameraCaptured event after the max duration seconds", function () { - //make test teh faster - spyOn(utils, "validateMultipleArgumentTypes"); - - s.stub(notifications, "openNotification"); - - var start = new Date(), - end; - - camera.onCameraCaptured = function (file) { - end = new Date(); - expect(file).toEqual("foo.avi"); - }; - - runs(function () { - camera.startVideoCapture("foo.avi", false, 0.01, false); - }); - waits(11); - runs(function () { - expect(end - start).toBeGreaterThan(9); - }); - }); - - it("it returns the path when calling startVideoCapture", function () { - var path = camera.startVideoCapture("videos/hot_date.avi", false, 1, false); - camera.stopVideoCapture(); - expect("videos/hot_date.avi").toEqual(path); - }); - - it("when capturing a video it overrides the file", function () { - //make test teh faster - spyOn(utils, "validateMultipleArgumentTypes"); - - s.mock(fileSystem).expects("override").never(); - s.mock(notifications).expects("openNotification").once(); - - camera.startVideoCapture("foo.avi", false, 0.01, false); - - waits(11); - }); - - it("we can end capturing a video early and we only get one callback invoked", function () { - - //make test teh faster - spyOn(utils, "validateMultipleArgumentTypes"); - s.stub(notifications, "openNotification"); - - camera.onCameraCaptured = s.mock().once(); - camera.startVideoCapture("foo.avi", false, 0.01, false); - camera.stopVideoCapture(); - - waits(11); - - }); - - it("we can call stop video capture without starting", function () { - camera.onCameraCaptured = s.mock().never(); - camera.stopVideoCapture(); - }); - - it("we can call stop video capture twice and it doesn't call the callback twice", function () { - s.stub(notifications, "openNotification"); - camera.startVideoCapture("foo.avi", false, 10, false); - camera.stopVideoCapture(); - camera.onCameraCaptured = s.mock().never(); - camera.stopVideoCapture(); - }); - - it("it should not show the buttons if we pass in false for showDefaultControls", function () { - camera.startVideoCapture("foo.avi", false, 10, false); - expect(domNode.childNodes[1].getAttribute("style")).toBeTruthy(); - camera.stopVideoCapture(); - }); - - it("it should show the buttons if we pass in true for showDefaultControls", function () { - camera.startVideoCapture("foo.avi", false, 10, true); - expect(domNode.childNodes[1].getAttribute("style")).toBeFalsy(); - camera.stopVideoCapture(); - }); - - it("it should hide the buttons when we call stop video capture", function () { - camera.startVideoCapture("foo.avi", false, 10, true); - camera.stopVideoCapture(); - expect(domNode.childNodes[1].getAttribute("style")).toBeTruthy(); - }); - - it("we can remove the window while recording a video and calling stop doesn't throw an error", function () { - camera.startVideoCapture("foo.avi", false, 10, true); - camera.setWindow(null); - camera.stopVideoCapture(); - }); - -}); diff --git a/test/unit/wac/Config.js b/test/unit/wac/Config.js deleted file mode 100644 index e4d38665..00000000 --- a/test/unit/wac/Config.js +++ /dev/null @@ -1,81 +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. - */ -describe("wac_Config", function () { - var Config = require('ripple/platform/wac/1.0/Config'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'); - - beforeEach(function () { - spyOn(platform, "current").andReturn({ - device: { - "Config": { - "msgRingtoneVolume": {control: {value: 5}}, - "ringtoneVolume": {control: {value: 3}}, - "vibrationSetting": {control: {value: "off"}} - } - } - }); - }); - - it("msgRingtoneVolume should return a default control value", function () { - expect(Config.msgRingtoneVolume).toEqual(5); - }); - - it("msgRingtoneVolume should return a registered value", function () { - deviceSettings.register("Config.msgRingtoneVolume", 7); - expect(Config.msgRingtoneVolume).toEqual(7); - deviceSettings.register("Config.msgRingtoneVolume", null); - }); - - it("ringtoneVolume should by default return default control", function () { - expect(Config.ringtoneVolume).toEqual(3); - }); - - it("ringtoneVolume shuold return a registered value", function () { - deviceSettings.register("Config.ringtoneVolume", 2); - expect(Config.ringtoneVolume).toEqual(2); - deviceSettings.register("Config.ringtoneVolume", null); - }); - - it("vibrationSetting should by default return default control", function () { - expect(Config.vibrationSetting).toEqual("off"); - }); - - it("vibrationSetting should return a registered valid string", function () { - deviceSettings.register("Config.vibrationSetting", "on"); - expect(Config.vibrationSetting).toEqual("on"); - deviceSettings.register("Config.vibrationSetting", null); - }); - - it("setDefaultRingtone throws no exception when valid call", function () { - expect(function () { - Config.setDefaultRingtone("/some/path"); - }).not.toThrow(); - }); - - it("setDefaultRingtone should throw a exception when invalid paramter is passed", function () { - var caught = false; - try { - Config.setDefaultRingtone(5); - } catch (e) { - if (e.name === ExceptionTypes.INVALID_PARAMETER || e.type === ExceptionTypes.INVALID_PARAMETER) { - caught = true; - } - } - expect(caught).toEqual(true); - }); -}); diff --git a/test/unit/wac/DataNetworkInfo.js b/test/unit/wac/DataNetworkInfo.js deleted file mode 100644 index 6ee680a1..00000000 --- a/test/unit/wac/DataNetworkInfo.js +++ /dev/null @@ -1,79 +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. - */ -describe("wac_DataNetworkInfo", function () { - var DataNetworkInfo = require('ripple/platform/wac/1.0/DataNetworkInfo'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'), - _console = require('ripple/console'), - event = require('ripple/event'); - - beforeEach(function () { - spyOn(platform, "current").andReturn({ - name: "default", - device: { - "DataNetworkInfo": { - "isDataNetworkConnected": {control: {value: false}}, - "networkConnectionType": {control: {value: ["dude"]}} - } - } - }); - }); - - describe("isDataNetworkConnected", function () { - it("isDataNetworkConnected should return a default control value", function () { - expect(DataNetworkInfo.isDataNetworkConnected).toEqual(false); - }); - - it("isDataNetworkConnected should return a registered boolean value", function () { - deviceSettings.register("DataNetworkInfo.isDataNetworkConnected", true); - expect(DataNetworkInfo.isDataNetworkConnected).toEqual(true); - }); - }); - - describe("networkConnectionType", function () { - it("should return a valid array of values", function () { - expect(DataNetworkInfo.networkConnectionType).toEqual(["dude"]); - }); - - it("should invoke onNetworkConnectionChanged when changed", function () { - var connectionType = ["EDGE"]; - spyOn(_console, "log"); - DataNetworkInfo.onNetworkConnectionChanged = jasmine.createSpy(); - event.trigger("DataNetworkConnectionChanged", connectionType, true); - expect(DataNetworkInfo.onNetworkConnectionChanged).toHaveBeenCalled(); - }); - }); - - describe("getNetworkConnectionName", function () { - it("throws INVALID_PARAMETER exception when invalid argument types", function () { - spyOn(_console, "log"); - expect(function () { - DataNetworkInfo.getNetworkConnectionName(60); - }).toThrow(function (e) { - return e.type === ExceptionTypes.INVALID_PARAMETER; - }); - }); - - it("returns a default control", function () { - expect(DataNetworkInfo.getNetworkConnectionName("wifi")).toEqual("WIFI"); - }); - - it("returns a null when non valid connection name", function () { - expect(DataNetworkInfo.getNetworkConnectionName("foo")).toEqual(null); - }); - }); -}); diff --git a/test/unit/wac/Device.js b/test/unit/wac/Device.js deleted file mode 100644 index 603d92e7..00000000 --- a/test/unit/wac/Device.js +++ /dev/null @@ -1,41 +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. - */ -describe("wac_Device", function () { - var Device = require('ripple/platform/wac/1.0/Device'), - ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'); - - function anInvalidParameterException(e) { - return e.type === ExceptionTypes.INVALID_PARAMETER; - } - - it("getAvailableApplications should return a valid non empty array", function () { - var arr = Device.getAvailableApplications(); - expect(arr instanceof Array).toEqual(true); - expect(arr.length > 0).toEqual(true); - }); - - it("vibrate should throw exception when not passed a valid start time", function () { - expect(function () { - Device.vibrate(); - }).toThrow(anInvalidParameterException); - }); - - it("vibrate should call successfully", function () { - expect(function () { - Device.vibrate(50); - }).not.toThrow(); - }); -}); diff --git a/test/unit/wac/DeviceInfo.js b/test/unit/wac/DeviceInfo.js deleted file mode 100644 index df00bbba..00000000 --- a/test/unit/wac/DeviceInfo.js +++ /dev/null @@ -1,88 +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. - */ -describe("wac_DeviceInfo", function () { - - var DeviceInfo = require('ripple/platform/wac/1.0/DeviceInfo'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'), - devices = require('ripple/devices'), - HVGA = require('ripple/devices/HVGA'); - - beforeEach(function () { - spyOn(platform, "current").andReturn({ - device: { - "DeviceInfo": { - "phoneColorDepthDefault": {control: {value: 32}}, - "totalMemory": {control: {value: 128}} - } - } - }); - }); - - it("phoneColorDepthDefault returns the current default color depth", function () { - var value = DeviceInfo.phoneColorDepthDefault; - expect(value).toEqual(32); - }); - - it("phoneColorDepthDefault returns the current 'persisted' device's default color depth", function () { - deviceSettings.register("DeviceInfo.phoneColorDepthDefault", 545454); - expect(DeviceInfo.phoneColorDepthDefault).toEqual(545454); - }); - - it("totalMemory returns the current device's memory", function () { - expect(DeviceInfo.totalMemory).toEqual(128); - }); - - it("totalMemory returns the current registered device total memory", function () { - deviceSettings.register("DeviceInfo.totalMemory", 6666); - expect(DeviceInfo.totalMemory).toEqual(6666); - }); - - it("phoneOS returns the current device's os", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneOS).toEqual(HVGA.osName + " " + HVGA.osVersion); - }); - - it("phoneManufacturer returns the current device's manufacturer", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneManufacturer).toEqual(HVGA.manufacturer); - }); - - it("phoneFirmware returns the current device's os firmware version", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneFirmware).toEqual(HVGA.firmware); - }); - - it("phoneModel returns the current device's model", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneModel).toEqual(HVGA.model); - }); - - it("phoneScreenHeightDefault returns the current pixel height of the device's primary screen", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneScreenHeightDefault).toEqual(HVGA.screen.height); - }); - - it("phoneScreenWidthDefault returns the current pixel width of the device's primary screen", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneScreenWidthDefault).toEqual(HVGA.screen.width); - }); - - it("phoneSoftware returns the current default software version", function () { - spyOn(devices, "getCurrentDevice").andReturn(HVGA); - expect(DeviceInfo.phoneSoftware).toEqual(HVGA.osVersion); - }); -}); diff --git a/test/unit/wac/DeviceStateInfo.js b/test/unit/wac/DeviceStateInfo.js deleted file mode 100644 index 62c46f3f..00000000 --- a/test/unit/wac/DeviceStateInfo.js +++ /dev/null @@ -1,152 +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. - */ -describe("wac_DeviceStateInfo", function () { - var DeviceStateInfo = require('ripple/platform/wac/1.0/DeviceStateInfo'), - sinon = require('sinon'), - event = require('ripple/event'), - deviceSettings = require('ripple/deviceSettings'), - platform = require('ripple/platform'), - _console = require('ripple/console'), - s; - - beforeEach(function () { - spyOn(_console, "log"); - s = sinon.sandbox.create(); - spyOn(platform, "current").andReturn({ - name: "default", - device: { - DeviceStateInfo: { - language: {control: {value: "en"}}, - availableMemory: {control: {value: 256}} - } - } - }); - - deviceSettings.initialize(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - describe("language", function () { - it("should return the default control value", function () { - expect(DeviceStateInfo.language).toEqual("en"); - }); - - it("should return the current 'persisted' device's language", function () { - deviceSettings.register("DeviceStateInfo.availableMemory", 66666); - var value = DeviceStateInfo.availableMemory; - expect(value).toEqual(66666); - }); - }); - - describe("availableMemory", function () { - it("should return the current device's available memory", function () { - var value = DeviceStateInfo.availableMemory; - expect(value).toBeGreaterThan(0); - }); - - it("should return the current 'persisted' device's available memory", function () { - deviceSettings.register("DeviceStateInfo.availableMemory", 66666); - var value = DeviceStateInfo.availableMemory; - expect(value).toEqual(66666); - }); - }); - - describe("keypadLightOn", function () { - it("should return the current 'persisted' device's key pad on boolean", function () { - deviceSettings.register("DeviceStateInfo.keypadLightOn", true); - var value = DeviceStateInfo.keypadLightOn; - expect(value).toBeTruthy(); - }); - - it("should return the current 'persisted' device's back light on boolean", function () { - deviceSettings.register("DeviceStateInfo.backLightOn", true); - var value = DeviceStateInfo.backLightOn; - expect(value).toBeTruthy(); - }); - }); - - describe("requestPositionInfo", function () { - it("validates argument length", function () { - expect(function () { - DeviceStateInfo.requestPositionInfo(); - }).toThrow(); - }); - - it("validates argument", function () { - expect(function () { - DeviceStateInfo.requestPositionInfo("abcdef"); - }).toThrow(); - }); - - it("accepts expected argument", function () { - expect(function () { - DeviceStateInfo.requestPositionInfo(""); - DeviceStateInfo.requestPositionInfo("gps"); - }).toThrow(); - }); - - it("calls onPositionRetrieved with empty positionInfo when time out", function () { - runs(function () { - var geo = require('ripple/geo'), - utils = require('ripple/utils'), - origTimeout = geo.timeout; - - geo.timeout = true; - - DeviceStateInfo.onPositionRetrieved = function (pos) { - expect(pos).toBeDefined(); - - utils.forEach(pos, function (prop) { - expect(prop).not.toBeDefined(); - }); - }; - - DeviceStateInfo.requestPositionInfo("gps"); - geo.timeout = origTimeout; - }); - }); - }); - - describe("audioPath", function () { - it("should return the current 'persisted' device's audio path", function () { - deviceSettings.register("DeviceStateInfo.audioPath", "WHATUP"); - var value = DeviceStateInfo.audioPath; - expect(value).toEqual("WHATUP"); - }); - }); - - describe("processorUtilizationPercent", function () { - it("should return the current 'persisted' cpu percentage", function () { - deviceSettings.register("DeviceStateInfo.processorUtilizationPercent", "500%"); - var value = DeviceStateInfo.processorUtilizationPercent; - expect(value).toEqual("500%"); - }); - }); - - describe("onScreenChangeDimensions", function () { - it("should fire when the screen changes dimensions", function () { - DeviceStateInfo.onScreenChangeDimensions = s.mock().once().withExactArgs(480, 800); - event.trigger("ScreenChangeDimensions", [480, 800]); - waits(1); - runs(function () { - DeviceStateInfo.onScreenChangeDimensions = null; - }); - }); - }); -}); diff --git a/test/unit/wac/Message.js b/test/unit/wac/Message.js deleted file mode 100644 index bbb7f38c..00000000 --- a/test/unit/wac/Message.js +++ /dev/null @@ -1,34 +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. - */ -describe("wac_Message", function () { - - var s, - sinon = require('sinon'), - Message = require('ripple/platform/wac/1.0/Message'); - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("it is an instance of message", function () { - expect(new Message() instanceof Message).toEqual(true); - }); - -}); diff --git a/test/unit/wac/Messaging.js b/test/unit/wac/Messaging.js deleted file mode 100644 index c70abe41..00000000 --- a/test/unit/wac/Messaging.js +++ /dev/null @@ -1,116 +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. - */ -describe("wac_Messaging", function () { - var messaging = require('ripple/platform/wac/1.0/Messaging'), - Message = require('ripple/platform/wac/1.0/Message'), - platform = require('ripple/platform'), - notifications = require('ripple/notifications'), - constants = require('ripple/constants'), - _console = require('ripple/console'), - MessageTypes = require('ripple/platform/wac/1.0/MessageTypes'), - sinon = require('sinon'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - spyOn(_console, "log"); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("is a message returned on create", function () { - var msg = messaging.createMessage(MessageTypes.SMSMessage); - expect(msg.messageType).toEqual(MessageTypes.SMSMessage, "The message isn't the right type"); - }); - - it("is a message sent on send", function () { - var text, - msg = new Message(); - - msg.messageType = MessageTypes.SMSMessage; - msg.messageId = 1; - msg.destinationAddress = "1234567890"; - text = "Sent " + msg.messageType + " " + msg.messageId + " to " + msg.destinationAddress; - - spyOn(platform, "current").andReturn({name: "whatup"}); - s.mock(notifications).expects("openNotification") - .withExactArgs(constants.NOTIFICATIONS.TYPES.NORMAL, text).once(); - - messaging.sendMessage(msg); - }); - - it("send throws invalid parameter when not passed a message object", function () { - expect(function () { - messaging.sendMessage({}); - }).toThrow(); - }); - - it("it can't add an address for something weird", function () { - var msg = new Message(); - msg.addAddress("FOOOBAR", "5199541707"); - expect(msg.FOOOBAR).not.toBeDefined(); - }); - - it("it can add the destination address", function () { - var msg = new Message(); - msg.addAddress("destination", "5199541707"); - expect(msg.destinationAddress[0]).toEqual("5199541707"); - }); - - it("it can add a couple destination addresses", function () { - var msg = new Message(); - msg.addAddress("destination", "5199541707;2269297927"); - expect(msg.destinationAddress[0]).toEqual("5199541707"); - expect(msg.destinationAddress[1]).toEqual("2269297927"); - }); - - it("it can add the cc address", function () { - var msg = new Message(); - msg.addAddress("cc", "5199541707"); - expect(msg.ccAddress[0]).toEqual("5199541707"); - }); - - it("it can add a couple cc addresses", function () { - var msg = new Message(); - msg.addAddress("cc", "5199541707;2269297927"); - expect(msg.ccAddress[0]).toEqual("5199541707"); - expect(msg.ccAddress[1]).toEqual("2269297927"); - }); - - it("it can add the bcc address", function () { - var msg = new Message(); - msg.addAddress("bcc", "5199541707"); - expect(msg.bccAddress[0]).toEqual("5199541707"); - }); - - it("it can add a couple bcc addresses", function () { - var msg = new Message(); - msg.addAddress("bcc", "5199541707;2269297927"); - expect(msg.bccAddress[0]).toEqual("5199541707"); - expect(msg.bccAddress[1]).toEqual("2269297927"); - }); - - it("it can delete a bcc address", function () { - var msg = new Message(); - msg.addAddress("bcc", "5199541707;2269297927"); - msg.deleteAddress("bcc", "2269297927"); - - expect(msg.bccAddress.length).toEqual(1); - expect(msg.bccAddress[0]).toEqual("5199541707"); - }); -}); diff --git a/test/unit/wac/Multimedia.js b/test/unit/wac/Multimedia.js deleted file mode 100644 index 9b36c5bd..00000000 --- a/test/unit/wac/Multimedia.js +++ /dev/null @@ -1,63 +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. - */ -describe("wac_Multimedia", function () { - - var Multimedia = require('ripple/platform/wac/1.0/Multimedia'), - AudioPlayer = require('ripple/platform/wac/1.0/AudioPlayer'), - VideoPlayer = require('ripple/platform/wac/1.0/VideoPlayer'), - event = require('ripple/event'); - - // -------- getVolume - - it("getVolume should return a number between zero and ten", function () { - event.trigger("MultimediaVolumeChanged", [7]); - waits(1); - runs(function () { - expect(Multimedia.getVolume()).toEqual(7); - }); - }); - - // -------- stopAll - - it("stopAll stops both audio and video modules", function () { - spyOn(VideoPlayer, "stop"); - spyOn(AudioPlayer, "stop"); - Multimedia.stopAll(); - expect(VideoPlayer.stop).toHaveBeenCalled(); - expect(AudioPlayer.stop).toHaveBeenCalled(); - }); - - // -------- isAudioPlaying - - it("isAudioPlaying returns false when not playing", function () { - event.trigger("MultimediaAudioStateChanged", ["playing"]); - waits(1); - runs(function () { - expect(Multimedia.isAudioPlaying).toEqual(true); - }); - }); - - // -------- isVideoPlaying - - it("isVideoPlaying returns false when not playing", function () { - event.trigger("MultimediaVideoStateChanged", ["playing"]); - waits(1); - runs(function () { - expect(Multimedia.isVideoPlaying).toEqual(true); - }); - }); - -}); diff --git a/test/unit/wac/PIM.js b/test/unit/wac/PIM.js deleted file mode 100644 index 1b66d69f..00000000 --- a/test/unit/wac/PIM.js +++ /dev/null @@ -1,867 +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. - */ -describe("wac_PIM", function () { - - var pim = require('ripple/platform/wac/1.0/PIM'), - sinon = require('sinon'), - CalendarItem = require('ripple/platform/wac/1.0/CalendarItem'), - AddressBookItem = require('ripple/platform/wac/1.0/AddressBookItem'), - constants = require('ripple/constants'), - db = require('ripple/db'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("createAddressBookItem returns an empty AddressBookItem", function () { - expect(pim.createAddressBookItem() instanceof AddressBookItem).toEqual(true); - }); - - it("getAddressBookItem returns the item for the given ID", function () { - var items = [ - {addressBookItemId: "1"}, - {addressBookItemId: "2"}, - {addressBookItemId: "3"} - ]; - - s.stub(db, "retrieveObject").returns(items); - expect(pim.getAddressBookItem("2").addressBookItemId).toEqual(items[1].addressBookItemId); - }); - - it("getAddressBookItem returns null when no items match the given ID", function () { - s.stub(db, "retrieveObject").returns([]); - expect(pim.getAddressBookItem("2")).toBeNull(); - }); - - it("getAddressBookItem returns null when nothing returned from persistence", function () { - s.stub(db, "retrieveObject").returns(undefined); - expect(pim.getAddressBookItem("2")).toBeNull(); - }); - - it("getAddressBookItemsCount returns the count of items", function () { - var items = [ - {addressBookItemId: "a"}, - {addressBookItemId: "b"}, - {addressBookItemId: "c"} - ]; - - s.stub(db, "retrieveObject").returns(items); - expect(pim.getAddressBookItemsCount()).toEqual(items.length); - }); - - it("getAddressBookItemsCount returns 5 when persitence returns undefined", function () { - //this is because of the default contacts ;) - s.stub(db, "retrieveObject").returns(undefined); - s.mock(db).expects("saveObject").once(); - - expect(pim.getAddressBookItemsCount()).toEqual(5); - }); - - it("addAddressBookItem should add an item to the persisted list", function () { - var items = [], - added = new AddressBookItem(); - - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.ADDRESS_LIST_KEY, [added]); - - pim.addAddressBookItem(added); - }); - - it("addAddressBookItem should set id if none provided", function () { - var items = [], - added = new AddressBookItem(); - - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.ADDRESS_LIST_KEY, [added]); - - pim.addAddressBookItem(added); - expect(added.addressBookItemId).toBeTruthy(); - }); - - it("addAddressBookItem should not set id if one is provided", function () { - var items = [], - added = new AddressBookItem(), - id = "AF7492"; - - added.addressBookItemId = id; - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.ADDRESS_LIST_KEY, [added]); - - pim.addAddressBookItem(added); - expect(added.addressBookItemId).toEqual(id); - }); - - it("addAddressBookItem throws an exception when passed in a null item", function () { - expect(function () { - var foo = null; - pim.addAddressBookItem(foo); - }).toThrow(); - }); - - it("addAddressBookItem throws an exception when passed in an invalid address book item", function () { - expect(function () { - pim.addAddressBookItem({ - title: "", - address: "" - }); - }).toThrow(); - }); - - it("deleteAddressBookItem should remove an item from the persisted list", function () { - var items = [ - {addressBookItemId: "a"}, - {addressBookItemId: "b"}, - {addressBookItemId: "c"} - ]; - - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.ADDRESS_LIST_KEY, [items[0], items[2]]); - - pim.deleteAddressBookItem("b"); - }); - - it("deleteAddressBookItem shouldn't delete if not match found", function () { - var items = [ - {addressBookItemId: "a"}, - {addressBookItemId: "b"}, - {addressBookItemId: "c"} - ]; - - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.ADDRESS_LIST_KEY, items); - - pim.deleteAddressBookItem("d"); - }); - - it("should raise the onAddressBookItemsFound event when searching", function () { - s.stub(db, "retrieveObject").returns([]); - s.stub(db, "saveObject"); - - pim.onAddressBookItemsFound = s.mock().withExactArgs([]).once(); - pim.findAddressBookItems({title: "Dr"}, 0, 1); - }); - - it("should be able to search for addressBookItemId", function () { - var items = [ - {addressBookItemId: "a"}, - {addressBookItemId: "b"}, - {addressBookItemId: "c"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({addressBookItemId: "b"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - - expect(result.length).toEqual(1); - expect(result[0].addressBookItemId).toEqual("b"); - }); - - it("should be able to search for fullName", function () { - var items = [ - {fullName: "Gord"}, - {fullName: "Steph"}, - {fullName: "Gwen"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gwen"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - - expect(result.length).toEqual(1); - expect(result[0].fullName).toEqual("Gwen"); - }); - - it("should be able to search for a blank fullName", function () { - var items = [ - {fullName: "Gord"}, - {fullName: "Steph"}, - {fullName: "", mobilePhone: "555-1234"}, - {fullName: "Gwen"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: ""}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].mobilePhone).toEqual("555-1234"); - expect(result[0].fullName).toEqual(""); - }); - - it("should be able to search for mobilePhone", function () { - var items = [ - {mobilePhone: "555-1234"}, - {mobilePhone: "555-2222"}, - {mobilePhone: "555-2222"}, - {mobilePhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({mobilePhone: "555-1234"}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].mobilePhone).toEqual("555-1234"); - expect(result[1].mobilePhone).toEqual("555-1234"); - }); - - it("should be able to search for a blank mobilePhone", function () { - var items = [ - {mobilePhone: "555-1234"}, - {mobilePhone: "555-2222"}, - {mobilePhone: ""}, - {mobilePhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({mobilePhone: ""}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].mobilePhone).toEqual(""); - }); - - it("should be able to search for homePhone", function () { - var items = [ - {homePhone: "555-1234"}, - {homePhone: "555-2222"}, - {homePhone: "555-2222"}, - {homePhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({homePhone: "555-2222"}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].homePhone).toEqual("555-2222"); - expect(result[1].homePhone).toEqual("555-2222"); - }); - - it("should be able to search for a blank homePhone", function () { - var items = [ - {homePhone: "555-1234"}, - {homePhone: ""}, - {homePhone: "555-2222"}, - {homePhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({homePhone: ""}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].homePhone).toEqual(""); - }); - - it("should be able to search for workPhone", function () { - var items = [ - {workPhone: "555-1234"}, - {workPhone: "555-2222"}, - {workPhone: "555-2222"}, - {workPhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({workPhone: "555-2222"}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].workPhone).toEqual("555-2222"); - expect(result[1].workPhone).toEqual("555-2222"); - }); - - it("should be able to search for a blank workPhone", function () { - var items = [ - {workPhone: ""}, - {workPhone: "555-2222"}, - {workPhone: ""}, - {workPhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({workPhone: ""}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].workPhone).toEqual(""); - expect(result[1].workPhone).toEqual(""); - }); - - it("should be able to search for eMail", function () { - var items = [ - {eMail: "gord@tinyhippos.com"}, - {eMail: "gtanner@gmail.com"}, - {eMail: "gord.tanner@tinyhippos.com"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({eMail: "gord@tinyhippos.com"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].eMail).toEqual("gord@tinyhippos.com"); - }); - - it("should be able to search for blank eMail", function () { - var items = [ - {eMail: "gord@tinyhippos.com"}, - {eMail: ""}, - {eMail: "gtanner@gmail.com"}, - {eMail: ""}, - {eMail: "gord.tanner@tinyhippos.com"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({eMail: ""}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].eMail).toEqual(""); - expect(result[1].eMail).toEqual(""); - }); - - it("should be able to search for company", function () { - var items = [ - {company: "tinyhippos.com"}, - {company: "tinyhippos.com"}, - {company: "tinyhippos.com"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({company: "tinyhippos.com"}, 0, 3); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(3); - }); - - it("should be able to search for a blank company", function () { - var items = [ - {company: "tinyhippos.com"}, - {company: ""}, - {company: "tinyhippos.com"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({company: ""}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].company).toEqual(""); - }); - - it("should be able to search for title", function () { - var items = [ - {title: "Dr"}, - {title: "Dr"}, - {title: "Overlord"}, - {title: "Dr"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({title: "Overlord"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].title).toEqual("Overlord"); - }); - - it("should be able to search for a blank title", function () { - var items = [ - {title: "Dr"}, - {title: ""}, - {title: "Overlord"}, - {title: "Dr"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({title: ""}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].title).toEqual(""); - }); - - it("should be able to search for address", function () { - var items = [ - {address: "123 Anystreet"}, - {address: "53 Patricia Ave"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({address: "123 Anystreet"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].address).toEqual("123 Anystreet"); - }); - - it("should be able to search for a blank address", function () { - var items = [ - {address: "123 Anystreet"}, - {address: ""}, - {address: "53 Patricia Ave"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({address: ""}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].address).toEqual(""); - }); - - it("can search by multiple values", function () { - var items = [ - {fullName: "Gord", workPhone: "555-1234"}, - {fullName: "Gord", workPhone: "555-2222"}, - {fullName: "Gord", workPhone: "555-2222"}, - {fullName: "Gord", workPhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gord", workPhone: "555-2222"}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - }); - - it("can search when a search param is null but the entity has a value", function () { - var items = [ - {fullName: "Gord", workPhone: "555-1234"}, - {fullName: "Gord", workPhone: null}, - {fullName: "Gord", workPhone: null}, - {fullName: "Gord", workPhone: "555-1234"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gord", workPhone: null}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - }); - - it("searching is case insensitive", function () { - var items = [ - {fullName: "Gord", workPhone: "5551111"}, - {fullName: "GORD", workPhone: "5552222"}, - {fullName: "GoRd", workPhone: "5552222"}, - {fullName: "gOrD", workPhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gord"}, 0, 4); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(4); - }); - - it("searching can use wildcards", function () { - var items = [ - {fullName: "Gord", workPhone: "5551111"}, - {fullName: "Gwen", workPhone: "5552222"}, - {fullName: "Griffin", workPhone: "5552222"}, - {fullName: "Steph", workPhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "G*"}, 0, 3); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(3); - expect(result[0].fullName).toEqual("Gord"); - }); - - it("can escape * when searching", function () { - var calls = [ - {fullName: "Steph", workPhone: "5551111"}, - {fullName: "Gwen", workPhone: "5552222"}, - {fullName: "Griffin", workPhone: "5552222"}, - {fullName: "Gord", workPhone: "*69"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({workPhone: "\\*69"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].workPhone).toEqual("*69"); - }); - - it("can search with multiple wildcards", function () { - var calls = [ - {fullName: "Steph", workPhone: "5551111"}, - {fullName: "Gwen", workPhone: "5551234"}, - {fullName: "Griffin", workPhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({workPhone: "*12*"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].workPhone).toEqual("5551234"); - }); - - it("can search for strings containing escaped single quotes", function () { - var calls = [ - {fullName: "George O'Conner"}, - {fullName: "Larry"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "*O\'Conner"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].fullName).toEqual("George O'Conner"); - }); - - it("can search for strings containing escaped double quotes", function () { - var calls = [ - {fullName: 'George O"Conner'}, - {fullName: "Larry"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "*O\"Conner"}, 0, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].fullName).toEqual('George O"Conner'); - }); - - it("can search for only the first 2 records", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "g*"}, 0, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].fullName).toEqual("Gwen"); - expect(result[1].fullName).toEqual("Griffin"); - }); - - it("can serach for the third and forth records", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "g*"}, 2, 4); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].fullName).toEqual("Gwen"); - expect(result[1].fullName).toEqual("Gwen"); - }); - - it("if startInx equals, only one item whose sequence number is startInx is returned", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "g*"}, 2, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].fullName).toEqual("Gwen"); - expect(result[0].homePhone).toEqual("5551234"); - }); - - it("if startInx is greater than endInx the returned callRecordsFound will be an empty array.", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "g*"}, 4, 2); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(0); - }); - - it("if startInx is greater than the number of found item the returned callRecordsFound will be an empty array.", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gord", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gord"}, 3, 6); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(0); - }); - - it("if endInx is greater than the number of found items the returned callRecordsFound will contain items between startInx and the last returned item", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gord", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gwen"}, 0, 6); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(2); - expect(result[0].fullName).toEqual("Gwen"); - expect(result[1].fullName).toEqual("Gwen"); - }); - - it("if endInx is positive and startInx is negative, startInx will be treated as 0", function () { - var calls = [ - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Gord", homePhone: "5551234"}, - {fullName: "Gwen", homePhone: "5551234"}, - {fullName: "Griffin", homePhone: "5552222"}, - {fullName: "Griffin", homePhone: "5552222"} - ], result; - - s.stub(db, "retrieveObject").returns(calls); - pim.onAddressBookItemsFound = s.mock().once(); - pim.findAddressBookItems({fullName: "Gwen"}, -1, 1); - - result = pim.onAddressBookItemsFound.args[0][0]; - expect(result.length).toEqual(1); - expect(result[0].fullName).toEqual("Gwen"); - }); - - it("if endInx is negative throws INVALID_PARAMETER exception", function () { - expect(function () { - pim.findAddressBookItems({fullName: "Gwen"}, 0, -1); - }).toThrow(); - }); - - it("if comparisonContact is invalid throws INVALID_PARAMETER exception", function () { - expect(function () { - pim.findAddressBookItems("Gwen", 0, 1); - }).toThrow(); - }); - - it("if startInx is not a number throws INVALID_PARAMETER exception", function () { - expect(function () { - pim.findAddressBookItems({fullName: "Gwen"}, "test", 1); - }).toThrow(); - }); - - it("if endInx is not a number throws INVALID_PARAMETER exception", function () { - expect(function () { - pim.findAddressBookItems({fullName: "Gwen"}, 0, "test"); - }).toThrow(); - }); - - it("addCalendarItem should add an item to the persisted list", function () { - var items = [], - added = new CalendarItem(); - - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.CALENDAR_LIST_KEY, [added]); - - pim.addCalendarItem(added); - }); - - it("deleteCalendarItem should remove an item from the persisted list", function () { - var items = [ - {calendarItemId: "a"}, - {calendarItemId: "b"}, - {calendarItemId: "c"} - ]; - - s.stub(db, "retrieveObject").returns(items); - s.mock(db).expects("saveObject").once().withExactArgs(constants.PIM.CALENDAR_LIST_KEY, [items[0], items[2]]); - - pim.deleteCalendarItem("b"); - }); - - it("getCalendarItem returns the item for the given ID", function () { - var items = [ - {calendarItemId: "1"}, - {calendarItemId: "2"}, - {calendarItemId: "3"} - ]; - - s.stub(db, "retrieveObject").returns(items); - expect(items[1].calendarItemId).toEqual(pim.getCalendarItem("2").calendarItemId); - }); - - it("should raise the onCalendarItemsFound event when searching", function () { - s.stub(db, "retrieveObject").returns([]); - - pim.onCalendarItemsFound = s.mock().withExactArgs([]).once(); - pim.findCalendarItems({eventName: "w00t"}); - }); - - it("should be able to search for calendarItemId", function () { - var items = [ - {calendarItemId: "a"}, - {calendarItemId: "b"}, - {calendarItemId: "c"} - ]; - - s.stub(db, "retrieveObject").returns(items); - pim.onCalendarItemsFound = s.mock().once(); - pim.findCalendarItems({calendarItemId: "b"}); - }); - - it("should be able to search for alarmDate", function () { - var items = [ - {alarmDate: new Date(new Date().setMonth(1))}, - {alarmDate: new Date(new Date().setMonth(2))}, - {alarmDate: new Date(new Date().setMonth(3))} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onCalendarItemsFound = s.mock().once(); - pim.findCalendarItems({alarmDate: items[1].alarmDate}); - - result = pim.onCalendarItemsFound.args[0][0]; - - expect(result.length).toEqual(1); - expect(result[0].alarmDate).toEqual(items[1].alarmDate); - }); - - it("should be able to search for eventStartTime", function () { - var items = [ - {eventStartTime: new Date(new Date().setMonth(1))}, - {eventStartTime: new Date(new Date().setMonth(2))}, - {eventStartTime: new Date(new Date().setMonth(3))} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onCalendarItemsFound = s.mock().once(); - pim.findCalendarItems({eventStartTime: items[1].eventStartTime}); - - result = pim.onCalendarItemsFound.args[0][0]; - - expect(result.length).toEqual(1); - expect(result[0].eventStartTime).toEqual(items[1].eventStartTime); - }); - - it("should be able to search for events in a timebox", function () { - var items = [ - {eventStartTime: new Date(new Date().setMonth(1)), eventEndTime: new Date(new Date().setMonth(3))}, - {eventStartTime: new Date(new Date().setMonth(2)), eventEndTime: new Date(new Date().setMonth(3))}, - {eventStartTime: new Date(new Date().setMonth(4)), eventEndTime: new Date(new Date().setMonth(5))} - ], result; - - s.stub(db, "retrieveObject").returns(items); - pim.onCalendarItemsFound = s.mock().never(); - - result = pim.getCalendarItems(items[0].eventStartTime, items[1].eventEndTime); - - expect(result.length).toEqual(2); - }); - - it("I can call a method on a returned addressbook item", function () { - var items = [ - {addressBookItemId: "1"}, - {addressBookItemId: "2"}, - {addressBookItemId: "3"} - ], - contact; - - s.stub(db, "retrieveObject").returns(items); - contact = pim.getAddressBookItem("1"); - - expect(contact.getAvailableAttributes()); - }); - - it("the returned calendar item has the update method", function () { - var items = [ - {calendarItemId: "a"}, - {calendarItemId: "b"}, - {calendarItemId: "c"} - ], - event; - - s.stub(db, "retrieveObject").returns(items); - event = pim.getCalendarItem("b"); - - expect(event.update); - }); -}); diff --git a/test/unit/wac/PositionInfo.js b/test/unit/wac/PositionInfo.js deleted file mode 100644 index fd733ff7..00000000 --- a/test/unit/wac/PositionInfo.js +++ /dev/null @@ -1,50 +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. - */ -describe("wac_PositionInfo", function () { - var PositionInfo = require('ripple/platform/wac/1.0/PositionInfo'), - db = require('ripple/db'), - geo = require('ripple/geo'), - stub = { - "latitude": 43.465187, - "longitude": -80.522372, - "altitude": 100, - "accuracy": 150, - "altitudeAccuracy": 80, - "cellID": 321654, - "timeStamp": new Date() - }, - sinon = require('sinon'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - s.stub(db, "retrieveObject").returns(stub); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("gets its default values from the db", function () { - spyOn(geo, "getPositionInfo").andReturn(stub); - expect(PositionInfo.latitude).toEqual(stub.latitude); - expect(PositionInfo.longitude).toEqual(stub.longitude); - expect(PositionInfo.altitude).toEqual(stub.altitude); - expect(PositionInfo.accuracy).toEqual(stub.accuracy); - expect(PositionInfo.altitudeAccuracy).toEqual(stub.altitudeAccuracy); - expect(PositionInfo.cellID).toEqual(stub.cellID); - }); -}); diff --git a/test/unit/wac/PowerInfo.js b/test/unit/wac/PowerInfo.js deleted file mode 100644 index 46b60643..00000000 --- a/test/unit/wac/PowerInfo.js +++ /dev/null @@ -1,104 +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. - */ -describe("wac_PowerInfo", function () { - var PowerInfo = require('ripple/platform/wac/1.0/PowerInfo'), - deviceSettings = require('ripple/deviceSettings'), - event = require('ripple/event'), - _console = require('ripple/console'), - platform = require('ripple/platform'); - - beforeEach(function () { - spyOn(_console, "error"); - spyOn(_console, "log"); - spyOn(platform, "current").andReturn({ - name: "whatup", - device: { - "PowerInfo": { - "isCharging": {control: {value: false}}, - "percentRemaining": {control: {value: 98}} - } - } - }); - }); - - it("isCharging should return default control value", function () { - expect(PowerInfo.isCharging).toEqual(false); - }); - - it("percentRemaining returns default control value", function () { - expect(PowerInfo.percentRemaining).toEqual(98); - }); - - it("isCharging state change invokes onChargeStateChange", function () { - spyOn(deviceSettings, "retrieve").andReturn(50); - PowerInfo.onChargeStateChange = jasmine.createSpy(); - - event.trigger("DeviceBatteryStateChanged", [], true); - - expect(PowerInfo.onChargeStateChange).toHaveBeenCalled(); - delete PowerInfo.onChargeStateChange; - }); - - it("isCharging state change invokes onChargeStateChange with discharging", function () { - spyOn(deviceSettings, "retrieve").andReturn(30); - PowerInfo.onChargeStateChange = jasmine.createSpy(); - - event.trigger("DeviceBatteryStateChanged", [true], true); - - expect(PowerInfo.onChargeStateChange).toHaveBeenCalledWith("charging"); - delete PowerInfo.onChargeStateChange; - }); - - it("onChargeStateChange invokes properly when changing to 100 percent battery level", function () { - spyOn(deviceSettings, "retrieve").andReturn(100); - PowerInfo.onChargeStateChange = jasmine.createSpy(); - - event.trigger("DeviceBatteryStateChanged", [true], true); - - expect(PowerInfo.onChargeStateChange).toHaveBeenCalledWith("full"); - delete PowerInfo.onChargeStateChange; - }); - - it("onChargeStateChange invokes properly when changing from 100 percent battery level", function () { - spyOn(deviceSettings, "retrieve").andReturn(99); - PowerInfo.onChargeStateChange = jasmine.createSpy(); - - event.trigger("DeviceBatteryStateChanged", [false], true); - - expect(PowerInfo.onChargeStateChange).toHaveBeenCalledWith("discharging"); - delete PowerInfo.onChargeStateChange; - }); - - it("percentRemaining update invokes onChargeLevelChange with proper args", function () { - spyOn(deviceSettings, "retrieve").andReturn(99); - PowerInfo.onChargeLevelChange = jasmine.createSpy(); - - event.trigger("DeviceBatteryLevelChanged", [5], true); - - expect(PowerInfo.onChargeLevelChange).toHaveBeenCalledWith(5); - delete PowerInfo.onChargeLevelChange; - }); - - it("percentRemaining should invoke onLowBattery when below ten percent", function () { - spyOn(deviceSettings, "retrieve").andReturn(99); - PowerInfo.onLowBattery = jasmine.createSpy(); - - event.trigger("DeviceBatteryLevelChanged", [7], true); - - expect(PowerInfo.onLowBattery).toHaveBeenCalledWith(7); - delete PowerInfo.onLowBattery; - }); -}); diff --git a/test/unit/wac/RadioInfo.js b/test/unit/wac/RadioInfo.js deleted file mode 100644 index 21c05bc5..00000000 --- a/test/unit/wac/RadioInfo.js +++ /dev/null @@ -1,80 +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. - */ -describe("wac_RadioInfo", function () { - - var RadioInfo = require('ripple/platform/wac/1.0/RadioInfo'), - RadioSignalSourceTypes = require('ripple/platform/wac/1.0/RadioSignalSourceTypes'), - utils = require('ripple/utils'), - event = require('ripple/event'), - _console = require('ripple/console'), - platform = require('ripple/platform'); - - function _isValidSignalSource(sourceToCheck) { - var validValues = RadioSignalSourceTypes, - flag = false; - - utils.forEach(validValues, function (sourceKey, sourceValue) { - if (sourceToCheck === sourceValue) { - flag = true; - return true; - } - }); - - return flag; - } - - beforeEach(function () { - spyOn(platform, "current").andReturn({ - name: "whatup", - device: { - "RadioInfo": { - "isRoaming": {control: {value: true}}, - "isRadioEnabled": {control: {value: false}}, - "radioSignalStrengthPercent": {control: {value: 60}}, - "radioSignalSource": {control: {value: "LTE"}} - } - } - }); - }); - - // --------- Tests -------- \\ - - it("isRoaming returns default control", function () { - expect(RadioInfo.isRoaming).toEqual(true); - }); - - it("isRadioEnabled returns a default control", function () { - expect(RadioInfo.isRadioEnabled).toEqual(false); - }); - - it("radioSignalStrengthPercent returns a default value", function () { - expect(RadioInfo.radioSignalStrengthPercent).toEqual(60); - }); - - it("radioSignalSource is returns a default value", function () { - expect(_isValidSignalSource(RadioInfo.radioSignalSource)).toEqual(true); - }); - - it("radioSignalSource change invokes onSignalSourceChange when changed", function () { - spyOn(_console, "log"); - RadioInfo.onSignalSourceChange = jasmine.createSpy(); - event.trigger("RadioSignalSourceChanged", [], true); - - expect(RadioInfo.onSignalSourceChange).toHaveBeenCalledWith("LTE", true); - delete RadioInfo.onSignalSourceChange; - }); - -}); diff --git a/test/unit/wac/Telephony.js b/test/unit/wac/Telephony.js deleted file mode 100644 index 046a6943..00000000 --- a/test/unit/wac/Telephony.js +++ /dev/null @@ -1,444 +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. - */ -describe("wac_Telephony", function () { - - var telephony = require('ripple/platform/wac/1.0/Telephony'), - CallRecord = require('ripple/platform/wac/1.0/CallRecord'), - callType = require('ripple/platform/wac/1.0/CallRecordTypes'), - device = require('ripple/platform/wac/1.0/Device'), - db = require('ripple/db'), - sinon = require('sinon'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("should initiate a voice call", function () { - s.mock(device) - .expects("launchApplication") - .withExactArgs("PHONECALL", "5199541707") - .once(); - - telephony.initiateVoiceCall("5199541707"); - }); - - it("call record is an instance of call record", function () { - expect(new CallRecord() instanceof CallRecord).toBeTruthy(); - }); - - it("should fire the onCallEvent when initiating a voice call", function () { - s.stub(device, "launchApplication"); - - telephony.onCallEvent = s.mock().withExactArgs(callType.OUTGOING, "5199541707").once(); - telephony.initiateVoiceCall("5199541707"); - }); - - it("should get the count of call records", function () { - s.stub(db, "retrieveObject") - .returns([{callRecordType: callType.MISSED}, - {callRecordType: callType.MISSED}]); - - expect(2).toEqual(telephony.getCallRecordCnt(callType.MISSED)); - }); - - it("should only count the call records of the requested type", function () { - s.mock(db) - .expects("retrieveObject") - .once() - .returns([{callRecordType: callType.MISSED}, - {callRecordType: callType.OUTGOING}]); - - expect(1).toEqual(telephony.getCallRecordCnt(callType.MISSED)); - }); - - it("should return a count of 0 call records if the type is unknown", function () { - s.mock(db) - .expects("retrieveObject") - .once() - .returns([{callRecordType: callType.MISSED}, - {callRecordType: callType.MISSED}]); - - expect(0).toEqual(telephony.getCallRecordCnt("foo")); - }); - - it("should return the callRecord with the given id", function () { - s.stub(db, "retrieveObject") - .returns([{callRecordType: callType.MISSED, callRecordId: "1"}, - {callRecordType: callType.MISSED, callRecordId: "2"}]); - - var call = telephony.getCallRecord(callType.MISSED, "1"); - - expect(call).not.toBeNull(); - }); - - it("should return null when attempt to get callRecord by not in found", function () { - s.stub(db, "retrieveObject").returns([]); - var call = telephony.getCallRecord(callType.MISSED, "1"); - expect(call).toBeNull(); - }); - - it("should delete a call record by id", function () { - var calls = [ - {callRecordType: callType.MISSED, callRecordId: "1"}, - {callRecordType: callType.MISSED, callRecordId: "2"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - s.mock(db).expects("saveObject").once(); - - telephony.deleteCallRecord(callType.MISSED, "1"); - - expect(1).toEqual(calls.length); - }); - - it("shouldn't delete a record if no matches", function () { - var calls = [ - {callRecordType: callType.MISSED, callRecordId: "1"}, - {callRecordType: callType.MISSED, callRecordId: "2"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - s.mock(db).expects("saveObject").never(); - - telephony.deleteCallRecord(callType.OUTGOING, "1"); - - expect(2).toEqual(calls.length); - }); - - it("should delete all calls of the given type", function () { - var calls = [ - {callRecordType: callType.OUTGOING, callRecordId: "1"}, - {callRecordType: callType.OUTGOING, callRecordId: "2"}, - {callRecordType: callType.MISSED, callRecordId: "1"}, - {callRecordType: callType.MISSED, callRecordId: "2"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - s.mock(db).expects("saveObject").once(); - - telephony.deleteAllCallRecords(callType.OUTGOING); - - expect(2).toEqual(calls.length); - }); - - it("should raise the onCallRecordsFound when searching", function () { - - s.stub(db, "retrieveObject").returns([]); - - telephony.onCallRecordsFound = s.mock().withExactArgs([]).once(); - telephony.findCallRecords({callRecordType: callType.MISSED}); - }); - - it("can search for records by type", function () { - - var calls = [ - {callRecordType: callType.OUTGOING, callRecordId: "1"}, - {callRecordType: callType.OUTGOING, callRecordId: "2"}, - {callRecordType: callType.MISSED, callRecordId: "1"}, - {callRecordType: callType.MISSED, callRecordId: "2"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[2], calls[3]]).once(); - telephony.findCallRecords({callRecordType: callType.MISSED}); - }); - - it("can search for records by id", function () { - - var calls = [ - {callRecordType: callType.OUTGOING, callRecordId: "1"}, - {callRecordType: callType.OUTGOING, callRecordId: "2"}, - {callRecordType: callType.MISSED, callRecordId: "1"}, - {callRecordType: callType.MISSED, callRecordId: "2"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[0], calls[2]]).once(); - telephony.findCallRecords({callRecordId: "1"}); - }); - - it("can search for records by name", function () { - var calls = [ - {callRecordName: "Gwen"}, - {callRecordName: "Steph"}, - {callRecordName: "Griffin"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[0]]).once(); - telephony.findCallRecords({callRecordName: "Gwen"}); - }); - - it("can search for records with a blank name", function () { - var calls = [ - {callRecordName: "Gwen"}, - {callRecordName: "Steph"}, - {callRecordName: "", callRecordAddress: "5551234"}, - {callRecordName: "Griffin"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[2]]).once(); - telephony.findCallRecords({callRecordName: ""}); - }); - - it("can search for records by address", function () { - var calls = [ - {callRecordAddress: "5552222"}, - {callRecordAddress: "5551111"}, - {callRecordAddress: "5551234"}, - {callRecordAddress: "5551111"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[1], calls[3]]).once(); - telephony.findCallRecords({callRecordAddress: "5551111"}); - }); - - it("can search for records with a blank address", function () { - var calls = [ - {callRecordAddress: "5552222"}, - {callRecordAddress: "5551111"}, - {callRecordAddress: ""}, - {callRecordAddress: "5551111"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[2]]).once(); - telephony.findCallRecords({callRecordAddress: ""}); - }); - - it("can search for records by duration", function () { - var calls = [ - {durationSeconds: 60}, - {durationSeconds: 120}, - {durationSeconds: 60} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[1]]).once(); - telephony.findCallRecords({durationSeconds: 120}); - }); - - it("can search for records by start time", function () { - var calls = [ - {startTime: new Date(new Date() - 100)}, - {startTime: new Date(new Date() - 200)}, - {startTime: new Date(new Date() - 300)} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[2]]).once(); - telephony.findCallRecords({startTime: calls[2].startTime}); - }); - - it("can search by multiple values", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551111"}, - {callRecordName: "Gwen", callRecordAddress: "5552222"}, - {callRecordName: "Gwen", callRecordAddress: "5552222"}, - {callRecordName: "Steph", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[1], calls[2]]).once(); - telephony.findCallRecords({callRecordName: "Gwen", callRecordAddress: "5552222"}); - }); - - it("searching is case insensitive", function () { - var calls = [ - {callRecordName: "Gord", callRecordAddress: "5551111"}, - {callRecordName: "GORD", callRecordAddress: "5552222"}, - {callRecordName: "GoRd", callRecordAddress: "5552222"}, - {callRecordName: "gOrD", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs(calls).once(); - telephony.findCallRecords({callRecordName: "gord"}); - }); - - it("can use wildcards when searching name", function () { - var calls = [ - {callRecordName: "Steph", callRecordAddress: "5551111"}, - {callRecordName: "Gwen", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gord", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[1], calls[2], calls[3]]).once(); - telephony.findCallRecords({callRecordName: "G*"}); - - }); - - it("can use wildcards when searching for address", function () { - var calls = [ - {callRecordName: "Steph", callRecordAddress: "5551111"}, - {callRecordName: "Gwen", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gord", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[1], calls[2], calls[3]]).once(); - telephony.findCallRecords({callRecordAddress: "*22*"}); - }); - - it("can escape * when searching", function () { - var calls = [ - {callRecordName: "Steph", callRecordAddress: "5551111"}, - {callRecordName: "Gwen", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gord", callRecordAddress: "*69"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[3]]).once(); - telephony.findCallRecords({callRecordAddress: "\\*69"}); - }); - - - it("can search with multiple wildcards", function () { - var calls = [ - {callRecordName: "Steph", callRecordAddress: "5551111"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[1]]).once(); - telephony.findCallRecords({callRecordAddress: "*12*"}); - }); - - it("can search for strings containing escaped single quotes", function () { - var calls = [ - {callRecordName: "George O'Conner"}, - {callRecordName: "Larry"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[0]]).once(); - telephony.findCallRecords({callRecordName: "*O\'Conner"}); - }); - - it("can search for strings containing escaped double quotes", function () { - var calls = [ - {callRecordName: 'George O"Conner'}, - {callRecordName: "Larry"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[0]]).once(); - telephony.findCallRecords({callRecordName: "*O\"Conner"}); - }); - - it("can search for only the first 2 records", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[0], calls[1]]).once(); - telephony.findCallRecords({callRecordName: "g*"}, 0, 2); - }); - - it("can serach for the third and forth records", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[2], calls[3]]).once(); - telephony.findCallRecords({callRecordName: "g*"}, 2, 4); - }); - - it("if startInx equals, only one item whose sequence number is startInx is returned", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[2]]).once(); - telephony.findCallRecords({callRecordName: "g*"}, 2, 2); - }); - - it("if startInx is greater than endInx the returned callRecordsFound will be an empty array.", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([]).once(); - telephony.findCallRecords({callRecordName: "g*"}, 4, 2); - }); - - - it("if startInx is greater than the number of found item the returned callRecordsFound will be an empty array.", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gord", callRecordAddress: "5551234"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([]).once(); - telephony.findCallRecords({callRecordName: "Gord"}, 3, 6); - }); - - it("if endInx is greater than the number of found items the returned callRecordsFound will contain items between startInx and the last returned item", function () { - var calls = [ - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Gord", callRecordAddress: "5551234"}, - {callRecordName: "Gwen", callRecordAddress: "5551234"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"}, - {callRecordName: "Griffin", callRecordAddress: "5552222"} - ]; - - s.stub(db, "retrieveObject").returns(calls); - telephony.onCallRecordsFound = s.mock().withExactArgs([calls[0], calls[3]]).once(); - telephony.findCallRecords({callRecordName: "Gwen"}, 0, 6); - }); -}); diff --git a/test/unit/wac/VideoPlayer.js b/test/unit/wac/VideoPlayer.js deleted file mode 100644 index bc6dc9e8..00000000 --- a/test/unit/wac/VideoPlayer.js +++ /dev/null @@ -1,404 +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. - */ -describe("wac_VideoPlayer", function () { - - var video = require('ripple/platform/wac/1.0/VideoPlayer'), - sinon = require('sinon'), - platform = require('ripple/platform'), - fileSystem = require('ripple/fileSystem'), - _console = require('ripple/console'), - event = require('ripple/event'), - videoNode, domNode, s, - A_VIDEO = "../../short_video.ogv"; - - beforeEach(function () { - s = sinon.sandbox.create(); - domNode = document.createElement("div"); - videoNode = document.createElement("video"); - videoNode.canPlayType = function () { - return "probably"; - }; - // think jsdom does not have special methods like play on videotag - videoNode.play = function () {}; - videoNode.pause = function () {}; - videoNode.stop = function () {}; - - spyOn(platform, "current").andReturn({name: "generic"}); - }); - - afterEach(function () { - domNode = null; - videoNode = null; - s.verifyAndRestore(); - //HACK: this is to clear the state of video player between tests - video.onStateChange = null; - event.trigger("MultimediaVideoStateChanged", [null], true); - }); - - - // -------- setWindow - - it("setWindow sets a video inside a dom object", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - expect(domNode.childNodes.length).toBe(1); - expect(videoNode.tagName.toLowerCase()).toBe("video"); - }); - - it("setWindow only sets one video in the dom object", function () { - video.setWindow(domNode); - video.setWindow(domNode); - expect(domNode.childNodes.length).toBe(1); - }); - - it("setWindow dissociates video from a set dom object", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.setWindow(null); - expect(domNode.childNodes.length).toBe(0); - }); - - // -------- open - - it("open throws invalid param when given invalid fileUrl", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - expect(function () { - video.setWindow(domNode); - video.open(false); - }).toThrow(); - }); - - it("open throws invalid param when given invalid number of arguments", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - expect(function () { - video.setWindow(domNode); - video.open(); - }).toThrow(); - }); - - it("open sets video tag src attribute", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open(A_VIDEO); - expect(videoNode.getAttribute("src")).toBe(A_VIDEO); - }); - - it("open washes file url for virtual direcories", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - s.mock(fileSystem).expects("getURI").once().withExactArgs(A_VIDEO).returns(A_VIDEO); - video.open(A_VIDEO); - }); - - // ------- invalid state checks - // TODO: this could be a lot more tight (test every state case) - - it("open warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - s.mock(videoNode).expects("setAttribute").never(); - video.open(A_VIDEO); - }); - - it("play warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - s.mock(videoNode).expects("play").never(); - video.play(1); - }); - - it("pause warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open(A_VIDEO); - s.mock(videoNode).expects("pause").never(); - video.pause(); - }); - - it("resume warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - s.mock(videoNode).expects("play").never(); - video.resume(); - }); - - it("stop warns to console when called from invalid state", function () { - s.mock(_console).expects("warn").once(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open(A_VIDEO); - s.mock(videoNode).expects("pause").never(); - video.stop(); - }); - - // -------- play - - it("play throws invalid param when given invalid number of plays (negative integer)", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - expect(function () { - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(-7); - }).toThrow(); - }); - - it("play throws invalid param when given invalid number of plays (boolean)", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - expect(function () { - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(false); - }).toThrow(); - }); - - it("play throws invalid param when given invalid number of plays (string)", function () { - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - expect(function () { - video.setWindow(domNode); - video.open(A_VIDEO); - video.play("what up dawg"); - }).toThrow(); - }); - - it("play throws invalid param when given invalid number of arguments", function () { - s.mock(document).expects("createElement").twice().withExactArgs("video").returns(videoNode); - - expect(function () { - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1, 2); - }).toThrow(); - - expect(function () { - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(); - }).toThrow(); - }); - - // -------- integration - - it("play initiates play on video tag", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - s.mock(videoNode).expects("play").once(); - video.play(1); - }); - - it("pause initiates pause on video tag", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - s.mock(videoNode).expects("pause").once(); - video.pause(); - }); - - it("resume initiates pause on video tag", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.pause(); - s.mock(videoNode).expects("play").once(); - video.resume(); - }); - - it("stop initiates pause on video tag", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - s.mock(videoNode).expects("pause").once(); - video.stop(); - }); - - it("stop resets video tag src", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - s.mock(videoNode).expects("setAttribute").once().withExactArgs("src", A_VIDEO); - video.stop(); - }); - - it("open triggers state change event", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.onStateChange = s.mock().once().withExactArgs("opened"); - video.setWindow(domNode); - video.open(A_VIDEO); - }); - - it("play triggers state change event", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.onStateChange = s.mock().once().withExactArgs("playing"); - video.play(1); - }); - - it("play does not trigger state change event when give 0 number of play times", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.onStateChange = s.mock().never(); - video.play(0); - }); - - it("pause triggers state change event", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.onStateChange = s.mock().once().withExactArgs("paused"); - video.pause(); - }); - - it("resume triggers state change event", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.pause(); - - video.onStateChange = s.mock().once().withExactArgs("playing"); - video.resume(); - }); - - it("stop triggers state change event", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.pause(); - video.resume(); - - video.onStateChange = s.mock().once().withExactArgs("stopped"); - video.stop(); - }); - - // TODO: mock fire ended event and mock onStateChange - //it("triggers completed state change event when video ends", function () {}, - - it("object flow executes without any invalid state warnings", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.pause(); - video.resume(); - video.stop(); - }); - - it("object flow is reusable", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").twice().withExactArgs("video").returns(videoNode); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.pause(); - video.resume(); - video.stop(); - - video.setWindow(domNode); - video.open(A_VIDEO); - video.play(1); - video.pause(); - video.resume(); - video.stop(); - }); - - // -------- codec/container handling - - it("open should raise notification when given unsupported codecs/containers", function () { - s.mock(_console).expects("warn").atLeast(1); - videoNode.canPlayType = function () { - return ""; - }; - s.mock(document).expects("createElement").once().withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open("video.dude"); - }); - - it("open should not raise notification when given supported codecs/containers (mp4)", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").once().withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open("video.mp4"); - }); - - it("open should not raise notification when given supported codecs/containers (ogg)", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").once().withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open("video.ogg"); - }); - - it("open should not raise notification when given supported codecs/containers (ogv)", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").once().withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open("video.ogv"); - }); - - it("open should not raise notification when given supported codecs/containers (webm)", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").once().withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open("video.webm"); - }); - - it("open should not raise notification when given supported codecs/containers (flv)", function () { - s.mock(_console).expects("warn").never(); - s.mock(document).expects("createElement").once().withExactArgs("video").returns(videoNode); - video.setWindow(domNode); - video.open("video.flv"); - }); -}); diff --git a/test/unit/wac/Widget.js b/test/unit/wac/Widget.js deleted file mode 100644 index b4d4f83d..00000000 --- a/test/unit/wac/Widget.js +++ /dev/null @@ -1,103 +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. - */ -describe("wac_Widget", function () { - var Widget = require('ripple/platform/wac/1.0/Widget'), - Exception = require('ripple/platform/wac/1.0/Exception'), - event = require('ripple/event'), - platform = require('ripple/platform'), - db = require('ripple/db'), - sinon = require('sinon'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - spyOn(platform, "current").andReturn({name: "generic"}); - s.stub(platform, "getPersistencePrefix").returns("default"); - spyOn(console, "log"); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - - it("Exception_can_be_thrown_properly", function () { - // TODO: look into more, so does this mean you can have race conditions where this Static Exception object is used around the same time? - var exception = Exception; - exception.message = "message"; - exception.type = "testype"; - - try { - throw exception; - } - catch (e) { - expect(e.message).toBe("message"); - expect(e.type).toBe("testype"); - } - }); - - it("setPreferenceForKey_throws_INVALID_PARAMETER_exception_when_invalid_argument_types", function () { - expect(function () { - Widget.setPreferenceForKey(new Date(), 5); - - }).toThrow(); - }); - - it("setPreferenceForKey_throws_INVALID_PARAMETER_exception_when_invalid_argument_lengths", function () { - expect(function () { - Widget.setPreferenceForKey({}, false, ""); - }).toThrow(); - - expect(function () { - Widget.setPreferenceForKey(); - }).toThrow(); - }); - - it("setPreferenceForKey calls into the db to save", function () { - s.mock(db).expects("save").once(); - Widget.setPreferenceForKey("p value", "pstring"); - }); - - it("setPreferenceForKey raises the StorageUpdatedEvent", function () { - s.stub(db, "save"); - s.mock(event).expects("trigger").withExactArgs("StorageUpdatedEvent").once(); - Widget.setPreferenceForKey("a", "b"); - }); - - it("setPreferenceForKey_adds_and_removes_key_properly", function () { - s.mock(db).expects("remove").once(); - Widget.setPreferenceForKey(null, "removes_key"); - }); - - it("setPreferenceForKey_returns_undefined_with_nonexistent_key", function () { - expect(Widget.preferenceForKey("nonexistentkey")).not.toBeDefined(); - }); - - it("preferenceForKey_throws_INVALID_PARAMETER_exception_when_invalid_argument_types", function () { - expect(function () { - Widget.preferenceForKey(5); - }).toThrow(); - }); - - it("preferenceForKey_throws_INVALID_PARAMETER_exception_when_invalid_argument_lengths", function () { - expect(function () { - Widget.preferenceForKey(false, new Date()); - }).toThrow(); - - expect(function () { - Widget.preferenceForKey(); - }).toThrow(); - }); -}); diff --git a/test/unit/webworks.handset/io/dir.js b/test/unit/webworks.handset/io/dir.js new file mode 100644 index 00000000..96946ac3 --- /dev/null +++ b/test/unit/webworks.handset/io/dir.js @@ -0,0 +1,93 @@ +/* + * 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("webworks.handset io.dir", function () { + var server = require('ripple/platform/webworks.handset/2.0.0/server/io/dir'), + client = require('ripple/platform/webworks.handset/2.0.0/client/io/dir'), + cache = require('ripple/platform/webworks.core/2.0.0/fsCache'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + FILE = "file://"; + + describe("platform spec index", function () { + it("includes module according to proper object structure", function () { + var spec = require('ripple/platform/webworks.handset/2.0.0/spec'); + expect(spec.objects.blackberry.children.io.children.dir).toEqual({ + path: "webworks.handset/2.0.0/client/io/dir", + feature: "blackberry.io.dir" + }); + }); + }); + + describe("server index", function () { + it("exposes the server module", function () { + var webworks = require('ripple/platform/webworks.handset/2.0.0/server'); + expect(webworks.blackberry.io.dir).toEqual(server); + }); + }); + + describe("client", function () { + beforeEach(function () { + spyOn(transport, "call"); + }); + + function _expectTransportToCall(url, data) { + var args = transport.call.argsForCall[0]; + expect(args[0]).toEqual(url); + expect(args[1]).toEqual(data); + } + + describe("getFreeSpaceForRoot", function () { + it("calls transport with appropriate args", function () { + var path = "/"; + transport.call.andReturn(50); + + expect(client.getFreeSpaceForRoot(FILE + path)).toEqual(50); + _expectTransportToCall("blackberry/io/dir/getFreeSpaceForRoot", {post: {path: path}}); + }); + }); + + describe("getRootDirs", function () { + it("calls transport with appropriate args", function () { + var dirs = ["foo", "bar"]; + transport.call.andReturn(dirs); + + expect(client.getRootDirs()).toEqual([FILE + "foo", FILE + "bar"]); + _expectTransportToCall("blackberry/io/dir/getRootDirs", {}); + }); + }); + }); + + describe("server", function () { + describe("getFreeSpaceForRoot", function () { + it("passes to cache.dir.getFreeSpaceForRoot", function () { + var path = "new/new/new/dir"; + spyOn(cache.dir, "getFreeSpaceForRoot").andReturn(1024); + + expect(server.getFreeSpaceForRoot(null, {path: path})).toEqual({code: 1, data: 1024}); + expect(cache.dir.getFreeSpaceForRoot).toHaveBeenCalledWith(path); + }); + }); + + describe("getRootDirs", function () { + it("passes to cache.dir.getRootDirs", function () { + var dirs = ["cool", "dude"]; + spyOn(cache.dir, "getRootDirs").andReturn(dirs); + + expect(server.getRootDirs(null, {})).toEqual({code: 1, data: dirs}); + expect(cache.dir.getRootDirs).toHaveBeenCalledWith(); + }); + }); + }); +}); diff --git a/test/unit/webworks.handset/system.js b/test/unit/webworks.handset/system.js new file mode 100644 index 00000000..b7b99f19 --- /dev/null +++ b/test/unit/webworks.handset/system.js @@ -0,0 +1,45 @@ +/* + * 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("webworks.handset system", function () { + var system = require('ripple/platform/webworks.core/2.0.0/server/system'), + systemEvent = require('ripple/platform/webworks.handset/2.0.0/server/systemEvent'), + client = require('ripple/platform/webworks.handset/2.0.0/client/system'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + utils = require('ripple/utils'); + + describe("using webworks.handset server", function () { + it("exposes the system module", function () { + var webworks = require('ripple/platform/webworks.handset/2.0.0/server'), + obj = {}; + obj.event = systemEvent; + utils.mixin(system, obj); + expect(webworks.blackberry.system).toEqual(obj); + }); + }); + + describe("client", function () { + describe("setHomeScreenBackground", function () { + it("calls the transport with id and properties", function () { + spyOn(transport, "call"); + client.setHomeScreenBackground("filepath"); + expect(transport.call).toHaveBeenCalledWith("blackberry/system/setHomeScreenBackground", { + get: {filePath: "filepath"}, + async: true + }); + }); + }); + }); +}); diff --git a/test/unit/webworks.tablet/appEvent.js b/test/unit/webworks.tablet/appEvent.js index 9ff751a9..08390f83 100644 --- a/test/unit/webworks.tablet/appEvent.js +++ b/test/unit/webworks.tablet/appEvent.js @@ -46,14 +46,22 @@ describe("webworks_appEvent", function () { }); describe("onSwipeStart", function () { - it("throws an exception", function () { - expect(client.onSwipeStart).toThrow("not implemented"); + it("polls the transport appropriately", function () { + spyOn(transport, "poll"); + client.onSwipeStart(null); + expect(transport.poll.argsForCall[0][0]).toEqual("blackberry/app/event/onSwipeStart"); + expect(transport.poll.argsForCall[0][1]).toEqual({}); + expect(typeof transport.poll.argsForCall[0][2]).toEqual("function"); // could tighten... }); }); describe("onSwipeDown", function () { - it("throws an exception", function () { - expect(client.onSwipeDown).toThrow("not implemented"); + it("polls the transport appropriately", function () { + spyOn(transport, "poll"); + client.onSwipeDown(null); + expect(transport.poll.argsForCall[0][0]).toEqual("blackberry/app/event/onSwipeDown"); + expect(transport.poll.argsForCall[0][1]).toEqual({}); + expect(typeof transport.poll.argsForCall[0][2]).toEqual("function"); // could tighten... }); }); @@ -77,13 +85,35 @@ describe("webworks_appEvent", function () { }); }); + describe("onSwipeDown", function () { + it("takes the baton", function () { + var baton = new MockBaton(); + + appEvent.onSwipeDown({}, {}, baton); + expect(baton.take).toHaveBeenCalled(); + }); + }); + + describe("onSwipeStart", function () { + it("takes the baton", function () { + var baton = new MockBaton(); + + appEvent.onSwipeStart({}, {}, baton); + expect(baton.take).toHaveBeenCalled(); + }); + }); + describe("the correct baton is passed when", function () { it("raises AppRequestBackground", function () { var bg = new MockBaton(), - fg = new MockBaton(); + fg = new MockBaton(), + sd = new MockBaton(), + ss = new MockBaton(); appEvent.onBackground({}, {}, bg); appEvent.onForeground({}, {}, fg); + appEvent.onSwipeDown({}, {}, sd); + appEvent.onSwipeStart({}, {}, ss); event.trigger("AppRequestBackground", [], true); expect(bg.pass).toHaveBeenCalled(); @@ -92,10 +122,14 @@ describe("webworks_appEvent", function () { it("raises AppRequestForeground", function () { var bg = new MockBaton(), - fg = new MockBaton(); + fg = new MockBaton(), + sd = new MockBaton(), + ss = new MockBaton(); appEvent.onBackground({}, {}, bg); appEvent.onForeground({}, {}, fg); + appEvent.onSwipeDown({}, {}, sd); + appEvent.onSwipeStart({}, {}, ss); event.trigger("AppRequestForeground", [], true); expect(bg.pass).not.toHaveBeenCalled(); diff --git a/test/unit/webworks.tablet/systemEvent.js b/test/unit/webworks.tablet/systemEvent.js index 537d4de5..c39bc3ad 100644 --- a/test/unit/webworks.tablet/systemEvent.js +++ b/test/unit/webworks.tablet/systemEvent.js @@ -16,7 +16,7 @@ describe("webworks.tablet system event", function () { var server = require('ripple/platform/webworks.tablet/2.0.0/server/systemEvent'), client = require('ripple/platform/webworks.tablet/2.0.0/client/systemEvent'), - spec = require('ripple/platform/webworks.tablet/2.0.0/spec/device'), + deviceSpec = require('ripple/platform/webworks.tablet/2.0.0/spec/device'), transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), event = require('ripple/event'), MockBaton = function () { @@ -25,12 +25,31 @@ describe("webworks.tablet system event", function () { }; describe("platform spec", function () { + var spec = require('ripple/platform/webworks.tablet/2.0.0/spec'); + // NOTE: system and system.event for Playbook do not require feature declarations (see docs) it("includes the module according to proper object structure", function () { - var spec = require('ripple/platform/webworks.tablet/2.0.0/spec'); expect(spec.objects.blackberry.children.system.children.event.path) .toEqual("webworks.tablet/2.0.0/client/systemEvent"); }); + + describe("events", function () { + describe("app.event.onSwipeDown callback", function () { + it("triggers AppSwipeDown", function () { + spyOn(event, "trigger"); + spec.events["app.event.onSwipeDown"].callback(); + expect(event.trigger).toHaveBeenCalledWith("AppSwipeDown"); + }); + }); + + describe("app.event.onSwipeStart callback", function () { + it("triggers AppSwipeStart", function () { + spyOn(event, "trigger"); + spec.events["app.event.onSwipeStart"].callback(); + expect(event.trigger).toHaveBeenCalledWith("AppSwipeStart"); + }); + }); + }); }); describe("server index", function () { @@ -42,23 +61,23 @@ describe("webworks.tablet system event", function () { describe("in the device spec", function () { it("includes setting to togger handset charging on and off", function () { - expect(typeof spec.battery.state.name).toEqual("string"); - expect(spec.battery.state.control.type).toEqual("checkbox"); + expect(typeof deviceSpec.battery.state.name).toEqual("string"); + expect(deviceSpec.battery.state.control.type).toEqual("checkbox"); - expect(typeof spec.battery.level.callback).toEqual("function"); + expect(typeof deviceSpec.battery.level.callback).toEqual("function"); spyOn(event, "trigger"); - spec.battery.state.callback(false); + deviceSpec.battery.state.callback(false); expect(event.trigger).toHaveBeenCalledWith("DeviceBatteryStateChanged", [false]); }); it("includes setting to set charge level of the handset", function () { - expect(typeof spec.battery.level.name).toEqual("string"); - expect(spec.battery.level.control.type).toEqual("select"); - expect(typeof spec.battery.level.options === "object").toEqual(true); + expect(typeof deviceSpec.battery.level.name).toEqual("string"); + expect(deviceSpec.battery.level.control.type).toEqual("select"); + expect(typeof deviceSpec.battery.level.options === "object").toEqual(true); - expect(typeof spec.battery.level.callback).toEqual("function"); + expect(typeof deviceSpec.battery.level.callback).toEqual("function"); spyOn(event, "trigger"); - spec.battery.level.callback(87); + deviceSpec.battery.level.callback(87); expect(event.trigger).toHaveBeenCalledWith("DeviceBatteryLevelChanged", [87]); }); }); @@ -163,7 +182,7 @@ describe("webworks.tablet system event", function () { expect(baton.pass).toHaveBeenCalledWith({code: 1, data: 3}); // state CHARGING }); - it("passes state CHARGING when charging is false", function () { + it("passes state CHARGING when charging is true", function () { var baton = new MockBaton(); server.deviceBatteryStateChange({}, {}, baton); event.trigger("DeviceBatteryStateChanged", [true], true); diff --git a/test/unit/webworks/Message.js b/test/unit/webworks/Message.js index 232a7d6f..7efc66d5 100644 --- a/test/unit/webworks/Message.js +++ b/test/unit/webworks/Message.js @@ -14,22 +14,12 @@ * limitations under the License. */ describe("webworks Message", function () { - var s, - sinon = require('sinon'), - Message = require('ripple/platform/webworks.handset/2.0.0/client/Message'), + var Message = require('ripple/platform/webworks.handset/2.0.0/client/Message'), Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'), select = require('ripple/platform/webworks.core/2.0.0/select'), FilterExpression = require('ripple/platform/webworks.handset/2.0.0/client/FilterExpression'), transport = require('ripple/platform/webworks.core/2.0.0/client/transport'); - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); - describe("client side code", function () { var identity = require('ripple/platform/webworks.handset/2.0.0/client/identity'); @@ -47,13 +37,15 @@ describe("webworks Message", function () { }); it("test when constructing without a service it gets the default email service", function () { - s.mock(identity).expects("getDefaultService").once().returns([]); + spyOn(identity, "getDefaultService").andReturn([]); new Message(); + expect(identity.getDefaultService).toHaveBeenCalled(); }); it("when constructing with a service it doesn't get the defeault email service", function () { - s.mock(identity).expects("getDefaultService").never(); + spyOn(identity, "getDefaultService"); new Message(new Service()); + expect(identity.getDefaultService).not.toHaveBeenCalled(); }); it("that the default values are set correctly on a new message", function () { @@ -76,7 +68,7 @@ describe("webworks Message", function () { }); it("that when saving a draft message it generates a uid", function () { - s.stub(Math, "uuid").returns("42"); + spyOn(Math, "uuid").andReturn("42"); var service = new Service(), msg = new Message(service); msg.save(); @@ -84,18 +76,18 @@ describe("webworks Message", function () { }); it("that when saving a message that was already saved it keeps the uid", function () { - var stub = s.stub(Math, "uuid").returns("42"), + var stub = spyOn(Math, "uuid").andReturn("42"), service = new Service(), msg = new Message(service); msg.save(); - stub.restore(); - s.stub(Math, "uuid").returns(123); + stub.reset(); + stub.andReturn(123); msg.save(); expect(42, msg.uid); }); it("when calling save on a draft the status stays as draft", function () { - s.stub(Math, "uuid").returns("42"); + spyOn(Math, "uuid").andReturn("42"); var service = new Service(), msg = new Message(service); msg.save(); @@ -103,7 +95,7 @@ describe("webworks Message", function () { }); it("when saving a message it sets the from and replyTo addresses from the service passed in", function () { - s.stub(Math, "uuid").returns("42"); + spyOn(Math, "uuid").andReturn("42"); var service = new Service(), msg = new Message(service); service.emailAddress = "gord@tinyHippos.com"; diff --git a/test/unit/webworks/XMLHttpRequest.js b/test/unit/webworks/XMLHttpRequest.js index 09c9b4e3..a7562e7a 100644 --- a/test/unit/webworks/XMLHttpRequest.js +++ b/test/unit/webworks/XMLHttpRequest.js @@ -130,6 +130,10 @@ describe("webworks XMLHttpRequest", function () { spy.andReturn(response); + spyOn(window, "setTimeout").andCallFake(function (func) { + func(); + }); + webworks.blackberry.abc = spy; xhr.onreadystatechange = function () { @@ -139,11 +143,9 @@ describe("webworks XMLHttpRequest", function () { xhr.open("GET", url, true); xhr.send(); - waits(50); - runs(function () { - expect(count).toEqual(4); - delete webworks.blackberry.abc; - }); + expect(count).toEqual(4); + expect(window.setTimeout).toHaveBeenCalled(); + delete webworks.blackberry.abc; }); it("parses individual get paramters as JSON", function () { diff --git a/test/unit/webworks/app.js b/test/unit/webworks/app.js index 85c8e9f4..eb04dea9 100644 --- a/test/unit/webworks/app.js +++ b/test/unit/webworks/app.js @@ -21,7 +21,6 @@ describe("webworks_app", function () { event = require('ripple/event'), app = require('ripple/app'), notifications = require('ripple/notifications'), - constants = require('ripple/constants'), frame; beforeEach(function () { @@ -58,6 +57,13 @@ describe("webworks_app", function () { }); }); + describe("isForeground", function () { + it("calls the transport appropriately", function () { + expect(appClient.isForeground).toBe(data); + expect(transport.call).toHaveBeenCalledWith("blackberry/app/isForeground"); + }); + }); + describe("setHomeScreenName", function () { it("calls the transport appropriately", function () { appClient.setHomeScreenName("text"); @@ -272,7 +278,7 @@ describe("webworks_app", function () { uri: "icon.png", hover: true }); - expect(notifications.openNotification).toHaveBeenCalledWith(constants.NOTIFICATIONS.TYPES.NORMAL, + expect(notifications.openNotification).toHaveBeenCalledWith("normal", "The application set the home screen hover icon to icon.png"); }); @@ -281,7 +287,7 @@ describe("webworks_app", function () { appServer.setHomeScreenIcon({ uri: "foo.png" }); - expect(notifications.openNotification).toHaveBeenCalledWith(constants.NOTIFICATIONS.TYPES.NORMAL, + expect(notifications.openNotification).toHaveBeenCalledWith("normal", "The application set the home screen icon to foo.png"); }); @@ -290,7 +296,7 @@ describe("webworks_app", function () { appServer.setHomeScreenName({ text: "Awesometown" }); - expect(notifications.openNotification).toHaveBeenCalledWith(constants.NOTIFICATIONS.TYPES.NORMAL, + expect(notifications.openNotification).toHaveBeenCalledWith("normal", "The application set the home screen name to Awesometown"); }); @@ -310,4 +316,25 @@ describe("webworks_app", function () { expect(event.trigger).toHaveBeenCalledWith("BannerUpdated", ["", 0]); expect(event.trigger.callCount).toBe(1); }); + describe("isForeground", function () { + it("returns false when app has requested the background", function () { + spyOn(event, "trigger"); + spyOn(ui, "showOverlay").andCallFake(function (url, callback) { + callback({children: {}}); + }); + + appServer.requestBackground(); + expect(appServer.isForeground({})).toEqual({code: 1, data: false}); + }); + + it("returns true when app has requested the foreground", function () { + spyOn(event, "trigger"); + spyOn(ui, "hideOverlay").andCallFake(function (url, callback) { + callback({children: {}}); + }); + + appServer.requestForeground(); + expect(appServer.isForeground({})).toEqual({code: 1, data: true}); + }); + }); }); diff --git a/test/unit/webworks/config.js b/test/unit/webworks/config.js index 42510cf7..340e8851 100644 --- a/test/unit/webworks/config.js +++ b/test/unit/webworks/config.js @@ -78,6 +78,44 @@ describe("webworks_config", function () { }] }, "access": { + children: { + feature: { + validationResult: [{ + attributes: { + id: { + value: "blackberry.pim.memo" + } + }, + node: { + parentNode: { + attributes: { uri: { value: "http://www.somedomain.com" } } + } + } + }, { + attributes: { + id: { + value: "blackberry.invoke" + } + }, + node: { + parentNode: { + attributes: { uri: { value: "http://www.somedomain.com" } } + } + } + }, { + attributes: { + id: { + value: "blackberry.invoke" + } + }, + node: { + parentNode: { + attributes: { uri: { value: "http://www.otherdomain.com" } } + } + } + } + ]} + }, validationResult: [{ attributes: { uri: { @@ -87,24 +125,7 @@ describe("webworks_config", function () { value: true } }, - valid: true, - children: { - feature: { - validationResult: [{ - attributes: { - id: { - value: "blackberry.pim.memo" - } - } - }, { - attributes: { - id: { - value: "blackberry.invoke" - } - } - }] - } - } + valid: true }, { attributes: { uri: { @@ -114,18 +135,7 @@ describe("webworks_config", function () { value: false } }, - valid: true, - children: { - feature: { - validationResult: [{ - attributes: { - id: { - value: "blackberry.invoke" - } - } - }] - } - } + valid: true }] } }, diff --git a/test/unit/webworks/fsCache.js b/test/unit/webworks/fsCache.js new file mode 100644 index 00000000..746ab1d2 --- /dev/null +++ b/test/unit/webworks/fsCache.js @@ -0,0 +1,311 @@ +/* + * 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 fs = require('ripple/fs'), + 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 = [{ + fullPath: "/dude", + name: "dude", + isDirectory: false, + file: function (success, error) { + success({ + lastModifiedDate: new Date(456), + size: 20, + type: "text/plain" + }); + } + }, { + fullPath: "/dudeDir", + name: "dudeDir", + isDirectory: true + }, { + fullPath: "/hungry.js", + name: "hungry.js", + isDirectory: false, + file: function (success, error) { + success({ + lastModifiedDate: new Date(123), + size: 50, + type: "application/x-javascript" + }); + } + }, { + fullPath: "/hippo", + name: "hippo", + isDirectory: true + }]; + + beforeEach(function () { + spyOn(fs, "read"); + spyOn(fs, "ls").andCallFake(function (path, success, error) { + success(path === "/" ? _root : []); + }); + + cache.refresh(); + }); + + // TODO: cache (get,set,delete) layer is not under test + it("calls refresh on FileSystemInitialized", function () { + spyOn(cache, "refresh"); + spyOn(fs, "mkdir").andCallFake(function (path, success, error) { + success(); + }); + event.trigger("FileSystemInitialized", null, true); + expect(cache.refresh).toHaveBeenCalled(); + }); + + describe("io.file", function () { + describe("exists", function () { + it("returns true when the file exists", function () { + spyOn(fs, "stat"); + expect(cache.file.exists("/hungry.js")).toBe(true); + expect(fs.stat.argsForCall[0][0]).toBe("/hungry.js"); + expect(typeof fs.stat.argsForCall[0][1]).toBe("function"); + expect(typeof fs.stat.argsForCall[0][2]).toBe("function"); + }); + + it("returns false when when given a directory", function () { + spyOn(fs, "stat"); + expect(cache.file.exists("/dudeDir")).toBe(false); + expect(fs.stat.argsForCall[0][0]).toBe("/dudeDir"); + expect(typeof fs.stat.argsForCall[0][1]).toBe("function"); + expect(typeof fs.stat.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("deleteFile", function () { + it("removes a file", function () { + spyOn(fs, "rm"); + cache.file.deleteFile("/hungry.js"); + expect(fs.rm.argsForCall[0][0]).toBe("/hungry.js"); + expect(typeof fs.rm.argsForCall[0][1]).toBe("function"); + expect(typeof fs.rm.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("copy", function () { + it("copies the file at the specified path", function () { + spyOn(fs, "cp"); + cache.file.copy("/hungry.js", "/hungrier"); + expect(fs.cp.argsForCall[0][0]).toBe("/hungry.js"); + expect(fs.cp.argsForCall[0][1]).toBe("/hungrier"); + expect(typeof fs.cp.argsForCall[0][2]).toBe("function"); + expect(typeof fs.cp.argsForCall[0][3]).toBe("function"); + }); + }); + + describe("getFileProperties", function () { + it("returns an object of file properties", function () { + spyOn(fs, "stat"); + + var properties = new FileProperties({ + dateModified: new Date(123), + size: 50, + mimeType: "application/x-javascript" + }), + result = cache.file.getFileProperties("/hungry.js"); + + expect(result.dateModified).toEqual(new Date(123)); + expect(result.dateCreated).toEqual(new Date(123)); + expect(result.directory).toEqual("/"); + expect(result.fileExtension).toEqual("js"); + expect(result.isHidden).toEqual(false); + expect(result.isReadonly).toEqual(false); + expect(result.mimeType).toEqual(properties.mimeType); + expect(result.size).toEqual(50); + expect(result instanceof FileProperties).toBe(true); + }); + }); + + describe("rename", function () { + it("renames a file", function () { + spyOn(cache.dir, "rename"); + cache.file.rename("/hungry.js", "hungryhungry.js"); + expect(cache.dir.rename).toHaveBeenCalledWith("/hungry.js", "hungryhungry.js"); + }); + }); + }); + + describe("io.dir", function () { + describe("createNewDir", function () { + it("creates a directory", function () { + spyOn(fs, "mkdir"); + cache.dir.createNewDir("/test"); + expect(fs.mkdir.argsForCall[0][0]).toBe("/test"); + expect(typeof fs.mkdir.argsForCall[0][1]).toBe("function"); + expect(typeof fs.mkdir.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("deleteDirectory", function () { + it("removes a directory", function () { + spyOn(fs, "rmdir"); + cache.dir.deleteDirectory("/dudeDir"); + expect(fs.rmdir.argsForCall[0][0]).toBe("/dudeDir"); + expect(typeof fs.rmdir.argsForCall[0][1]).toBe("function"); + expect(typeof fs.rmdir.argsForCall[0][2]).toBe("function"); + }); + + it("removes a directory recursively", function () { + spyOn(fs, "rm"); + cache.dir.deleteDirectory("/dudeDir", true); + expect(fs.rm.argsForCall[0][0]).toBe("/dudeDir"); + expect(typeof fs.rm.argsForCall[0][1]).toBe("function"); + expect(typeof fs.rm.argsForCall[0][2]).toBe("function"); + expect(fs.rm.argsForCall[0][3]).toEqual({recursive: true}); + }); + }); + + describe("exists", function () { + it("returns true when the directory exists", function () { + spyOn(fs, "stat"); + expect(cache.dir.exists("/dudeDir")).toBe(true); + expect(fs.stat.argsForCall[0][0]).toBe("/dudeDir"); + expect(typeof fs.stat.argsForCall[0][1]).toBe("function"); + expect(typeof fs.stat.argsForCall[0][2]).toBe("function"); + }); + + it("returns false when given a file", function () { + spyOn(fs, "stat"); + expect(cache.dir.exists("/hungry.js")).toBe(false); + expect(fs.stat.argsForCall[0][0]).toBe("/hungry.js"); + expect(typeof fs.stat.argsForCall[0][1]).toBe("function"); + expect(typeof fs.stat.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("getParentDirectory", function () { + it("returns the path to the parent directory", function () { + var entry = { + getParent: jasmine.createSpy() + }; + + spyOn(fs, "stat").andCallFake(function (path, success, error) { + success(entry); + }); + + expect(cache.dir.getParentDirectory("/dudeDir")).toBe("/"); + expect(fs.stat.argsForCall[0][0]).toBe("/dudeDir"); + expect(typeof fs.stat.argsForCall[0][1]).toBe("function"); + expect(typeof fs.stat.argsForCall[0][2]).toBe("function"); + expect(typeof entry.getParent.argsForCall[0][0]).toBe("function"); + expect(typeof entry.getParent.argsForCall[0][1]).toBe("function"); + }); + }); + + describe("listDirectories", function () { + it("returns an array of all directories in a path", function () { + expect(cache.dir.listDirectories("/")).toEqual(["dudeDir", "hippo"]); + expect(fs.ls.argsForCall[0][0]).toBe("/"); + expect(typeof fs.ls.argsForCall[0][1]).toBe("function"); + expect(typeof fs.ls.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("listFiles", function () { + it("returns an array of all files in a path", function () { + expect(cache.dir.listFiles("/")).toEqual(["dude", "hungry.js"]); + expect(fs.ls.argsForCall[0][0]).toBe("/"); + expect(typeof fs.ls.argsForCall[0][1]).toBe("function"); + expect(typeof fs.ls.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("rename", function () { + it("renames a directory at the specified path", function () { + spyOn(fs, "mv"); + cache.dir.rename("/dudeDir", "theDudeDir"); + expect(fs.mv.argsForCall[0][0]).toBe("/dudeDir"); + expect(fs.mv.argsForCall[0][1]).toBe("/theDudeDir"); + expect(typeof fs.mv.argsForCall[0][2]).toBe("function"); + expect(typeof fs.mv.argsForCall[0][3]).toBe("function"); + }); + }); + + describe("getRootDirs", function () { + it("returns an array of top level directories", function () { + spyOn(cache.dir, "listDirectories").andReturn(["foo"]); + expect(cache.dir.getRootDirs()).toEqual(["foo"]); + expect(cache.dir.listDirectories).toHaveBeenCalledWith("/"); + }); + }); + }); + + describe("readFile", function () { + it("asynchronously reads data from a file", function () { + var blob = {size: 5}, + path = "/hungry.js", + success = jasmine.createSpy(); + + fs.read.reset(); + fs.read.andCallFake(function (path, success, error) { + setTimeout(function () { + success(blob); + }, 1); + }); + + spyOn(bbUtils, "stringToBlob").andReturn(blob); + + cache.file.readFile(path, success, true); + + waits(1); + runs(function () { + expect(success).toHaveBeenCalledWith(blob); + expect(fs.read.argsForCall[0][0]).toBe(path); + expect(typeof fs.read.argsForCall[0][1]).toBe("function"); + expect(typeof fs.read.argsForCall[0][2]).toBe("function"); + }); + }); + + it("synchronously reads data from a file", function () { + var blob = {size: 5}, + path = "/hungry.js", + success = jasmine.createSpy(); + + fs.read.reset(); + + spyOn(bbUtils, "stringToBlob").andReturn(blob); + + cache.file.readFile(path, success, false); + + expect(success).toHaveBeenCalledWith(blob); + expect(fs.read.argsForCall[0][0]).toBe(path); + expect(typeof fs.read.argsForCall[0][1]).toBe("function"); + expect(typeof fs.read.argsForCall[0][2]).toBe("function"); + }); + }); + + describe("saveFile", function () { + it("asynchronously writes data to a file", function () { + var blob = {size: 5}, + path = "/hungry.js"; + + spyOn(fs, "write"); + spyOn(bbUtils, "blobToString").andReturn("contents"); + + cache.file.saveFile(path, blob); + + expect(fs.write.argsForCall[0][0]).toBe(path); + expect(fs.write.argsForCall[0][1]).toBe("contents"); + expect(typeof fs.write.argsForCall[0][2]).toBe("function"); + expect(typeof fs.write.argsForCall[0][3]).toBe("function"); + }); + }); +}); diff --git a/test/unit/webworks/invoke.js b/test/unit/webworks/invoke.js index 9710f269..13562489 100644 --- a/test/unit/webworks/invoke.js +++ b/test/unit/webworks/invoke.js @@ -16,30 +16,49 @@ describe("webworks_invoke", function () { describe("for handset", function () { var webworks = require('ripple/platform/webworks.handset/2.0.0/server'), - Invoke = require('ripple/platform/webworks.handset/2.0.0/client/invoke'), - notifications = require('ripple/notifications'), - constants = require('ripple/constants'), - sinon = require('sinon'), - transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); + Invoke = require('ripple/platform/webworks.handset/2.0.0/client/invoke'), + notifications = require('ripple/notifications'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'); it("raises a notification when calling invoke", function () { - s.mock(notifications) - .expects("openNotification") - .withExactArgs(constants.NOTIFICATIONS.TYPES.NORMAL, "Requested to launch: Browser application.") - .once(); + spyOn(notifications, "openNotification"); webworks.blackberry.invoke.invoke({ appType: "http://www.google.com" }); + + expect(notifications.openNotification) + .toHaveBeenCalledWith("normal", "Requested to launch: Browser application."); + }); + + describe("BrowserArguments", function () { + beforeEach(function () { + spyOn(transport, "call"); + }); + + it("handles launching http protocol", function () { + expect(function () { + Invoke.invoke(Invoke.APP_BROWSER, { + url: "http://somewhere.com" + }); + }).not.toThrow(); + }); + + it("handles launching https protocol", function () { + expect(function () { + Invoke.invoke(Invoke.APP_BROWSER, { + url: "https://somewhere.com" + }); + }).not.toThrow(); + }); + + it("throws exception when given unsupported protocol", function () { + expect(function () { + Invoke.invoke(Invoke.APP_BROWSER, { + url: "file:///somewhere/" + }); + }).toThrow(); + }); }); it("calls the correct invoke URI", function () { @@ -55,32 +74,52 @@ describe("webworks_invoke", function () { }); }); }); + describe("for tablet", function () { var webworks = require('ripple/platform/webworks.tablet/2.0.0/server'), - Invoke = require('ripple/platform/webworks.tablet/2.0.0/client/invoke'), - notifications = require('ripple/notifications'), - constants = require('ripple/constants'), - sinon = require('sinon'), - transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), - s; - - beforeEach(function () { - s = sinon.sandbox.create(); - }); - - afterEach(function () { - s.verifyAndRestore(); - }); + Invoke = require('ripple/platform/webworks.tablet/2.0.0/client/invoke'), + notifications = require('ripple/notifications'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'); it("raises a notification when calling invoke", function () { - s.mock(notifications) - .expects("openNotification") - .withExactArgs(constants.NOTIFICATIONS.TYPES.NORMAL, "Requested to launch: Browser application.") - .once(); + spyOn(notifications, "openNotification"); webworks.blackberry.invoke.invoke({ appType: "http://www.google.com" }); + + expect(notifications.openNotification) + .toHaveBeenCalledWith("normal", "Requested to launch: Browser application."); + }); + + describe("BrowserArguments", function () { + beforeEach(function () { + spyOn(transport, "call"); + }); + + it("handles launching http protocol", function () { + expect(function () { + Invoke.invoke(Invoke.APP_BROWSER, { + url: "http://somewhere.com" + }); + }).not.toThrow(); + }); + + it("handles launching https protocol", function () { + expect(function () { + Invoke.invoke(Invoke.APP_BROWSER, { + url: "https://somewhere.com" + }); + }).not.toThrow(); + }); + + it("throws exception when given unsupported protocol", function () { + expect(function () { + Invoke.invoke(Invoke.APP_BROWSER, { + url: "file:///somewhere/" + }); + }).toThrow(); + }); }); it("calls the correct invoke URI", function () { diff --git a/test/unit/webworks/io/dir.js b/test/unit/webworks/io/dir.js new file mode 100644 index 00000000..5aa1d3b7 --- /dev/null +++ b/test/unit/webworks/io/dir.js @@ -0,0 +1,204 @@ +/* + * 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("webworks.core io.dir", function () { + var server = require('ripple/platform/webworks.core/2.0.0/server/io/dir'), + client = require('ripple/platform/webworks.core/2.0.0/client/io/dir'), + cache = require('ripple/platform/webworks.core/2.0.0/fsCache'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + FILE = "file://"; + + describe("tablet", function () { + describe("platform spec index", function () { + it("includes module according to proper object structure", function () { + var spec = require('ripple/platform/webworks.tablet/2.0.0/spec'); + expect(spec.objects.blackberry.children.io.children.dir).toEqual({ + path: "webworks.core/2.0.0/client/io/dir", + feature: "blackberry.io.dir" + }); + }); + }); + + describe("server index", function () { + it("exposes the server module", function () { + var webworks = require('ripple/platform/webworks.tablet/2.0.0/server'); + expect(webworks.blackberry.io.dir).toEqual(server); + }); + }); + }); + + describe("core", function () { + describe("client", function () { + beforeEach(function () { + spyOn(transport, "call"); + }); + + function _expectTransportToCall(url, data) { + var args = transport.call.argsForCall[0]; + expect(args[0]).toEqual(url); + expect(args[1]).toEqual(data); + } + + describe("createNewDir", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir"; + + expect(client.createNewDir(FILE + path)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/dir/createNewDir", {post: {path: path}}); + }); + }); + + describe("deleteDirectory", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir"; + + expect(client.deleteDirectory(FILE + path)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/dir/deleteDirectory", {post: {path: path}}); + }); + }); + + describe("exists", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir"; + transport.call.andReturn(true); + + expect(client.exists(FILE + path)).toEqual(true); + _expectTransportToCall("blackberry/io/dir/exists", {post: {path: path}}); + }); + }); + + describe("getParentDirectory", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir"; + transport.call.andReturn("new/new/new"); + + expect(client.getParentDirectory(FILE + path)).toEqual(FILE + "new/new/new"); + _expectTransportToCall("blackberry/io/dir/getParentDirectory", {post: {path: path}}); + }); + }); + + describe("listDirectories", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir", + dirs = ["foo", "bar"]; + + transport.call.andReturn(dirs); + + expect(client.listDirectories(FILE + path)).toEqual(dirs); + _expectTransportToCall("blackberry/io/dir/listDirectories", {post: {path: path}}); + }); + }); + + describe("listFiles", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir", + dirs = ["foo", "bar"]; + + transport.call.andReturn(dirs); + + expect(client.listFiles(FILE + path)).toEqual(dirs); + _expectTransportToCall("blackberry/io/dir/listFiles", {post: {path: path}}); + }); + }); + + describe("rename", function () { + it("calls transport with appropriate args", function () { + var path = "new/new/new/dir", + newName = "hawtness"; + + expect(client.rename(FILE + path, newName)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/dir/rename", {post: {path: path, newName: newName}}); + }); + }); + }); + + // TODO: server should also support any changed URI methods and what they return + describe("server", function () { + describe("createNewDir", function () { + it("passes to cache.dir.createNewDir", function () { + var path = "new/new/new/dir"; + spyOn(cache.dir, "createNewDir"); + + expect(server.createNewDir(null, {path: path})).toEqual({code: 1, data: undefined}); + expect(cache.dir.createNewDir).toHaveBeenCalledWith(path); + }); + }); + + describe("deleteDirectory", function () { + it("passes to cache.dir.deleteDirectory", function () { + var path = "new/new/new/dir"; + spyOn(cache.dir, "deleteDirectory"); + + expect(server.deleteDirectory(null, {path: path, recursive: false})).toEqual({code: 1, data: undefined}); + expect(cache.dir.deleteDirectory).toHaveBeenCalledWith(path, false); + }); + }); + + describe("exists", function () { + it("passes to cache.dir.exists", function () { + var path = "new/new/new/dir"; + spyOn(cache.dir, "exists").andReturn(true); + + expect(server.exists(null, {path: path})).toEqual({code: 1, data: true}); + expect(cache.dir.exists).toHaveBeenCalledWith(path); + }); + }); + + describe("getParentDirectory", function () { + it("passes to cache.dir.getParentDirectory", function () { + var path = "new/new/new/dir"; + spyOn(cache.dir, "getParentDirectory").andReturn("new/new/new"); + + expect(server.getParentDirectory(null, {path: path})).toEqual({code: 1, data: "new/new/new"}); + expect(cache.dir.getParentDirectory).toHaveBeenCalledWith(path); + }); + }); + + describe("listDirectories", function () { + it("passes to cache.dir.listDirectories", function () { + var path = "new/new/new/dir", + dirs = ["cool", "dude"]; + spyOn(cache.dir, "listDirectories").andReturn(dirs); + + expect(server.listDirectories(null, {path: path})).toEqual({code: 1, data: dirs}); + expect(cache.dir.listDirectories).toHaveBeenCalledWith(path); + }); + }); + + describe("listFiles", function () { + it("passes to cache.dir.listFiles", function () { + var path = "new/new/new/dir", + files = ["cool", "dude"]; + spyOn(cache.dir, "listFiles").andReturn(files); + + expect(server.listFiles(null, {path: path})).toEqual({code: 1, data: files}); + expect(cache.dir.listFiles).toHaveBeenCalledWith(path); + }); + }); + + describe("rename", function () { + it("passes to cache.dir.rename", function () { + var path = "new/new/new/dir", + newName = "hawtness"; + + spyOn(cache.dir, "rename"); + + expect(server.rename(null, {path: path, newName: newName})).toEqual({code: 1, data: undefined}); + expect(cache.dir.rename).toHaveBeenCalledWith(path, newName); + }); + }); + }); + }); +}); diff --git a/test/unit/webworks/io/file.js b/test/unit/webworks/io/file.js new file mode 100644 index 00000000..f568cf00 --- /dev/null +++ b/test/unit/webworks/io/file.js @@ -0,0 +1,316 @@ +/* + * 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("webworks.core io.file", function () { + var server = require('ripple/platform/webworks.core/2.0.0/server/io/file'), + client = require('ripple/platform/webworks.core/2.0.0/client/io/file'), + cache = require('ripple/platform/webworks.core/2.0.0/fsCache'), + transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), + notifications = require('ripple/notifications'), + MockBaton = function () { + this.take = jasmine.createSpy("baton.take"); + this.pass = jasmine.createSpy("baton.pass"); + }, + FILE = "file://"; + + describe("handset", function () { + describe("platform spec index", function () { + it("includes module according to proper object structure", function () { + var spec = require('ripple/platform/webworks.handset/2.0.0/spec'); + expect(spec.objects.blackberry.children.io.children.file).toEqual({ + path: "webworks.core/2.0.0/client/io/file", + feature: "blackberry.io.file" + }); + }); + }); + + describe("server index", function () { + it("exposes the server module", function () { + var webworks = require('ripple/platform/webworks.handset/2.0.0/server'); + expect(webworks.blackberry.io.file).toEqual(server); + }); + }); + }); + + describe("tablet", function () { + describe("platform spec index", function () { + it("includes module according to proper object structure", function () { + var spec = require('ripple/platform/webworks.tablet/2.0.0/spec'); + expect(spec.objects.blackberry.children.io.children.file).toEqual({ + path: "webworks.core/2.0.0/client/io/file", + feature: "blackberry.io.file" // required, but permissions are optional (see docs) + }); + }); + }); + + describe("server index", function () { + it("exposes the server module", function () { + var webworks = require('ripple/platform/webworks.tablet/2.0.0/server'); + expect(webworks.blackberry.io.file).toEqual(server); + }); + }); + }); + + describe("core", function () { + describe("client", function () { + beforeEach(function () { + spyOn(transport, "call"); + }); + + function _expectTransportToCall(url, data) { + var args = transport.call.argsForCall[0]; + expect(args[0]).toEqual(url); + expect(args[1]).toEqual(data); + } + + describe("copy", function () { + it("calls transport with appropriate args", function () { + var from = "afile", + to = "somefile"; + expect(client.copy(FILE + from, FILE + to)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/file/copy", {post: { + from: from, + to: to + }}); + }); + }); + + describe("deleteFile", function () { + it("calls transport with appropriate args", function () { + var path = "foo.js"; + expect(client.deleteFile(FILE + path)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/file/deleteFile", {post: {path: path}}); + }); + }); + + describe("exists", function () { + it("calls transport with appropriate args", function () { + var path = "foo.js"; + transport.call.andReturn("result"); + expect(client.exists(FILE + path)).toEqual("result"); + _expectTransportToCall("blackberry/io/file/exists", {post: {path: path}}); + }); + }); + + describe("getFileProperties", function () { + it("calls transport with appropriate args", function () { + var path = "foo.js", + properties = { + directory: "foo" + }, + result; + + transport.call.andReturn(properties); + result = client.getFileProperties(FILE + path); + + expect(result).toEqual(properties); + expect(result.directory).toEqual(FILE + "foo"); + _expectTransportToCall("blackberry/io/file/getFileProperties", {post: {path: path}}); + }); + }); + + describe("open", function () { + it("calls transport with appropriate args", function () { + var path = "openpath"; + expect(client.open(FILE + path)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/file/open", {post: {path: path}}); + }); + }); + + describe("readFile", function () { + it("calls the transport when sync", function () { + var success = jasmine.createSpy(), + data = "file data", + path = "path", + async = false; + + transport.call.andReturn({ + fullPath: path, + blobData: data + }); + + expect(client.readFile(FILE + path, success, async)).not.toBeDefined(); + expect(success).toHaveBeenCalledWith(FILE + path, data); + _expectTransportToCall("blackberry/io/file/readFile", {post: {path: path, async: async}}); + }); + + it("polls the transport when async", function () { + var success = jasmine.createSpy(), + data = "file data", + path = "path", + async = true; + + spyOn(transport, "poll").andCallFake(function (url, opts, callback) { + expect(callback({ + fullPath: path, + blobData: data + })).toEqual(false); + }); + + expect(client.readFile(FILE + path, success, async)).not.toBeDefined(); + expect(transport.poll.argsForCall[0][0]).toEqual("blackberry/io/file/readFile"); + expect(transport.poll.argsForCall[0][1]).toEqual({post: {path: path, async: async}}); + expect(success).toHaveBeenCalledWith(FILE + path, data); + }); + }); + + describe("rename", function () { + it("calls transport with appropriate args", function () { + var path = "foo/bar.js", + newName = "new.js"; + expect(client.rename(FILE + path, newName)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/file/rename", {post: {path: path, newName: newName}}); + }); + }); + + describe("saveFile", function () { + it("calls transport with appropriate args", function () { + var path = "foo/bar.js", + blob = { + size: 4 + }; + expect(client.saveFile(FILE + path, blob)).not.toBeDefined(); + _expectTransportToCall("blackberry/io/file/saveFile", {post: {path: path, blob: blob}}); + }); + }); + }); + + // TODO: server should also support any changed URI methods and what they return + describe("server", function () { + describe("copy", function () { + it("passes to cache.file.copy", function () { + var from = "path", + to = "newpath"; + spyOn(cache.file, "copy"); + expect(server.copy(null, {from: from, to: to})).toEqual({code: 1, data: undefined}); + expect(cache.file.copy).toHaveBeenCalledWith(from, to); + }); + }); + + describe("deleteFile", function () { + it("passes to cache.file.deleteFile", function () { + var path = "apath"; + spyOn(cache.file, "deleteFile"); + expect(server.deleteFile(null, {path: path})).toEqual({code: 1, data: undefined}); + expect(cache.file.deleteFile).toHaveBeenCalledWith(path); + }); + }); + + describe("exists", function () { + it("passes to cache.file.exists", function () { + var path = "apath"; + spyOn(cache.file, "exists").andReturn(true); + expect(server.exists(null, {path: path})).toEqual({code: 1, data: true}); + expect(cache.file.exists).toHaveBeenCalledWith(path); + }); + }); + + describe("getFileProperties", function () { + it("passes to cache.file.getFileProperties", function () { + var path = "apath"; + spyOn(cache.file, "getFileProperties").andReturn({prop: 1}); + expect(server.getFileProperties(null, {path: path})).toEqual({code: 1, data: {prop: 1}}); + expect(cache.file.getFileProperties).toHaveBeenCalledWith(path); + }); + }); + + describe("open", function () { + it("raises a notification that the file was opened", function () { + var path = "path"; + spyOn(notifications, "openNotification"); + spyOn(cache.file, "exists"); + server.open(null, {path: path}); + expect(notifications.openNotification.argsForCall[0][0]).toEqual("normal"); + }); + + it("returns true when file exists", function () { + var path = "path"; + spyOn(cache.file, "exists").andReturn(true); + expect(server.open(null, {path: path})).toEqual({code: 1, data: true}); + }); + + it("returns false when file does not exist", function () { + var path = "path"; + spyOn(cache.file, "exists").andReturn(false); + expect(server.open(null, {path: path})).toEqual({code: 1, data: false}); + }); + }); + + describe("readFile", function () { + it("returns file data synchronously", function () { + var baton = new MockBaton(), + async = false, + path = "filepath", + data = "filedata"; + + spyOn(cache.file, "readFile").andCallFake(function (p, success, async) { + success(data); + }); + + expect(server.readFile(null, {path: path, async: async}, baton)).toEqual({code: 1, data: { + fullPath: path, + blobData: data + }}); + + expect(cache.file.readFile.argsForCall[0][0]).toEqual(path); + expect(cache.file.readFile.argsForCall[0][2]).toEqual(async); + expect(baton.take).not.toHaveBeenCalled(); + expect(baton.pass).not.toHaveBeenCalledWith(); + }); + + it("returns file data asynchronously", function () { + var baton = new MockBaton(), + async = true, + path = "filepath", + data = "filedata"; + + spyOn(cache.file, "readFile").andCallFake(function (p, success, async) { + success(data); + }); + + server.readFile(null, {path: path, async: async}, baton); + + expect(cache.file.readFile.argsForCall[0][0]).toEqual(path); + expect(cache.file.readFile.argsForCall[0][2]).toEqual(async); + expect(baton.take).toHaveBeenCalled(); + expect(baton.pass).toHaveBeenCalledWith({code: 1, data: { + fullPath: path, + blobData: data + }}); + }); + }); + + describe("rename", function () { + it("passes to cache.file.rename", function () { + var path = "foo/bar", + newName = "bar2"; + spyOn(cache.file, "rename"); + expect(server.rename(null, {path: path, newName: newName})).toEqual({code: 1, data: undefined}); + expect(cache.file.rename).toHaveBeenCalledWith(path, newName); + }); + }); + + describe("saveFile", function () { + it("passes to cache.file.saveFile", function () { + var path = "apath", + blob = {size: 3}; + spyOn(cache.file, "saveFile"); + expect(server.saveFile(null, {path: path, blob: blob})).toEqual({code: 1, data: undefined}); + expect(cache.file.saveFile).toHaveBeenCalledWith(path, blob); + }); + }); + }); + }); +}); diff --git a/test/unit/webworks/menu.js b/test/unit/webworks/menu.js index 20d4c827..4c9273d3 100644 --- a/test/unit/webworks/menu.js +++ b/test/unit/webworks/menu.js @@ -84,6 +84,8 @@ describe("webworks menu", function () { it("calls the transport", function () { var item = new MenuItem(1, 2); spyOn(transport, "call"); + + client.addMenuItem(item); client.setDefaultMenuItem(item); expect(transport.call).toHaveBeenCalledWith("blackberry/ui/menu/setDefaultMenuItem", { get: {id: item.id} diff --git a/test/unit/webworks/phone.js b/test/unit/webworks/phone.js index 26fd7c25..bc90372a 100644 --- a/test/unit/webworks/phone.js +++ b/test/unit/webworks/phone.js @@ -68,17 +68,43 @@ describe("webworks phone", function () { describe("addPhoneLogListener", function () { var callback = function () {}; - it("calls the transport with proper args when there are callbacks", function () { + beforeEach(function () { spyOn(transport, "poll"); + }); + + it("calls the transport with proper args when there are callbacks", function () { PhoneLogs.addPhoneLogListener(callback, callback, callback, callback); expect(transport.poll.callCount).toBe(4); }); it("does not register the event handler if a callback is null", function () { - spyOn(transport, "poll"); PhoneLogs.addPhoneLogListener(callback, null, callback, null); expect(transport.poll.callCount).toBe(2); }); + + it("maps the response into CallLog objects", function () { + var data = {log: {status: 5}, log2: {status: 3}}; + + callback = jasmine.createSpy(); + transport.poll.andCallFake(function (url, opts, callback) { + callback(data); + }); + + PhoneLogs.addPhoneLogListener(callback, null, null, null); + + expect(callback.argsForCall[0][0] instanceof CallLog).toBe(true); + expect(callback.argsForCall[0][0].status).toBe(data.log.status); + expect(callback.argsForCall[0][1] instanceof CallLog).toBe(true); + expect(callback.argsForCall[0][1].status).toBe(data.log2.status); + }); + + it("returns true when adding some listeners", function () { + expect(PhoneLogs.addPhoneLogListener(callback, null, null, callback)).toBe(true); + }); + + it("returns false when adding no listeners", function () { + expect(PhoneLogs.addPhoneLogListener()).toBe(false); + }); }); describe("callAt", function () { @@ -211,10 +237,14 @@ describe("webworks phone", function () { }); it("passes the baton when PhoneCallLogAdded raised", function () { - var baton = new MockBaton(); + var baton = new MockBaton(), + log = new CallLog(); phone.logs.onCallLogAdded(null, null, baton); - event.trigger("PhoneCallLogAdded", [new CallLog()], true); - expect(baton.pass).toHaveBeenCalled(); + event.trigger("PhoneCallLogAdded", [log], true); + expect(baton.pass).toHaveBeenCalledWith({ + code: 1, + data: {log: log} + }); }); }); @@ -226,10 +256,14 @@ describe("webworks phone", function () { }); it("passes the baton when PhoneCallLogRemoved raised", function () { - var baton = new MockBaton(); + var baton = new MockBaton(), + log = new CallLog(); phone.logs.onCallLogRemoved(null, null, baton); - event.trigger("PhoneCallLogRemoved", [new CallLog()], true); - expect(baton.pass).toHaveBeenCalled(); + event.trigger("PhoneCallLogRemoved", [log], true); + expect(baton.pass).toHaveBeenCalledWith({ + code: 1, + data: {log: log} + }); }); }); @@ -241,10 +275,15 @@ describe("webworks phone", function () { }); it("passes the baton when PhoneCallLogRemoved raised", function () { - var baton = new MockBaton(); + var baton = new MockBaton(), + log = new CallLog(); phone.logs.onCallLogRemoved(null, null, baton); - event.trigger("PhoneCallLogRemoved", [new CallLog()], true); + event.trigger("PhoneCallLogRemoved", [log], true); expect(baton.pass).toHaveBeenCalled(); + expect(baton.pass).toHaveBeenCalledWith({ + code: 1, + data: {log: log} + }); }); }); @@ -256,10 +295,19 @@ describe("webworks phone", function () { }); it("passes the baton when PhoneCallLogUpdated raised", function () { - var baton = new MockBaton(); + var baton = new MockBaton(), + log = new CallLog(), + log2 = new CallLog(); phone.logs.onCallLogUpdated(null, null, baton); - event.trigger("PhoneCallLogUpdated", [new CallLog(), new CallLog()], true); + event.trigger("PhoneCallLogUpdated", [log, log2], true); expect(baton.pass).toHaveBeenCalled(); + expect(baton.pass).toHaveBeenCalledWith({ + code: 1, + data: { + newLog: log, + oldLog: log2 + } + }); }); }); @@ -553,7 +601,7 @@ describe("webworks phone", function () { expect(baton.pass).toHaveBeenCalled(); result = baton.pass.mostRecentCall.args[0]; - expect(result.id).toBe(1); + expect(result.code).toBe(1); expect(result.data.callId).toBe(456); expect(result.data.error).toBe(789); }); diff --git a/test/unit/webworks/sms.js b/test/unit/webworks/sms.js index 097c249c..e049826b 100644 --- a/test/unit/webworks/sms.js +++ b/test/unit/webworks/sms.js @@ -18,26 +18,18 @@ describe("webworks_sms", function () { smsClient = require('ripple/platform/webworks.handset/2.0.0/client/sms'), transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), event = require('ripple/event'), - sinon = require('sinon'), platform = require('ripple/platform'), notifications = require('ripple/notifications'), - constants = require('ripple/constants'), _console = require('ripple/console'), MockBaton = function () { this.take = jasmine.createSpy('baton.take'); this.pass = jasmine.createSpy('baton.pass'); - }, - s; + }; beforeEach(function () { - s = sinon.sandbox.create(); spyOn(_console, "log"); }); - afterEach(function () { - s.verifyAndRestore(); - }); - describe("in server", function () { it("exposes the sms module", function () { var webworks = require('ripple/platform/webworks.handset/2.0.0/server'); @@ -76,18 +68,45 @@ describe("webworks_sms", function () { expect(transport.poll.argsForCall[0][0]).toEqual("blackberry/message/sms/onReceive"); }); }); + + describe("isListeningForMessage", function () { + describe("getter", function () { + it("calls the transport appropriately", function () { + spyOn(transport, "call").andReturn(true); + + expect(smsClient.isListeningForMessage).toBe(true); + expect(transport.call).toHaveBeenCalledWith("blackberry/message/sms/isListeningForMessage", { + async: false + }); + }); + }); + + describe("setter", function () { + it("calls the transport appropriately", function () { + spyOn(transport, "call").andReturn(true); + smsClient.isListeningForMessage = false; + + expect(transport.call).toHaveBeenCalledWith("blackberry/message/sms/isListeningForMessage", { + async: false, + get: {isListeningForMessage: false} + }); + }); + }); + }); }); describe("in server/sms", function () { it("send raises a notification", function () { spyOn(platform, "current").andReturn({name: "generic"}); - s.mock(notifications).expects("openNotification") - .withExactArgs(constants.NOTIFICATIONS.TYPES.NORMAL, - "To 5199541707: Pick up some milk").once(); + spyOn(notifications, "openNotification"); + sms.send({ message: "Pick up some milk", address: "5199541707" }); + + expect(notifications.openNotification).toHaveBeenCalledWith("normal", + "To 5199541707: Pick up some milk"); }); describe("when calling onSMS", function () { @@ -138,6 +157,36 @@ describe("webworks_sms", function () { body: "ILOVEYOULETTER.txt.vbs" }], true); expect(baton.pass).not.toHaveBeenCalled(); + event.trigger("MessageReceived", [{type: 'sms'}], true); // clear isListeningForMessage + }); + }); + + describe("isListeningForMessage", function () { + it("returns false if not currently listening", function () { + expect(sms.isListeningForMessage()).toEqual({code: 1, data: false}); + }); + + it("can be set", function () { + expect(sms.isListeningForMessage()).toEqual({code: 1, data: false}); + expect(sms.isListeningForMessage({isListeningForMessage: true})).toEqual({ + code: 1, + data: true + }); + }); + + it("it doesn't pass the baton if isListeningForMessage is false", function () { + var baton = new MockBaton(); + + sms.onReceive({}, {}, baton); + expect(sms.isListeningForMessage()).toEqual({code: 1, data: true}); + sms.isListeningForMessage({isListeningForMessage: false}); + + event.trigger("MessageReceived", [{type: 'sms'}], true); + expect(baton.pass).not.toHaveBeenCalled(); + expect(sms.isListeningForMessage()).toEqual({code: 1, data: false}); + + // cleanup + event.trigger("MessageReceived", [{type: 'sms'}], true); }); }); }); diff --git a/test/unit/webworks/system.js b/test/unit/webworks/system.js index 43648e91..2041fc93 100644 --- a/test/unit/webworks/system.js +++ b/test/unit/webworks/system.js @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -describe("webworks system", function () { +describe("webworks.core system", function () { var system = require('ripple/platform/webworks.core/2.0.0/server/system'), - systemEvent = require('ripple/platform/webworks.handset/2.0.0/server/systemEvent'), client = require('ripple/platform/webworks.core/2.0.0/client/system'), transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), deviceSpec = require('ripple/platform/webworks.handset/2.0.0/spec/device'), @@ -23,22 +22,10 @@ describe("webworks system", function () { utils = require('ripple/utils'), deviceSettings = require('ripple/deviceSettings'), notifications = require('ripple/notifications'), - constants = require('ripple/constants'), Playbook = require('ripple/devices/Playbook'), devices = require('ripple/devices'), platform = require('ripple/platform'); - // this only tests handset (not tablet) - describe("using server", function () { - it("exposes the system module", function () { - var webworks = require('ripple/platform/webworks.handset/2.0.0/server'), - obj = {}; - obj.event = systemEvent; - utils.mixin(system, obj); - expect(webworks.blackberry.system).toEqual(obj); - }); - }); - describe("client", function () { describe("hasCapability", function () { it("calls the transport with id and properties", function () { @@ -77,17 +64,6 @@ describe("webworks system", function () { expect(transport.call).toHaveBeenCalledWith("blackberry/system/isMassStorageActive"); }); }); - - describe("setHomeScreenBackground", function () { - it("calls the transport with id and properties", function () { - spyOn(transport, "call"); - client.setHomeScreenBackground("filepath"); - expect(transport.call).toHaveBeenCalledWith("blackberry/system/setHomeScreenBackground", { - get: {filePath: "filepath"}, - async: true - }); - }); - }); }); describe("using server/system", function () { @@ -161,7 +137,7 @@ describe("webworks system", function () { var args = {filePath: "the path"}; spyOn(notifications, "openNotification"); system.setHomeScreenBackground(args); - expect(notifications.openNotification.mostRecentCall.args[0]).toEqual(constants.NOTIFICATIONS.TYPES.NORMAL); + expect(notifications.openNotification.mostRecentCall.args[0]).toEqual("normal"); expect(notifications.openNotification.mostRecentCall.args[1]).toMatch(args.filePath); }); }); @@ -271,6 +247,14 @@ describe("webworks system", function () { desiredModule: "blackberry.pim.memo" }).data).toBe(client.ALLOW); }); + + it("returns ALLOW by default if there is are no declared features", function () { + spyOn(app, "getInfo").andReturn({}); + + expect(system.hasPermission({ + desiredModule: "blackberry.invoke" + }).data).toBe(client.ALLOW); + }); }); describe("network", function () { diff --git a/test/unit/webworks/systemEvent.js b/test/unit/webworks/systemEvent.js index 5265f078..06364d68 100644 --- a/test/unit/webworks/systemEvent.js +++ b/test/unit/webworks/systemEvent.js @@ -23,6 +23,49 @@ describe("webworks.handset system event", function () { this.pass = jasmine.createSpy('baton.pass'); }; + describe("core platform spec", function () { + var events = require('ripple/platform/webworks.core/2.0.0/spec/events'); + + describe("events", function () { + describe("app.event.onBackground callback", function () { + it("triggers AppSwipeDown", function () { + spyOn(event, "trigger"); + events["app.event.onBackground"].callback(); + expect(event.trigger).toHaveBeenCalledWith("AppRequestBackground"); + }); + }); + + describe("app.event.onForeground callback", function () { + it("triggers AppSwipeStart", function () { + spyOn(event, "trigger"); + events["app.event.onForeground"].callback(); + expect(event.trigger).toHaveBeenCalledWith("AppRequestForeground"); + }); + }); + }); + }); + + describe("handset platform spec", function () { + describe("events", function () { + var events = require('ripple/platform/webworks.handset/2.0.0/spec').events; + + describe("system.event.onHardwareKey callback", function () { + it("triggers HardwareKey", function () { + spyOn(event, "trigger"); + events["system.event.onHardwareKey"].callback(2); + expect(event.trigger).toHaveBeenCalledWith("HardwareKey", [2]); + }); + }); + + describe("system.event.onCoverageChange callback", function () { + it("triggers CoverageChange", function () { + spyOn(event, "trigger"); + events["system.event.onCoverageChange"].callback(); + expect(event.trigger).toHaveBeenCalledWith("CoverageChange"); + }); + }); + }); + }); describe("using server", function () { it("exposes the system event module", function () { var webworks = require('ripple/platform/webworks.handset/2.0.0/server'); @@ -64,7 +107,7 @@ describe("webworks.handset system event", function () { expect(baton.take).toHaveBeenCalled(); }); - it("passes the baton when CoverageChanged is raised", function () { + it("passes the baton when CoverageChange is raised", function () { var baton = new MockBaton(); sysEvent.onCoverageChange({}, {}, baton); event.trigger("CoverageChange", [], true); diff --git a/test/unit/webworks/utils.js b/test/unit/webworks/utils.js new file mode 100644 index 00000000..f7d77d27 --- /dev/null +++ b/test/unit/webworks/utils.js @@ -0,0 +1,84 @@ +/* + * 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/platform/webworks.core/2.0.0/client/utils'); + +describe("utils", function () { + beforeEach(function () { + global.FileReader = jasmine.createSpy(); + global.BlobBuilder = global.WebKitBlobBuilder = jasmine.createSpy(); + }); + + afterEach(function () { + delete global.FileReader; + delete global.BlobBuilder; + delete global.WebKitBlobBuilder; + }); + + describe("handset", function () { + describe("platform spec index", function () { + it("includes module according to proper object structure", function () { + var spec = require('ripple/platform/webworks.handset/2.0.0/spec'); + expect(spec.objects.blackberry.children.utils).toEqual({ + path: "webworks.core/2.0.0/client/utils", + feature: "blackberry.utils" + }); + }); + }); + }); + + describe("tablet", function () { + describe("platform spec index", function () { + it("includes module according to proper object structure", function () { + var spec = require('ripple/platform/webworks.tablet/2.0.0/spec'); + expect(spec.objects.blackberry.children.utils).toEqual({ + path: "webworks.core/2.0.0/client/utils", + feature: "blackberry.utils" + }); + }); + }); + }); + + describe("blobToString and stringToBlob", function () { + it("can translate a blob into a string and back", function () { + var blobBuilder = { + append: jasmine.createSpy(), + getBlob: jasmine.createSpy().andReturn({}) + }, + str = "da foo", + fileReader = { + readAsText: jasmine.createSpy().andCallFake(function (blob, encoding) { + fileReader.result = str; + runs(function () { + fileReader.onloadend(); + }); + }), + result: null + }, + blob; + + FileReader.andReturn(fileReader); + BlobBuilder.andReturn(blobBuilder); + + blob = utils.stringToBlob(str); + + expect(blob.uuid).toBeDefined(); + expect(utils.blobToString(blob)).toEqual(fileReader.result); + expect(fileReader.readAsText).toHaveBeenCalledWith(blob); + expect(utils.stringToBlob(str)).toEqual(blob); + expect(blobBuilder.append).toHaveBeenCalledWith(str); + }); + }); +}); diff --git a/test/unit/widgetConfig.js b/test/unit/widgetConfig.js index d780dabb..1aee8898 100644 --- a/test/unit/widgetConfig.js +++ b/test/unit/widgetConfig.js @@ -23,159 +23,131 @@ describeBrowser("widgetConfig", function () { return xmlHttp.responseXML; } - window.fooConfig = _getConfig; - var widgetConfig = require('ripple/widgetConfig'), platform = require('ripple/platform'); - it("validateNumberOfArguments_Throws_Exception_If_No_Arguments", function () { - expect(function () { - widgetConfig.validate(); - }).toThrow(function (e) { - return e.type === "ArgumentLength"; + describe("phonegap config", function () { + beforeEach(function () { + spyOn(platform, "current").andReturn(require('ripple/platform/phonegap/1.0/spec')); }); - }); - - it("load_config_file", function () { - var configXML = _getConfig("config.xml"); - expect(typeof configXML === "object"); - }); - it("config_no_namespaces_file_loads_and_we_can_parse_the_first_node", function () { - var evaluator, - configXML, - resolver, - results, - configNodes; - - configXML = _getConfig("config_no_namespaces.xml"); + it("validateNumberOfArguments_Throws_Exception_If_No_Arguments", function () { + expect(function () { + widgetConfig.validate(); + }).toThrow(function (e) { + return e.type === "ArgumentLength"; + }); + }); - evaluator = new XPathEvaluator(); - resolver = evaluator.createNSResolver(configXML); - configNodes = evaluator.evaluate("//*[name()='widget']", configXML, - null, XPathResult.ANY_TYPE, null); + it("load_config_file", function () { + var configXML = _getConfig("config.xml"); + expect(typeof configXML === "object"); + }); - results = configNodes.iterateNext(); + it("config_no_namespaces_file_loads_and_we_can_parse_the_first_node", function () { + var evaluator, + configXML, + resolver, + results, + configNodes; - expect(typeof configNodes === "object"); - }); + configXML = _getConfig("config_no_namespaces.xml"); - it("config_file_loads_and_we_can_parse_a_namespaced_node", function () { - var configXML, - evaluator, - resolver, - configNodes; + evaluator = new XPathEvaluator(); + resolver = evaluator.createNSResolver(configXML); + configNodes = evaluator.evaluate("//*[name()='widget']", configXML, + null, XPathResult.ANY_TYPE, null); - configXML = _getConfig("config.xml"); + results = configNodes.iterateNext(); - evaluator = new XPathEvaluator(); - resolver = evaluator.createNSResolver(configXML); - configNodes = configXML.evaluate("//*[name()='JIL:billing']", configXML, - resolver, XPathResult.ANY_TYPE, null); + expect(typeof configNodes === "object"); + }); - expect(typeof configNodes).toEqual("object"); - }); + it("config_file_loads_and_we_can_parse_a_namespaced_node", function () { + var configXML, + evaluator, + resolver, + configNodes; - it("config_file_validation_returns_true_for_a_valid_config_file", function () { - var configXML; + configXML = _getConfig("config.xml"); - configXML = _getConfig("config.xml"); - expect(widgetConfig.validate(configXML).widget.validationResult[0].valid).toEqual(true); - }); + evaluator = new XPathEvaluator(); + resolver = evaluator.createNSResolver(configXML); + configNodes = configXML.evaluate("//*[name()='JIL:billing']", configXML, + resolver, XPathResult.ANY_TYPE, null); - it("config_file_validation_returns_returns_proper_nodes_as_being_validated", function () { - var configXML, - result; - - configXML = _getConfig("config.xml"); - - result = widgetConfig.validate(configXML).widget; - - expect(result.validationResult[0].valid).toEqual(true); - expect(result.children["preference"].validationResult[0].valid).toEqual(true); - expect(result.children["name"].validationResult[0].valid).toEqual(true); - expect(result.children["description"].validationResult[0].valid).toEqual(true); - expect(result.children["icon"].validationResult[0].valid).toEqual(true); - expect(result.children["author"].validationResult[0].valid).toEqual(true); - expect(result.children["content"].validationResult[0].valid).toEqual(true); - expect(result.children["feature"].validationResult[0].valid).toEqual(true); - expect(result.children["JIL:maximum_display_mode"].validationResult[0].valid).toEqual(true); - expect(result.children["JIL:update"].validationResult[0].valid).toEqual(true); - expect(result.children["JIL:access"].validationResult[0].valid).toEqual(true); - expect(result.children["JIL:billing"].validationResult[0].valid).toEqual(true); - }); - - it("config_file_validation_validates_for_required_widget_and_icon_nodes", function () { - var configXML, - result; + expect(typeof configNodes).toEqual("object"); + }); - configXML = _getConfig("config_no_widet_node.xml"); + it("config_file_validation_returns_true_for_a_valid_config_file", function () { + var configXML = _getConfig("config.xml"); + expect(widgetConfig.validate(configXML).widget.validationResult[0].valid).toEqual(true); + }); - result = widgetConfig.validate(configXML).widget; + it("config_file_validation_returns_returns_proper_nodes_as_being_validated", function () { + var configXML = _getConfig("config.xml"), + result = widgetConfig.validate(configXML).widget; - expect(result).toBeTruthy(); - expect(result.validationResult[0].message).toEqual("widget node expected, but not found"); - }); + expect(result.validationResult[0].valid).toEqual(true); + expect(result.children["name"].validationResult[0].valid).toEqual(true); + expect(result.children["description"].validationResult[0].valid).toEqual(true); + expect(result.children["icon"].validationResult[0].valid).toEqual(true); + expect(result.children["author"].validationResult[0].valid).toEqual(true); + expect(result.children["feature"].validationResult[0].valid).toEqual(true); + }); - it("config_file_validation_validates_that_only_one_name_node_can_exist", function () { - var configXML, - result; + it("config_file_validation_validates_for_required_widget_and_icon_nodes", function () { + var configXML = _getConfig("config_no_widget_node.xml"), + result = widgetConfig.validate(configXML).widget; - configXML = _getConfig("config_multiple_name_nodes.xml"); + expect(result).toBeTruthy(); + expect(result.validationResult[0].message).toEqual("widget node expected, but not found"); + }); - result = widgetConfig.validate(configXML).widget; + it("config_file_validation_validates_that_only_one_name_node_can_exist", function () { + var configXML = _getConfig("config_multiple_name_nodes.xml"), + result = widgetConfig.validate(configXML).widget; - expect(result.children.name.validationResult[1].attributes["xml:lang"].message) - .toEqual("name.xml:lang node is allowed to appear multiple times, however it must be unique based on " + - "this attribute and in this case another node with an identical attribute vale was found"); - }); + expect(result.children.name.validationResult[1].attributes["xml:lang"].message) + .toEqual("name.xml:lang node is allowed to appear multiple times, however it must be unique based on " + + "this attribute and in this case another node with an identical attribute vale was found"); + }); - it("config_file_validation_validates_that_multiple_unique_name_node_can_exist", function () { - var configXML, - result; + it("config_file_validation_validates_that_multiple_unique_name_node_can_exist", function () { + var configXML = _getConfig("config_multiple_name_nodes_unique.xml"), + result = widgetConfig.validate(configXML).widget; - configXML = _getConfig("config_multiple_name_nodes_unique.xml"); - result = widgetConfig.validate(configXML).widget; - expect(result.children.name.validationResult[0].valid).toEqual(true); - }); + expect(result.children.name.validationResult[0].valid).toEqual(true); + }); - it("config_file_validation_fails_for_bad_attributes", function () { - var configXML, - result; + it("config_file_validation_fails_for_bad_attributes", function () { + var configXML = _getConfig("config_with_missing_attributes.xml"), + result = widgetConfig.validate(configXML).widget; - configXML = _getConfig("config_with_missing_attributes.xml"); + expect(result.children.icon.validationResult[0].attributes.src.message).toEqual("icon.src attribute was expected but not found"); + }); - result = widgetConfig.validate(configXML).widget; + it("config_file_validation_catches_bad_urls_and_emails_in_attributes", function () { + var configXML = _getConfig("config_with_bad_url_email_attributes.xml"), + result = widgetConfig.validate(configXML).widget; - expect(result.validationResult[0].attributes.id.message).toEqual("widget.id attribute was expected but not found"); - expect(result.validationResult[0].attributes.version.message).toEqual("widget.version attribute was expected but not found"); - expect(result.validationResult[0].attributes.height.message).toEqual("widget.height attribute was expected but not found"); - expect(result.validationResult[0].attributes.width.message).toEqual("widget.width attribute was expected but not found"); - expect(result.children.icon.validationResult[0].attributes.src.message).toEqual("icon.src attribute was expected but not found"); + expect(result.children.author.validationResult[0].attributes.email.message) + .toEqual("author.email value does not match expected format. Value should pass this regular expression validation: " + + (/^([^@\s]+)@((?:[\-a-z0-9]+\.)+[a-z]{2,})$/)); + }); }); - it("config_file_validation_catches_bad_urls_and_emails_in_attributes", function () { - var configXML, - result; - - configXML = _getConfig("config_with_bad_url_email_attributes.xml"); - result = widgetConfig.validate(configXML).widget; - - expect("author.email value does not match expected format. Value should pass this regular expression validation: " + (/^([^@\s]+)@((?:[\-a-z0-9]+\.)+[a-z]{2,})$/)) - .toEqual(result.children.author.validationResult[0].attributes.email.message); - expect("JIL:update.href value does not match expected format. Value should pass this regular expression validation: " + - (/^((https?|ftp|gopher|telnet|file|notes|ms-help):((\/\/)|(\\\\))+[\w\d:#@%\/;$()~_?\+-=\\\.&]*)$/)) - .toEqual(result.children["JIL:update"].validationResult[0].attributes.href.message); - }); + describe("webworks config", function () { + beforeEach(function () { + spyOn(platform, "current").andReturn(require('ripple/platform/webworks.handset/2.0.0/spec')); + }); - it("can handle duplicate nodes at different levels", function () { - var configXML, - widget; + it("can handle duplicate nodes at different levels", function () { + var configXML = _getConfig("config_multiple_nested_features.xml"), + widget = widgetConfig.validate(configXML).widget; - spyOn(platform, "current").andReturn(require('ripple/platform/webworks.handset/2.0.0/spec')); - configXML = _getConfig("config_multiple_nested_features.xml"); - widget = widgetConfig.validate(configXML).widget; - expect(widget.children.feature.validationResult.length).toBe(1); - expect(widget.children.access.children.feature.validationResult.length).toBe(2); + expect(widget.children.feature.validationResult.length).toBe(1); + expect(widget.children.access.children.feature.validationResult.length).toBe(2); + }); }); }); diff --git a/test/unit/xhr.js b/test/unit/xhr.js index e625cef0..42761207 100644 --- a/test/unit/xhr.js +++ b/test/unit/xhr.js @@ -105,7 +105,6 @@ describe("xhr", function () { }); // TODO: add tests (cors) - // open (ex fileSystem.getURI) // test defaulting to base on local request describe("xhr/cors", function () { it("exports a mappable xhr object", function () { diff --git a/thirdparty/jasmine b/thirdparty/jasmine index d7cced2e..6b595672 160000 --- a/thirdparty/jasmine +++ b/thirdparty/jasmine @@ -1 +1 @@ -Subproject commit d7cced2e7ceb793a7643120b276ac81d3799531c +Subproject commit 6b5956724b7e64325c6465bc426bd924d6f2aefe diff --git a/thirdparty/jquery.dimensions.js b/thirdparty/jquery.dimensions.js deleted file mode 100644 index 0655c649..00000000 --- a/thirdparty/jquery.dimensions.js +++ /dev/null @@ -1,655 +0,0 @@ -/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * $LastChangedDate: 2007-08-17 13:14:11 -0500 (Fri, 17 Aug 2007) $ - * $Rev: 2759 $ - * - * Version: 1.1.2 - * - * Requires: jQuery 1.1.3+ - */ - -(function($){ - -// store a copy of the core height and width methods -var height = $.fn.height, - width = $.fn.width; - -$.fn.extend({ - /** - * If used on document, returns the document's height (innerHeight). - * If used on window, returns the viewport's (window) height. - * See core docs on height() to see what happens when used on an element. - * - * @example $("#testdiv").height() - * @result 200 - * - * @example $(document).height() - * @result 800 - * - * @example $(window).height() - * @result 400 - * - * @name height - * @type Number - * @cat Plugins/Dimensions - */ - height: function() { - if ( !this[0] ) error(); - if ( this[0] == window ) - if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) ) - return self.innerHeight - (($(document).height() > self.innerHeight) ? getScrollbarWidth() : 0); - else if ( $.browser.safari ) - return self.innerHeight; - else - return $.boxModel && document.documentElement.clientHeight || document.body.clientHeight; - - if ( this[0] == document ) - return Math.max( ($.boxModel && document.documentElement.scrollHeight || document.body.scrollHeight), document.body.offsetHeight ); - - return height.apply(this, arguments); - }, - - /** - * If used on document, returns the document's width (innerWidth). - * If used on window, returns the viewport's (window) width. - * See core docs on width() to see what happens when used on an element. - * - * @example $("#testdiv").width() - * @result 200 - * - * @example $(document).width() - * @result 800 - * - * @example $(window).width() - * @result 400 - * - * @name width - * @type Number - * @cat Plugins/Dimensions - */ - width: function() { - if (!this[0]) error(); - if ( this[0] == window ) - if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) ) - return self.innerWidth - (($(document).width() > self.innerWidth) ? getScrollbarWidth() : 0); - else if ( $.browser.safari ) - return self.innerWidth; - else - return $.boxModel && document.documentElement.clientWidth || document.body.clientWidth; - - if ( this[0] == document ) - if ($.browser.mozilla) { - // mozilla reports scrollWidth and offsetWidth as the same - var scrollLeft = self.pageXOffset; - self.scrollTo(99999999, self.pageYOffset); - var scrollWidth = self.pageXOffset; - self.scrollTo(scrollLeft, self.pageYOffset); - return document.body.offsetWidth + scrollWidth; - } - else - return Math.max( (($.boxModel && !$.browser.safari) && document.documentElement.scrollWidth || document.body.scrollWidth), document.body.offsetWidth ); - - return width.apply(this, arguments); - }, - - /** - * Gets the inner height (excludes the border and includes the padding) for the first matched element. - * If used on document, returns the document's height (innerHeight). - * If used on window, returns the viewport's (window) height. - * - * @example $("#testdiv").innerHeight() - * @result 210 - * - * @name innerHeight - * @type Number - * @cat Plugins/Dimensions - */ - innerHeight: function() { - if (!this[0]) error(); - return this[0] == window || this[0] == document ? - this.height() : - this.is(':visible') ? - this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') : - this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom'); - }, - - /** - * Gets the inner width (excludes the border and includes the padding) for the first matched element. - * If used on document, returns the document's width (innerWidth). - * If used on window, returns the viewport's (window) width. - * - * @example $("#testdiv").innerWidth() - * @result 210 - * - * @name innerWidth - * @type Number - * @cat Plugins/Dimensions - */ - innerWidth: function() { - if (!this[0]) error(); - return this[0] == window || this[0] == document ? - this.width() : - this.is(':visible') ? - this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') : - this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight'); - }, - - /** - * Gets the outer height (includes the border and padding) for the first matched element. - * If used on document, returns the document's height (innerHeight). - * If used on window, returns the viewport's (window) height. - * - * The margin can be included in the calculation by passing an options map with margin - * set to true. - * - * @example $("#testdiv").outerHeight() - * @result 220 - * - * @example $("#testdiv").outerHeight({ margin: true }) - * @result 240 - * - * @name outerHeight - * @type Number - * @param Map options Optional settings to configure the way the outer height is calculated. - * @cat Plugins/Dimensions - */ - outerHeight: function(options) { - if (!this[0]) error(); - options = $.extend({ margin: false }, options || {}); - return this[0] == window || this[0] == document ? - this.height() : - this.is(':visible') ? - this[0].offsetHeight + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0) : - this.height() - + num(this,'borderTopWidth') + num(this, 'borderBottomWidth') - + num(this, 'paddingTop') + num(this, 'paddingBottom') - + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0); - }, - - /** - * Gets the outer width (including the border and padding) for the first matched element. - * If used on document, returns the document's width (innerWidth). - * If used on window, returns the viewport's (window) width. - * - * The margin can be included in the calculation by passing an options map with margin - * set to true. - * - * @example $("#testdiv").outerWidth() - * @result 1000 - * - * @example $("#testdiv").outerWidth({ margin: true }) - * @result 1020 - * - * @name outerHeight - * @type Number - * @param Map options Optional settings to configure the way the outer width is calculated. - * @cat Plugins/Dimensions - */ - outerWidth: function(options) { - if (!this[0]) error(); - options = $.extend({ margin: false }, options || {}); - return this[0] == window || this[0] == document ? - this.width() : - this.is(':visible') ? - this[0].offsetWidth + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0) : - this.width() - + num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') - + num(this, 'paddingLeft') + num(this, 'paddingRight') - + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0); - }, - - /** - * Gets how many pixels the user has scrolled to the right (scrollLeft). - * Works on containers with overflow: auto and window/document. - * - * @example $(window).scrollLeft() - * @result 100 - * - * @example $(document).scrollLeft() - * @result 100 - * - * @example $("#testdiv").scrollLeft() - * @result 100 - * - * @name scrollLeft - * @type Number - * @cat Plugins/Dimensions - */ - /** - * Sets the scrollLeft property for each element and continues the chain. - * Works on containers with overflow: auto and window/document. - * - * @example $(window).scrollLeft(100).scrollLeft() - * @result 100 - * - * @example $(document).scrollLeft(100).scrollLeft() - * @result 100 - * - * @example $("#testdiv").scrollLeft(100).scrollLeft() - * @result 100 - * - * @name scrollLeft - * @param Number value A positive number representing the desired scrollLeft. - * @type jQuery - * @cat Plugins/Dimensions - */ - scrollLeft: function(val) { - if (!this[0]) error(); - if ( val != undefined ) - // set the scroll left - return this.each(function() { - if (this == window || this == document) - window.scrollTo( val, $(window).scrollTop() ); - else - this.scrollLeft = val; - }); - - // return the scroll left offest in pixels - if ( this[0] == window || this[0] == document ) - return self.pageXOffset || - $.boxModel && document.documentElement.scrollLeft || - document.body.scrollLeft; - - return this[0].scrollLeft; - }, - - /** - * Gets how many pixels the user has scrolled to the bottom (scrollTop). - * Works on containers with overflow: auto and window/document. - * - * @example $(window).scrollTop() - * @result 100 - * - * @example $(document).scrollTop() - * @result 100 - * - * @example $("#testdiv").scrollTop() - * @result 100 - * - * @name scrollTop - * @type Number - * @cat Plugins/Dimensions - */ - /** - * Sets the scrollTop property for each element and continues the chain. - * Works on containers with overflow: auto and window/document. - * - * @example $(window).scrollTop(100).scrollTop() - * @result 100 - * - * @example $(document).scrollTop(100).scrollTop() - * @result 100 - * - * @example $("#testdiv").scrollTop(100).scrollTop() - * @result 100 - * - * @name scrollTop - * @param Number value A positive number representing the desired scrollTop. - * @type jQuery - * @cat Plugins/Dimensions - */ - scrollTop: function(val) { - if (!this[0]) error(); - if ( val != undefined ) - // set the scroll top - return this.each(function() { - if (this == window || this == document) - window.scrollTo( $(window).scrollLeft(), val ); - else - this.scrollTop = val; - }); - - // return the scroll top offset in pixels - if ( this[0] == window || this[0] == document ) - return self.pageYOffset || - $.boxModel && document.documentElement.scrollTop || - document.body.scrollTop; - - return this[0].scrollTop; - }, - - /** - * Gets the top and left positioned offset in pixels. - * The positioned offset is the offset between a positioned - * parent and the element itself. - * - * For accurate calculations make sure to use pixel values for margins, borders and padding. - * - * @example $("#testdiv").position() - * @result { top: 100, left: 100 } - * - * @example var position = {}; - * $("#testdiv").position(position) - * @result position = { top: 100, left: 100 } - * - * @name position - * @param Object returnObject Optional An object to store the return value in, so as not to break the chain. If passed in the - * chain will not be broken and the result will be assigned to this object. - * @type Object - * @cat Plugins/Dimensions - */ - position: function(returnObject) { - return this.offset({ margin: false, scroll: false, relativeTo: this.offsetParent() }, returnObject); - }, - - /** - * Gets the location of the element in pixels from the top left corner of the viewport. - * The offset method takes an optional map of key value pairs to configure the way - * the offset is calculated. Here are the different options. - * - * (Boolean) margin - Should the margin of the element be included in the calculations? True by default. - * (Boolean) border - Should the border of the element be included in the calculations? False by default. - * (Boolean) padding - Should the padding of the element be included in the calculations? False by default. - * (Boolean) scroll - Should the scroll offsets of the parent elements be included in the calculations? True by default. - * When true it adds the total scroll offsets of all parents to the total offset and also adds two - * properties to the returned object, scrollTop and scrollLeft. - * (Boolean) lite - When true it will use the offsetLite method instead of the full-blown, slower offset method. False by default. - * Only use this when margins, borders and padding calculations don't matter. - * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative). - * It will retreive the offset relative to this parent element. By default it is the body element. - * - * Also an object can be passed as the second paramater to - * catch the value of the return and continue the chain. - * - * For accurate calculations make sure to use pixel values for margins, borders and padding. - * - * Known issues: - * - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari - * Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden - * - * @example $("#testdiv").offset() - * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 } - * - * @example $("#testdiv").offset({ scroll: false }) - * @result { top: 90, left: 90 } - * - * @example var offset = {} - * $("#testdiv").offset({ scroll: false }, offset) - * @result offset = { top: 90, left: 90 } - * - * @name offset - * @param Map options Optional settings to configure the way the offset is calculated. - * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the - * chain will not be broken and the result will be assigned to this object. - * @type Object - * @cat Plugins/Dimensions - */ - offset: function(options, returnObject) { - if (!this[0]) error(); - var x = 0, y = 0, sl = 0, st = 0, - elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'), - mo = $.browser.mozilla, ie = $.browser.msie, oa = $.browser.opera, - sf = $.browser.safari, sf3 = $.browser.safari && parseInt($.browser.version) > 520, - absparent = false, relparent = false, - options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false, relativeTo: document.body }, options || {}); - - // Use offsetLite if lite option is true - if (options.lite) return this.offsetLite(options, returnObject); - // Get the HTMLElement if relativeTo is a jquery collection - if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0]; - - if (elem.tagName == 'BODY') { - // Safari 2 is the only one to get offsetLeft and offsetTop properties of the body "correct" - // Except they all mess up when the body is positioned absolute or relative - x = elem.offsetLeft; - y = elem.offsetTop; - // Mozilla ignores margin and subtracts border from body element - if (mo) { - x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2); - y += num(elem, 'marginTop') + (num(elem, 'borderTopWidth') *2); - } else - // Opera ignores margin - if (oa) { - x += num(elem, 'marginLeft'); - y += num(elem, 'marginTop'); - } else - // IE does not add the border in Standards Mode - if ((ie && jQuery.boxModel)) { - x += num(elem, 'borderLeftWidth'); - y += num(elem, 'borderTopWidth'); - } else - // Safari 3 doesn't not include border or margin - if (sf3) { - x += num(elem, 'marginLeft') + num(elem, 'borderLeftWidth'); - y += num(elem, 'marginTop') + num(elem, 'borderTopWidth'); - } - } else { - do { - parPos = $.css(parent, 'position'); - - x += parent.offsetLeft; - y += parent.offsetTop; - - // Mozilla and IE do not add the border - // Mozilla adds the border for table cells - if ((mo && !parent.tagName.match(/^t[d|h]$/i)) || ie || sf3) { - // add borders to offset - x += num(parent, 'borderLeftWidth'); - y += num(parent, 'borderTopWidth'); - - // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent - if (mo && parPos == 'absolute') absparent = true; - // IE does not include the border on the body if an element is position static and without an absolute or relative parent - if (ie && parPos == 'relative') relparent = true; - } - - op = parent.offsetParent || document.body; - if (options.scroll || mo) { - do { - if (options.scroll) { - // get scroll offsets - sl += parent.scrollLeft; - st += parent.scrollTop; - } - - // Opera sometimes incorrectly reports scroll offset for elements with display set to table-row or inline - if (oa && ($.css(parent, 'display') || '').match(/table-row|inline/)) { - sl = sl - ((parent.scrollLeft == parent.offsetLeft) ? parent.scrollLeft : 0); - st = st - ((parent.scrollTop == parent.offsetTop) ? parent.scrollTop : 0); - } - - // Mozilla does not add the border for a parent that has overflow set to anything but visible - if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') { - x += num(parent, 'borderLeftWidth'); - y += num(parent, 'borderTopWidth'); - } - - parent = parent.parentNode; - } while (parent != op); - } - parent = op; - - // exit the loop if we are at the relativeTo option but not if it is the body or html tag - if (parent == options.relativeTo && !(parent.tagName == 'BODY' || parent.tagName == 'HTML')) { - // Mozilla does not add the border for a parent that has overflow set to anything but visible - if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') { - x += num(parent, 'borderLeftWidth'); - y += num(parent, 'borderTopWidth'); - } - // Safari 2 and opera includes border on positioned parents - if ( ((sf && !sf3) || oa) && parPos != 'static' ) { - x -= num(op, 'borderLeftWidth'); - y -= num(op, 'borderTopWidth'); - } - break; - } - if (parent.tagName == 'BODY' || parent.tagName == 'HTML') { - // Safari 2 and IE Standards Mode doesn't add the body margin for elments positioned with static or relative - if (((sf && !sf3) || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') { - x += num(parent, 'marginLeft'); - y += num(parent, 'marginTop'); - } - // Safari 3 does not include the border on body - // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent - // IE does not include the border on the body if an element is positioned static and without an absolute or relative parent - if ( sf3 || (mo && !absparent && elemPos != 'fixed') || - (ie && elemPos == 'static' && !relparent) ) { - x += num(parent, 'borderLeftWidth'); - y += num(parent, 'borderTopWidth'); - } - break; // Exit the loop - } - } while (parent); - } - - var returnValue = handleOffsetReturn(elem, options, x, y, sl, st); - - if (returnObject) { $.extend(returnObject, returnValue); return this; } - else { return returnValue; } - }, - - /** - * Gets the location of the element in pixels from the top left corner of the viewport. - * This method is much faster than offset but not as accurate when borders and margins are - * on the element and/or its parents. This method can be invoked - * by setting the lite option to true in the offset method. - * The offsetLite method takes an optional map of key value pairs to configure the way - * the offset is calculated. Here are the different options. - * - * (Boolean) margin - Should the margin of the element be included in the calculations? True by default. - * (Boolean) border - Should the border of the element be included in the calculations? False by default. - * (Boolean) padding - Should the padding of the element be included in the calcuations? False by default. - * (Boolean) scroll - Sould the scroll offsets of the parent elements be included int he calculations? True by default. - * When true it adds the total scroll offsets of all parents to the total offset and also adds two - * properties to the returned object, scrollTop and scrollLeft. - * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative). - * It will retreive the offset relative to this parent element. By default it is the body element. - * - * @name offsetLite - * @param Map options Optional settings to configure the way the offset is calculated. - * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the - * chain will not be broken and the result will be assigned to this object. - * @type Object - * @cat Plugins/Dimensions - */ - offsetLite: function(options, returnObject) { - if (!this[0]) error(); - var x = 0, y = 0, sl = 0, st = 0, parent = this[0], offsetParent, - options = $.extend({ margin: true, border: false, padding: false, scroll: true, relativeTo: document.body }, options || {}); - - // Get the HTMLElement if relativeTo is a jquery collection - if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0]; - - do { - x += parent.offsetLeft; - y += parent.offsetTop; - - offsetParent = parent.offsetParent || document.body; - if (options.scroll) { - // get scroll offsets - do { - sl += parent.scrollLeft; - st += parent.scrollTop; - parent = parent.parentNode; - } while(parent != offsetParent); - } - parent = offsetParent; - } while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML' && parent != options.relativeTo); - - var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st); - - if (returnObject) { $.extend(returnObject, returnValue); return this; } - else { return returnValue; } - }, - - /** - * Returns a jQuery collection with the positioned parent of - * the first matched element. This is the first parent of - * the element that has position (as in relative or absolute). - * - * @name offsetParent - * @type jQuery - * @cat Plugins/Dimensions - */ - offsetParent: function() { - if (!this[0]) error(); - var offsetParent = this[0].offsetParent; - while ( offsetParent && (offsetParent.tagName != 'BODY' && $.css(offsetParent, 'position') == 'static') ) - offsetParent = offsetParent.offsetParent; - return $(offsetParent); - } -}); - -/** - * Throws an error message when no elements are in the jQuery collection - * @private - */ -var error = function() { - throw "Dimensions: jQuery collection is empty"; -}; - -/** - * Handles converting a CSS Style into an Integer. - * @private - */ -var num = function(el, prop) { - return parseInt($.css(el.jquery?el[0]:el,prop))||0; -}; - -/** - * Handles the return value of the offset and offsetLite methods. - * @private - */ -var handleOffsetReturn = function(elem, options, x, y, sl, st) { - if ( !options.margin ) { - x -= num(elem, 'marginLeft'); - y -= num(elem, 'marginTop'); - } - - // Safari and Opera do not add the border for the element - if ( options.border && (($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) { - x += num(elem, 'borderLeftWidth'); - y += num(elem, 'borderTopWidth'); - } else if ( !options.border && !(($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) { - x -= num(elem, 'borderLeftWidth'); - y -= num(elem, 'borderTopWidth'); - } - - if ( options.padding ) { - x += num(elem, 'paddingLeft'); - y += num(elem, 'paddingTop'); - } - - // do not include scroll offset on the element ... opera sometimes reports scroll offset as actual offset - if ( options.scroll && (!$.browser.opera || elem.offsetLeft != elem.scrollLeft && elem.offsetTop != elem.scrollLeft) ) { - sl -= elem.scrollLeft; - st -= elem.scrollTop; - } - - return options.scroll ? { top: y - st, left: x - sl, scrollTop: st, scrollLeft: sl } - : { top: y, left: x }; -}; - -/** - * Gets the width of the OS scrollbar - * @private - */ -var scrollbarWidth = 0; -var getScrollbarWidth = function() { - if (!scrollbarWidth) { - var testEl = $('
') - .css({ - width: 100, - height: 100, - overflow: 'auto', - position: 'absolute', - top: -1000, - left: -1000 - }) - .appendTo('body'); - scrollbarWidth = 100 - testEl - .append('
') - .find('div') - .css({ - width: '100%', - height: 200 - }) - .width(); - testEl.remove(); - } - return scrollbarWidth; -}; - -})(jQuery); diff --git a/thirdparty/node-XMLHttpRequest b/thirdparty/node-XMLHttpRequest index fdcdd8a9..13d0ef11 160000 --- a/thirdparty/node-XMLHttpRequest +++ b/thirdparty/node-XMLHttpRequest @@ -1 +1 @@ -Subproject commit fdcdd8a9e82a85611aa56d83b871076134a242e4 +Subproject commit 13d0ef11c228692e8349d1f545ba0010cff04908 diff --git a/thirdparty/sinon.js b/thirdparty/sinon.js deleted file mode 100644 index fce2fed4..00000000 --- a/thirdparty/sinon.js +++ /dev/null @@ -1,2447 +0,0 @@ -/** - * Sinon.JS 1.0.0, 2010/12/09 - * - * @author Christian Johansen (christian@cjohansen.no) - * - * (The BSD License) - * - * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Christian Johansen nor the names of his contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/ -/*global module, require, __dirname, document*/ -/** - * Sinon core utilities. For internal use only. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -var sinon = (function () { - var div = typeof document != "undefined" && document.createElement("div"); - - function isNode(obj) { - try { - div.appendChild(obj); - div.removeChild(obj); - } catch (e) { - return false; - } - - return true; - } - - function isElement(obj) { - return div && obj && obj.nodeType === 1 && isNode(obj); - } - - return { - wrapMethod: function wrapMethod(object, property, method) { - if (!object) { - throw new TypeError("Should wrap property of object"); - } - - if (typeof method != "function") { - throw new TypeError("Method wrapper should be function"); - } - - var wrappedMethod = object[property]; - var type = typeof wrappedMethod; - - if (type != "function") { - throw new TypeError("Attempted to wrap " + type + " property " + property + - " as function"); - } - - if (wrappedMethod.restore && wrappedMethod.restore.sinon) { - throw new TypeError("Attempted to wrap " + property + " which is already wrapped"); - } - - if (wrappedMethod.calledBefore) { - var verb = !!wrappedMethod.returns ? "stubbed" : "spied on"; - throw new TypeError("Attempted to wrap " + property + " which is already " + verb); - } - - object[property] = method; - method.displayName = property; - - method.restore = function () { - object[property] = wrappedMethod; - }; - - method.restore.sinon = true; - - return method; - }, - - extend: function extend(target) { - for (var i = 1, l = arguments.length; i < l; i += 1) { - for (var prop in arguments[i]) { - if (arguments[i].hasOwnProperty(prop)) { - target[prop] = arguments[i][prop]; - } - } - } - - return target; - }, - - create: function create(proto) { - if (Object.create) { - return Object.create(proto); - } else { - var F = function () {}; - F.prototype = proto; - return new F(); - } - }, - - deepEqual: function deepEqual(a, b) { - if (typeof a != "object" || typeof b != "object") { - return a === b; - } - - if (isElement(a) || isElement(b)) { - return a === b; - } - - if (a === b) { - return true; - } - - if (Object.prototype.toString.call(a) == "[object Array]") { - if (a.length !== b.length) { - return false; - } - - for (var i = 0, l = a.length; i < l; i += 1) { - if (!deepEqual(a[i], b[i])) { - return false; - } - } - - return true; - } - - var prop, aLength = 0, bLength = 0; - - for (prop in a) { - aLength += 1; - - if (!deepEqual(a[prop], b[prop])) { - return false; - } - } - - for (prop in b) { - bLength += 1; - } - - if (aLength != bLength) { - return false; - } - - return true; - }, - - keys: function keys(object) { - var objectKeys = []; - - for (var prop in object) { - if (object.hasOwnProperty(prop)) { - objectKeys.push(prop); - } - } - - return objectKeys.sort(); - }, - - functionName: function functionName(func) { - var name = func.displayName || func.name; - - // Use function decomposition as a last resort to get function - // name. Does not rely on function decomposition to work - if it - // doesn't debugging will be slightly less informative - // (i.e. toString will say 'spy' rather than 'myFunc'). - if (!name) { - var matches = func.toString().match(/function ([^\s\(]+)/); - name = matches && matches[1]; - } - - return name; - }, - - functionToString: function toString() { - if (this.getCall && this.callCount) { - var thisValue, prop, i = this.callCount; - - while (i--) { - thisValue = this.getCall(i).thisValue; - - for (prop in thisValue) { - if (thisValue[prop] === this) { - return prop; - } - } - } - } - - return this.displayName || "sinon fake"; - }, - - getConfig: function (custom) { - var config = {}; - custom = custom || {}; - var defaults = sinon.defaultConfig; - - for (var prop in defaults) { - if (defaults.hasOwnProperty(prop)) { - config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop]; - } - } - - return config; - }, - - defaultConfig: { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "server", "requests"], - useFakeTimers: true, - useFakeServer: true - } - }; -}()); - -if (typeof module == "object" && typeof require == "function") { - require.paths.unshift(__dirname); - module.exports = sinon; - module.exports.spy = require("sinon/spy"); - module.exports.stub = require("sinon/stub"); - module.exports.mock = require("sinon/mock"); - module.exports.collection = require("sinon/collection"); - module.exports.assert = require("sinon/assert"); - module.exports.test = require("sinon/test"); - module.exports.testCase = require("sinon/test_case"); - require.paths.shift(); -} - -/* @depend ../sinon.js */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Spy functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - var spyCall; - var callId = 0; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon) { - return; - } - - function spy(object, property) { - if (!property && typeof object == "function") { - return spy.create(object); - } - - if (!object || !property) { - return spy.create(function () {}); - } - - var method = object[property]; - return sinon.wrapMethod(object, property, spy.create(method)); - } - - sinon.extend(spy, (function () { - var slice = Array.prototype.slice; - - function delegateToCalls(api, method, matchAny, actual) { - api[method] = function () { - if (!this.called) { - return false; - } - - var currentCall; - var matches = 0; - - for (var i = 0, l = this.callCount; i < l; i += 1) { - currentCall = this.getCall(i); - - if (currentCall[actual || method].apply(currentCall, arguments)) { - matches += 1; - - if (matchAny) { - return true; - } - } - } - - return matches === this.callCount; - }; - } - - // Public API - var spyApi = { - called: false, - calledOnce: false, - calledTwice: false, - calledThrice: false, - callCount: 0, - - create: function create(func) { - var name; - - if (typeof func != "function") { - func = function () {}; - } else { - name = sinon.functionName(func); - } - - function proxy() { - return proxy.invoke(func, this, slice.call(arguments)); - } - - sinon.extend(proxy, spy); - delete proxy.create; - sinon.extend(proxy, func); - - proxy.args = []; - proxy.returnValues = []; - proxy.thisValues = []; - proxy.exceptions = []; - proxy.callIds = []; - proxy.prototype = func.prototype; - proxy.displayName = name || "spy"; - proxy.toString = sinon.functionToString; - - return proxy; - }, - - invoke: function invoke(func, thisValue, args) { - var exception, returnValue; - this.called = true; - this.callCount += 1; - this.calledOnce = this.callCount == 1; - this.calledTwice = this.callCount == 2; - this.calledThrice = this.callCount == 3; - this.thisValues.push(thisValue); - this.args.push(args); - this.callIds.push(callId++); - - try { - returnValue = func.apply(thisValue, args); - } catch (e) { - this.returnValues.push(undefined); - exception = e; - throw e; - } finally { - this.exceptions.push(exception); - } - - this.returnValues.push(returnValue); - - return returnValue; - }, - - getCall: function getCall(i) { - if (i < 0 || i >= this.callCount) { - return null; - } - - return spyCall.create(this.thisValues[i], this.args[i], - this.returnValues[i], this.exceptions[i], - this.callIds[i]); - }, - - calledBefore: function calledBefore(spyFn) { - if (!this.called) { - return false; - } - - if (!spyFn.called) { - return true; - } - - return this.callIds[0] < spyFn.callIds[0]; - }, - - calledAfter: function calledAfter(spyFn) { - if (!this.called || !spyFn.called) { - return false; - } - - return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1]; - } - }; - - delegateToCalls(spyApi, "calledOn", true); - delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn"); - delegateToCalls(spyApi, "calledWith", true); - delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith"); - delegateToCalls(spyApi, "calledWithExactly", true); - delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly"); - delegateToCalls(spyApi, "threw", true); - delegateToCalls(spyApi, "alwaysThrew", false, "threw"); - delegateToCalls(spyApi, "returned", true); - delegateToCalls(spyApi, "alwaysReturned", false, "returned"); - - return spyApi; - }())); - - spyCall = (function () { - return { - create: function create(thisValue, args, returnValue, exception, id) { - var proxyCall = sinon.create(spyCall); - delete proxyCall.create; - proxyCall.thisValue = thisValue; - proxyCall.args = args; - proxyCall.returnValue = returnValue; - proxyCall.exception = exception; - proxyCall.callId = typeof id == "number" && id || callId++; - - return proxyCall; - }, - - calledOn: function calledOn(thisValue) { - return this.thisValue === thisValue; - }, - - calledWith: function calledWith() { - for (var i = 0, l = arguments.length; i < l; i += 1) { - if (!sinon.deepEqual(arguments[i], this.args[i])) { - return false; - } - } - - return true; - }, - - calledWithExactly: function calledWithExactly() { - return arguments.length == this.args.length && - this.calledWith.apply(this, arguments); - }, - - returned: function returned(value) { - return this.returnValue === value; - }, - - threw: function threw(error) { - if (typeof error == "undefined" || !this.exception) { - return !!this.exception; - } - - if (typeof error == "string") { - return this.exception.name == error; - } - - return this.exception === error; - }, - - calledBefore: function (other) { - return this.callId < other.callId; - }, - - calledAfter: function (other) { - return this.callId > other.callId; - } - }; - }()); - - if (commonJSModule) { - module.exports = spy; - } else { - sinon.spy = spy; - sinon.spyCall = spyCall; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend spy.js - */ -/*jslint eqeqeq: false, onevar: false*/ -/*global module, require, sinon*/ -/** - * Stub functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon) { - return; - } - - function stub(object, property, func) { - if (!!func && typeof func != "function") { - throw new TypeError("Custom stub should be function"); - } - - var wrapper; - - if (func) { - wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func; - } else { - wrapper = stub.create(); - } - - if (!object && !property) { - return sinon.stub.create(); - } - - if (!property && !!object && typeof object == "object") { - for (var prop in object) { - if (object.hasOwnProperty(prop) && typeof object[prop] == "function") { - stub(object, prop); - } - } - - return object; - } - - return sinon.wrapMethod(object, property, wrapper); - } - - sinon.extend(stub, (function () { - var slice = Array.prototype.slice; - - return { - create: function create() { - var functionStub = function () { - if (functionStub.exception) { - throw functionStub.exception; - } - - if (typeof functionStub.callArgAt == "number") { - var func = arguments[functionStub.callArgAt]; - - if (typeof func != "function") { - throw new TypeError("argument at index " + functionStub.callArgAt + - " is not a function: " + func); - } - - func.apply(null, functionStub.callbackArguments); - } - - return functionStub.returnValue; - }; - - if (sinon.spy) { - functionStub = sinon.spy.create(functionStub); - } - - sinon.extend(functionStub, stub); - functionStub.displayName = "stub"; - functionStub.toString = sinon.functionToString; - - return functionStub; - }, - - returns: function returns(value) { - this.returnValue = value; - - return this; - }, - - throws: function throws(error, message) { - if (typeof error == "string") { - this.exception = new Error(message); - this.exception.name = error; - } else if (!error) { - this.exception = new Error("Error"); - } else { - this.exception = error; - } - - return this; - }, - - callsArg: function callsArg(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.callArgAt = pos; - this.callbackArguments = []; - }, - - callsArgWith: function callsArgWith(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.callArgAt = pos; - this.callbackArguments = slice.call(arguments, 1); - } - }; - }())); - - if (commonJSModule) { - module.exports = stub; - } else { - sinon.stub = stub; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - */ -/*jslint eqeqeq: false, onevar: false, nomen: false*/ -/*global module, require, sinon*/ -/** - * Mock functions. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon) { - return; - } - - function mock(object) { - if (!object) { - return sinon.expectation.create("Anonymous mock"); - } - - return mock.create(object); - } - - sinon.mock = mock; - - sinon.extend(mock, (function () { - function each(collection, callback) { - if (!collection) { - return; - } - - for (var i = 0, l = collection.length; i < l; i += 1) { - callback(collection[i]); - } - } - - return { - create: function create(object) { - if (!object) { - throw new TypeError("object is null"); - } - - var mockObject = sinon.extend({}, mock); - mockObject.object = object; - delete mockObject.create; - - return mockObject; - }, - - expects: function expects(method) { - if (!method) { - throw new TypeError("method is falsy"); - } - - if (!this.expectations) { - this.expectations = {}; - this.proxies = []; - } - - if (!this.expectations[method]) { - this.expectations[method] = []; - var mockObject = this; - - sinon.wrapMethod(this.object, method, function () { - return mockObject.invokeMethod(method, this, arguments); - }); - - this.proxies.push(method); - } - - var expectation = sinon.expectation.create(method); - this.expectations[method].push(expectation); - - return expectation; - }, - - restore: function restore() { - var object = this.object; - - each(this.proxies, function (proxy) { - if (typeof object[proxy].restore == "function") { - object[proxy].restore(); - } - }); - }, - - verify: function verify() { - var expectations = this.expectations || {}; - var exception; - - try { - each(this.proxies, function (proxy) { - each(expectations[proxy], function (expectation) { - expectation.verify(); - }); - }); - } catch (e) { - exception = e; - } - - this.restore(); - - if (exception) { - throw exception; - } - - return true; - }, - - invokeMethod: function invokeMethod(method, thisValue, args) { - var expectations = this.expectations && this.expectations[method]; - var length = expectations && expectations.length || 0; - - for (var i = 0; i < length; i += 1) { - if (!expectations[i].met()) { - return expectations[i].apply(thisValue, args); - } - } - - return expectations[length - 1].apply(thisValue, args); - } - }; - }())); - - function err(message) { - var exception = new Error(message); - exception.name = "ExpectationError"; - - throw exception; - } - - sinon.expectation = (function () { - var slice = Array.prototype.slice; - var _invoke = sinon.spy.invoke; - - function timesInWords(times) { - if (times == 1) { - return "once"; - } else if (times == 2) { - return "twice"; - } else if (times == 3) { - return "thrice"; - } - - return times + " times"; - } - - function receivedMinCalls(expectation) { - var hasMinLimit = typeof expectation.minCalls == "number"; - return !hasMinLimit || expectation.callCount >= expectation.minCalls; - } - - function receivedMaxCalls(expectation) { - if (typeof expectation.maxCalls != "number") { - return false; - } - - return expectation.callCount == expectation.maxCalls; - } - - return { - minCalls: 1, - maxCalls: 1, - - create: function create(methodName) { - var expectation = sinon.extend(sinon.stub.create(), sinon.expectation); - delete expectation.create; - expectation.method = methodName; - - return expectation; - }, - - invoke: function invoke(func, thisValue, args) { - this.verifyCallAllowed(thisValue, args); - - return _invoke.apply(this, arguments); - }, - - atLeast: function atLeast(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not number"); - } - - if (!this.limitsSet) { - this.maxCalls = null; - this.limitsSet = true; - } - - this.minCalls = num; - - return this; - }, - - atMost: function atMost(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not number"); - } - - if (!this.limitsSet) { - this.minCalls = null; - this.limitsSet = true; - } - - this.maxCalls = num; - - return this; - }, - - never: function never() { - return this.exactly(0); - }, - - once: function once() { - return this.exactly(1); - }, - - twice: function twice() { - return this.exactly(2); - }, - - thrice: function thrice() { - return this.exactly(3); - }, - - exactly: function exactly(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not a number"); - } - - this.atLeast(num); - return this.atMost(num); - }, - - met: function met() { - return !this.failed && receivedMinCalls(this); - }, - - verifyCallAllowed: function verifyCallAllowed(thisValue, args) { - if (receivedMaxCalls(this)) { - this.failed = true; - err(this.method + " already called " + timesInWords(this.maxCalls)); - } - - if ("expectedThis" in this && this.expectedThis !== thisValue) { - err(this.method + " called with " + thisValue + " as thisValue, expected " + - this.expectedThis); - } - - if (!("expectedArguments" in this)) { - return; - } - - if (!args || args.length === 0) { - err(this.method + " received no arguments, expected " + - this.expectedArguments.join()); - } - - if (args.length < this.expectedArguments.length) { - err(this.method + " received too few arguments (" + args.join() + - "), expected " + this.expectedArguments.join()); - } - - if (this.expectsExactArgCount && - args.length != this.expectedArguments.length) { - err(this.method + " received too many arguments (" + args.join() + - "), expected " + this.expectedArguments.join()); - } - - for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) { - if (!sinon.deepEqual(this.expectedArguments[i], args[i])) { - err(this.method + " received wrong arguments (" + args.join() + - "), expected " + this.expectedArguments.join()); - } - } - }, - - withArgs: function withArgs() { - this.expectedArguments = slice.call(arguments); - return this; - }, - - withExactArgs: function withExactArgs() { - this.withArgs.apply(this, arguments); - this.expectsExactArgCount = true; - return this; - }, - - on: function on(thisValue) { - this.expectedThis = thisValue; - return this; - }, - - verify: function verify() { - if (!this.met()) { - err(this.method + " expected to be called " + timesInWords(this.minCalls) + - ", but was called " + timesInWords(this.callCount)); - } - - return true; - } - }; - }()); - - if (commonJSModule) { - module.exports = mock; - } else { - sinon.mock = mock; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - * @depend mock.js - */ -/*jslint eqeqeq: false, onevar: false, forin: true*/ -/*global module, require, sinon*/ -/** - * Collections of stubs, spies and mocks. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon) { - return; - } - - function getFakes(fakeCollection) { - if (!fakeCollection.fakes) { - fakeCollection.fakes = []; - } - - return fakeCollection.fakes; - } - - function each(fakeCollection, method) { - var fakes = getFakes(fakeCollection); - - for (var i = 0, l = fakes.length; i < l; i += 1) { - if (typeof fakes[i][method] == "function") { - fakes[i][method](); - } - } - } - - var collection = { - verify: function resolve() { - each(this, "verify"); - }, - - restore: function restore() { - each(this, "restore"); - }, - - verifyAndRestore: function verifyAndRestore() { - var exception; - - try { - this.verify(); - } catch (e) { - exception = e; - } - - this.restore(); - - if (exception) { - throw exception; - } - }, - - add: function add(fake) { - getFakes(this).push(fake); - - return fake; - }, - - spy: function spy() { - return this.add(sinon.spy.apply(sinon, arguments)); - }, - - stub: function stub() { - return this.add(sinon.stub.apply(sinon, arguments)); - }, - - mock: function mock() { - return this.add(sinon.mock.apply(sinon, arguments)); - }, - - inject: function inject(obj) { - var col = this; - - obj.spy = function () { - return col.spy.apply(col, arguments); - }; - - obj.stub = function () { - return col.stub.apply(col, arguments); - }; - - obj.mock = function () { - return col.mock.apply(col, arguments); - }; - - return obj; - } - }; - - if (commonJSModule) { - module.exports = collection; - } else { - sinon.collection = collection; - } -}(typeof sinon == "object" && sinon || null)); - -/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/ -/*global module, require, window*/ -/** - * Fake timer API - * setTimeout - * setInterval - * clearTimeout - * clearInterval - * tick - * reset - * Date - * - * Inspired by jsUnitMockTimeOut from JsUnit - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -if (typeof this.sinon == "undefined") { - var sinon = {}; -} - -sinon.clock = (function () { - var id = 0; - - function addTimer(args, recurring) { - if (args.length === 0) { - throw new Error("Function requires at least 1 parameter"); - } - - var toId = id++; - var delay = args[1] || 0; - - if (!this.timeouts) { - this.timeouts = {}; - } - - this.timeouts[toId] = { - id: toId, - func: args[0], - callAt: this.now + delay - }; - - if (recurring === true) { - this.timeouts[toId].interval = delay; - } - - return toId; - } - - function parseTime(str) { - if (!str) { - return 0; - } - - var strings = str.split(":"); - var l = strings.length, i = l; - var ms = 0, parsed; - - if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { - throw new Error("tick only understands numbers and 'h:m:s'"); - } - - while (i--) { - parsed = parseInt(strings[i], 10); - - if (parsed >= 60) { - throw new Error("Invalid time " + str); - } - - ms += parsed * Math.pow(60, (l - i - 1)); - } - - return ms * 1000; - } - - function createObject(object) { - var newObject; - - if (Object.create) { - newObject = Object.create(object); - } else { - var F = function () {}; - F.prototype = object; - newObject = new F(); - } - - newObject.Date.clock = newObject; - return newObject; - } - - return { - now: 0, - - create: function create(now) { - var clock = createObject(this); - - if (typeof now == "number") { - this.now = now; - } - - return clock; - }, - - setTimeout: function setTimeout(callback, timeout) { - return addTimer.call(this, arguments, false); - }, - - clearTimeout: function clearTimeout(timerId) { - if (!this.timeouts) { - this.timeouts = []; - } - - delete this.timeouts[timerId]; - }, - - setInterval: function setInterval(callback, timeout) { - return addTimer.call(this, arguments, true); - }, - - clearInterval: function clearInterval(timerId) { - this.clearTimeout(timerId); - }, - - tick: function tick(ms) { - ms = typeof ms == "number" ? ms : parseTime(ms); - var tickFrom = this.now, tickTo = this.now + ms, previous = this.now; - var timer = this.firstTimerInRange(tickFrom, tickTo); - - while (timer && tickFrom <= tickTo) { - if (this.timeouts[timer.id]) { - tickFrom = this.now = timer.callAt; - this.callTimer(timer); - } - - timer = this.firstTimerInRange(previous, tickTo); - previous = tickFrom; - } - - this.now = tickTo; - }, - - firstTimerInRange: function (from, to) { - var timer, smallest, originalTimer; - - for (var id in this.timeouts) { - if (this.timeouts.hasOwnProperty(id)) { - if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) { - continue; - } - - if (!smallest || this.timeouts[id].callAt < smallest) { - originalTimer = this.timeouts[id]; - smallest = this.timeouts[id].callAt; - - timer = { - func: this.timeouts[id].func, - callAt: this.timeouts[id].callAt, - interval: this.timeouts[id].interval, - id: this.timeouts[id].id - }; - } - } - } - - return timer || null; - }, - - callTimer: function (timer) { - try { - if (typeof timer.func == "function") { - timer.func.call(null); - } else { - eval(timer.func); - } - } catch (e) {} - - if (!this.timeouts[timer.id]) { - return; - } - - if (typeof timer.interval == "number") { - this.timeouts[timer.id].callAt += timer.interval; - } else { - delete this.timeouts[timer.id]; - } - }, - - reset: function reset() { - this.timeouts = {}; - }, - - Date: (function () { - var NativeDate = Date; - - function ClockDate(year, month, date, hour, minute, second, ms) { - // Defensive and verbose to avoid potential harm in passing - // explicit undefined when user does not pass argument - switch (arguments.length) { - case 0: - return new NativeDate(ClockDate.clock.now); - case 1: - return new NativeDate(year); - case 2: - return new NativeDate(year, month); - case 3: - return new NativeDate(year, month, date); - case 4: - return new NativeDate(year, month, date, hour); - case 5: - return new NativeDate(year, month, date, hour, minute); - case 6: - return new NativeDate(year, month, date, hour, minute, second); - default: - return new NativeDate(year, month, date, hour, minute, second, ms); - } - } - - if (NativeDate.now) { - ClockDate.now = function now() { - return ClockDate.clock.now; - }; - } - - if (NativeDate.toSource) { - ClockDate.toSource = function toSource() { - return NativeDate.toSource(); - }; - } - - ClockDate.toString = function toString() { - return NativeDate.toString(); - }; - - ClockDate.prototype = NativeDate.prototype; - ClockDate.parse = NativeDate.parse; - ClockDate.UTC = NativeDate.UTC; - - return ClockDate; - }()) - }; -}()); - -sinon.timers = { - setTimeout: setTimeout, - clearTimeout: clearTimeout, - setInterval: setInterval, - clearInterval: clearInterval, - Date: Date -}; - -sinon.useFakeTimers = (function () { - var global = this; - var methods = ["Date", "setTimeout", "setInterval", "clearTimeout", "clearInterval"]; - - function restore() { - var method; - - for (var i = 0, l = this.methods.length; i < l; i++) { - method = this.methods[i]; - global[method] = this["_" + method]; - } - } - - function stubGlobal(method, clock) { - clock["_" + method] = global[method]; - - global[method] = function () { - return clock[method].apply(clock, arguments); - }; - - for (var prop in clock[method]) { - if (clock[method].hasOwnProperty(prop)) { - global[method][prop] = clock[method][prop]; - } - } - - global[method].clock = clock; - } - - return function useFakeTimers(now) { - var clock = sinon.clock.create(now); - clock.restore = restore; - clock.methods = Array.prototype.slice.call(arguments, - typeof now == "number" ? 1 : 0); - - if (clock.methods.length === 0) { - clock.methods = methods; - } - - for (var i = 0, l = clock.methods.length; i < l; i++) { - stubGlobal(clock.methods[i], clock); - } - - return clock; - }; -}()); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; -} - -/*jslint eqeqeq: false, onevar: false*/ -/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/ -/** - * Fake XMLHttpRequest object - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -if (typeof sinon == "undefined") { - this.sinon = {}; -} - -sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; - -sinon.FakeXMLHttpRequest = (function () { - /*jsl:ignore*/ - var unsafeHeaders = { - "Accept-Charset": true, - "Accept-Encoding": true, - "Connection": true, - "Content-Length": true, - "Cookie": true, - "Cookie2": true, - "Content-Transfer-Encoding": true, - "Date": true, - "Expect": true, - "Host": true, - "Keep-Alive": true, - "Referer": true, - "TE": true, - "Trailer": true, - "Transfer-Encoding": true, - "Upgrade": true, - "User-Agent": true, - "Via": true - }; - /*jsl:end*/ - - function FakeXMLHttpRequest() { - this.readyState = FakeXMLHttpRequest.UNSENT; - this.requestHeaders = {}; - this.requestBody = null; - this.status = 0; - this.statusText = ""; - - if (typeof FakeXMLHttpRequest.onCreate == "function") { - FakeXMLHttpRequest.onCreate(this); - } - } - - function verifyState(xhr) { - if (xhr.readyState !== FakeXMLHttpRequest.OPENED) { - throw new Error("INVALID_STATE_ERR"); - } - - if (xhr.sendFlag) { - throw new Error("INVALID_STATE_ERR"); - } - } - - sinon.extend(FakeXMLHttpRequest.prototype, { - async: true, - - open: function open(method, url, async, username, password) { - this.method = method; - this.url = url; - this.async = typeof async == "boolean" ? async : true; - this.username = username; - this.password = password; - this.responseText = null; - this.responseXML = null; - this.requestHeaders = {}; - this.sendFlag = false; - this.readyStateChange(FakeXMLHttpRequest.OPENED); - }, - - readyStateChange: function readyStateChange(state) { - this.readyState = state; - - if (typeof this.onreadystatechange == "function") { - this.onreadystatechange(); - } - }, - - setRequestHeader: function setRequestHeader(header, value) { - verifyState(this); - - if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) { - throw new Error("Refused to set unsafe header \"" + header + "\""); - } - - if (this.requestHeaders[header]) { - this.requestHeaders[header] += "," + value; - } else { - this.requestHeaders[header] = value; - } - }, - - // Helps testing - setResponseHeaders: function setResponseHeaders(headers) { - this.responseHeaders = {}; - - for (var header in headers) { - if (headers.hasOwnProperty(header)) { - this.responseHeaders[header.toLowerCase()] = headers[header]; - } - } - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED); - } - }, - - // Currently treats ALL data as a DOMString (i.e. no Document) - send: function send(data) { - verifyState(this); - - if (!/^(get|head)$/i.test(this.method)) { - if (this.requestHeaders["Content-Type"]) { - var value = this.requestHeaders["Content-Type"].split(";"); - this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8"; - } else { - this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8"; - } - - this.requestBody = data; - } - - this.errorFlag = false; - this.sendFlag = this.async; - this.readyStateChange(FakeXMLHttpRequest.OPENED); - - if (typeof this.onSend == "function") { - this.onSend(this); - } - }, - - abort: function abort() { - this.aborted = true; - this.responseText = null; - this.errorFlag = true; - this.requestHeaders = {}; - - if (this.readyState > sinon.FakeXMLHttpRequest.OPENED) { - this.readyStateChange(sinon.FakeXMLHttpRequest.DONE); - this.sendFlag = false; - } - - this.readyState = sinon.FakeXMLHttpRequest.UNSENT; - }, - - getResponseHeader: function getResponseHeader(header) { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return null; - } - - if (/^Set-Cookie2?$/i.test(header)) { - return null; - } - - return this.responseHeaders[header.toLowerCase()]; - }, - - getAllResponseHeaders: function getAllResponseHeaders() { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return null; - } - - var headers = {}; - - for (var header in this.responseHeaders) { - if (this.responseHeaders.hasOwnProperty(header) && - !/^Set-Cookie2?$/i.test(header)) { - headers[header] = this.responseHeaders[header]; - } - } - - return headers; - }, - - setResponseBody: function setResponseBody(body) { - if (this.readyState == FakeXMLHttpRequest.DONE) { - throw new Error("Request done"); - } - - if (this.async && this.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) { - throw new Error("No headers received"); - } - - var chunkSize = this.chunkSize || 10; - var index = 0; - this.responseText = ""; - - do { - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.LOADING); - } - - this.responseText += body.substring(index, index + chunkSize); - index += chunkSize; - } while (index < body.length); - - var type = this.getResponseHeader("Content-Type"); - - if (this.responseText && - (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) { - this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText); - } - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.DONE); - } else { - this.readyState = FakeXMLHttpRequest.DONE; - } - }, - - respond: function respond(status, headers, body) { - this.setResponseHeaders(headers || {}); - this.status = typeof status == "number" ? status : 200; - this.statusText = FakeXMLHttpRequest.statusCodes[this.status]; - this.setResponseBody(body || ""); - } - }); - - sinon.extend(FakeXMLHttpRequest, { - UNSENT: 0, - OPENED: 1, - HEADERS_RECEIVED: 2, - LOADING: 3, - DONE: 4 - }); - - // Borrowed from JSpec - FakeXMLHttpRequest.parseXML = function parseXML(text) { - var xmlDoc; - - if (typeof DOMParser != "undefined") { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(text, "text/xml"); - } else { - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = "false"; - xmlDoc.loadXML(text); - } - - return xmlDoc; - }; - - FakeXMLHttpRequest.statusCodes = { - 100: "Continue", - 101: "Switching Protocols", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 300: "Multiple Choice", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 307: "Temporary Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request-URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 422: "Unprocessable Entity", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported" - }; - - return FakeXMLHttpRequest; -}()); - -(function (global) { - var GlobalXMLHttpRequest = global.XMLHttpRequest; - var GlobalActiveXObject = global.ActiveXObject; - var supportsActiveX = typeof ActiveXObject != "undefined"; - var supportsXHR = typeof XMLHttpRequest != "undefined"; - - sinon.useFakeXMLHttpRequest = function () { - sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) { - if (supportsXHR) { - global.XMLHttpRequest = GlobalXMLHttpRequest; - } - - if (supportsActiveX) { - global.ActiveXObject = GlobalActiveXObject; - } - - delete sinon.FakeXMLHttpRequest.restore; - - if (keepOnCreate !== true) { - delete sinon.FakeXMLHttpRequest.onCreate; - } - }; - - if (supportsXHR) { - global.XMLHttpRequest = sinon.FakeXMLHttpRequest; - } - - if (supportsActiveX) { - global.ActiveXObject = function ActiveXObject(objId) { - if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/.test(objId)) { - return new sinon.FakeXMLHttpRequest(); - } - - return new GlobalActiveXObject(objId); - }; - } - - return sinon.FakeXMLHttpRequest; - }; -}(this)); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; -} - -/** - * @depend fake_xml_http_request.js - */ -/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/ -/*global module, require, window*/ -/** - * The Sinon "server" mimics a web server that receives requests from - * sinon.FakeXMLHttpRequest and provides an API to respond to those requests, - * both synchronously and asynchronously. To respond synchronuously, canned - * answers have to be provided upfront. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -if (typeof this.sinon == "undefined") { - var sinon = {}; -} - -sinon.fakeServer = (function () { - function F() {} - - function create(proto) { - F.prototype = proto; - return new F(); - } - - function responseArray(strOrArray) { - if (Object.prototype.toString.call(strOrArray) == "[object Array]") { - return strOrArray; - } - - return [200, {}, strOrArray]; - } - - var wloc = window.location; - var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host); - - function matchOne(response, requestMethod, requestUrl) { - var rmeth = response.method; - var matchMethod = !rmeth || rmeth.toLowerCase() == requestMethod.toLowerCase(); - var url = response.url; - var matchUrl = !url || url == requestUrl || (typeof url.test == "function" && url.test(requestUrl)); - - return matchMethod && matchUrl; - } - - function match(response, requestMethod, requestUrl) { - if (matchOne(response, requestMethod, requestUrl)) { - return true; - } - - if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) { - var strippedUrl = requestUrl.replace(rCurrLoc, ""); - - return matchOne(response, requestMethod, strippedUrl); - } - - return false; - } - - return { - create: function () { - var server = create(this); - this.xhr = sinon.useFakeXMLHttpRequest(); - server.requests = []; - - this.xhr.onCreate = function (xhrObj) { - server.addRequest(xhrObj); - }; - - return server; - }, - - addRequest: function addRequest(xhrObj) { - var server = this; - this.requests.push(xhrObj); - - xhrObj.onSend = function () { - server.handleRequest(this); - }; - }, - - getHTTPMethod: function getHTTPMethod(request) { - if (this.fakeHTTPMethods && /post/i.test(request.method)) { - var matches = request.requestBody.match(/_method=([^\b;]+)/); - return !!matches ? matches[1] : request.method; - } - - return request.method; - }, - - handleRequest: function handleRequest(xhr) { - if (xhr.async) { - if (!this.queue) { - this.queue = []; - } - - this.queue.push(xhr); - } else { - this.processRequest(xhr); - } - }, - - respondWith: function respondWith(method, url, body) { - if (arguments.length == 1) { - this.response = responseArray(method); - } else { - if (!this.responses) { - this.responses = []; - } - - if (arguments.length == 2) { - body = url; - url = method; - method = null; - } - - this.responses.push({ - method: method, - url: url, - response: responseArray(body) - }); - } - }, - - respond: function respond() { - var queue = this.queue || []; - - for (var i = 0, l = queue.length; i < l; i++) { - this.processRequest(queue[i]); - } - - this.queue = []; - }, - - processRequest: function processRequest(request) { - try { - if (request.aborted) { - return; - } - - var response = this.response || [404, {}, ""]; - - if (this.responses) { - for (var i = 0, l = this.responses.length; i < l; i++) { - if (match(this.responses[i], this.getHTTPMethod(request), request.url)) { - response = this.responses[i].response; - break; - } - } - } - - request.respond(response[0], response[1], response[2]); - } catch (e) {} - }, - - restore: function restore() { - return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments); - } - }; -}()); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; -} - -/** - * @depend fake_server.js - * @depend fake_timers.js - */ -/*jslint browser: true, eqeqeq: false, onevar: false*/ -/*global sinon*/ -/** - * Add-on for sinon.fakeServer that automatically handles a fake timer along with - * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery - * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead, - * it polls the object for completion with setInterval. Dispite the direct - * motivation, there is nothing jQuery-specific in this file, so it can be used - * in any environment where the ajax implementation depends on setInterval or - * setTimeout. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function () { - function Server() {} - Server.prototype = sinon.fakeServer; - - sinon.fakeServerWithClock = new Server(); - - sinon.fakeServerWithClock.addRequest = function addRequest(xhr) { - if (xhr.async) { - if (typeof setTimeout.clock == "object") { - this.clock = setTimeout.clock; - } else { - this.clock = sinon.useFakeTimers(); - this.resetClock = true; - } - - if (!this.longestTimeout) { - var clockSetTimeout = this.clock.setTimeout; - var clockSetInterval = this.clock.setInterval; - var server = this; - - this.clock.setTimeout = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetTimeout.apply(this, arguments); - }; - - this.clock.setInterval = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetInterval.apply(this, arguments); - }; - } - } - - return sinon.fakeServer.addRequest.call(this, xhr); - }; - - sinon.fakeServerWithClock.respond = function respond() { - var returnVal = sinon.fakeServer.respond.apply(this, arguments); - - if (this.clock) { - this.clock.tick(this.longestTimeout || 0); - this.longestTimeout = 0; - - if (this.resetClock) { - this.clock.restore(); - this.resetClock = false; - } - } - - return returnVal; - }; - - sinon.fakeServerWithClock.restore = function restore() { - if (this.clock) { - this.clock.restore(); - } - - return sinon.fakeServer.restore.apply(this, arguments); - }; -}()); - -/** - * @depend ../sinon.js - * @depend collection.js - * @depend util/fake_timers.js - * @depend util/fake_server_with_clock.js - */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global require, module*/ -/** - * Manages fake collections as well as fake utilities such as Sinon's - * timers and fake XHR implementation in one convenient object. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -if (typeof require == "function") { - var sinon = require("sinon"); - sinon.extend(sinon, require("sinon/util/fake_timers")); -} - -(function () { - function exposeValue(sandbox, config, key, value) { - if (!value) { - return; - } - - if (config.injectInto) { - config.injectInto[key] = value; - } else { - sandbox.args.push(value); - } - } - - function prepareSandboxFromConfig(config) { - var sandbox = sinon.create(sinon.sandbox); - - if (config.useFakeServer) { - if (typeof config.useFakeServer == "object") { - sandbox.serverPrototype = config.useFakeServer; - } - - sandbox.useFakeServer(); - } - - if (config.useFakeTimers) { - if (typeof config.useFakeTimers == "object") { - sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers); - } else { - sandbox.useFakeTimers(); - } - } - - return sandbox; - } - - sinon.sandbox = sinon.extend(sinon.create(sinon.collection), { - useFakeTimers: function useFakeTimers() { - this.clock = sinon.useFakeTimers.apply(sinon, arguments); - - return this.add(this.clock); - }, - - serverPrototype: sinon.fakeServer, - - useFakeServer: function useFakeServer() { - this.server = (this.serverPrototype || sinon.fakeServer).create(); - - return this.add(this.server); - }, - - inject: function (obj) { - sinon.collection.inject.call(this, obj); - - if (this.clock) { - obj.clock = this.clock; - } - - if (this.server) { - obj.server = this.server; - obj.requests = this.server.requests; - } - - return obj; - }, - - create: function (config) { - if (!config) { - return sinon.create(sinon.sandbox); - } - - var sandbox = prepareSandboxFromConfig(config); - sandbox.args = sandbox.args || []; - var prop, value, exposed = sandbox.inject({}); - - if (config.properties) { - for (var i = 0, l = config.properties.length; i < l; i++) { - prop = config.properties[i]; - value = exposed[prop] || prop == "sandbox" && sandbox; - exposeValue(sandbox, config, prop, value); - } - } else { - exposeValue(sandbox, config, "sandbox", value); - } - - return sandbox; - } - }); - - sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer; - - if (typeof module != "undefined") { - module.exports = sinon.sandbox; - } -}()); - -/** - * @depend ../sinon.js - * @depend stub.js - * @depend mock.js - * @depend sandbox.js - */ -/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Test function, sandboxes fakes - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon) { - return; - } - - function test(callback) { - var type = typeof callback; - - if (type != "function") { - throw new TypeError("sinon.test needs to wrap a test function, got " + type); - } - - return function () { - var config = sinon.getConfig(sinon.config); - config.injectInto = config.injectIntoThis && this || config.injectInto; - var sandbox = sinon.sandbox.create(config); - var exception, result; - var args = Array.prototype.slice.call(arguments).concat(sandbox.args); - - try { - result = callback.apply(this, args); - } catch (e) { - exception = e; - } - - sandbox.verifyAndRestore(); - - if (exception) { - throw exception; - } - - return result; - }; - } - - test.config = { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "server", "requests"], - useFakeTimers: true, - useFakeServer: true - }; - - if (commonJSModule) { - module.exports = test; - } else { - sinon.test = test; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend test.js - */ -/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/ -/*global module, require, sinon*/ -/** - * Test case, sandboxes all test functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon || !Object.prototype.hasOwnProperty) { - return; - } - - function createTest(property, setUp, tearDown) { - return function () { - if (setUp) { - setUp.apply(this, arguments); - } - - var exception; - - try { - property.apply(this, arguments); - } catch (e) { - exception = e; - } - - if (tearDown) { - tearDown.apply(this, arguments); - } - - if (exception) { - throw exception; - } - }; - } - - function testCase(tests, prefix) { - /*jsl:ignore*/ - if (!tests || typeof tests != "object") { - throw new TypeError("sinon.testCase needs an object with test functions"); - } - /*jsl:end*/ - - prefix = prefix || "test"; - var rPrefix = new RegExp("^" + prefix); - var methods = {}, testName, property, method; - var setUp = tests.setUp; - var tearDown = tests.tearDown; - - for (testName in tests) { - if (tests.hasOwnProperty(testName)) { - property = tests[testName]; - - if (/^(setUp|tearDown)$/.test(testName)) { - continue; - } - - if (typeof property == "function" && rPrefix.test(testName)) { - method = property; - - if (setUp || tearDown) { - method = createTest(property, setUp, tearDown); - } - - methods[testName] = sinon.test(method); - } - } - } - - return methods; - } - - if (commonJSModule) { - module.exports = testCase; - } else { - sinon.testCase = testCase; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - */ -/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Assertions matching the test spy retrieval interface. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - var slice = Array.prototype.slice; - var assert; - - if (!sinon && commonJSModule) { - sinon = require("sinon"); - } - - if (!sinon) { - return; - } - - function times(count) { - return count == 1 && "once" || - count == 2 && "twice" || - count == 3 && "thrice" || - (count || 0) + " times"; - } - - function verifyIsStub(method) { - if (!method) { - assert.fail("fake is not a spy"); - } - - if (typeof method != "function") { - assert.fail(method + " is not a function"); - } - - if (typeof method.getCall != "function") { - assert.fail(method + " is not stubbed"); - } - } - - function failAssertion(object, msg) { - var failMethod = object.fail || assert.fail; - failMethod.call(object, msg); - } - - function mirrorAssertion(method, message) { - assert[method] = function (fake) { - verifyIsStub(fake); - - var failed = typeof fake[method] == "function" ? - !fake[method].apply(fake, slice.call(arguments, 1)) : !fake[method]; - - if (failed) { - var msg = message.replace("%c", times(fake.callCount)); - msg = msg.replace("%n", fake + ""); - msg = msg.replace("%*", [].slice.call(arguments, 1).join(", ")); - - for (var i = 0, l = arguments.length; i < l; i++) { - msg = msg.replace("%" + i, arguments[i]); - } - - failAssertion(this, msg); - } else { - assert.pass(method); - } - }; - } - - assert = { - failException: "AssertError", - - fail: function fail(message) { - var error = new Error(message); - error.name = this.failException || assert.failException; - - throw error; - }, - - pass: function pass(assertion) {}, - - called: function assertCalled(method) { - verifyIsStub(method); - - if (!method.called) { - failAssertion(this, "expected " + method + - " to have been called at least once but was never called"); - } else { - assert.pass("called"); - } - }, - - notCalled: function assertNotCalled(method) { - verifyIsStub(method); - - if (method.called) { - failAssertion(this, "expected " + method + " to not have been called " + - "but was called " + times(method.callCount)); - } else { - assert.pass("notCalled"); - } - }, - - callOrder: function assertCallOrder() { - verifyIsStub(arguments[0]); - var expected = []; - var actual = []; - var failed = false; - expected.push(arguments[0]); - - for (var i = 1, l = arguments.length; i < l; i++) { - verifyIsStub(arguments[i]); - expected.push(arguments[i]); - - if (!arguments[i - 1].calledBefore(arguments[i])) { - failed = true; - } - } - - if (failed) { - actual = [].concat(expected).sort(function (a, b) { - var aId = a.getCall(0).callId; - var bId = b.getCall(0).callId; - - // uuid, won't ever be equal - return aId < bId ? -1 : 1; - }); - - var expectedStr, actualStr; - - try { - expectedStr = expected.join(", "); - actualStr = actual.join(", "); - } catch (e) {} - - failAssertion(this, "expected " + (expectedStr || "") + " to be " + - "called in order but were called as " + actualStr); - } else { - assert.pass("callOrder"); - } - }, - - callCount: function assertCallCount(method, count) { - verifyIsStub(method); - - if (method.callCount != count) { - failAssertion(this, "expected " + method + " to be called " + times(count) + - " but was called " + times(method.callCount)); - } else { - assert.pass("callCount"); - } - }, - - expose: function expose(target, options) { - if (!target) { - throw new TypeError("target is null or undefined"); - } - - options = options || {}; - var prefix = typeof options.prefix == "undefined" && "assert" || options.prefix; - - var name = function (prop) { - if (!prefix) { - return prop; - } - - return prefix + prop.substring(0, 1).toUpperCase() + prop.substring(1); - }; - - for (var assertion in this) { - if (!/^(fail|expose)/.test(assertion)) { - target[name(assertion)] = this[assertion]; - } - } - - if (typeof options.includeFail == "undefined" || !!options.includeFail) { - target.fail = this.fail; - target.failException = this.failException; - } - - return target; - } - }; - - mirrorAssertion("calledOnce", "expected %n to be called once but was called %c"); - mirrorAssertion("calledTwice", "expected %n to be called twice but was called %c"); - mirrorAssertion("calledThrice", "expected %n to be called thrice but was called %c"); - mirrorAssertion("calledOn", "expected %n to be called with %1 as this"); - mirrorAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this"); - mirrorAssertion("calledWith", "expected %n to be called with arguments %*"); - mirrorAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*"); - mirrorAssertion("calledWithExactly", "expected %n to be called with exact arguments %*"); - mirrorAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*"); - mirrorAssertion("threw", "%n did not throw exception"); - mirrorAssertion("alwaysThrew", "%n did not always throw exception"); - - if (commonJSModule) { - module.exports = assert; - } else { - sinon.assert = assert; - } -}(typeof sinon == "object" && sinon || null)); -