Commit 887f8b76 by Sebastián Katzer

Update plugin dependencies and ios platform

parent 41b51ab6
{
"prepare_queue": {
"installed": [],
"uninstalled": []
},
"config_munge": {
"files": {
"res/xml/config.xml": {
"parents": {
"/*": [
{
"xml": "<feature name=\"Toast\"><param name=\"android-package\" value=\"nl.xservices.plugins.Toast\" /></feature>",
"count": 1
},
{
"xml": "<feature name=\"Device\"><param name=\"android-package\" value=\"org.apache.cordova.device.Device\" /></feature>",
"count": 1
},
{
"xml": "<feature name=\"LocalNotification\"><param name=\"android-package\" value=\"de.appplant.cordova.plugin.localnotification.LocalNotification\" /></feature>",
"count": 1
}
]
}
},
"AndroidManifest.xml": {
"parents": {
"/manifest/application": [
{
"xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.localnotification.TriggerReceiver\" />",
"count": 1
},
{
"xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.localnotification.ClearReceiver\" />",
"count": 1
},
{
"xml": "<activity android:exported=\"false\" android:launchMode=\"singleInstance\" android:name=\"de.appplant.cordova.plugin.localnotification.ClickActivity\" android:theme=\"@android:style/Theme.NoDisplay\" />",
"count": 1
},
{
"xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.notification.TriggerReceiver\" />",
"count": 1
},
{
"xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.notification.ClearReceiver\" />",
"count": 1
},
{
"xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.localnotification.RestoreReceiver\"><intent-filter><action android:name=\"android.intent.action.BOOT_COMPLETED\" /></intent-filter></receiver>",
"count": 1
},
{
"xml": "<activity android:exported=\"false\" android:launchMode=\"singleInstance\" android:name=\"de.appplant.cordova.plugin.notification.ClickActivity\" android:theme=\"@android:style/Theme.NoDisplay\" />",
"count": 1
}
],
"/manifest": [
{
"xml": "<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\" />",
"count": 1
},
{
"xml": "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />",
"count": 1
}
]
}
}
}
},
"installed_plugins": {
"cordova-plugin-x-toast": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"cordova-android-support-v4": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"cordova-plugin-device": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"de.appplant.cordova.plugin.local-notification": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
}
},
"dependent_plugins": {},
"modules": [
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local",
"plugin.notification.local"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
}
]
}
\ No newline at end of file
cordova.define('cordova/plugin_list', function(require, exports, module) { cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [ module.exports = [
{ {
"file": "plugins/nl.x-services.plugins.toast/www/Toast.js", "file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "nl.x-services.plugins.toast.Toast", "id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [ "clobbers": [
"window.plugins.toast" "window.plugins.toast"
] ]
}, },
{ {
"file": "plugins/nl.x-services.plugins.toast/test/tests.js", "file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "nl.x-services.plugins.toast.tests" "id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
}, },
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [ "clobbers": [
"cordova.plugins.notification.local", "cordova.plugins.notification.local",
"plugin.notification.local" "plugin.notification.local"
...@@ -22,6 +33,7 @@ module.exports = [ ...@@ -22,6 +33,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [ "clobbers": [
"cordova.plugins.notification.local.core", "cordova.plugins.notification.local.core",
"plugin.notification.local.core" "plugin.notification.local.core"
...@@ -30,27 +42,15 @@ module.exports = [ ...@@ -30,27 +42,15 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [ "merges": [
"cordova.plugins.notification.local.core", "cordova.plugins.notification.local.core",
"plugin.notification.local.core" "plugin.notification.local.core"
] ]
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"clobbers": [
"device"
]
} }
]; ];
module.exports.metadata = module.exports.metadata =
// TOP OF METADATA // TOP OF METADATA
{ {}
"android.support.v4": "21.0.1",
"de.appplant.cordova.common.registerusernotificationsettings": "1.0.1",
"nl.x-services.plugins.toast": "2.0.4",
"de.appplant.cordova.plugin.local-notification": "0.8.2-dev",
"cordova-plugin-device": "1.0.1"
}
// BOTTOM OF METADATA // BOTTOM OF METADATA
}); });
\ No newline at end of file
cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, module) { exports.defineAutoTests = function() { cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) { var fail = function (done) {
expect(true).toBe(false); expect(true).toBe(false);
done(); done();
...@@ -20,6 +20,14 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m ...@@ -20,6 +20,14 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m
expect(window.plugins.toast.show).toBeDefined(); expect(window.plugins.toast.show).toBeDefined();
}); });
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() { it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined(); expect(window.plugins.toast.showShortTop).toBeDefined();
}); });
...@@ -47,11 +55,7 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m ...@@ -47,11 +55,7 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m
describe('Invalid usage', function () { describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) { it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done)); window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
it("should fail due to an invalid duration", function(done) {
window.plugins.toast.show('hi', 'medium', 'top', fail.bind(null, done), succeed.bind(null, done));
}); });
}); });
}; };
......
cordova.define("nl.x-services.plugins.toast.Toast", function(require, exports, module) { function Toast() { cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) { function Toast() {
} }
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) { Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [message, duration, position]); this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
}; };
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) { Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba ...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba
this.show(message, "long", "bottom", successCallback, errorCallback); this.show(message, "long", "bottom", successCallback, errorCallback);
}; };
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () { Toast.install = function () {
if (!window.plugins) { if (!window.plugins) {
window.plugins = {}; window.plugins = {};
......
...@@ -248,7 +248,6 @@ dependencies { ...@@ -248,7 +248,6 @@ dependencies {
// SUB-PROJECT DEPENDENCIES START // SUB-PROJECT DEPENDENCIES START
debugCompile project(path: ":CordovaLib", configuration: "debug") debugCompile project(path: ":CordovaLib", configuration: "debug")
releaseCompile project(path: ":CordovaLib", configuration: "release") releaseCompile project(path: ":CordovaLib", configuration: "release")
compile "com.android.support:support-v4:+"
// SUB-PROJECT DEPENDENCIES END // SUB-PROJECT DEPENDENCIES END
} }
......
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local",
"plugin.notification.local"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
}
];
module.exports.metadata =
// TOP OF METADATA
{}
// BOTTOM OF METADATA
});
\ No newline at end of file
cordova.define("cordova-plugin-device.device", function(require, exports, module) { /*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 argscheck = require('cordova/argscheck'),
channel = require('cordova/channel'),
utils = require('cordova/utils'),
exec = require('cordova/exec'),
cordova = require('cordova');
channel.createSticky('onCordovaInfoReady');
// Tell cordova channel to wait on the CordovaInfoReady event
channel.waitForInitialization('onCordovaInfoReady');
/**
* This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
* phone, etc.
* @constructor
*/
function Device() {
this.available = false;
this.platform = null;
this.version = null;
this.uuid = null;
this.cordova = null;
this.model = null;
this.manufacturer = null;
var me = this;
channel.onCordovaReady.subscribe(function() {
me.getInfo(function(info) {
//ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js
//TODO: CB-5105 native implementations should not return info.cordova
var buildLabel = cordova.version;
me.available = true;
me.platform = info.platform;
me.version = info.version;
me.uuid = info.uuid;
me.cordova = buildLabel;
me.model = info.model;
me.manufacturer = info.manufacturer || 'unknown';
channel.onCordovaInfoReady.fire();
},function(e) {
me.available = false;
utils.alert("[ERROR] Error initializing Cordova: " + e);
});
});
}
/**
* Get device info
*
* @param {Function} successCallback The function to call when the heading data is available
* @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
*/
Device.prototype.getInfo = function(successCallback, errorCallback) {
argscheck.checkArgs('fF', 'Device.getInfo', arguments);
exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
};
module.exports = new Device();
});
cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, module) { exports.defineAutoTests = function() { cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) { var fail = function (done) {
expect(true).toBe(false); expect(true).toBe(false);
done(); done();
...@@ -20,6 +20,14 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m ...@@ -20,6 +20,14 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m
expect(window.plugins.toast.show).toBeDefined(); expect(window.plugins.toast.show).toBeDefined();
}); });
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() { it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined(); expect(window.plugins.toast.showShortTop).toBeDefined();
}); });
...@@ -47,11 +55,7 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m ...@@ -47,11 +55,7 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m
describe('Invalid usage', function () { describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) { it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done)); window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
it("should fail due to an invalid duration", function(done) {
window.plugins.toast.show('hi', 'medium', 'top', fail.bind(null, done), succeed.bind(null, done));
}); });
}); });
}; };
......
cordova.define("nl.x-services.plugins.toast.Toast", function(require, exports, module) { function Toast() { cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) { function Toast() {
} }
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) { Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [message, duration, position]); this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
}; };
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) { Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba ...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba
this.show(message, "long", "bottom", successCallback, errorCallback); this.show(message, "long", "bottom", successCallback, errorCallback);
}; };
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () { Toast.install = function () {
if (!window.plugins) { if (!window.plugins) {
window.plugins = {}; window.plugins = {};
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
var exec = require('cordova/exec');
/********
* CORE *
********/
/**
* Returns the default settings.
*
* @return {Object}
*/
exports.getDefaults = function () {
return this._defaults;
};
/**
* Overwrite default settings.
*
* @param {Object} defaults
*/
exports.setDefaults = function (newDefaults) {
var defaults = this.getDefaults();
for (var key in defaults) {
if (newDefaults.hasOwnProperty(key)) {
defaults[key] = newDefaults[key];
}
}
};
/**
* Schedule a new local notification.
*
* @param {Object} opts
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.schedule = function (opts, callback, scope) {
this.registerPermission(function(granted) {
if (!granted)
return;
var notifications = Array.isArray(opts) ? opts : [opts];
for (var i = 0; i < notifications.length; i++) {
var properties = notifications[i];
this.mergeWithDefaults(properties);
this.convertProperties(properties);
}
this.exec('schedule', notifications, callback, scope);
}, this);
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Object} options
* The notification properties to update
* @param {Function} callback
* A function to be called after the notification has been updated
* @param {Object?} scope
* The scope for the callback function
*/
exports.update = function (opts, callback, scope) {
var notifications = Array.isArray(opts) ? opts : [opts];
for (var i = 0; i < notifications.length; i++) {
var properties = notifications[i];
this.convertProperties(properties);
}
this.exec('update', notifications, callback, scope);
};
/**
* Clear the specified notification.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clear = function (ids, callback, scope) {
ids = Array.isArray(ids) ? ids : [ids];
ids = this.convertIds(ids);
this.exec('clear', ids, callback, scope);
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clearAll = function (callback, scope) {
this.exec('clearAll', null, callback, scope);
};
/**
* Cancel the specified notifications.
*
* @param {String[]} ids
* The IDs of the notifications
* @param {Function} callback
* A function to be called after the notifications has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancel = function (ids, callback, scope) {
ids = Array.isArray(ids) ? ids : [ids];
ids = this.convertIds(ids);
this.exec('cancel', ids, callback, scope);
};
/**
* Remove all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancelAll = function (callback, scope) {
this.exec('cancelAll', null, callback, scope);
};
/**
* Check if a notification with an ID is present.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isPresent = function (id, callback, scope) {
this.exec('isPresent', id || 0, callback, scope);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isScheduled = function (id, callback, scope) {
this.exec('isScheduled', id || 0, callback, scope);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isTriggered = function (id, callback, scope) {
this.exec('isTriggered', id || 0, callback, scope);
};
/**
* List all local notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllIds = function (callback, scope) {
this.exec('getAllIds', null, callback, scope);
};
/**
* Alias for `getAllIds`.
*/
exports.getIds = function () {
this.getAllIds.apply(this, arguments);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduledIds = function (callback, scope) {
this.exec('getScheduledIds', null, callback, scope);
};
/**
* List all triggered notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggeredIds = function (callback, scope) {
this.exec('getTriggeredIds', null, callback, scope);
};
/**
* Property list for given local notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.get = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
this.exec('getSingle', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getAll', ids, callback, scope);
};
/**
* Property list for all local notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAll = function (callback, scope) {
this.exec('getAll', null, callback, scope);
};
/**
* Property list for given scheduled notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduled = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
ids = [ids];
}
if (!Array.isArray(ids)) {
this.exec('getSingleScheduled', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getScheduled', ids, callback, scope);
};
/**
* Property list for all scheduled notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllScheduled = function (callback, scope) {
this.exec('getScheduled', null, callback, scope);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggered = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
ids = [ids];
}
if (!Array.isArray(ids)) {
this.exec('getSingleTriggered', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getTriggered', ids, callback, scope);
};
/**
* Property list for all triggered notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllTriggered = function (callback, scope) {
this.exec('getTriggered', null, callback, scope);
};
/**
* Informs if the app has the permission to show notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.hasPermission = function (callback, scope) {
var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'hasPermission', []);
};
/**
* Register permission to show notifications if not already granted.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.registerPermission = function (callback, scope) {
var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'registerPermission', []);
};
/**********
* EVENTS *
**********/
/**
* Register callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
* @param {Object?} scope
* The callback function's scope
*/
exports.on = function (event, callback, scope) {
if (!this._listener[event]) {
this._listener[event] = [];
}
var item = [callback, scope || window];
this._listener[event].push(item);
};
/**
* Unregister callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
*/
exports.un = function (event, callback) {
var listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0];
if (fn == callback) {
listener.splice(i, 1);
break;
}
}
};
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
var exec = require('cordova/exec'),
channel = require('cordova/channel');
/***********
* MEMBERS *
***********/
// Default values
exports._defaults = {
text: '',
title: '',
sound: 'res://platform_default',
badge: 0,
id: 0,
data: undefined,
every: undefined,
at: undefined
};
// listener
exports._listener = {};
/********
* UTIL *
********/
/**
* Merge platform specific properties into the default ones.
*
* @return {Object}
* The default properties for the platform
*/
exports.applyPlatformSpecificOptions = function () {
var defaults = this._defaults;
switch (device.platform) {
case 'Android':
defaults.icon = 'res://icon';
defaults.smallIcon = 'res://ic_popup_reminder';
defaults.ongoing = false;
defaults.autoClear = true;
defaults.led = 'FFFFFF';
break;
}
return defaults;
};
/**
* Merge custom properties with the default values.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The merged property list
*/
exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults();
options.at = this.getValueFor(options, 'at', 'firstAt', 'date');
options.text = this.getValueFor(options, 'text', 'message');
options.data = this.getValueFor(options, 'data', 'json');
if (defaults.hasOwnProperty('autoClear')) {
options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel');
}
if (options.autoClear !== true && options.ongoing) {
options.autoClear = false;
}
if (options.at === undefined || options.at === null) {
options.at = new Date();
}
for (var key in defaults) {
if (options[key] === null || options[key] === undefined) {
if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
options[key] = undefined;
} else {
options[key] = defaults[key];
}
}
}
for (key in options) {
if (!defaults.hasOwnProperty(key)) {
delete options[key];
console.warn('Unknown property: ' + key);
}
}
return options;
};
/**
* Convert the passed values to their required type.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The converted property list
*/
exports.convertProperties = function (options) {
if (options.id) {
if (isNaN(options.id)) {
options.id = this.getDefaults().id;
console.warn('Id is not a number: ' + options.id);
} else {
options.id = Number(options.id);
}
}
if (options.title) {
options.title = options.title.toString();
}
if (options.text) {
options.text = options.text.toString();
}
if (options.badge) {
if (isNaN(options.badge)) {
options.badge = this.getDefaults().badge;
console.warn('Badge number is not a number: ' + options.id);
} else {
options.badge = Number(options.badge);
}
}
if (options.at) {
if (typeof options.at == 'object') {
options.at = options.at.getTime();
}
options.at = Math.round(options.at/1000);
}
if (typeof options.data == 'object') {
options.data = JSON.stringify(options.data);
}
return options;
};
/**
* Create callback, which will be executed within a specific scope.
*
* @param {Function} callbackFn
* The callback function
* @param {Object} scope
* The scope for the function
*
* @return {Function}
* The new callback function
*/
exports.createCallbackFn = function (callbackFn, scope) {
if (typeof callbackFn != 'function')
return;
return function () {
callbackFn.apply(scope || this, arguments);
};
};
/**
* Convert the IDs to numbers.
*
* @param {String/Number[]} ids
*
* @return Array of Numbers
*/
exports.convertIds = function (ids) {
var convertedIds = [];
for (var i = 0; i < ids.length; i++) {
convertedIds.push(Number(ids[i]));
}
return convertedIds;
};
/**
* First found value for the given keys.
*
* @param {Object} options
* Object with key-value properties
* @param {String[]} keys*
* Key list
*/
exports.getValueFor = function (options) {
var keys = Array.apply(null, arguments).slice(1);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (options.hasOwnProperty(key)) {
return options[key];
}
}
};
/**
* Fire event with given arguments.
*
* @param {String} event
* The event's name
* @param {args*}
* The callback's arguments
*/
exports.fireEvent = function (event) {
var args = Array.apply(null, arguments).slice(1),
listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0],
scope = listener[i][1];
fn.apply(scope, args);
}
};
/**
* Execute the native counterpart.
*
* @param {String} action
* The name of the action
* @param args[]
* Array of arguments
* @param {Function} callback
* The callback function
* @param {Object} scope
* The scope for the function
*/
exports.exec = function (action, args, callback, scope) {
var fn = this.createCallbackFn(callback, scope),
params = [];
if (Array.isArray(args)) {
params = args;
} else if (args) {
params.push(args);
}
exec(fn, null, 'LocalNotification', action, params);
};
/*********
* HOOKS *
*********/
// Called after 'deviceready' event
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// and all queued events can be executed.
exec(null, null, 'LocalNotification', 'deviceready', []);
});
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Device plugin is ready now
channel.onCordovaInfoReady.subscribe(function () {
// Merge platform specifics into defaults
exports.applyPlatformSpecificOptions();
});
});
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
/*************
* INTERFACE *
*************/
/**
* Returns the default settings.
*
* @return {Object}
*/
exports.getDefaults = function () {
return this.core.getDefaults();
};
/**
* Overwrite default settings.
*
* @param {Object} defaults
*/
exports.setDefaults = function (defaults) {
this.core.setDefaults(defaults);
};
/**
* Schedule a new local notification.
*
* @param {Object} opts
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.schedule = function (opts, callback, scope) {
this.core.schedule(opts, callback, scope);
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Object} options
* The notification properties to update
* @param {Function} callback
* A function to be called after the notification has been updated
* @param {Object?} scope
* The scope for the callback function
*/
exports.update = function (opts, callback, scope) {
this.core.update(opts, callback, scope);
};
/**
* Clear the specified notification.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clear = function (ids, callback, scope) {
this.core.clear(ids, callback, scope);
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clearAll = function (callback, scope) {
this.core.clearAll(callback, scope);
};
/**
* Cancel the specified notifications.
*
* @param {String[]} ids
* The IDs of the notifications
* @param {Function} callback
* A function to be called after the notifications has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancel = function (ids, callback, scope) {
this.core.cancel(ids, callback, scope);
};
/**
* Remove all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancelAll = function (callback, scope) {
this.core.cancelAll(callback, scope);
};
/**
* Check if a notification with an ID is present.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isPresent = function (id, callback, scope) {
this.core.isPresent(id, callback, scope);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isScheduled = function (id, callback, scope) {
this.core.isScheduled(id, callback, scope);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isTriggered = function (id, callback, scope) {
this.core.isTriggered(id, callback, scope);
};
/**
* List all local notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllIds = function (callback, scope) {
this.core.getAllIds(callback, scope);
};
/**
* Alias for `getAllIds`.
*/
exports.getIds = function () {
this.getAllIds.apply(this, arguments);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduledIds = function (callback, scope) {
this.core.getScheduledIds(callback, scope);
};
/**
* List all triggered notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggeredIds = function (callback, scope) {
this.core.getTriggeredIds(callback, scope);
};
/**
* Property list for given local notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.get = function () {
this.core.get.apply(this.core, arguments);
};
/**
* Property list for all local notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAll = function (callback, scope) {
this.core.getAll(callback, scope);
};
/**
* Property list for given scheduled notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduled = function () {
this.core.getScheduled.apply(this.core, arguments);
};
/**
* Property list for all scheduled notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllScheduled = function (callback, scope) {
this.core.getAllScheduled(callback, scope);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggered = function () {
this.core.getTriggered.apply(this.core, arguments);
};
/**
* Property list for all triggered notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllTriggered = function (callback, scope) {
this.core.getAllTriggered(callback, scope);
};
/**
* Informs if the app has the permission to show notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.hasPermission = function (callback, scope) {
this.core.hasPermission(callback, scope);
};
/**
* Register permission to show notifications if not already granted.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.registerPermission = function (callback, scope) {
this.core.registerPermission(callback, scope);
};
/****************
* DEPRECATIONS *
****************/
/**
* Schedule a new local notification.
*/
exports.add = function () {
console.warn('Depreated: Please use `notification.local.schedule` instead.');
this.schedule.apply(this, arguments);
};
/**
* Register permission to show notifications
* if not already granted.
*/
exports.promptForPermission = function () {
console.warn('Depreated: Please use `notification.local.registerPermission` instead.');
this.registerPermission.apply(this, arguments);
};
/**********
* EVENTS *
**********/
/**
* Register callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
* @param {Object?} scope
* The callback function's scope
*/
exports.on = function (event, callback, scope) {
this.core.on(event, callback, scope);
};
/**
* Unregister callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
*/
exports.un = function (event, callback) {
this.core.un(event, callback, scope);
};
});
...@@ -4,6 +4,12 @@ ...@@ -4,6 +4,12 @@
<feature name="Toast"> <feature name="Toast">
<param name="android-package" value="nl.xservices.plugins.Toast" /> <param name="android-package" value="nl.xservices.plugins.Toast" />
</feature> </feature>
<feature name="Device">
<param name="android-package" value="org.apache.cordova.device.Device" />
</feature>
<feature name="LocalNotification">
<param name="android-package" value="de.appplant.cordova.plugin.localnotification.LocalNotification" />
</feature>
<name>NotificationExample</name> <name>NotificationExample</name>
<description> <description>
A sample Apache Cordova application that responds to the deviceready event. A sample Apache Cordova application that responds to the deviceready event.
...@@ -13,10 +19,4 @@ ...@@ -13,10 +19,4 @@
</author> </author>
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<feature name="Device">
<param name="android-package" value="org.apache.cordova.device.Device" />
</feature>
<feature name="LocalNotification">
<param name="android-package" value="de.appplant.cordova.plugin.localnotification.LocalNotification" />
</feature>
</widget> </widget>
...@@ -5,6 +5,7 @@ import org.apache.cordova.CallbackContext; ...@@ -5,6 +5,7 @@ import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
/* /*
// TODO nice way for the Toast plugin to offer a longer delay than the default short and long options // TODO nice way for the Toast plugin to offer a longer delay than the default short and long options
...@@ -19,6 +20,7 @@ import org.json.JSONException; ...@@ -19,6 +20,7 @@ import org.json.JSONException;
public class Toast extends CordovaPlugin { public class Toast extends CordovaPlugin {
private static final String ACTION_SHOW_EVENT = "show"; private static final String ACTION_SHOW_EVENT = "show";
private static final String ACTION_HIDE_EVENT = "hide";
private android.widget.Toast mostRecentToast; private android.widget.Toast mostRecentToast;
...@@ -27,40 +29,44 @@ public class Toast extends CordovaPlugin { ...@@ -27,40 +29,44 @@ public class Toast extends CordovaPlugin {
@Override @Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if (ACTION_SHOW_EVENT.equals(action)) { if (ACTION_HIDE_EVENT.equals(action)) {
if (mostRecentToast != null) {
mostRecentToast.cancel();
}
callbackContext.success();
return true;
} else if (ACTION_SHOW_EVENT.equals(action)) {
if (this.isPaused) { if (this.isPaused) {
return true; return true;
} }
final String message = args.getString(0); final JSONObject options = args.getJSONObject(0);
final String duration = args.getString(1);
final String position = args.getString(2); final String message = options.getString("message");
final String duration = options.getString("duration");
final String position = options.getString("position");
final int addPixelsY = options.has("addPixelsY") ? options.getInt("addPixelsY") : 0;
cordova.getActivity().runOnUiThread(new Runnable() { cordova.getActivity().runOnUiThread(new Runnable() {
public void run() { public void run() {
android.widget.Toast toast = android.widget.Toast.makeText(webView.getContext(), message, 0); android.widget.Toast toast = android.widget.Toast.makeText(
cordova.getActivity().getApplicationContext(),
message,
"short".equals(duration) ? android.widget.Toast.LENGTH_SHORT : android.widget.Toast.LENGTH_LONG);
if ("top".equals(position)) { if ("top".equals(position)) {
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 20); toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 20 + addPixelsY);
} else if ("bottom".equals(position)) { } else if ("bottom".equals(position)) {
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 20); toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 20 - addPixelsY);
} else if ("center".equals(position)) { } else if ("center".equals(position)) {
toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0); toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, addPixelsY);
} else { } else {
callbackContext.error("invalid position. valid options are 'top', 'center' and 'bottom'"); callbackContext.error("invalid position. valid options are 'top', 'center' and 'bottom'");
return; return;
} }
if ("short".equals(duration)) {
toast.setDuration(android.widget.Toast.LENGTH_SHORT);
} else if ("long".equals(duration)) {
toast.setDuration(android.widget.Toast.LENGTH_LONG);
} else {
callbackContext.error("invalid duration. valid options are 'short' and 'long'");
return;
}
toast.show(); toast.show();
mostRecentToast = toast; mostRecentToast = toast;
callbackContext.success(); callbackContext.success();
...@@ -86,4 +92,4 @@ public class Toast extends CordovaPlugin { ...@@ -86,4 +92,4 @@ public class Toast extends CordovaPlugin {
public void onResume(boolean multitasking) { public void onResume(boolean multitasking) {
this.isPaused = false; this.isPaused = false;
} }
} }
\ No newline at end of file
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#define __CORDOVA_3_8_0 30800 #define __CORDOVA_3_8_0 30800
#define __CORDOVA_3_9_0 30900 #define __CORDOVA_3_9_0 30900
#define __CORDOVA_3_9_1 30901 #define __CORDOVA_3_9_1 30901
#define __CORDOVA_3_9_2 30902
#define __CORDOVA_NA 99999 /* not available */ #define __CORDOVA_NA 99999 /* not available */
/* /*
...@@ -67,7 +68,7 @@ ...@@ -67,7 +68,7 @@
#endif #endif
*/ */
#ifndef CORDOVA_VERSION_MIN_REQUIRED #ifndef CORDOVA_VERSION_MIN_REQUIRED
#define CORDOVA_VERSION_MIN_REQUIRED __CORDOVA_3_9_1 #define CORDOVA_VERSION_MIN_REQUIRED __CORDOVA_3_9_2
#endif #endif
/* /*
......
...@@ -38,7 +38,7 @@ extern NSString* const CDVRemoteNotificationError; ...@@ -38,7 +38,7 @@ extern NSString* const CDVRemoteNotificationError;
@property (readonly, assign) BOOL hasPendingOperation; @property (readonly, assign) BOOL hasPendingOperation;
- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView; - (CDVPlugin*)initWithWebView:(UIWebView*)theWebView CDV_DEPRECATED(3.9.2, "Use pluginInitialize method instead. This will be removed in 4.0.0");
- (void)pluginInitialize; - (void)pluginInitialize;
- (void)handleOpenURL:(NSNotification*)notification; - (void)handleOpenURL:(NSNotification*)notification;
......
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
@property (nonatomic, readonly, strong) NSDictionary* pluginsMap; @property (nonatomic, readonly, strong) NSDictionary* pluginsMap;
@property (nonatomic, readonly, strong) NSMutableDictionary* settings; @property (nonatomic, readonly, strong) NSMutableDictionary* settings;
@property (nonatomic, readonly, strong) NSXMLParser* configParser; @property (nonatomic, readonly, strong) NSXMLParser* configParser;
@property (nonatomic, readonly, strong) CDVWhitelist* whitelist; // readonly for public @property (nonatomic, readonly, strong) CDVWhitelist* whitelist CDV_DEPRECATED(3.9.2, "Use URLisAllowed to check specific URL. This will be removed in 4.0.0"); // readonly for public
@property (nonatomic, readonly, assign) BOOL loadFromString; @property (nonatomic, readonly, assign) BOOL loadFromString CDV_DEPRECATED(3.9.2, "This will be removed in 4.0.0");
@property (nonatomic, readwrite, copy) NSString* wwwFolderName; @property (nonatomic, readwrite, copy) NSString* wwwFolderName;
@property (nonatomic, readwrite, copy) NSString* startPage; @property (nonatomic, readwrite, copy) NSString* startPage;
...@@ -61,14 +61,14 @@ ...@@ -61,14 +61,14 @@
*/ */
@property (nonatomic, readwrite, copy) NSString* baseUserAgent; @property (nonatomic, readwrite, copy) NSString* baseUserAgent;
+ (NSDictionary*)getBundlePlist:(NSString*)plistName; + (NSDictionary*)getBundlePlist:(NSString*)plistName CDV_DEPRECATED(3.9.2, "This will be removed in 4.0.0");
+ (NSString*)applicationDocumentsDirectory; + (NSString*)applicationDocumentsDirectory CDV_DEPRECATED(3.9.2, "This will be removed in 4.0.0");
- (void)printMultitaskingInfo; - (void)printMultitaskingInfo CDV_DEPRECATED(3.9.2, "This will be removed in 4.0.0");
- (void)createGapView; - (void)createGapView CDV_DEPRECATED(3.9.2, "This will be removed in 4.0.0");
- (UIWebView*)newCordovaViewWithFrame:(CGRect)bounds; - (UIWebView*)newCordovaViewWithFrame:(CGRect)bounds;
- (void)javascriptAlert:(NSString*)text; - (void)javascriptAlert:(NSString*)text CDV_DEPRECATED(3.9.2, "Use the CDVCommandDelegate evalJs: directly. This will be removed in 4.0.0");
- (NSString*)appURLScheme; - (NSString*)appURLScheme;
- (NSArray*)parseInterfaceOrientations:(NSArray*)orientations; - (NSArray*)parseInterfaceOrientations:(NSArray*)orientations;
......
...@@ -197,7 +197,7 @@ static NSString *stripFragment(NSString* url) ...@@ -197,7 +197,7 @@ static NSString *stripFragment(NSString* url)
{ {
NSString* scheme = [[request URL] scheme]; NSString* scheme = [[request URL] scheme];
if ([scheme isEqualToString:@"mailto"] || [scheme isEqualToString:@"tel"] || [scheme isEqualToString:@"sms"]) { if ([scheme isEqualToString:@"mailto"] || [scheme isEqualToString:@"tel"] || [scheme isEqualToString:@"sms"] || [scheme isEqualToString:@"blob"]) {
return YES; return YES;
} }
......
...@@ -41,7 +41,7 @@ char *CDVNewBase64Encode( ...@@ -41,7 +41,7 @@ char *CDVNewBase64Encode(
- (NSString*)base64EncodedString CDV_DEPRECATED(3.8 .0, "Use [NSData cdv_base64EncodedString]"); - (NSString*)base64EncodedString CDV_DEPRECATED(3.8 .0, "Use [NSData cdv_base64EncodedString]");
+ (NSData*)cdv_dataFromBase64String:(NSString*)aString; + (NSData*)cdv_dataFromBase64String:(NSString*)aString CDV_DEPRECATED(3.9.2, "Use NSData initWithBase64EncodedString instead. This will be removed in 4.0.0");
- (NSString*)cdv_base64EncodedString; - (NSString*)cdv_base64EncodedString CDV_DEPRECATED(3.9.2, "Use NSData base64EncodedStringWithOptions instead. This will be removed in 4.0.0");
@end @end
...@@ -325,7 +325,7 @@ ...@@ -325,7 +325,7 @@
0867D690FE84028FC02AAC07 /* Project object */ = { 0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 0700; LastUpgradeCheck = 0710;
}; };
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "CordovaLib" */; buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "CordovaLib" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0700" LastUpgradeVersion = "0710"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
......
// Platform: ios // Platform: ios
// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c // 49a8db57fa070d20ea7b304a53ffec3d7250c5af
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
under the License. under the License.
*/ */
;(function() { ;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '3.9.1'; var PLATFORM_VERSION_BUILD_LABEL = '3.9.2';
// file: src/scripts/require.js // file: src/scripts/require.js
/*jshint -W079 */ /*jshint -W079 */
...@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { ...@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") {
// file: src/cordova.js // file: src/cordova.js
define("cordova", function(require, exports, module) { define("cordova", function(require, exports, module) {
if(window.cordova){ // Workaround for Windows 10 in hosted environment case
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
throw new Error("cordova already defined"); throw new Error("cordova already defined");
} }
...@@ -815,7 +817,7 @@ module.exports = channel; ...@@ -815,7 +817,7 @@ module.exports = channel;
}); });
// file: /Users/steveng/repo/cordova/cordova-ios/cordova-js-src/exec.js // file: e:/cordova/cordova-ios/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) { define("cordova/exec", function(require, exports, module) {
/** /**
...@@ -1286,10 +1288,12 @@ define("cordova/init_b", function(require, exports, module) { ...@@ -1286,10 +1288,12 @@ define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var cordova = require('cordova'); var cordova = require('cordova');
var modulemapper = require('cordova/modulemapper');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
var pluginloader = require('cordova/pluginloader');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
// setting exec // setting exec
cordova.exec = require('cordova/exec'); cordova.exec = require('cordova/exec');
...@@ -1374,10 +1378,19 @@ if (window._nativeReady) { ...@@ -1374,10 +1378,19 @@ if (window._nativeReady) {
// Call the platform-specific initialization. // Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap(); platform.bootstrap && platform.bootstrap();
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
// The delay allows the attached modules to be defined before the plugin loader looks for them.
setTimeout(function() {
pluginloader.load(function() {
channel.onPluginsReady.fire();
});
}, 0);
/** /**
* Create all cordova objects once native side is ready. * Create all cordova objects once native side is ready.
*/ */
channel.join(function() { channel.join(function() {
modulemapper.mapModules(window);
platform.initialize && platform.initialize(); platform.initialize && platform.initialize();
...@@ -1496,7 +1509,104 @@ exports.reset(); ...@@ -1496,7 +1509,104 @@ exports.reset();
}); });
// file: /Users/steveng/repo/cordova/cordova-ios/cordova-js-src/platform.js // file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder'),
symbolList = [],
deprecationMap;
exports.reset = function() {
symbolList = [];
deprecationMap = {};
};
function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
symbolList.push(strategy, moduleName, symbolPath);
if (opt_deprecationMessage) {
deprecationMap[symbolPath] = opt_deprecationMessage;
}
}
// Note: Android 2.3 does have Function.bind().
exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
};
exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
};
exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
};
exports.runs = function(moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace(symbolPath, context) {
if (!symbolPath) {
return context;
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
cur = cur[part] = cur[part] || {};
}
return cur;
}
exports.mapModules = function(context) {
var origSymbols = {};
context.CDV_origSymbols = origSymbols;
for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i];
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
}
}
};
exports.getOriginalSymbol = function(context, symbolPath) {
var origSymbols = context.CDV_origSymbols;
if (origSymbols && (symbolPath in origSymbols)) {
return origSymbols[symbolPath];
}
var parts = symbolPath.split('.');
var obj = context;
for (var i = 0; i < parts.length; ++i) {
obj = obj && obj[parts[i]];
}
return obj;
};
exports.reset();
});
// file: e:/cordova/cordova-ios/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) { define("cordova/platform", function(require, exports, module) {
module.exports = { module.exports = {
...@@ -1512,10 +1622,6 @@ module.exports = { ...@@ -1512,10 +1622,6 @@ module.exports = {
// file: src/common/pluginloader.js // file: src/common/pluginloader.js
define("cordova/pluginloader", function(require, exports, module) { define("cordova/pluginloader", function(require, exports, module) {
/*
NOTE: this file is NOT used when we use the browserify workflow
*/
var modulemapper = require('cordova/modulemapper'); var modulemapper = require('cordova/modulemapper');
var urlutil = require('cordova/urlutil'); var urlutil = require('cordova/urlutil');
...@@ -1625,6 +1731,54 @@ exports.load = function(callback) { ...@@ -1625,6 +1731,54 @@ exports.load = function(callback) {
}); });
// file: src/common/pluginloader_b.js
define("cordova/pluginloader_b", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
// Handler for the cordova_plugins.js content.
// See plugman's plugin_loader.js for the details of this object.
function handlePluginsObject(moduleList) {
// if moduleList is not defined or empty, we've nothing to do
if (!moduleList || !moduleList.length) {
return;
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
if (module.clobbers && module.clobbers.length) {
for (var j = 0; j < module.clobbers.length; j++) {
modulemapper.clobbers(module.id, module.clobbers[j]);
}
}
if (module.merges && module.merges.length) {
for (var k = 0; k < module.merges.length; k++) {
modulemapper.merges(module.id, module.merges[k]);
}
}
// Finally, if runs is truthy we want to simply require() the module.
if (module.runs) {
modulemapper.runs(module.id);
}
}
}
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
// but the method accepts callback to be compatible with non-browserify flow.
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
// no plugins to load, or they are all done.
exports.load = function(callback) {
var moduleList = require("cordova/plugin_list");
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js // file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) { define("cordova/urlutil", function(require, exports, module) {
......
...@@ -5,10 +5,14 @@ ...@@ -5,10 +5,14 @@
}; };
objectVersion = 46; objectVersion = 46;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
0C0E2A31DDEF48E2B4D0F3E9 /* Toast.m in Sources */ = {isa = PBXBuildFile; fileRef = 5617A54733CB4B97BDB6F2F1 /* Toast.m */; };
1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; };
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };
29FEBD0E2E0645EA81FC891A /* APPLocalNotificationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = F17A776F5B1545D4B54C57E9 /* APPLocalNotificationOptions.m */; };
2E64E4DBC7414234A8815767 /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 90FEACFA561C484FBE18A018 /* AppDelegate+APPRegisterUserNotificationSettings.m */; };
301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; }; 301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; };
302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; }; 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; };
302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; }; 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; };
...@@ -27,8 +31,9 @@ ...@@ -27,8 +31,9 @@
30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */; }; 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */; };
30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30C1856519D5FC0A00212699 /* icon-60@3x.png */; }; 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30C1856519D5FC0A00212699 /* icon-60@3x.png */; };
30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30FC414816E50CA1004E6F35 /* icon-72@2x.png */; }; 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30FC414816E50CA1004E6F35 /* icon-72@2x.png */; };
4C7B935B9D894F72B9E4C247 /* UIApplication+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 04020B4053F447DDA00B0D7C /* UIApplication+APPLocalNotification.m */; };
512344C179EC48DFADC955BB /* APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = C260FC27FFFC469BBCFB0D9C /* APPLocalNotification.m */; };
5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */; }; 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */; };
6A8F96ADE761487C81E6E457 /* Toast+UIView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3A9F0FD8971443ABE2CD997 /* Toast+UIView.m */; };
7E7966DE1810823500FA85AD /* icon-40.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D41810823500FA85AD /* icon-40.png */; }; 7E7966DE1810823500FA85AD /* icon-40.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D41810823500FA85AD /* icon-40.png */; };
7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D51810823500FA85AD /* icon-40@2x.png */; }; 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D51810823500FA85AD /* icon-40@2x.png */; };
7E7966E01810823500FA85AD /* icon-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D61810823500FA85AD /* icon-50.png */; }; 7E7966E01810823500FA85AD /* icon-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D61810823500FA85AD /* icon-50.png */; };
...@@ -39,15 +44,11 @@ ...@@ -39,15 +44,11 @@
7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; }; 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; };
7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; }; 7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; };
7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; }; 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; };
B71D8D446BDD468D91312FC4 /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 52D79A2853814BD1A3A10B7D /* AppDelegate+APPRegisterUserNotificationSettings.m */; };
BFDE0D6A4AE64EBB98F82923 /* Toast.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DB052EC20A4E42A76FEEDA /* Toast.m */; };
C34903A0A98845C5B3980421 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA0BA11967D24FFF9A8729E3 /* QuartzCore.framework */; };
D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; }; D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; };
D4A8F9ED5C744DF9AE0F017C /* CDVDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F8F08CF872443B99B4C7F0C /* CDVDevice.m */; }; D501EA92B01747F4AFC08C75 /* UILocalNotification+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = E352A55911264E1996D8EEA5 /* UILocalNotification+APPLocalNotification.m */; };
B27FD1146F2346B8A25D8B58 /* APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = E4AC231569274FDC9A337CE1 /* APPLocalNotification.m */; }; D7D9ED2B2D7C4097B0EDB950 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DAE83A9E43845B29CE75F17 /* QuartzCore.framework */; };
F5781270C72C46AEB4DE2F9A /* APPLocalNotificationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F35C3B0341549BCB67F40AF /* APPLocalNotificationOptions.m */; }; EDCBCFDC019B493099D01F59 /* Toast+UIView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E7966BF0D4846DCA2ADE3BE /* Toast+UIView.m */; };
821357C60CE6476988324E2A /* UIApplication+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A54961A48724D74972157C8 /* UIApplication+APPLocalNotification.m */; }; F7B4BDC76BE440BDAC7D7D47 /* CDVDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = E034746E86E84A50B0AC5EA9 /* CDVDevice.m */; };
24888EC32C55469EA588670F /* UILocalNotification+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = DD2C696409F449568F10BD80 /* UILocalNotification+APPLocalNotification.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
...@@ -68,12 +69,14 @@ ...@@ -68,12 +69,14 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
04020B4053F447DDA00B0D7C /* UIApplication+APPLocalNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIApplication+APPLocalNotification.m"; path = "de.appplant.cordova.plugin.local-notification/UIApplication+APPLocalNotification.m"; sourceTree = "<group>"; };
14D7E452DEE64773A12E60E2 /* APPLocalNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APPLocalNotification.h; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotification.h"; sourceTree = "<group>"; };
18F8F22E883249FD90F5F066 /* CDVDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVDevice.h; path = "cordova-plugin-device/CDVDevice.h"; sourceTree = "<group>"; };
1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
1D6058910D05DD3D006BFB54 /* NotificationExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NotificationExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1D6058910D05DD3D006BFB54 /* NotificationExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NotificationExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
29DB052EC20A4E42A76FEEDA /* Toast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Toast.m; path = "nl.x-services.plugins.toast/Toast.m"; sourceTree = "<group>"; };
301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; }; 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; };
301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; }; 301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; };
302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; }; 302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; };
...@@ -95,10 +98,13 @@ ...@@ -95,10 +98,13 @@
30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = "<group>"; }; 30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = "<group>"; };
30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = "<group>"; }; 30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* NotificationExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NotificationExample-Prefix.pch"; sourceTree = "<group>"; }; 32CA4F630368D1EE00C91783 /* NotificationExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NotificationExample-Prefix.pch"; sourceTree = "<group>"; };
52D79A2853814BD1A3A10B7D /* AppDelegate+APPRegisterUserNotificationSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "AppDelegate+APPRegisterUserNotificationSettings.m"; path = "de.appplant.cordova.common.registerusernotificationsettings/AppDelegate+APPRegisterUserNotificationSettings.m"; sourceTree = "<group>"; }; 3E7966BF0D4846DCA2ADE3BE /* Toast+UIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Toast+UIView.m"; path = "cordova-plugin-x-toast/Toast+UIView.m"; sourceTree = "<group>"; };
53BC65B8679643FD87A02C6E /* Toast+UIView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Toast+UIView.h"; path = "nl.x-services.plugins.toast/Toast+UIView.h"; sourceTree = "<group>"; }; 5617A54733CB4B97BDB6F2F1 /* Toast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Toast.m; path = "cordova-plugin-x-toast/Toast.m"; sourceTree = "<group>"; };
5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
78F93C2A583F42ACAE4095E8 /* AppDelegate+APPRegisterUserNotificationSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AppDelegate+APPRegisterUserNotificationSettings.h"; path = "de.appplant.cordova.common.registerusernotificationsettings/AppDelegate+APPRegisterUserNotificationSettings.h"; sourceTree = "<group>"; }; 63E5C218518249B6980B2F8F /* UILocalNotification+APPLocalNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UILocalNotification+APPLocalNotification.h"; path = "de.appplant.cordova.plugin.local-notification/UILocalNotification+APPLocalNotification.h"; sourceTree = "<group>"; };
65DF25FE02664C129FB5CC2D /* UIApplication+APPLocalNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIApplication+APPLocalNotification.h"; path = "de.appplant.cordova.plugin.local-notification/UIApplication+APPLocalNotification.h"; sourceTree = "<group>"; };
6DAE83A9E43845B29CE75F17 /* QuartzCore.framework */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
785B371A98324A8A9DA56DEF /* AppDelegate+APPRegisterUserNotificationSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AppDelegate+APPRegisterUserNotificationSettings.h"; path = "de.appplant.cordova.common.registerusernotificationsettings/AppDelegate+APPRegisterUserNotificationSettings.h"; sourceTree = "<group>"; };
7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = "<group>"; }; 7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = "<group>"; };
7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = "<group>"; }; 7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = "<group>"; };
7E7966D61810823500FA85AD /* icon-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50.png"; sourceTree = "<group>"; }; 7E7966D61810823500FA85AD /* icon-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50.png"; sourceTree = "<group>"; };
...@@ -110,23 +116,18 @@ ...@@ -110,23 +116,18 @@
7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; }; 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; };
7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = "<group>"; }; 7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* NotificationExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NotificationExample-Info.plist"; path = "../NotificationExample-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; }; 8D1107310486CEB800E47090 /* NotificationExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NotificationExample-Info.plist"; path = "../NotificationExample-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
AA0BA11967D24FFF9A8729E3 /* QuartzCore.framework */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 90FEACFA561C484FBE18A018 /* AppDelegate+APPRegisterUserNotificationSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "AppDelegate+APPRegisterUserNotificationSettings.m"; path = "de.appplant.cordova.common.registerusernotificationsettings/AppDelegate+APPRegisterUserNotificationSettings.m"; sourceTree = "<group>"; };
B511C166ACE7434AA298EEE0 /* Toast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Toast.h; path = "nl.x-services.plugins.toast/Toast.h"; sourceTree = "<group>"; }; 938E77E02A1A48E79F19901F /* Toast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Toast.h; path = "cordova-plugin-x-toast/Toast.h"; sourceTree = "<group>"; };
C3A9F0FD8971443ABE2CD997 /* Toast+UIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Toast+UIView.m"; path = "nl.x-services.plugins.toast/Toast+UIView.m"; sourceTree = "<group>"; }; A637E8005CD04BF9BAE9901B /* Toast+UIView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Toast+UIView.h"; path = "cordova-plugin-x-toast/Toast+UIView.h"; sourceTree = "<group>"; };
C260FC27FFFC469BBCFB0D9C /* APPLocalNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = APPLocalNotification.m; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotification.m"; sourceTree = "<group>"; };
D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; }; D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; };
E034746E86E84A50B0AC5EA9 /* CDVDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVDevice.m; path = "cordova-plugin-device/CDVDevice.m"; sourceTree = "<group>"; };
E352A55911264E1996D8EEA5 /* UILocalNotification+APPLocalNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UILocalNotification+APPLocalNotification.m"; path = "de.appplant.cordova.plugin.local-notification/UILocalNotification+APPLocalNotification.m"; sourceTree = "<group>"; };
EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = "<group>"; }; EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = "<group>"; };
EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = "<group>"; }; EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = "<group>"; };
F072C5B0F4394D75995BD4DE /* APPLocalNotificationOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APPLocalNotificationOptions.h; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotificationOptions.h"; sourceTree = "<group>"; };
F17A776F5B1545D4B54C57E9 /* APPLocalNotificationOptions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = APPLocalNotificationOptions.m; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotificationOptions.m"; sourceTree = "<group>"; };
F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = NotificationExample/config.xml; sourceTree = "<group>"; }; F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = NotificationExample/config.xml; sourceTree = "<group>"; };
3F8F08CF872443B99B4C7F0C /* CDVDevice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "CDVDevice.m"; path = "cordova-plugin-device/CDVDevice.m"; sourceTree = "<group>"; fileEncoding = 4; };
E4AB18AB2B9447FAAB56CFFA /* CDVDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "CDVDevice.h"; path = "cordova-plugin-device/CDVDevice.h"; sourceTree = "<group>"; fileEncoding = 4; };
E4AC231569274FDC9A337CE1 /* APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "APPLocalNotification.m"; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
0F35C3B0341549BCB67F40AF /* APPLocalNotificationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "APPLocalNotificationOptions.m"; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotificationOptions.m"; sourceTree = "<group>"; fileEncoding = 4; };
6A54961A48724D74972157C8 /* UIApplication+APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UIApplication+APPLocalNotification.m"; path = "de.appplant.cordova.plugin.local-notification/UIApplication+APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
DD2C696409F449568F10BD80 /* UILocalNotification+APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UILocalNotification+APPLocalNotification.m"; path = "de.appplant.cordova.plugin.local-notification/UILocalNotification+APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
657DD45362F04979AF1782CE /* APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "APPLocalNotification.h"; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
20047DC97F7A4DBEB4608A12 /* APPLocalNotificationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "APPLocalNotificationOptions.h"; path = "de.appplant.cordova.plugin.local-notification/APPLocalNotificationOptions.h"; sourceTree = "<group>"; fileEncoding = 4; };
90749E99DCA6429D9C535ED1 /* UIApplication+APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UIApplication+APPLocalNotification.h"; path = "de.appplant.cordova.plugin.local-notification/UIApplication+APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
BF3E0B730811413DB3F91222 /* UILocalNotification+APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UILocalNotification+APPLocalNotification.h"; path = "de.appplant.cordova.plugin.local-notification/UILocalNotification+APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -138,7 +139,7 @@ ...@@ -138,7 +139,7 @@
301BF552109A68D80062928A /* libCordova.a in Frameworks */, 301BF552109A68D80062928A /* libCordova.a in Frameworks */,
288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */,
305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */, 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */,
C34903A0A98845C5B3980421 /* QuartzCore.framework in Frameworks */, D7D9ED2B2D7C4097B0EDB950 /* QuartzCore.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -210,7 +211,7 @@ ...@@ -210,7 +211,7 @@
5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */, 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */,
288765FC0DF74451002DB57D /* CoreGraphics.framework */, 288765FC0DF74451002DB57D /* CoreGraphics.framework */,
305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */,
AA0BA11967D24FFF9A8729E3 /* QuartzCore.framework */, 6DAE83A9E43845B29CE75F17 /* QuartzCore.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -226,22 +227,22 @@ ...@@ -226,22 +227,22 @@
307C750510C5A3420062BCA9 /* Plugins */ = { 307C750510C5A3420062BCA9 /* Plugins */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
52D79A2853814BD1A3A10B7D /* AppDelegate+APPRegisterUserNotificationSettings.m */, E034746E86E84A50B0AC5EA9 /* CDVDevice.m */,
78F93C2A583F42ACAE4095E8 /* AppDelegate+APPRegisterUserNotificationSettings.h */, 18F8F22E883249FD90F5F066 /* CDVDevice.h */,
C3A9F0FD8971443ABE2CD997 /* Toast+UIView.m */, 3E7966BF0D4846DCA2ADE3BE /* Toast+UIView.m */,
29DB052EC20A4E42A76FEEDA /* Toast.m */, 5617A54733CB4B97BDB6F2F1 /* Toast.m */,
53BC65B8679643FD87A02C6E /* Toast+UIView.h */, A637E8005CD04BF9BAE9901B /* Toast+UIView.h */,
B511C166ACE7434AA298EEE0 /* Toast.h */, 938E77E02A1A48E79F19901F /* Toast.h */,
3F8F08CF872443B99B4C7F0C /* CDVDevice.m */, 90FEACFA561C484FBE18A018 /* AppDelegate+APPRegisterUserNotificationSettings.m */,
E4AB18AB2B9447FAAB56CFFA /* CDVDevice.h */, 785B371A98324A8A9DA56DEF /* AppDelegate+APPRegisterUserNotificationSettings.h */,
E4AC231569274FDC9A337CE1 /* APPLocalNotification.m */, C260FC27FFFC469BBCFB0D9C /* APPLocalNotification.m */,
0F35C3B0341549BCB67F40AF /* APPLocalNotificationOptions.m */, F17A776F5B1545D4B54C57E9 /* APPLocalNotificationOptions.m */,
6A54961A48724D74972157C8 /* UIApplication+APPLocalNotification.m */, 04020B4053F447DDA00B0D7C /* UIApplication+APPLocalNotification.m */,
DD2C696409F449568F10BD80 /* UILocalNotification+APPLocalNotification.m */, E352A55911264E1996D8EEA5 /* UILocalNotification+APPLocalNotification.m */,
657DD45362F04979AF1782CE /* APPLocalNotification.h */, 14D7E452DEE64773A12E60E2 /* APPLocalNotification.h */,
20047DC97F7A4DBEB4608A12 /* APPLocalNotificationOptions.h */, F072C5B0F4394D75995BD4DE /* APPLocalNotificationOptions.h */,
90749E99DCA6429D9C535ED1 /* UIApplication+APPLocalNotification.h */, 65DF25FE02664C129FB5CC2D /* UIApplication+APPLocalNotification.h */,
BF3E0B730811413DB3F91222 /* UILocalNotification+APPLocalNotification.h */, 63E5C218518249B6980B2F8F /* UILocalNotification+APPLocalNotification.h */,
); );
name = Plugins; name = Plugins;
path = NotificationExample/Plugins; path = NotificationExample/Plugins;
...@@ -323,7 +324,7 @@ ...@@ -323,7 +324,7 @@
29B97313FDCFA39411CA2CEA /* Project object */ = { 29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 700; LastUpgradeCheck = 0710;
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "NotificationExample" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "NotificationExample" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
...@@ -426,14 +427,14 @@ ...@@ -426,14 +427,14 @@
1D60589B0D05DD56006BFB54 /* main.m in Sources */, 1D60589B0D05DD56006BFB54 /* main.m in Sources */,
1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */,
302D95F114D2391D003F00A1 /* MainViewController.m in Sources */, 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */,
B71D8D446BDD468D91312FC4 /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */, F7B4BDC76BE440BDAC7D7D47 /* CDVDevice.m in Sources */,
6A8F96ADE761487C81E6E457 /* Toast+UIView.m in Sources */, EDCBCFDC019B493099D01F59 /* Toast+UIView.m in Sources */,
BFDE0D6A4AE64EBB98F82923 /* Toast.m in Sources */, 0C0E2A31DDEF48E2B4D0F3E9 /* Toast.m in Sources */,
D4A8F9ED5C744DF9AE0F017C /* CDVDevice.m in Sources */, 2E64E4DBC7414234A8815767 /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */,
B27FD1146F2346B8A25D8B58 /* APPLocalNotification.m in Sources */, 512344C179EC48DFADC955BB /* APPLocalNotification.m in Sources */,
F5781270C72C46AEB4DE2F9A /* APPLocalNotificationOptions.m in Sources */, 29FEBD0E2E0645EA81FC891A /* APPLocalNotificationOptions.m in Sources */,
821357C60CE6476988324E2A /* UIApplication+APPLocalNotification.m in Sources */, 4C7B935B9D894F72B9E4C247 /* UIApplication+APPLocalNotification.m in Sources */,
24888EC32C55469EA588670F /* UILocalNotification+APPLocalNotification.m in Sources */, D501EA92B01747F4AFC08C75 /* UILocalNotification+APPLocalNotification.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -578,6 +579,7 @@ ...@@ -578,6 +579,7 @@
"\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
"\"$(OBJROOT)/UninstalledProducts/include\"", "\"$(OBJROOT)/UninstalledProducts/include\"",
"\"$(BUILT_PRODUCTS_DIR)\"", "\"$(BUILT_PRODUCTS_DIR)\"",
"\"$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include\"",
); );
IPHONEOS_DEPLOYMENT_TARGET = 6.0; IPHONEOS_DEPLOYMENT_TARGET = 6.0;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0700" LastUpgradeVersion = "0710"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
......
...@@ -135,7 +135,11 @@ ...@@ -135,7 +135,11 @@
} }
#endif #endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window - (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
#else
- (UIInterfaceOrientationMask)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
#endif
{ {
// iPhone doesn't support upside down by default, while the iPad does. Override to allow all orientations always, and let the root view controller decide what's allowed (the supported orientations mask gets intersected). // iPhone doesn't support upside down by default, while the iPad does. Override to allow all orientations always, and let the root view controller decide what's allowed (the supported orientations mask gets intersected).
NSUInteger supportedInterfaceOrientations = (1 << UIInterfaceOrientationPortrait) | (1 << UIInterfaceOrientationLandscapeLeft) | (1 << UIInterfaceOrientationLandscapeRight) | (1 << UIInterfaceOrientationPortraitUpsideDown); NSUInteger supportedInterfaceOrientations = (1 << UIInterfaceOrientationPortrait) | (1 << UIInterfaceOrientationLandscapeLeft) | (1 << UIInterfaceOrientationLandscapeRight) | (1 << UIInterfaceOrientationPortraitUpsideDown);
......
...@@ -64,6 +64,11 @@ ...@@ -64,6 +64,11 @@
<string>0.0.1</string> <string>0.0.1</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string></string> <string></string>
<key>NSMainNibFile~ipad</key> <key>NSMainNibFile~ipad</key>
...@@ -171,5 +176,7 @@ ...@@ -171,5 +176,7 @@
<string>{768, 1024}</string> <string>{768, 1024}</string>
</dict> </dict>
</array> </array>
<key>UIRequiresFullScreen</key>
<true/>
</dict> </dict>
</plist> </plist>
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
// each makeToast method creates a view and displays it as toast // each makeToast method creates a view and displays it as toast
- (void)makeToast:(NSString *)message; - (void)makeToast:(NSString *)message;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position addPixelsY:(int)addPixelsY;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position image:(UIImage *)image; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position image:(UIImage *)image;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title image:(UIImage *)image; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title image:(UIImage *)image;
- (void)hideToast;
// displays toast with an activity spinner // displays toast with an activity spinner
- (void)makeToastActivity; - (void)makeToastActivity;
- (void)makeToastActivity:(id)position; - (void)makeToastActivity:(id)position;
...@@ -16,6 +19,7 @@ ...@@ -16,6 +19,7 @@
// the showToast methods display any view as toast // the showToast methods display any view as toast
- (void)showToast:(UIView *)toast; - (void)showToast:(UIView *)toast;
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point; - (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point ;
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point addedPixelsY:(int)addPixelsY;
@end @end
...@@ -12,7 +12,7 @@ static const CGFloat CSToastMaxWidth = 0.8; // 80% of parent vie ...@@ -12,7 +12,7 @@ static const CGFloat CSToastMaxWidth = 0.8; // 80% of parent vie
static const CGFloat CSToastMaxHeight = 0.8; // 80% of parent view height static const CGFloat CSToastMaxHeight = 0.8; // 80% of parent view height
static const CGFloat CSToastHorizontalPadding = 16.0; static const CGFloat CSToastHorizontalPadding = 16.0;
static const CGFloat CSToastVerticalPadding = 12.0; static const CGFloat CSToastVerticalPadding = 12.0;
static const CGFloat CSToastTopBottomOffset = 10.0; static const CGFloat CSToastTopBottomOffset = 20.0;
static const CGFloat CSToastCornerRadius = 20.0; static const CGFloat CSToastCornerRadius = 20.0;
static const CGFloat CSToastOpacity = 0.8; static const CGFloat CSToastOpacity = 0.8;
static const CGFloat CSToastFontSize = 13.0; static const CGFloat CSToastFontSize = 13.0;
...@@ -53,7 +53,7 @@ static UIView *prevToast = NULL; ...@@ -53,7 +53,7 @@ static UIView *prevToast = NULL;
- (void)hideToast:(UIView *)toast; - (void)hideToast:(UIView *)toast;
- (void)toastTimerDidFinish:(NSTimer *)timer; - (void)toastTimerDidFinish:(NSTimer *)timer;
- (void)handleToastTapped:(UITapGestureRecognizer *)recognizer; - (void)handleToastTapped:(UITapGestureRecognizer *)recognizer;
- (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast; - (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast withAddedPixelsY:(int) addPixelsY;
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image; - (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
- (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode; - (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode;
...@@ -70,22 +70,27 @@ static UIView *prevToast = NULL; ...@@ -70,22 +70,27 @@ static UIView *prevToast = NULL;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position {
UIView *toast = [self viewForMessage:message title:nil image:nil]; UIView *toast = [self viewForMessage:message title:nil image:nil];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
}
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position addPixelsY:(int)addPixelsY {
UIView *toast = [self viewForMessage:message title:nil image:nil];
[self showToast:toast duration:duration position:position addedPixelsY:addPixelsY];
} }
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title {
UIView *toast = [self viewForMessage:message title:title image:nil]; UIView *toast = [self viewForMessage:message title:title image:nil];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
} }
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position image:(UIImage *)image { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position image:(UIImage *)image {
UIView *toast = [self viewForMessage:message title:nil image:image]; UIView *toast = [self viewForMessage:message title:nil image:image];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
} }
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image {
UIView *toast = [self viewForMessage:message title:title image:image]; UIView *toast = [self viewForMessage:message title:title image:image];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
} }
- (void)showToast:(UIView *)toast { - (void)showToast:(UIView *)toast {
...@@ -93,22 +98,27 @@ static UIView *prevToast = NULL; ...@@ -93,22 +98,27 @@ static UIView *prevToast = NULL;
} }
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point { - (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point {
if(prevToast){ [self showToast:toast duration:CSToastDefaultDuration position:CSToastDefaultPosition addedPixelsY:0];
[self hideToast:prevToast]; }
}
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point addedPixelsY:(int) addPixelsY {
[self hideToast];
prevToast = toast; prevToast = toast;
toast.center = [self centerPointForPosition:point withToast:toast]; toast.center = [self centerPointForPosition:point withToast:toast withAddedPixelsY:addPixelsY];
toast.alpha = 0.0; toast.alpha = 0.0;
if (CSToastHidesOnTap) { if (CSToastHidesOnTap) {
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:toast action:@selector(handleToastTapped:)]; UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:toast action:@selector(handleToastTapped:)];
[toast addGestureRecognizer:recognizer]; [toast addGestureRecognizer:recognizer];
toast.userInteractionEnabled = YES; toast.userInteractionEnabled = YES;
toast.exclusiveTouch = YES; toast.exclusiveTouch = YES;
} }
[self addSubview:toast]; // make sure that if InAppBrowser is active, we're still showing Toasts on top of it
UIViewController *vc = [self getTopMostViewController];
UIView *v = [vc view];
[v addSubview:toast];
[UIView animateWithDuration:CSToastFadeDuration [UIView animateWithDuration:CSToastFadeDuration
delay:0.0 delay:0.0
options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction) options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction)
...@@ -119,7 +129,21 @@ static UIView *prevToast = NULL; ...@@ -119,7 +129,21 @@ static UIView *prevToast = NULL;
// associate the timer with the toast view // associate the timer with the toast view
objc_setAssociatedObject (toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject (toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}]; }];
}
- (UIViewController*) getTopMostViewController {
UIViewController *presentingViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (presentingViewController.presentedViewController != nil) {
presentingViewController = presentingViewController.presentedViewController;
}
return presentingViewController;
}
- (void)hideToast {
if (prevToast){
[self hideToast:prevToast];
}
} }
- (void)hideToast:(UIView *)toast { - (void)hideToast:(UIView *)toast {
...@@ -142,7 +166,7 @@ static UIView *prevToast = NULL; ...@@ -142,7 +166,7 @@ static UIView *prevToast = NULL;
- (void)handleToastTapped:(UITapGestureRecognizer *)recognizer { - (void)handleToastTapped:(UITapGestureRecognizer *)recognizer {
NSTimer *timer = (NSTimer *)objc_getAssociatedObject(self, &CSToastTimerKey); NSTimer *timer = (NSTimer *)objc_getAssociatedObject(self, &CSToastTimerKey);
[timer invalidate]; [timer invalidate];
[self hideToast:recognizer.view]; [self hideToast:recognizer.view];
} }
...@@ -156,31 +180,31 @@ static UIView *prevToast = NULL; ...@@ -156,31 +180,31 @@ static UIView *prevToast = NULL;
// sanity // sanity
UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
if (existingActivityView != nil) return; if (existingActivityView != nil) return;
UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CSToastActivityWidth, CSToastActivityHeight)]; UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CSToastActivityWidth, CSToastActivityHeight)];
activityView.center = [self centerPointForPosition:position withToast:activityView]; activityView.center = [self centerPointForPosition:position withToast:activityView withAddedPixelsY:0];
activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity]; activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity];
activityView.alpha = 0.0; activityView.alpha = 0.0;
activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
activityView.layer.cornerRadius = CSToastCornerRadius; activityView.layer.cornerRadius = CSToastCornerRadius;
if (CSToastDisplayShadow) { if (CSToastDisplayShadow) {
activityView.layer.shadowColor = [UIColor blackColor].CGColor; activityView.layer.shadowColor = [UIColor blackColor].CGColor;
activityView.layer.shadowOpacity = CSToastShadowOpacity; activityView.layer.shadowOpacity = CSToastShadowOpacity;
activityView.layer.shadowRadius = CSToastShadowRadius; activityView.layer.shadowRadius = CSToastShadowRadius;
activityView.layer.shadowOffset = CSToastShadowOffset; activityView.layer.shadowOffset = CSToastShadowOffset;
} }
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2); activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2);
[activityView addSubview:activityIndicatorView]; [activityView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating]; [activityIndicatorView startAnimating];
// associate the activity view with self // associate the activity view with self
objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addSubview:activityView]; [self addSubview:activityView];
[UIView animateWithDuration:CSToastFadeDuration [UIView animateWithDuration:CSToastFadeDuration
delay:0.0 delay:0.0
options:UIViewAnimationOptionCurveEaseOut options:UIViewAnimationOptionCurveEaseOut
...@@ -206,22 +230,22 @@ static UIView *prevToast = NULL; ...@@ -206,22 +230,22 @@ static UIView *prevToast = NULL;
#pragma mark - Helpers #pragma mark - Helpers
- (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast { - (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast withAddedPixelsY:(int) addPixelsY {
if([point isKindOfClass:[NSString class]]) { if([point isKindOfClass:[NSString class]]) {
// convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint // convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint
if([point caseInsensitiveCompare:@"top"] == NSOrderedSame) { if([point caseInsensitiveCompare:@"top"] == NSOrderedSame) {
return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + CSToastVerticalPadding + CSToastTopBottomOffset); return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + addPixelsY + CSToastVerticalPadding + CSToastTopBottomOffset);
} else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) { } else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) {
return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding - CSToastTopBottomOffset); return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding - CSToastTopBottomOffset + addPixelsY);
} else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) { } else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) {
return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); return CGPointMake(self.bounds.size.width / 2, (self.bounds.size.height / 2) + addPixelsY);
} }
} else if ([point isKindOfClass:[NSValue class]]) { } else if ([point isKindOfClass:[NSValue class]]) {
return [point CGPointValue]; return [point CGPointValue];
} }
NSLog(@"Warning: Invalid position for toast."); NSLog(@"Warning: Invalid position for toast.");
return [self centerPointForPosition:CSToastDefaultPosition withToast:toast]; return [self centerPointForPosition:CSToastDefaultPosition withToast:toast withAddedPixelsY:addPixelsY];
} }
- (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode { - (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode {
...@@ -233,7 +257,10 @@ static UIView *prevToast = NULL; ...@@ -233,7 +257,10 @@ static UIView *prevToast = NULL;
return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height)); return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height));
} }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [string sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:lineBreakMode]; return [string sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:lineBreakMode];
#pragma clang diagnostic pop
} }
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image { - (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
......
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
@interface Toast : CDVPlugin @interface Toast : CDVPlugin
- (void)show:(CDVInvokedUrlCommand*)command; - (void)show:(CDVInvokedUrlCommand*)command;
- (void)hide:(CDVInvokedUrlCommand*)command;
@end @end
\ No newline at end of file
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
- (void)show:(CDVInvokedUrlCommand*)command { - (void)show:(CDVInvokedUrlCommand*)command {
NSString *message = [command.arguments objectAtIndex:0]; NSDictionary* options = [command.arguments objectAtIndex:0];
NSString *duration = [command.arguments objectAtIndex:1];
NSString *position = [command.arguments objectAtIndex:2]; NSString *message = [options objectForKey:@"message"];
NSString *duration = [options objectForKey:@"duration"];
NSString *position = [options objectForKey:@"position"];
NSNumber *addPixelsY = [options objectForKey:@"addPixelsY"];
if (![position isEqual: @"top"] && ![position isEqual: @"center"] && ![position isEqual: @"bottom"]) { if (![position isEqual: @"top"] && ![position isEqual: @"center"] && ![position isEqual: @"bottom"]) {
CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"invalid position. valid options are 'top', 'center' and 'bottom'"]; CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"invalid position. valid options are 'top', 'center' and 'bottom'"];
...@@ -27,7 +30,14 @@ ...@@ -27,7 +30,14 @@
return; return;
} }
[self.webView makeToast:message duration:durationInt position:position]; [self.webView makeToast:message duration:durationInt position:position addPixelsY:addPixelsY == nil ? 0 : [addPixelsY intValue]];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
- (void)hide:(CDVInvokedUrlCommand*)command {
[self.webView hideToast];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
......
...@@ -14,6 +14,16 @@ ...@@ -14,6 +14,16 @@
<feature name="LocalStorage"> <feature name="LocalStorage">
<param name="ios-package" value="CDVLocalStorage" /> <param name="ios-package" value="CDVLocalStorage" />
</feature> </feature>
<feature name="Device">
<param name="ios-package" value="CDVDevice" />
</feature>
<feature name="Toast">
<param name="ios-package" value="Toast" />
</feature>
<feature name="LocalNotification">
<param name="ios-package" onload="true" value="APPLocalNotification" />
<param name="onload" value="true" />
</feature>
<name>NotificationExample</name> <name>NotificationExample</name>
<description> <description>
A sample Apache Cordova application that responds to the deviceready event. A sample Apache Cordova application that responds to the deviceready event.
...@@ -23,14 +33,4 @@ ...@@ -23,14 +33,4 @@
</author> </author>
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<feature name="Toast">
<param name="ios-package" value="Toast" />
</feature>
<feature name="Device">
<param name="ios-package" value="CDVDevice" />
</feature>
<feature name="LocalNotification">
<param name="ios-package" onload="true" value="APPLocalNotification" />
<param name="onload" value="true" />
</feature>
</widget> </widget>
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
//
//
// Auto-generated config file to override configuration files (build-release/build-debug).
//
...@@ -28,5 +28,5 @@ ...@@ -28,5 +28,5 @@
CODE_SIGN_IDENTITY = iPhone Developer CODE_SIGN_IDENTITY = iPhone Developer
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
// (CB-7872) Solution for XCode 6.1 signing errors related to resource envelope format deprecation // (CB-9721) Set ENABLE_BITCODE to NO in build.xcconfig
CODE_SIGN_RESOURCE_RULES_PATH = $(SDKROOT)/ResourceRules.plist ENABLE_BITCODE = NO
\ No newline at end of file
...@@ -50,7 +50,7 @@ module.exports.run = function (argv) { ...@@ -50,7 +50,7 @@ module.exports.run = function (argv) {
// Valid values for "--target" (case sensitive): // Valid values for "--target" (case sensitive):
var validTargets = ['iPhone-4s', 'iPhone-5', 'iPhone-5s', 'iPhone-6-Plus', 'iPhone-6', var validTargets = ['iPhone-4s', 'iPhone-5', 'iPhone-5s', 'iPhone-6-Plus', 'iPhone-6',
'iPad-2', 'iPad-Retina', 'iPad-Air', 'Resizable-iPhone', 'Resizable-iPad']; 'iPad-2', 'iPad-Retina', 'iPad-Air', 'Resizable-iPhone', 'Resizable-iPad'];
if (args.target && validTargets.indexOf(args.target) < 0 ) { if (!(args.device) && args.target && validTargets.indexOf(args.target.split(',')[0]) < 0 ) {
return Q.reject(args.target + ' is not a valid target for emulator'); return Q.reject(args.target + ' is not a valid target for emulator');
} }
...@@ -174,4 +174,4 @@ module.exports.help = function () { ...@@ -174,4 +174,4 @@ module.exports.help = function () {
console.log(' run --emulator --debug'); console.log(' run --emulator --debug');
console.log(''); console.log('');
process.exit(0); process.exit(0);
}; };
\ No newline at end of file
...@@ -25,6 +25,6 @@ ...@@ -25,6 +25,6 @@
Note: it does not work if the --shared option was used to create the project. Note: it does not work if the --shared option was used to create the project.
*/ */
var VERSION="3.9.1" var VERSION="3.9.2"
console.log(VERSION); console.log(VERSION);
{
"QuartzCore.framework": 1
}
\ No newline at end of file
{
"prepare_queue": {
"installed": [],
"uninstalled": []
},
"config_munge": {
"files": {
"config.xml": {
"parents": {
"/*": [
{
"xml": "<feature name=\"Device\"><param name=\"ios-package\" value=\"CDVDevice\" /></feature>",
"count": 1
},
{
"xml": "<feature name=\"Toast\"><param name=\"ios-package\" value=\"Toast\" /></feature>",
"count": 1
},
{
"xml": "<feature name=\"LocalNotification\"><param name=\"ios-package\" onload=\"true\" value=\"APPLocalNotification\" /><param name=\"onload\" value=\"true\" /></feature>",
"count": 1
}
]
}
}
}
},
"installed_plugins": {
"cordova-android-support-v4": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"cordova-plugin-device": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"cordova-plugin-x-toast": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"de.appplant.cordova.common.registerusernotificationsettings": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"de.appplant.cordova.plugin.local-notification": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
}
},
"dependent_plugins": {},
"modules": [
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local",
"plugin.notification.local"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
}
]
}
\ No newline at end of file
// Platform: ios // Platform: ios
// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c // 49a8db57fa070d20ea7b304a53ffec3d7250c5af
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
under the License. under the License.
*/ */
;(function() { ;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '3.9.1'; var PLATFORM_VERSION_BUILD_LABEL = '3.9.2';
// file: src/scripts/require.js // file: src/scripts/require.js
/*jshint -W079 */ /*jshint -W079 */
...@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { ...@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") {
// file: src/cordova.js // file: src/cordova.js
define("cordova", function(require, exports, module) { define("cordova", function(require, exports, module) {
if(window.cordova){ // Workaround for Windows 10 in hosted environment case
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
throw new Error("cordova already defined"); throw new Error("cordova already defined");
} }
...@@ -815,7 +817,7 @@ module.exports = channel; ...@@ -815,7 +817,7 @@ module.exports = channel;
}); });
// file: /Users/steveng/repo/cordova/cordova-ios/cordova-js-src/exec.js // file: e:/cordova/cordova-ios/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) { define("cordova/exec", function(require, exports, module) {
/** /**
...@@ -1286,10 +1288,12 @@ define("cordova/init_b", function(require, exports, module) { ...@@ -1286,10 +1288,12 @@ define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var cordova = require('cordova'); var cordova = require('cordova');
var modulemapper = require('cordova/modulemapper');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
var pluginloader = require('cordova/pluginloader');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
// setting exec // setting exec
cordova.exec = require('cordova/exec'); cordova.exec = require('cordova/exec');
...@@ -1374,10 +1378,19 @@ if (window._nativeReady) { ...@@ -1374,10 +1378,19 @@ if (window._nativeReady) {
// Call the platform-specific initialization. // Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap(); platform.bootstrap && platform.bootstrap();
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
// The delay allows the attached modules to be defined before the plugin loader looks for them.
setTimeout(function() {
pluginloader.load(function() {
channel.onPluginsReady.fire();
});
}, 0);
/** /**
* Create all cordova objects once native side is ready. * Create all cordova objects once native side is ready.
*/ */
channel.join(function() { channel.join(function() {
modulemapper.mapModules(window);
platform.initialize && platform.initialize(); platform.initialize && platform.initialize();
...@@ -1496,7 +1509,104 @@ exports.reset(); ...@@ -1496,7 +1509,104 @@ exports.reset();
}); });
// file: /Users/steveng/repo/cordova/cordova-ios/cordova-js-src/platform.js // file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder'),
symbolList = [],
deprecationMap;
exports.reset = function() {
symbolList = [];
deprecationMap = {};
};
function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
symbolList.push(strategy, moduleName, symbolPath);
if (opt_deprecationMessage) {
deprecationMap[symbolPath] = opt_deprecationMessage;
}
}
// Note: Android 2.3 does have Function.bind().
exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
};
exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
};
exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
};
exports.runs = function(moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace(symbolPath, context) {
if (!symbolPath) {
return context;
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
cur = cur[part] = cur[part] || {};
}
return cur;
}
exports.mapModules = function(context) {
var origSymbols = {};
context.CDV_origSymbols = origSymbols;
for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i];
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
}
}
};
exports.getOriginalSymbol = function(context, symbolPath) {
var origSymbols = context.CDV_origSymbols;
if (origSymbols && (symbolPath in origSymbols)) {
return origSymbols[symbolPath];
}
var parts = symbolPath.split('.');
var obj = context;
for (var i = 0; i < parts.length; ++i) {
obj = obj && obj[parts[i]];
}
return obj;
};
exports.reset();
});
// file: e:/cordova/cordova-ios/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) { define("cordova/platform", function(require, exports, module) {
module.exports = { module.exports = {
...@@ -1512,10 +1622,6 @@ module.exports = { ...@@ -1512,10 +1622,6 @@ module.exports = {
// file: src/common/pluginloader.js // file: src/common/pluginloader.js
define("cordova/pluginloader", function(require, exports, module) { define("cordova/pluginloader", function(require, exports, module) {
/*
NOTE: this file is NOT used when we use the browserify workflow
*/
var modulemapper = require('cordova/modulemapper'); var modulemapper = require('cordova/modulemapper');
var urlutil = require('cordova/urlutil'); var urlutil = require('cordova/urlutil');
...@@ -1625,6 +1731,54 @@ exports.load = function(callback) { ...@@ -1625,6 +1731,54 @@ exports.load = function(callback) {
}); });
// file: src/common/pluginloader_b.js
define("cordova/pluginloader_b", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
// Handler for the cordova_plugins.js content.
// See plugman's plugin_loader.js for the details of this object.
function handlePluginsObject(moduleList) {
// if moduleList is not defined or empty, we've nothing to do
if (!moduleList || !moduleList.length) {
return;
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
if (module.clobbers && module.clobbers.length) {
for (var j = 0; j < module.clobbers.length; j++) {
modulemapper.clobbers(module.id, module.clobbers[j]);
}
}
if (module.merges && module.merges.length) {
for (var k = 0; k < module.merges.length; k++) {
modulemapper.merges(module.id, module.merges[k]);
}
}
// Finally, if runs is truthy we want to simply require() the module.
if (module.runs) {
modulemapper.runs(module.id);
}
}
}
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
// but the method accepts callback to be compatible with non-browserify flow.
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
// no plugins to load, or they are all done.
exports.load = function(callback) {
var moduleList = require("cordova/plugin_list");
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js // file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) { define("cordova/urlutil", function(require, exports, module) {
......
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local",
"plugin.notification.local"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
}
];
module.exports.metadata =
// TOP OF METADATA
{}
// BOTTOM OF METADATA
});
\ No newline at end of file
cordova.define("cordova-plugin-device.device", function(require, exports, module) { /*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 argscheck = require('cordova/argscheck'),
channel = require('cordova/channel'),
utils = require('cordova/utils'),
exec = require('cordova/exec'),
cordova = require('cordova');
channel.createSticky('onCordovaInfoReady');
// Tell cordova channel to wait on the CordovaInfoReady event
channel.waitForInitialization('onCordovaInfoReady');
/**
* This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
* phone, etc.
* @constructor
*/
function Device() {
this.available = false;
this.platform = null;
this.version = null;
this.uuid = null;
this.cordova = null;
this.model = null;
this.manufacturer = null;
var me = this;
channel.onCordovaReady.subscribe(function() {
me.getInfo(function(info) {
//ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js
//TODO: CB-5105 native implementations should not return info.cordova
var buildLabel = cordova.version;
me.available = true;
me.platform = info.platform;
me.version = info.version;
me.uuid = info.uuid;
me.cordova = buildLabel;
me.model = info.model;
me.manufacturer = info.manufacturer || 'unknown';
channel.onCordovaInfoReady.fire();
},function(e) {
me.available = false;
utils.alert("[ERROR] Error initializing Cordova: " + e);
});
});
}
/**
* Get device info
*
* @param {Function} successCallback The function to call when the heading data is available
* @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
*/
Device.prototype.getInfo = function(successCallback, errorCallback) {
argscheck.checkArgs('fF', 'Device.getInfo', arguments);
exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
};
module.exports = new Device();
});
cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, module) { exports.defineAutoTests = function() { cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) { var fail = function (done) {
expect(true).toBe(false); expect(true).toBe(false);
done(); done();
...@@ -20,6 +20,14 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m ...@@ -20,6 +20,14 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m
expect(window.plugins.toast.show).toBeDefined(); expect(window.plugins.toast.show).toBeDefined();
}); });
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() { it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined(); expect(window.plugins.toast.showShortTop).toBeDefined();
}); });
...@@ -47,11 +55,7 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m ...@@ -47,11 +55,7 @@ cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, m
describe('Invalid usage', function () { describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) { it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done)); window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
it("should fail due to an invalid duration", function(done) {
window.plugins.toast.show('hi', 'medium', 'top', fail.bind(null, done), succeed.bind(null, done));
}); });
}); });
}; };
......
cordova.define("nl.x-services.plugins.toast.Toast", function(require, exports, module) { function Toast() { cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) { function Toast() {
} }
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) { Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [message, duration, position]); this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
}; };
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) { Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba ...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba
this.show(message, "long", "bottom", successCallback, errorCallback); this.show(message, "long", "bottom", successCallback, errorCallback);
}; };
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () { Toast.install = function () {
if (!window.plugins) { if (!window.plugins) {
window.plugins = {}; window.plugins = {};
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
var exec = require('cordova/exec');
/********
* CORE *
********/
/**
* Returns the default settings.
*
* @return {Object}
*/
exports.getDefaults = function () {
return this._defaults;
};
/**
* Overwrite default settings.
*
* @param {Object} defaults
*/
exports.setDefaults = function (newDefaults) {
var defaults = this.getDefaults();
for (var key in defaults) {
if (newDefaults.hasOwnProperty(key)) {
defaults[key] = newDefaults[key];
}
}
};
/**
* Schedule a new local notification.
*
* @param {Object} opts
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.schedule = function (opts, callback, scope) {
this.registerPermission(function(granted) {
if (!granted)
return;
var notifications = Array.isArray(opts) ? opts : [opts];
for (var i = 0; i < notifications.length; i++) {
var properties = notifications[i];
this.mergeWithDefaults(properties);
this.convertProperties(properties);
}
this.exec('schedule', notifications, callback, scope);
}, this);
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Object} options
* The notification properties to update
* @param {Function} callback
* A function to be called after the notification has been updated
* @param {Object?} scope
* The scope for the callback function
*/
exports.update = function (opts, callback, scope) {
var notifications = Array.isArray(opts) ? opts : [opts];
for (var i = 0; i < notifications.length; i++) {
var properties = notifications[i];
this.convertProperties(properties);
}
this.exec('update', notifications, callback, scope);
};
/**
* Clear the specified notification.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clear = function (ids, callback, scope) {
ids = Array.isArray(ids) ? ids : [ids];
ids = this.convertIds(ids);
this.exec('clear', ids, callback, scope);
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clearAll = function (callback, scope) {
this.exec('clearAll', null, callback, scope);
};
/**
* Cancel the specified notifications.
*
* @param {String[]} ids
* The IDs of the notifications
* @param {Function} callback
* A function to be called after the notifications has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancel = function (ids, callback, scope) {
ids = Array.isArray(ids) ? ids : [ids];
ids = this.convertIds(ids);
this.exec('cancel', ids, callback, scope);
};
/**
* Remove all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancelAll = function (callback, scope) {
this.exec('cancelAll', null, callback, scope);
};
/**
* Check if a notification with an ID is present.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isPresent = function (id, callback, scope) {
this.exec('isPresent', id || 0, callback, scope);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isScheduled = function (id, callback, scope) {
this.exec('isScheduled', id || 0, callback, scope);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isTriggered = function (id, callback, scope) {
this.exec('isTriggered', id || 0, callback, scope);
};
/**
* List all local notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllIds = function (callback, scope) {
this.exec('getAllIds', null, callback, scope);
};
/**
* Alias for `getAllIds`.
*/
exports.getIds = function () {
this.getAllIds.apply(this, arguments);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduledIds = function (callback, scope) {
this.exec('getScheduledIds', null, callback, scope);
};
/**
* List all triggered notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggeredIds = function (callback, scope) {
this.exec('getTriggeredIds', null, callback, scope);
};
/**
* Property list for given local notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.get = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
this.exec('getSingle', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getAll', ids, callback, scope);
};
/**
* Property list for all local notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAll = function (callback, scope) {
this.exec('getAll', null, callback, scope);
};
/**
* Property list for given scheduled notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduled = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
ids = [ids];
}
if (!Array.isArray(ids)) {
this.exec('getSingleScheduled', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getScheduled', ids, callback, scope);
};
/**
* Property list for all scheduled notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllScheduled = function (callback, scope) {
this.exec('getScheduled', null, callback, scope);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggered = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
ids = [ids];
}
if (!Array.isArray(ids)) {
this.exec('getSingleTriggered', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getTriggered', ids, callback, scope);
};
/**
* Property list for all triggered notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllTriggered = function (callback, scope) {
this.exec('getTriggered', null, callback, scope);
};
/**
* Informs if the app has the permission to show notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.hasPermission = function (callback, scope) {
var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'hasPermission', []);
};
/**
* Register permission to show notifications if not already granted.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.registerPermission = function (callback, scope) {
var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'registerPermission', []);
};
/**********
* EVENTS *
**********/
/**
* Register callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
* @param {Object?} scope
* The callback function's scope
*/
exports.on = function (event, callback, scope) {
if (!this._listener[event]) {
this._listener[event] = [];
}
var item = [callback, scope || window];
this._listener[event].push(item);
};
/**
* Unregister callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
*/
exports.un = function (event, callback) {
var listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0];
if (fn == callback) {
listener.splice(i, 1);
break;
}
}
};
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
var exec = require('cordova/exec'),
channel = require('cordova/channel');
/***********
* MEMBERS *
***********/
// Default values
exports._defaults = {
text: '',
title: '',
sound: 'res://platform_default',
badge: 0,
id: 0,
data: undefined,
every: undefined,
at: undefined
};
// listener
exports._listener = {};
/********
* UTIL *
********/
/**
* Merge platform specific properties into the default ones.
*
* @return {Object}
* The default properties for the platform
*/
exports.applyPlatformSpecificOptions = function () {
var defaults = this._defaults;
switch (device.platform) {
case 'Android':
defaults.icon = 'res://icon';
defaults.smallIcon = 'res://ic_popup_reminder';
defaults.ongoing = false;
defaults.autoClear = true;
defaults.led = 'FFFFFF';
break;
}
return defaults;
};
/**
* Merge custom properties with the default values.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The merged property list
*/
exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults();
options.at = this.getValueFor(options, 'at', 'firstAt', 'date');
options.text = this.getValueFor(options, 'text', 'message');
options.data = this.getValueFor(options, 'data', 'json');
if (defaults.hasOwnProperty('autoClear')) {
options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel');
}
if (options.autoClear !== true && options.ongoing) {
options.autoClear = false;
}
if (options.at === undefined || options.at === null) {
options.at = new Date();
}
for (var key in defaults) {
if (options[key] === null || options[key] === undefined) {
if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
options[key] = undefined;
} else {
options[key] = defaults[key];
}
}
}
for (key in options) {
if (!defaults.hasOwnProperty(key)) {
delete options[key];
console.warn('Unknown property: ' + key);
}
}
return options;
};
/**
* Convert the passed values to their required type.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The converted property list
*/
exports.convertProperties = function (options) {
if (options.id) {
if (isNaN(options.id)) {
options.id = this.getDefaults().id;
console.warn('Id is not a number: ' + options.id);
} else {
options.id = Number(options.id);
}
}
if (options.title) {
options.title = options.title.toString();
}
if (options.text) {
options.text = options.text.toString();
}
if (options.badge) {
if (isNaN(options.badge)) {
options.badge = this.getDefaults().badge;
console.warn('Badge number is not a number: ' + options.id);
} else {
options.badge = Number(options.badge);
}
}
if (options.at) {
if (typeof options.at == 'object') {
options.at = options.at.getTime();
}
options.at = Math.round(options.at/1000);
}
if (typeof options.data == 'object') {
options.data = JSON.stringify(options.data);
}
return options;
};
/**
* Create callback, which will be executed within a specific scope.
*
* @param {Function} callbackFn
* The callback function
* @param {Object} scope
* The scope for the function
*
* @return {Function}
* The new callback function
*/
exports.createCallbackFn = function (callbackFn, scope) {
if (typeof callbackFn != 'function')
return;
return function () {
callbackFn.apply(scope || this, arguments);
};
};
/**
* Convert the IDs to numbers.
*
* @param {String/Number[]} ids
*
* @return Array of Numbers
*/
exports.convertIds = function (ids) {
var convertedIds = [];
for (var i = 0; i < ids.length; i++) {
convertedIds.push(Number(ids[i]));
}
return convertedIds;
};
/**
* First found value for the given keys.
*
* @param {Object} options
* Object with key-value properties
* @param {String[]} keys*
* Key list
*/
exports.getValueFor = function (options) {
var keys = Array.apply(null, arguments).slice(1);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (options.hasOwnProperty(key)) {
return options[key];
}
}
};
/**
* Fire event with given arguments.
*
* @param {String} event
* The event's name
* @param {args*}
* The callback's arguments
*/
exports.fireEvent = function (event) {
var args = Array.apply(null, arguments).slice(1),
listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0],
scope = listener[i][1];
fn.apply(scope, args);
}
};
/**
* Execute the native counterpart.
*
* @param {String} action
* The name of the action
* @param args[]
* Array of arguments
* @param {Function} callback
* The callback function
* @param {Object} scope
* The scope for the function
*/
exports.exec = function (action, args, callback, scope) {
var fn = this.createCallbackFn(callback, scope),
params = [];
if (Array.isArray(args)) {
params = args;
} else if (args) {
params.push(args);
}
exec(fn, null, 'LocalNotification', action, params);
};
/*********
* HOOKS *
*********/
// Called after 'deviceready' event
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// and all queued events can be executed.
exec(null, null, 'LocalNotification', 'deviceready', []);
});
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Device plugin is ready now
channel.onCordovaInfoReady.subscribe(function () {
// Merge platform specifics into defaults
exports.applyPlatformSpecificOptions();
});
});
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
/*************
* INTERFACE *
*************/
/**
* Returns the default settings.
*
* @return {Object}
*/
exports.getDefaults = function () {
return this.core.getDefaults();
};
/**
* Overwrite default settings.
*
* @param {Object} defaults
*/
exports.setDefaults = function (defaults) {
this.core.setDefaults(defaults);
};
/**
* Schedule a new local notification.
*
* @param {Object} opts
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.schedule = function (opts, callback, scope) {
this.core.schedule(opts, callback, scope);
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Object} options
* The notification properties to update
* @param {Function} callback
* A function to be called after the notification has been updated
* @param {Object?} scope
* The scope for the callback function
*/
exports.update = function (opts, callback, scope) {
this.core.update(opts, callback, scope);
};
/**
* Clear the specified notification.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clear = function (ids, callback, scope) {
this.core.clear(ids, callback, scope);
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clearAll = function (callback, scope) {
this.core.clearAll(callback, scope);
};
/**
* Cancel the specified notifications.
*
* @param {String[]} ids
* The IDs of the notifications
* @param {Function} callback
* A function to be called after the notifications has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancel = function (ids, callback, scope) {
this.core.cancel(ids, callback, scope);
};
/**
* Remove all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancelAll = function (callback, scope) {
this.core.cancelAll(callback, scope);
};
/**
* Check if a notification with an ID is present.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isPresent = function (id, callback, scope) {
this.core.isPresent(id, callback, scope);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isScheduled = function (id, callback, scope) {
this.core.isScheduled(id, callback, scope);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isTriggered = function (id, callback, scope) {
this.core.isTriggered(id, callback, scope);
};
/**
* List all local notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllIds = function (callback, scope) {
this.core.getAllIds(callback, scope);
};
/**
* Alias for `getAllIds`.
*/
exports.getIds = function () {
this.getAllIds.apply(this, arguments);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduledIds = function (callback, scope) {
this.core.getScheduledIds(callback, scope);
};
/**
* List all triggered notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggeredIds = function (callback, scope) {
this.core.getTriggeredIds(callback, scope);
};
/**
* Property list for given local notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.get = function () {
this.core.get.apply(this.core, arguments);
};
/**
* Property list for all local notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAll = function (callback, scope) {
this.core.getAll(callback, scope);
};
/**
* Property list for given scheduled notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduled = function () {
this.core.getScheduled.apply(this.core, arguments);
};
/**
* Property list for all scheduled notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllScheduled = function (callback, scope) {
this.core.getAllScheduled(callback, scope);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggered = function () {
this.core.getTriggered.apply(this.core, arguments);
};
/**
* Property list for all triggered notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllTriggered = function (callback, scope) {
this.core.getAllTriggered(callback, scope);
};
/**
* Informs if the app has the permission to show notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.hasPermission = function (callback, scope) {
this.core.hasPermission(callback, scope);
};
/**
* Register permission to show notifications if not already granted.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.registerPermission = function (callback, scope) {
this.core.registerPermission(callback, scope);
};
/****************
* DEPRECATIONS *
****************/
/**
* Schedule a new local notification.
*/
exports.add = function () {
console.warn('Depreated: Please use `notification.local.schedule` instead.');
this.schedule.apply(this, arguments);
};
/**
* Register permission to show notifications
* if not already granted.
*/
exports.promptForPermission = function () {
console.warn('Depreated: Please use `notification.local.registerPermission` instead.');
this.registerPermission.apply(this, arguments);
};
/**********
* EVENTS *
**********/
/**
* Register callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
* @param {Object?} scope
* The callback function's scope
*/
exports.on = function (event, callback, scope) {
this.core.on(event, callback, scope);
};
/**
* Unregister callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
*/
exports.un = function (event, callback) {
this.core.un(event, callback, scope);
};
});
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*
*/
/**
* Creates a gap bridge iframe used to notify the native code about queued
* commands.
*/
var cordova = require('cordova'),
channel = require('cordova/channel'),
utils = require('cordova/utils'),
base64 = require('cordova/base64'),
// XHR mode does not work on iOS 4.2.
// XHR mode's main advantage is working around a bug in -webkit-scroll, which
// doesn't exist only on iOS 5.x devices.
// IFRAME_NAV is the fastest.
// IFRAME_HASH could be made to enable synchronous bridge calls if we wanted this feature.
jsToNativeModes = {
IFRAME_NAV: 0, // Default. Uses a new iframe for each poke.
// XHR bridge appears to be flaky sometimes: CB-3900, CB-3359, CB-5457, CB-4970, CB-4998, CB-5134
XHR_NO_PAYLOAD: 1, // About the same speed as IFRAME_NAV. Performance not about the same as IFRAME_NAV, but more variable.
XHR_WITH_PAYLOAD: 2, // Flakey, and not as performant
XHR_OPTIONAL_PAYLOAD: 3, // Flakey, and not as performant
IFRAME_HASH_NO_PAYLOAD: 4, // Not fully baked. A bit faster than IFRAME_NAV, but risks jank since poke happens synchronously.
IFRAME_HASH_WITH_PAYLOAD: 5, // Slower than no payload. Maybe since it has to be URI encoded / decoded.
WK_WEBVIEW_BINDING: 6 // Only way that works for WKWebView :)
},
bridgeMode,
execIframe,
execHashIframe,
hashToggle = 1,
execXhr,
requestCount = 0,
vcHeaderValue = null,
commandQueue = [], // Contains pending JS->Native messages.
isInContextOfEvalJs = 0,
failSafeTimerId = 0;
function shouldBundleCommandJson() {
if (bridgeMode === jsToNativeModes.XHR_WITH_PAYLOAD) {
return true;
}
if (bridgeMode === jsToNativeModes.XHR_OPTIONAL_PAYLOAD) {
var payloadLength = 0;
for (var i = 0; i < commandQueue.length; ++i) {
payloadLength += commandQueue[i].length;
}
// The value here was determined using the benchmark within CordovaLibApp on an iPad 3.
return payloadLength < 4500;
}
return false;
}
function massageArgsJsToNative(args) {
if (!args || utils.typeName(args) != 'Array') {
return args;
}
var ret = [];
args.forEach(function(arg, i) {
if (utils.typeName(arg) == 'ArrayBuffer') {
ret.push({
'CDVType': 'ArrayBuffer',
'data': base64.fromArrayBuffer(arg)
});
} else {
ret.push(arg);
}
});
return ret;
}
function massageMessageNativeToJs(message) {
if (message.CDVType == 'ArrayBuffer') {
var stringToArrayBuffer = function(str) {
var ret = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
ret[i] = str.charCodeAt(i);
}
return ret.buffer;
};
var base64ToArrayBuffer = function(b64) {
return stringToArrayBuffer(atob(b64));
};
message = base64ToArrayBuffer(message.data);
}
return message;
}
function convertMessageToArgsNativeToJs(message) {
var args = [];
if (!message || !message.hasOwnProperty('CDVType')) {
args.push(message);
} else if (message.CDVType == 'MultiPart') {
message.messages.forEach(function(e) {
args.push(massageMessageNativeToJs(e));
});
} else {
args.push(massageMessageNativeToJs(message));
}
return args;
}
function iOSExec() {
if (bridgeMode === undefined) {
bridgeMode = jsToNativeModes.IFRAME_NAV;
}
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.cordova && window.webkit.messageHandlers.cordova.postMessage) {
bridgeMode = jsToNativeModes.WK_WEBVIEW_BINDING;
}
var successCallback, failCallback, service, action, actionArgs, splitCommand;
var callbackId = null;
if (typeof arguments[0] !== "string") {
// FORMAT ONE
successCallback = arguments[0];
failCallback = arguments[1];
service = arguments[2];
action = arguments[3];
actionArgs = arguments[4];
// Since we need to maintain backwards compatibility, we have to pass
// an invalid callbackId even if no callback was provided since plugins
// will be expecting it. The Cordova.exec() implementation allocates
// an invalid callbackId and passes it even if no callbacks were given.
callbackId = 'INVALID';
} else {
// FORMAT TWO, REMOVED
try {
splitCommand = arguments[0].split(".");
action = splitCommand.pop();
service = splitCommand.join(".");
actionArgs = Array.prototype.splice.call(arguments, 1);
console.log('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' +
"cordova.exec(null, null, \"" + service + "\", \"" + action + "\"," + JSON.stringify(actionArgs) + ");"
);
return;
} catch (e) {}
}
// If actionArgs is not provided, default to an empty array
actionArgs = actionArgs || [];
// Register the callbacks and add the callbackId to the positional
// arguments if given.
if (successCallback || failCallback) {
callbackId = service + cordova.callbackId++;
cordova.callbacks[callbackId] =
{success:successCallback, fail:failCallback};
}
actionArgs = massageArgsJsToNative(actionArgs);
var command = [callbackId, service, action, actionArgs];
// Stringify and queue the command. We stringify to command now to
// effectively clone the command arguments in case they are mutated before
// the command is executed.
commandQueue.push(JSON.stringify(command));
if (bridgeMode === jsToNativeModes.WK_WEBVIEW_BINDING) {
window.webkit.messageHandlers.cordova.postMessage(command);
} else {
// If we're in the context of a stringByEvaluatingJavaScriptFromString call,
// then the queue will be flushed when it returns; no need for a poke.
// Also, if there is already a command in the queue, then we've already
// poked the native side, so there is no reason to do so again.
if (!isInContextOfEvalJs && commandQueue.length == 1) {
pokeNative();
}
}
}
function pokeNative() {
switch (bridgeMode) {
case jsToNativeModes.XHR_NO_PAYLOAD:
case jsToNativeModes.XHR_WITH_PAYLOAD:
case jsToNativeModes.XHR_OPTIONAL_PAYLOAD:
pokeNativeViaXhr();
break;
default: // iframe-based.
pokeNativeViaIframe();
}
}
function pokeNativeViaXhr() {
// This prevents sending an XHR when there is already one being sent.
// This should happen only in rare circumstances (refer to unit tests).
if (execXhr && execXhr.readyState != 4) {
execXhr = null;
}
// Re-using the XHR improves exec() performance by about 10%.
execXhr = execXhr || new XMLHttpRequest();
// Changing this to a GET will make the XHR reach the URIProtocol on 4.2.
// For some reason it still doesn't work though...
// Add a timestamp to the query param to prevent caching.
execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);
if (!vcHeaderValue) {
vcHeaderValue = /.*\((.*)\)$/.exec(navigator.userAgent)[1];
}
execXhr.setRequestHeader('vc', vcHeaderValue);
execXhr.setRequestHeader('rc', ++requestCount);
if (shouldBundleCommandJson()) {
execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());
}
execXhr.send(null);
}
function pokeNativeViaIframe() {
// CB-5488 - Don't attempt to create iframe before document.body is available.
if (!document.body) {
setTimeout(pokeNativeViaIframe);
return;
}
if (bridgeMode === jsToNativeModes.IFRAME_HASH_NO_PAYLOAD || bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
// TODO: This bridge mode doesn't properly support being removed from the DOM (CB-7735)
if (!execHashIframe) {
execHashIframe = document.createElement('iframe');
execHashIframe.style.display = 'none';
document.body.appendChild(execHashIframe);
// Hash changes don't work on about:blank, so switch it to file:///.
execHashIframe.contentWindow.history.replaceState(null, null, 'file:///#');
}
// The delegate method is called only when the hash changes, so toggle it back and forth.
hashToggle = hashToggle ^ 3;
var hashValue = '%0' + hashToggle;
if (bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
hashValue += iOSExec.nativeFetchMessages();
}
execHashIframe.contentWindow.location.hash = hashValue;
} else {
// Check if they've removed it from the DOM, and put it back if so.
if (execIframe && execIframe.contentWindow) {
execIframe.contentWindow.location = 'gap://ready';
} else {
execIframe = document.createElement('iframe');
execIframe.style.display = 'none';
execIframe.src = 'gap://ready';
document.body.appendChild(execIframe);
}
// Use a timer to protect against iframe being unloaded during the poke (CB-7735).
// This makes the bridge ~ 7% slower, but works around the poke getting lost
// when the iframe is removed from the DOM.
// An onunload listener could be used in the case where the iframe has just been
// created, but since unload events fire only once, it doesn't work in the normal
// case of iframe reuse (where unload will have already fired due to the attempted
// navigation of the page).
failSafeTimerId = setTimeout(function() {
if (commandQueue.length) {
pokeNative();
}
}, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
}
}
iOSExec.jsToNativeModes = jsToNativeModes;
iOSExec.setJsToNativeBridgeMode = function(mode) {
// Remove the iFrame since it may be no longer required, and its existence
// can trigger browser bugs.
// https://issues.apache.org/jira/browse/CB-593
if (execIframe) {
if (execIframe.parentNode) {
execIframe.parentNode.removeChild(execIframe);
}
execIframe = null;
}
bridgeMode = mode;
};
iOSExec.nativeFetchMessages = function() {
// Stop listing for window detatch once native side confirms poke.
if (failSafeTimerId) {
clearTimeout(failSafeTimerId);
failSafeTimerId = 0;
}
// Each entry in commandQueue is a JSON string already.
if (!commandQueue.length) {
return '';
}
var json = '[' + commandQueue.join(',') + ']';
commandQueue.length = 0;
return json;
};
iOSExec.nativeCallback = function(callbackId, status, message, keepCallback) {
return iOSExec.nativeEvalAndFetch(function() {
var success = status === 0 || status === 1;
var args = convertMessageToArgsNativeToJs(message);
cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
});
};
iOSExec.nativeEvalAndFetch = function(func) {
// This shouldn't be nested, but better to be safe.
isInContextOfEvalJs++;
try {
func();
return iOSExec.nativeFetchMessages();
} finally {
isInContextOfEvalJs--;
}
};
module.exports = iOSExec;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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: 'ios',
bootstrap: function() {
require('cordova/channel').onNativeReady.fire();
}
};
// Platform: ios // Platform: ios
// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c // 49a8db57fa070d20ea7b304a53ffec3d7250c5af
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
under the License. under the License.
*/ */
;(function() { ;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '3.9.1'; var PLATFORM_VERSION_BUILD_LABEL = '3.9.2';
// file: src/scripts/require.js // file: src/scripts/require.js
/*jshint -W079 */ /*jshint -W079 */
...@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { ...@@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") {
// file: src/cordova.js // file: src/cordova.js
define("cordova", function(require, exports, module) { define("cordova", function(require, exports, module) {
if(window.cordova){ // Workaround for Windows 10 in hosted environment case
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
throw new Error("cordova already defined"); throw new Error("cordova already defined");
} }
...@@ -815,7 +817,7 @@ module.exports = channel; ...@@ -815,7 +817,7 @@ module.exports = channel;
}); });
// file: /Users/steveng/repo/cordova/cordova-ios/cordova-js-src/exec.js // file: e:/cordova/cordova-ios/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) { define("cordova/exec", function(require, exports, module) {
/** /**
...@@ -1286,10 +1288,12 @@ define("cordova/init_b", function(require, exports, module) { ...@@ -1286,10 +1288,12 @@ define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var cordova = require('cordova'); var cordova = require('cordova');
var modulemapper = require('cordova/modulemapper');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
var pluginloader = require('cordova/pluginloader');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
// setting exec // setting exec
cordova.exec = require('cordova/exec'); cordova.exec = require('cordova/exec');
...@@ -1374,10 +1378,19 @@ if (window._nativeReady) { ...@@ -1374,10 +1378,19 @@ if (window._nativeReady) {
// Call the platform-specific initialization. // Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap(); platform.bootstrap && platform.bootstrap();
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
// The delay allows the attached modules to be defined before the plugin loader looks for them.
setTimeout(function() {
pluginloader.load(function() {
channel.onPluginsReady.fire();
});
}, 0);
/** /**
* Create all cordova objects once native side is ready. * Create all cordova objects once native side is ready.
*/ */
channel.join(function() { channel.join(function() {
modulemapper.mapModules(window);
platform.initialize && platform.initialize(); platform.initialize && platform.initialize();
...@@ -1496,7 +1509,104 @@ exports.reset(); ...@@ -1496,7 +1509,104 @@ exports.reset();
}); });
// file: /Users/steveng/repo/cordova/cordova-ios/cordova-js-src/platform.js // file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder'),
symbolList = [],
deprecationMap;
exports.reset = function() {
symbolList = [];
deprecationMap = {};
};
function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
symbolList.push(strategy, moduleName, symbolPath);
if (opt_deprecationMessage) {
deprecationMap[symbolPath] = opt_deprecationMessage;
}
}
// Note: Android 2.3 does have Function.bind().
exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
};
exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
};
exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
};
exports.runs = function(moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace(symbolPath, context) {
if (!symbolPath) {
return context;
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
cur = cur[part] = cur[part] || {};
}
return cur;
}
exports.mapModules = function(context) {
var origSymbols = {};
context.CDV_origSymbols = origSymbols;
for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i];
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
}
}
};
exports.getOriginalSymbol = function(context, symbolPath) {
var origSymbols = context.CDV_origSymbols;
if (origSymbols && (symbolPath in origSymbols)) {
return origSymbols[symbolPath];
}
var parts = symbolPath.split('.');
var obj = context;
for (var i = 0; i < parts.length; ++i) {
obj = obj && obj[parts[i]];
}
return obj;
};
exports.reset();
});
// file: e:/cordova/cordova-ios/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) { define("cordova/platform", function(require, exports, module) {
module.exports = { module.exports = {
...@@ -1512,10 +1622,6 @@ module.exports = { ...@@ -1512,10 +1622,6 @@ module.exports = {
// file: src/common/pluginloader.js // file: src/common/pluginloader.js
define("cordova/pluginloader", function(require, exports, module) { define("cordova/pluginloader", function(require, exports, module) {
/*
NOTE: this file is NOT used when we use the browserify workflow
*/
var modulemapper = require('cordova/modulemapper'); var modulemapper = require('cordova/modulemapper');
var urlutil = require('cordova/urlutil'); var urlutil = require('cordova/urlutil');
...@@ -1625,6 +1731,54 @@ exports.load = function(callback) { ...@@ -1625,6 +1731,54 @@ exports.load = function(callback) {
}); });
// file: src/common/pluginloader_b.js
define("cordova/pluginloader_b", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
// Handler for the cordova_plugins.js content.
// See plugman's plugin_loader.js for the details of this object.
function handlePluginsObject(moduleList) {
// if moduleList is not defined or empty, we've nothing to do
if (!moduleList || !moduleList.length) {
return;
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
if (module.clobbers && module.clobbers.length) {
for (var j = 0; j < module.clobbers.length; j++) {
modulemapper.clobbers(module.id, module.clobbers[j]);
}
}
if (module.merges && module.merges.length) {
for (var k = 0; k < module.merges.length; k++) {
modulemapper.merges(module.id, module.merges[k]);
}
}
// Finally, if runs is truthy we want to simply require() the module.
if (module.runs) {
modulemapper.runs(module.id);
}
}
}
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
// but the method accepts callback to be compatible with non-browserify flow.
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
// no plugins to load, or they are all done.
exports.load = function(callback) {
var moduleList = require("cordova/plugin_list");
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js // file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) { define("cordova/urlutil", function(require, exports, module) {
......
cordova.define('cordova/plugin_list', function(require, exports, module) { cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [ module.exports = [
{ {
"file": "plugins/nl.x-services.plugins.toast/www/Toast.js", "file": "plugins/cordova-plugin-device/www/device.js",
"id": "nl.x-services.plugins.toast.Toast", "id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [ "clobbers": [
"window.plugins.toast" "window.plugins.toast"
] ]
}, },
{ {
"file": "plugins/nl.x-services.plugins.toast/test/tests.js", "file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "nl.x-services.plugins.toast.tests" "id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
}, },
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [ "clobbers": [
"cordova.plugins.notification.local", "cordova.plugins.notification.local",
"plugin.notification.local" "plugin.notification.local"
...@@ -22,6 +33,7 @@ module.exports = [ ...@@ -22,6 +33,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [ "clobbers": [
"cordova.plugins.notification.local.core", "cordova.plugins.notification.local.core",
"plugin.notification.local.core" "plugin.notification.local.core"
...@@ -30,27 +42,15 @@ module.exports = [ ...@@ -30,27 +42,15 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [ "merges": [
"cordova.plugins.notification.local.core", "cordova.plugins.notification.local.core",
"plugin.notification.local.core" "plugin.notification.local.core"
] ]
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"clobbers": [
"device"
]
} }
]; ];
module.exports.metadata = module.exports.metadata =
// TOP OF METADATA // TOP OF METADATA
{ {}
"android.support.v4": "21.0.1",
"de.appplant.cordova.common.registerusernotificationsettings": "1.0.1",
"nl.x-services.plugins.toast": "2.0.4",
"de.appplant.cordova.plugin.local-notification": "0.8.2-dev",
"cordova-plugin-device": "1.0.1"
}
// BOTTOM OF METADATA // BOTTOM OF METADATA
}); });
\ No newline at end of file
cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) {
expect(true).toBe(false);
done();
},
succeed = function (done) {
expect(true).toBe(true);
done();
};
describe('Plugin availability', function () {
it("window.plugins.toast should exist", function() {
expect(window.plugins.toast).toBeDefined();
});
});
describe('API functions', function () {
it("should define show", function() {
expect(window.plugins.toast.show).toBeDefined();
});
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined();
});
it("should define showShortCenter", function() {
expect(window.plugins.toast.showShortCenter).toBeDefined();
});
it("should define showShortBottom", function() {
expect(window.plugins.toast.showShortBottom).toBeDefined();
});
it("should define showLongTop", function() {
expect(window.plugins.toast.showLongTop).toBeDefined();
});
it("should define showLongCenter", function() {
expect(window.plugins.toast.showLongCenter).toBeDefined();
});
it("should define showLongBottom", function() {
expect(window.plugins.toast.showLongBottom).toBeDefined();
});
});
describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
});
};
});
cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) { function Toast() {
}
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
};
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
this.show(message, "short", "top", successCallback, errorCallback);
};
Toast.prototype.showShortCenter = function (message, successCallback, errorCallback) {
this.show(message, "short", "center", successCallback, errorCallback);
};
Toast.prototype.showShortBottom = function (message, successCallback, errorCallback) {
this.show(message, "short", "bottom", successCallback, errorCallback);
};
Toast.prototype.showLongTop = function (message, successCallback, errorCallback) {
this.show(message, "long", "top", successCallback, errorCallback);
};
Toast.prototype.showLongCenter = function (message, successCallback, errorCallback) {
this.show(message, "long", "center", successCallback, errorCallback);
};
Toast.prototype.showLongBottom = function (message, successCallback, errorCallback) {
this.show(message, "long", "bottom", successCallback, errorCallback);
};
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () {
if (!window.plugins) {
window.plugins = {};
}
window.plugins.toast = new Toast();
return window.plugins.toast;
};
cordova.addConstructor(Toast.install);
});
{ {
"ios": "3.9.1" "ios": "3.9.2"
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version='1.0' encoding='utf-8'?>
<!-- <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<OutputPath>build\phone\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>build\phone\$(Configuration)\$(Platform)\</OutputPath>
<IntermediateOutputPath>build\phone\bld\</IntermediateOutputPath> <IntermediateOutputPath>build\phone\bld\</IntermediateOutputPath>
...@@ -59,7 +41,7 @@ ...@@ -59,7 +41,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>31b67a35-9503-4213-857e-f44eb42ae549</ProjectGuid> <ProjectGuid>31b67a35-9503-4213-857e-f44eb42ae549</ProjectGuid>
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'"> <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'">
<VisualStudioVersion>12.0</VisualStudioVersion> <VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
...@@ -78,22 +60,11 @@ ...@@ -78,22 +60,11 @@
<AppxManifest Include="package.phone.appxmanifest"> <AppxManifest Include="package.phone.appxmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AppxManifest> </AppxManifest>
<Content Include="images\*.png" Exclude="images\*.scale-180.*" /> <Content Exclude="images\*.scale-180.*" Include="images\*.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.Phone.WinJS.2.1, Version=1.0" /> <SDKReference Include="Microsoft.Phone.WinJS.2.1, Version=1.0" />
</ItemGroup> </ItemGroup>
<Import Project="CordovaApp.projitems" Label="Shared" /> <Import Label="Shared" Project="CordovaApp.projitems" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment </Project>
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version='1.0' encoding='utf-8'?>
<!-- <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<OutputPath>build\windows\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>build\windows\$(Configuration)\$(Platform)\</OutputPath>
<IntermediateOutputPath>build\windows\bld\</IntermediateOutputPath> <IntermediateOutputPath>build\windows\bld\</IntermediateOutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU"> <ProjectConfiguration Include="Debug|AnyCPU">
...@@ -59,7 +41,7 @@ ...@@ -59,7 +41,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>58950fb6-2f93-4963-b9cd-637f83f3efbf</ProjectGuid> <ProjectGuid>58950fb6-2f93-4963-b9cd-637f83f3efbf</ProjectGuid>
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'"> <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'">
<VisualStudioVersion>12.0</VisualStudioVersion> <VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
...@@ -77,23 +59,12 @@ ...@@ -77,23 +59,12 @@
<AppxManifest Include="package.windows.appxmanifest"> <AppxManifest Include="package.windows.appxmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AppxManifest> </AppxManifest>
<Content Include="images\*.png" Exclude="images\*.scale-240.*" /> <Content Exclude="images\*.scale-240.*" Include="images\*.png" />
<None Include="CordovaApp_TemporaryKey.pfx" /> <None Include="CordovaApp_TemporaryKey.pfx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.WinJS.2.0, Version=1.0" /> <SDKReference Include="Microsoft.WinJS.2.0, Version=1.0" />
</ItemGroup> </ItemGroup>
<Import Project="CordovaApp.projitems" Label="Shared" /> <Import Label="Shared" Project="CordovaApp.projitems" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment </Project>
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version='1.0' encoding='utf-8'?>
<!-- <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<OutputPath>build\windows80\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>build\windows80\$(Configuration)\$(Platform)\</OutputPath>
<IntermediateOutputPath>build\windows80\bld\</IntermediateOutputPath> <IntermediateOutputPath>build\windows80\bld\</IntermediateOutputPath>
...@@ -62,7 +44,7 @@ ...@@ -62,7 +44,7 @@
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0'"> <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0'">
<VisualStudioVersion>11.0</VisualStudioVersion> <VisualStudioVersion>11.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup> <PropertyGroup>
...@@ -75,13 +57,13 @@ ...@@ -75,13 +57,13 @@
<AppxManifest Include="package.windows80.appxmanifest"> <AppxManifest Include="package.windows80.appxmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AppxManifest> </AppxManifest>
<Content Include="images\*.png" Exclude="images\*.scale-240.*" /> <Content Exclude="images\*.scale-240.*" Include="images\*.png" />
<None Include="CordovaApp_TemporaryKey.pfx" /> <None Include="CordovaApp_TemporaryKey.pfx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.WinJS.1.0, Version=1.0" /> <SDKReference Include="Microsoft.WinJS.1.0, Version=1.0" />
</ItemGroup> </ItemGroup>
<Import Project="CordovaApp.projitems" Label="Shared" /> <Import Label="Shared" Project="CordovaApp.projitems" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<PropertyGroup> <PropertyGroup>
<BuildFromCordovaTooling>false</BuildFromCordovaTooling> <BuildFromCordovaTooling>false</BuildFromCordovaTooling>
...@@ -90,4 +72,4 @@ ...@@ -90,4 +72,4 @@
node -e "require('./cordova/lib/prepare.js').applyPlatformConfig()" node -e "require('./cordova/lib/prepare.js').applyPlatformConfig()"
</PreBuildEvent> </PreBuildEvent>
</PropertyGroup> </PropertyGroup>
</Project> </Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"> <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
<Identity Name="1482d0c0-f943-11e4-ad39-81ab0f14e62c" Version="1.0.0.0" Publisher="CN=$username$" /> <Identity Name="de.appplant.localnotification.example" Publisher="CN=$username$" Version="0.0.1.0" />
<mp:PhoneIdentity PhoneProductId="1482d0c0-f943-11e4-ad39-81ab0f14e62c" PhonePublisherId="db093ed5-53b1-45f7-af72-751e8f36ab80" /> <mp:PhoneIdentity PhoneProductId="1482d0c0-f943-11e4-ad39-81ab0f14e62c" PhonePublisherId="db093ed5-53b1-45f7-af72-751e8f36ab80" />
<Properties> <Properties>
<DisplayName>NotificationExample</DisplayName> <DisplayName>NotificationExample</DisplayName>
<PublisherDisplayName>$username$</PublisherDisplayName> <PublisherDisplayName>Apache Cordova Team</PublisherDisplayName>
<Logo>images\StoreLogo.png</Logo> <Logo>images\StoreLogo.png</Logo>
</Properties> </Properties>
<Prerequisites> <Prerequisites>
<OSMinVersion>6.3.1</OSMinVersion> <OSMinVersion>6.3.1</OSMinVersion>
<OSMaxVersionTested>6.3.1</OSMaxVersionTested> <OSMaxVersionTested>6.3.1</OSMaxVersionTested>
</Prerequisites> </Prerequisites>
<Resources> <Resources>
<Resource Language="x-generate" /> <Resource Language="x-generate" />
</Resources> </Resources>
<Applications> <Applications>
<Application Id="de.appplant.localnotification.example" StartPage="www/index.html"> <Application Id="de.appplant.localnotification.example" StartPage="www/index.html">
<m3:VisualElements ToastCapable="true" DisplayName="NotificationExample" <m3:VisualElements BackgroundColor="transparent" Description="CordovaApp" DisplayName="NotificationExample" ForegroundText="light" Square150x150Logo="images\Square150x150Logo.png" Square44x44Logo="images\Square44x44Logo.png" ToastCapable="true">
Square150x150Logo="images\Square150x150Logo.png" <m3:DefaultTile Square71x71Logo="images\Square71x71Logo.png" Wide310x150Logo="images\Wide310x150Logo.png">
Square44x44Logo="images\Square44x44Logo.png" <m3:ShowNameOnTiles>
Description="CordovaApp" <m3:ShowOn Tile="square150x150Logo" />
ForegroundText="light" <m3:ShowOn Tile="wide310x150Logo" />
BackgroundColor="transparent"> </m3:ShowNameOnTiles>
<m3:DefaultTile Wide310x150Logo="images\Wide310x150Logo.png" </m3:DefaultTile>
Square71x71Logo="images\Square71x71Logo.png"> <m3:SplashScreen Image="images\SplashScreenPhone.png" />
<m3:ShowNameOnTiles> </m3:VisualElements>
<m3:ShowOn Tile="square150x150Logo" /> </Application>
<m3:ShowOn Tile="wide310x150Logo" /> </Applications>
</m3:ShowNameOnTiles> <Capabilities>
</m3:DefaultTile> <Capability Name="internetClientServer" />
<m3:SplashScreen Image="images\SplashScreenPhone.png" /> </Capabilities>
</m3:VisualElements> </Package>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClientServer" />
</Capabilities>
</Package>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest"> <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
<Identity Name="1482d0c0-f943-11e4-ad39-81ab0f14e62c" Version="1.0.0.0" Publisher="CN=$username$" /> <Identity Name="de.appplant.localnotification.example" Publisher="CN=$username$" Version="0.0.1.0" />
<Properties> <Properties>
<DisplayName>NotificationExample</DisplayName> <DisplayName>NotificationExample</DisplayName>
<PublisherDisplayName>$username$</PublisherDisplayName> <PublisherDisplayName>Apache Cordova Team</PublisherDisplayName>
<Logo>images\StoreLogo.png</Logo> <Logo>images\StoreLogo.png</Logo>
</Properties> </Properties>
<Prerequisites> <Prerequisites>
<OSMinVersion>6.3.0</OSMinVersion> <OSMinVersion>6.3.0</OSMinVersion>
<OSMaxVersionTested>6.3.0</OSMaxVersionTested> <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
</Prerequisites> </Prerequisites>
<Resources> <Resources>
<Resource Language="x-generate" /> <Resource Language="x-generate" />
</Resources> </Resources>
<Applications> <Applications>
<Application Id="de.appplant.localnotification.example" StartPage="www/index.html"> <Application Id="de.appplant.localnotification.example" StartPage="www/index.html">
<m2:VisualElements ToastCapable="true" DisplayName="NotificationExample" <m2:VisualElements BackgroundColor="#464646" Description="CordovaApp" DisplayName="NotificationExample" ForegroundText="light" Square150x150Logo="images\Square150x150Logo.png" Square30x30Logo="images\Square30x30Logo.png" ToastCapable="true">
Description="CordovaApp" <m2:DefaultTile Square310x310Logo="images\Square310x310Logo.png" Square70x70Logo="images\Square70x70Logo.png" Wide310x150Logo="images\Wide310x150Logo.png">
ForegroundText="light" <m2:ShowNameOnTiles>
BackgroundColor="#464646" <m2:ShowOn Tile="square150x150Logo" />
Square150x150Logo="images\Square150x150Logo.png" <m2:ShowOn Tile="wide310x150Logo" />
Square30x30Logo="images\Square30x30Logo.png"> <m2:ShowOn Tile="square310x310Logo" />
<m2:DefaultTile Square70x70Logo="images\Square70x70Logo.png" </m2:ShowNameOnTiles>
Square310x310Logo="images\Square310x310Logo.png" </m2:DefaultTile>
Wide310x150Logo="images\Wide310x150Logo.png"> <m2:SplashScreen Image="images\SplashScreen.png" />
<m2:ShowNameOnTiles> </m2:VisualElements>
<m2:ShowOn Tile="square150x150Logo" /> </Application>
<m2:ShowOn Tile="wide310x150Logo" /> </Applications>
<m2:ShowOn Tile="square310x310Logo" /> <Capabilities>
</m2:ShowNameOnTiles> <Capability Name="internetClient" />
</m2:DefaultTile> </Capabilities>
<m2:SplashScreen Image="images\SplashScreen.png" /> </Package>
</m2:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest"> <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Identity Name="1482d0c0-f943-11e4-ad39-81ab0f14e62c" Version="1.0.0.0" Publisher="CN=$username$" /> <Identity Name="de.appplant.localnotification.example" Publisher="CN=$username$" Version="0.0.1.0" />
<Properties> <Properties>
<DisplayName>NotificationExample</DisplayName> <DisplayName>NotificationExample</DisplayName>
<PublisherDisplayName>$username$</PublisherDisplayName> <PublisherDisplayName>Apache Cordova Team</PublisherDisplayName>
<Logo>images\storelogo.png</Logo> <Logo>images\storelogo.png</Logo>
</Properties> </Properties>
<Prerequisites> <Prerequisites>
<OSMinVersion>6.2.1</OSMinVersion> <OSMinVersion>6.2.1</OSMinVersion>
<OSMaxVersionTested>6.2.1</OSMaxVersionTested> <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
</Prerequisites> </Prerequisites>
<Resources> <Resources>
<Resource Language="x-generate" /> <Resource Language="x-generate" />
</Resources> </Resources>
<Applications> <Applications>
<Application Id="de.appplant.localnotification.example" StartPage="www/index.html"> <Application Id="de.appplant.localnotification.example" StartPage="www/index.html">
<VisualElements ToastCapable="true" DisplayName="NotificationExample" <VisualElements BackgroundColor="#464646" Description="CordovaApp" DisplayName="NotificationExample" ForegroundText="light" Logo="images\Square150x150Logo.png" SmallLogo="images\Square30x30Logo.png" ToastCapable="true">
Logo="images\Square150x150Logo.png" <DefaultTile ShowName="allLogos" WideLogo="images\Wide310x150Logo.png" />
SmallLogo="images\Square30x30Logo.png" <SplashScreen Image="images\splashscreen.png" />
Description="CordovaApp" </VisualElements>
ForegroundText="light" </Application>
BackgroundColor="#464646"> </Applications>
<DefaultTile ShowName="allLogos" WideLogo="images\Wide310x150Logo.png"/> <Capabilities>
<SplashScreen Image="images\splashscreen.png" /> <Capability Name="internetClient" />
</VisualElements> </Capabilities>
</Application> </Package>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
\ No newline at end of file
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-device/src/windows/DeviceProxy.js",
"id": "cordova-plugin-device.DeviceProxy",
"pluginId": "cordova-plugin-device",
"merges": [
""
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local",
"plugin.notification.local"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
""
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
""
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
""
]
}
];
module.exports.metadata =
// TOP OF METADATA
{}
// BOTTOM OF METADATA
});
\ No newline at end of file
cordova.define("cordova-plugin-device.DeviceProxy", function(require, exports, module) { /*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 ROOT_CONTAINER = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}";
var DEVICE_CLASS_KEY = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10";
var DEVICE_CLASS_KEY_NO_SEMICOLON = '{A45C254E-DF1C-4EFD-8020-67D146A850E0}10';
var ROOT_CONTAINER_QUERY = "System.Devices.ContainerId:=\"" + ROOT_CONTAINER + "\"";
var HAL_DEVICE_CLASS = "4d36e966-e325-11ce-bfc1-08002be10318";
var DEVICE_DRIVER_VERSION_KEY = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3";
var MANU_KEY = "System.Devices.Manufacturer";
module.exports = {
getDeviceInfo:function(win, fail, args) {
// deviceId aka uuid, stored in Windows.Storage.ApplicationData.current.localSettings.values.deviceId
var deviceId;
var manufacturer = "unknown";
// get deviceId, or create and store one
var localSettings = Windows.Storage.ApplicationData.current.localSettings;
if (localSettings.values.deviceId) {
deviceId = localSettings.values.deviceId;
}
else {
// App-specific hardware id could be used as uuid, but it changes if the hardware changes...
try {
var ASHWID = Windows.System.Profile.HardwareIdentification.getPackageSpecificToken(null).id;
deviceId = Windows.Storage.Streams.DataReader.fromBuffer(ASHWID).readGuid();
} catch (e) {
// Couldn't get the hardware UUID
deviceId = createUUID();
}
//...so cache it per-install
localSettings.values.deviceId = deviceId;
}
var userAgent = window.clientInformation.userAgent;
// this will report "windows" in windows8.1 and windows phone 8.1 apps
// and "windows8" in windows 8.0 apps similar to cordova.js
// See https://github.com/apache/cordova-js/blob/master/src/windows/platform.js#L25
var devicePlatform = userAgent.indexOf("MSAppHost/1.0") == -1 ? "windows" : "windows8";
var versionString = userAgent.match(/Windows (?:Phone |NT )?([0-9.]+)/)[1];
var Pnp = Windows.Devices.Enumeration.Pnp;
Pnp.PnpObject.findAllAsync(Pnp.PnpObjectType.deviceContainer,[MANU_KEY])
.then(function (infoList) {
var numDevices = infoList.length;
if (numDevices) {
for (var i = 0; i < numDevices; i++) {
var devContainer = infoList[i];
if (devContainer.id == ROOT_CONTAINER) {
manufacturer = devContainer.properties[MANU_KEY];
break;
}
}
}
})
.then(function () {
Pnp.PnpObject.findAllAsync(Pnp.PnpObjectType.device,
[DEVICE_DRIVER_VERSION_KEY, DEVICE_CLASS_KEY],
ROOT_CONTAINER_QUERY)
.then(function (rootDevices) {
for (var i = 0; i < rootDevices.length; i++) {
var rootDevice = rootDevices[i];
if (!rootDevice.properties) continue;
if (rootDevice.properties[DEVICE_CLASS_KEY_NO_SEMICOLON] == HAL_DEVICE_CLASS) {
versionString = rootDevice.properties[DEVICE_DRIVER_VERSION_KEY];
break;
}
}
setTimeout(function () {
win({ platform: devicePlatform,
version: versionString,
uuid: deviceId,
model: window.clientInformation.platform,
manufacturer:manufacturer});
}, 0);
});
});
}
}; // exports
require("cordova/exec/proxy").add("Device", module.exports);
});
cordova.define("cordova-plugin-device.device", function(require, exports, module) { /*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 argscheck = require('cordova/argscheck'),
channel = require('cordova/channel'),
utils = require('cordova/utils'),
exec = require('cordova/exec'),
cordova = require('cordova');
channel.createSticky('onCordovaInfoReady');
// Tell cordova channel to wait on the CordovaInfoReady event
channel.waitForInitialization('onCordovaInfoReady');
/**
* This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
* phone, etc.
* @constructor
*/
function Device() {
this.available = false;
this.platform = null;
this.version = null;
this.uuid = null;
this.cordova = null;
this.model = null;
this.manufacturer = null;
var me = this;
channel.onCordovaReady.subscribe(function() {
me.getInfo(function(info) {
//ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js
//TODO: CB-5105 native implementations should not return info.cordova
var buildLabel = cordova.version;
me.available = true;
me.platform = info.platform;
me.version = info.version;
me.uuid = info.uuid;
me.cordova = buildLabel;
me.model = info.model;
me.manufacturer = info.manufacturer || 'unknown';
channel.onCordovaInfoReady.fire();
},function(e) {
me.available = false;
utils.alert("[ERROR] Error initializing Cordova: " + e);
});
});
}
/**
* Get device info
*
* @param {Function} successCallback The function to call when the heading data is available
* @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
*/
Device.prototype.getInfo = function(successCallback, errorCallback) {
argscheck.checkArgs('fF', 'Device.getInfo', arguments);
exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
};
module.exports = new Device();
});
cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) {
expect(true).toBe(false);
done();
},
succeed = function (done) {
expect(true).toBe(true);
done();
};
describe('Plugin availability', function () {
it("window.plugins.toast should exist", function() {
expect(window.plugins.toast).toBeDefined();
});
});
describe('API functions', function () {
it("should define show", function() {
expect(window.plugins.toast.show).toBeDefined();
});
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined();
});
it("should define showShortCenter", function() {
expect(window.plugins.toast.showShortCenter).toBeDefined();
});
it("should define showShortBottom", function() {
expect(window.plugins.toast.showShortBottom).toBeDefined();
});
it("should define showLongTop", function() {
expect(window.plugins.toast.showLongTop).toBeDefined();
});
it("should define showLongCenter", function() {
expect(window.plugins.toast.showLongCenter).toBeDefined();
});
it("should define showLongBottom", function() {
expect(window.plugins.toast.showLongBottom).toBeDefined();
});
});
describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
});
};
});
cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) { function Toast() {
}
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
};
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
this.show(message, "short", "top", successCallback, errorCallback);
};
Toast.prototype.showShortCenter = function (message, successCallback, errorCallback) {
this.show(message, "short", "center", successCallback, errorCallback);
};
Toast.prototype.showShortBottom = function (message, successCallback, errorCallback) {
this.show(message, "short", "bottom", successCallback, errorCallback);
};
Toast.prototype.showLongTop = function (message, successCallback, errorCallback) {
this.show(message, "long", "top", successCallback, errorCallback);
};
Toast.prototype.showLongCenter = function (message, successCallback, errorCallback) {
this.show(message, "long", "center", successCallback, errorCallback);
};
Toast.prototype.showLongBottom = function (message, successCallback, errorCallback) {
this.show(message, "long", "bottom", successCallback, errorCallback);
};
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () {
if (!window.plugins) {
window.plugins = {};
}
window.plugins.toast = new Toast();
return window.plugins.toast;
};
cordova.addConstructor(Toast.install);
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core", function(require, exports, module) { /*
Copyright 2013-2015 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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 proxy = require('de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy');
var Notifications = Windows.UI.Notifications;
proxy.core = {
/**
* Executes all queued events.
*/
deviceready: function () {
var plugin = cordova.plugins.notification.local,
events = this.eventQueue;
this.isReady = true;
for (var i = 0; i < events.length; i++) {
plugin.fireEvent.apply(plugin, events[i]);
}
this.eventQueue = [];
},
/**
* Schedules new local notifications.
*
* @param {Object[]} notifications
* Array of local notifications
* @param {String} event
* 'schedule' or 'update'
*/
schedule: function (notifications) {
var triggerFn = function (notification) {
this.updateBadge(notification.badge);
this.fireEvent('trigger', notification);
};
for (var i = 0; i < notifications.length; i++) {
var options = notifications[i],
notification = this.build(options);
this.cancelLocalNotification(options.id);
this.scheduleLocalNotification(notification, options);
this.scheduleBackupNotification(notification, options);
this.fireEvent('schedule', options);
this.callOnTrigger(options, triggerFn);
}
},
/**
* Schedules a single local notification.
*
* @param {Windows.Data.Xml.Dom.XmlDocument} notification
* The local notification
* @param {Object} options
* Local notification properties
*/
scheduleLocalNotification: function (notification, options) {
var interval = this.getRepeatInterval(options.every),
triggerTime = new Date((options.at * 1000)),
now = new Date().getTime(),
toast;
if (triggerTime <= now) {
triggerTime = new Date(now + 10);
}
try {
if (interval !== 0 && interval < 360001 && interval > 59999) {
toast = new Notifications.ScheduledToastNotification(
notification, triggerTime, interval, 5);
} else {
toast = new Notifications.ScheduledToastNotification(
notification, triggerTime);
}
} catch (e) {
console.error(e);
return;
}
toast.id = options.id;
toast.tag = 'Toast' + toast.id;
Notifications.ToastNotificationManager
.createToastNotifier()
.addToSchedule(toast);
},
/**
* Schedules a backup local notification 10 years later.
*
* @param {Object} notification
* The local notification
*/
scheduleBackupNotification: function (notification, options) {
var properties = Object.create(options);
properties.id = options.id + '-2';
properties.at = options.at + 315360000; // 10 years later
this.scheduleLocalNotification(notification, properties);
},
/**
* Updates the badge number of the active tile.
*
* @param {Number} badge
* The badge number. Zero will clean the badge.
*/
updateBadge: function (badge) {
var notifications = Windows.UI.Notifications,
type = notifications.BadgeTemplateType.badgeNumber,
xml = notifications.BadgeUpdateManager.getTemplateContent(type),
attrs = xml.getElementsByTagName('badge'),
notification = new notifications.BadgeNotification(xml);
attrs[0].setAttribute('value', badge);
notifications.BadgeUpdateManager.createBadgeUpdaterForApplication()
.update(notification);
},
/**
* Updates existing notifications specified by IDs in options.
*
* @param {Object[]} notifications
* Array of local notifications
*/
update: function (notifications) {
for (var i = 0; i < notifications.length; i++) {
var updates = notifications[i],
options = getAll(updates.id || '0')[0];
this.updateLocalNotification(options, updates);
this.fireEvent('update', options);
}
},
/**
* Updates a single local notification.
*
* @param {Object} notification
* The local notification
* @param {Object} updates
* Updated properties
*/
updateLocalNotification: function (notification, updates) {
for (var key in updates) {
notification[key] = updates[key];
}
this.cancelLocalNotification(notification.id);
this.scheduleLocalNotification(notification);
},
/**
* Clears the specified notifications.
*
* @param {int[]} ids
* List of local notification IDs
*/
clear: function (ids) {
for (var i = 0; i < ids.length; i++) {
var id = ids[i],
notification = this.getAll([id])[0];
this.clearLocalNotification(id);
this.fireEvent('clear', notification);
}
},
/**
* Clears the local notification with the given ID.
*
* @param {String} id
* Local notification ID
*/
clearLocalNotification: function (id) {
var notification = this.getAll([id])[0];
try {
this.getToastHistory().remove('Toast' + id);
} catch (e) {/*Only Phones support the NotificationHistory*/ }
if (this.isRepeating(notification))
return;
if (this.isTriggered(id) && !this.isScheduled(id)) {
this.cancelLocalNotification(id);
}
},
/**
* Clears all notifications.
*/
clearAll: function () {
var ids = this.getTriggeredIds();
for (var i = 0; i < ids.length; i++) {
this.clearLocalNotification(ids[i]);
}
try {
this.getToastHistory().clear();
} catch (e) {/*Only Phones support the NotificationHistory*/ }
this.fireEvent('clearall');
},
/**
* Cancels all specified notifications.
*
* @param {int[]} ids
* List of local notification IDs
*/
cancel: function (ids) {
for (var i = 0; i < ids.length; i++) {
var id = ids[i],
notification = this.getAll([id])[0];
this.cancelLocalNotification(ids[i]);
this.fireEvent('cancel', notification);
}
},
/**
* Cancels the local notification with the given ID.
*
* @param {String} id
* Local notification ID
*/
cancelLocalNotification: function (id) {
var notifier = this.getToastNotifier(),
history = this.getToastHistory(),
toasts = this.getScheduledToasts();
try {
history.remove('Toast' + id);
} catch (e) {/*Only Phones support the NotificationHistory*/ }
for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i];
if (toast.id == id || toast.id == id + '-2') {
notifier.removeFromSchedule(toast);
}
}
},
/**
* Cancels all notifications.
*/
cancelAll: function () {
var ids = this.getAllIds();
for (var i = 0; i < ids.length; i++) {
this.cancelLocalNotification(ids[i]);
}
try {
this.getToastHistory().clear();
} catch (e) {/*Only Phones support the NotificationHistory*/ }
this.fireEvent('cancelall');
},
/**
* Checks if a notification with an ID is present.
*
* @param {int} id
* Local notification ID
*/
isPresent: function (id) {
return !!this.findToastById(id);
},
/**
* Checks if a notification with an ID was scheduled.
*
* @param {int} id
* Local notification ID
*/
isScheduled: function (id) {
var toast = this.findToastById(id);
return toast && this.isToastScheduled(toast);
},
/**
* Checks if a notification with an ID was triggered.
*
* @param {int} id
* Local notification ID
*/
isTriggered: function (id) {
var toast = this.findToastById(id);
return toast && this.isToastTriggered(toast);
},
/**
* Lists all local notification IDs.
*/
getAllIds: function () {
var toasts = this.getScheduledToasts(),
ids = [];
for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i];
ids.push(this.getToastId(toast));
}
return ids;
},
/**
* Lists all scheduled notification IDs.
*/
getScheduledIds: function () {
var toasts = this.getScheduledToasts(),
ids = [];
for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i];
if (!this.isToastScheduled(toast))
continue;
ids.push(this.getToastId(toast));
}
return ids;
},
/**
* Lists all scheduled notification IDs.
*/
getTriggeredIds: function () {
var toasts = this.getScheduledToasts(),
ids = [];
for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i];
if (!this.isToastTriggered(toast))
continue;
ids.push(this.getToastId(toast));
}
return ids;
},
/**
* Property list for given notifications.
* If called without IDs, all notification will be returned.
*
* @param {int[]} ids
* List of local notification IDs.
* @param {String?} type
* Local notification life cycle type
*/
getAll: function (ids, type) {
var toasts = this.getScheduledToasts(),
notifications = [];
if (!ids || ids.length === 0) {
ids = this.getAllIds();
}
for (var index = 0; index < ids.length; index++) {
var id = ids[index],
toast = this.findToastById(id);
if (!toast || type && this.getToastType(toast) != type)
continue;
var json = toast.content.lastChild.lastChild.innerText;
notifications.push(JSON.parse(json));
}
return notifications;
},
/**
* Property list for given notifications.
* If called without IDs, all notification will be returned.
*
* @param {int[]} ids
* List of local notification IDs
*/
getScheduled: function (ids) {
if (!ids || ids.length === 0) {
ids = this.getAllIds();
}
return this.getAll(ids, 'scheduled');
},
/**
* Property list for given notifications.
* If called without IDs, all notification will be returned.
*
* @param {int[]} ids
* List of local notification IDs
*/
getTriggered: function (ids) {
if (!ids || ids.length === 0) {
ids = this.getAllIds();
}
return this.getAll(ids, 'triggered');
},
};
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy", function(require, exports, module) { /*
Copyright 2013-2015 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
*/
/**
* Executes all queued events.
*/
exports.deviceready = function () {
exports.core.deviceready();
};
/**
* Schedule a new local notification.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {Object[]} notifications
* Array of local notifications
*/
exports.schedule = function (success, error, notifications) {
exports.core.schedule(notifications, 'schedule');
success();
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {Object[]} notifications
* Array of local notifications
*/
exports.update = function (success, error, notifications) {
exports.core.update(notifications);
success();
};
/**
* Clear the specified notification.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.clear = function (success, error, ids) {
exports.core.clear(ids, true);
success();
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
*/
exports.clearAll = function (success, error) {
exports.core.clearAll();
success();
};
/**
* Cancel the specified notifications.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.cancel = function (success, error, ids) {
exports.core.cancel(ids, true);
success();
};
/**
* Remove all previously registered notifications.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
*/
exports.cancelAll = function (success, error) {
exports.core.cancelAll();
success();
};
/**
* Check if a notification with an ID is present.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int} id
* Local notification ID
*/
exports.isPresent = function (success, error, args) {
var found = exports.core.isPresent(args[0]);
success(found);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int} id
* Local notification ID
*/
exports.isScheduled = function (success, error, args) {
var found = exports.core.isScheduled(args[0]);
success(found);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int} id
* Local notification ID
*/
exports.isTriggered = function (success, error, args) {
var found = exports.core.isTriggered(args[0]);
success(found);
};
/**
* List all local notification IDs.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
*/
exports.getAllIds = function (success, error) {
var ids = exports.core.getAllIds();
success(ids);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
*/
exports.getScheduledIds = function (success, error) {
var ids = exports.core.getScheduledIds();
success(ids);
};
/**
* List all triggered notification IDs.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
*/
exports.getTriggeredIds = function (success, error) {
var ids = exports.core.getTriggeredIds();
success(ids);
};
/**
* Propertys for given notification.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.getSingle = function (success, error, ids) {
var notification = exports.core.getAll(ids)[0];
success(notification);
};
/**
* Propertys for given scheduled notification.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.getSingleScheduled = function (success, error, ids) {
var notification = exports.core.getScheduled(ids)[0];
success(notification);
};
/**
* Propertys for given triggered notification.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.getSingleTriggered = function (success, error, ids) {
var notification = exports.core.getTriggered(ids)[0];
success(notification);
};
/**
* Property list for given notifications.
* If called without IDs, all notification will be returned.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.getAll = function (success, error, ids) {
var notifications = exports.core.getAll(ids);
success(notifications);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.getScheduled = function (success, error, ids) {
var notifications = exports.core.getScheduled(ids);
success(notifications);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Function} success
* Success callback
* @param {Function} error
* Error callback
* @param {int[]} ids
* List of local notification IDs
*/
exports.getTriggered = function (success, error, ids) {
var notifications = exports.core.getTriggered(ids);
success(notifications);
};
cordova.commandProxy.add('LocalNotification', exports);
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util", function(require, exports, module) { /*
Copyright 2013-2015 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
*/
exports = require('de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy').core;
var channel = require('cordova/channel');
/***********
* MEMBERS *
***********/
// True if App is running, false if suspended
exports.isInBackground = true;
// Indicates if the device is ready (to receive events)
exports.isReady = false;
// Queues all events before deviceready
exports.eventQueue = [];
/********
* UTIL *
********/
/**
* The repeating interval in milliseconds.
*
* @param {String} interval
* A number or a placeholder like `minute`.
*
* @return {Number}
* Interval in milliseconds
*/
exports.getRepeatInterval = function (every) {
if (!every)
return 0;
if (every == 'minute')
return 60000;
if (every == 'hour')
return 360000;
if (!NaN(every))
return parseInt(every) * 60000;
return 0;
};
/**
* If the notification is repeating.
*
* @param {Object} notification
* Local notification object
*
* @return Boolean
*/
exports.isRepeating = function (notification) {
return this.getRepeatInterval(notification.every) !== 0;
};
/**
* Parses sound file path.
*
* @param {String} path
* Relative path to sound resource
*
* @return {String} XML Tag for Sound-File
*/
exports.parseSound = function (path) {
if (!path.match(/^file/))
return '';
var uri = this.parseUri(path),
audio = "<audio src=" + uri + " loop='false'/>";
return audio;
};
/**
* Parses image file path.
*
* @param {String} path
* Relative path to image resource
*
* @return {String} XML-Tag for Image-File
*/
exports.parseImage = function (path) {
if (!path.match(/^file/))
return '';
var uri = this.parseUri(path),
image = "<image id='1' src=" + uri + " />";
return image;
};
/**
* Parses file path to URI.
*
* @param {String} path
* Relative path to a resource
*
* @return {String} URI to File
*/
exports.parseUri = function (path) {
var pkg = Windows.ApplicationModel.Package.current,
pkgId = pkg.id,
pkgName = pkgId.name;
var uri = "'ms-appx://" + pkgName + "/www" + path.slice(6, path.length) + "'";
return uri;
};
/**
* Builds the xml payload for a local notification based on its options.
*
* @param {Object} options
* Local notification properties
*
* @return Windows.Data.Xml.Dom.XmlDocument
*/
exports.build = function (options) {
var template = this.buildToastTemplate(options),
notification = new Windows.Data.Xml.Dom.XmlDocument();
try {
notification.loadXml(template);
} catch (e) {
console.error(
'LocalNotification#schedule',
'Error loading the xml, check for invalid characters.');
}
// Launch Attribute to enable onClick event
var launchAttr = notification.createAttribute('launch'),
toastNode = notification.selectSingleNode('/toast');
launchAttr.value = options.id.toString();
toastNode.attributes.setNamedItem(launchAttr);
return notification;
};
/**
* Builds the toast template with the right style depend on the options.
*
* @param {Object} options
* Local notification properties
*
* @return String
*/
exports.buildToastTemplate = function (options) {
var title = options.title,
message = options.text || '',
json = JSON.stringify(options),
sound = '';
if (options.sound && options.sound !== '') {
sound = this.parseSound(options.sound);
}
var templateName = "ToastText",
imageNode;
if (options.icon && options.icon !== '') {
imageNode = this.parseImage(options.icon);
// template with Image
if (imageNode !== '') {
templateName = "ToastImageAndText";
}
} else {
imageNode = "";
}
var bindingNode;
if (title && title !== '') {
bindingNode = "<binding template='" + templateName + "02'>" +
imageNode +
"<text id='1'>" + title + "</text>" +
"<text id='2'>" + message + "</text>" +
"</binding>";
} else {
bindingNode = "<binding template='" + templateName + "01'>" +
imageNode +
"<text id='1'>" + message + "</text>" +
"</binding>";
}
return "<toast>" +
"<visual>" +
bindingNode +
"</visual>" +
sound +
"<json>" + json + "</json>" +
"</toast>";
};
/**
* Short-hand method for the toast notification history.
*/
exports.getToastHistory = function () {
return Windows.UI.Notifications.ToastNotificationManager.history;
};
/**
* Gets a toast notifier instance.
*
* @return Object
*/
exports.getToastNotifier = function () {
return Windows.UI.Notifications.ToastNotificationManager
.createToastNotifier();
};
/**
* List of all scheduled toast notifiers.
*
* @return Array
*/
exports.getScheduledToasts = function () {
return this.getToastNotifier().getScheduledToastNotifications();
};
/**
* Gets the Id from the toast notifier.
*
* @param {Object} toast
* A toast notifier object
*
* @return String
*/
exports.getToastId = function (toast) {
var id = toast.id;
if (id.match(/-2$/))
return id.match(/^[^-]+/)[0];
return id;
};
/**
* Gets the notification life cycle type
* (scheduled or triggered)
*
* @param {Object} toast
* A toast notifier object
*
* @return String
*/
exports.getToastType = function (toast) {
return this.isToastTriggered(toast) ? 'triggered' : 'scheduled';
};
/**
* If the toast is already scheduled.
*
* @param {Object} toast
* A toast notifier object
*
* @return Boolean
*/
exports.isToastScheduled = function (toast) {
return !this.isToastTriggered(toast);
};
/**
* If the toast is already triggered.
*
* @param {Object} toast
* A toast notifier object
*
* @return Boolean
*/
exports.isToastTriggered = function (toast) {
var id = this.getToastId(toast),
notification = this.getAll([id])[0],
fireDate = new Date((notification.at) * 1000);
if (this.isRepeating(notification))
return false;
return fireDate <= new Date();
};
/**
* Finds the toast by it's ID.
*
* @param {String} id
* Local notification ID
*
* @param Object
*/
exports.findToastById = function (id) {
var toasts = this.getScheduledToasts();
for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i];
if (this.getToastId(toast) == id)
return toast;
}
return null;
};
/**
* Sets trigger event for local notification.
*
* @param {Object} notification
* Local notification object
* @param {Function} callback
* Callback function
*/
exports.callOnTrigger = function (notification, callback) {
var triggerTime = new Date((notification.at * 1000)),
interval = triggerTime - new Date();
if (interval <= 0) {
callback.call(this, notification);
return;
}
WinJS.Promise.timeout(interval).then(function () {
if (exports.isPresent(notification.id)) {
callback.call(exports, notification);
}
});
};
/**
* Sets trigger event for all scheduled local notification.
*
* @param {Function} callback
* Callback function
*/
exports.callOnTriggerForScheduled = function (callback) {
var notifications = this.getScheduled();
for (var i = 0; i < notifications.length; i++) {
this.callOnTrigger(notifications[i], callback);
}
};
/**
* The application state - background or foreground.
*
* @return String
*/
exports.getApplicationState = function () {
return this.isInBackground ? 'background' : 'foreground';
};
/**
* Fires the event about a local notification.
*
* @param {String} event
* The event
* @param {Object} notification
* The notification
*/
exports.fireEvent = function (event, notification) {
var plugin = cordova.plugins.notification.local.core,
state = this.getApplicationState(),
args;
if (notification) {
args = [event, notification, state];
} else {
args = [event, state];
}
if (this.isReady && plugin) {
plugin.fireEvent.apply(plugin, args);
} else {
this.eventQueue.push(args);
}
};
/**************
* LIFE CYCLE *
**************/
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Register trigger handler for each scheduled notification
exports.callOnTriggerForScheduled(function (notification) {
this.updateBadge(notification.badge);
this.fireEvent('trigger', notification);
});
});
// Handle onclick event
WinJS.Application.addEventListener('activated', function (args) {
var id = args.detail.arguments,
notification = exports.getAll([id])[0];
if (!notification)
return;
exports.clearLocalNotification(id);
var repeating = exports.isRepeating(notification);
exports.fireEvent('click', notification);
exports.fireEvent(repeating ? 'clear' : 'cancel', notification);
}, false);
// App is running in background
document.addEventListener('pause', function () {
exports.isInBackground = true;
}, false);
// App is running in foreground
document.addEventListener('resume', function () {
exports.isInBackground = false;
}, false);
// App is running in foreground
document.addEventListener('deviceready', function () {
exports.isInBackground = false;
}, false);
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
var exec = require('cordova/exec');
/********
* CORE *
********/
/**
* Returns the default settings.
*
* @return {Object}
*/
exports.getDefaults = function () {
return this._defaults;
};
/**
* Overwrite default settings.
*
* @param {Object} defaults
*/
exports.setDefaults = function (newDefaults) {
var defaults = this.getDefaults();
for (var key in defaults) {
if (newDefaults.hasOwnProperty(key)) {
defaults[key] = newDefaults[key];
}
}
};
/**
* Schedule a new local notification.
*
* @param {Object} opts
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.schedule = function (opts, callback, scope) {
this.registerPermission(function(granted) {
if (!granted)
return;
var notifications = Array.isArray(opts) ? opts : [opts];
for (var i = 0; i < notifications.length; i++) {
var properties = notifications[i];
this.mergeWithDefaults(properties);
this.convertProperties(properties);
}
this.exec('schedule', notifications, callback, scope);
}, this);
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Object} options
* The notification properties to update
* @param {Function} callback
* A function to be called after the notification has been updated
* @param {Object?} scope
* The scope for the callback function
*/
exports.update = function (opts, callback, scope) {
var notifications = Array.isArray(opts) ? opts : [opts];
for (var i = 0; i < notifications.length; i++) {
var properties = notifications[i];
this.convertProperties(properties);
}
this.exec('update', notifications, callback, scope);
};
/**
* Clear the specified notification.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clear = function (ids, callback, scope) {
ids = Array.isArray(ids) ? ids : [ids];
ids = this.convertIds(ids);
this.exec('clear', ids, callback, scope);
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clearAll = function (callback, scope) {
this.exec('clearAll', null, callback, scope);
};
/**
* Cancel the specified notifications.
*
* @param {String[]} ids
* The IDs of the notifications
* @param {Function} callback
* A function to be called after the notifications has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancel = function (ids, callback, scope) {
ids = Array.isArray(ids) ? ids : [ids];
ids = this.convertIds(ids);
this.exec('cancel', ids, callback, scope);
};
/**
* Remove all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancelAll = function (callback, scope) {
this.exec('cancelAll', null, callback, scope);
};
/**
* Check if a notification with an ID is present.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isPresent = function (id, callback, scope) {
this.exec('isPresent', id || 0, callback, scope);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isScheduled = function (id, callback, scope) {
this.exec('isScheduled', id || 0, callback, scope);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isTriggered = function (id, callback, scope) {
this.exec('isTriggered', id || 0, callback, scope);
};
/**
* List all local notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllIds = function (callback, scope) {
this.exec('getAllIds', null, callback, scope);
};
/**
* Alias for `getAllIds`.
*/
exports.getIds = function () {
this.getAllIds.apply(this, arguments);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduledIds = function (callback, scope) {
this.exec('getScheduledIds', null, callback, scope);
};
/**
* List all triggered notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggeredIds = function (callback, scope) {
this.exec('getTriggeredIds', null, callback, scope);
};
/**
* Property list for given local notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.get = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
this.exec('getSingle', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getAll', ids, callback, scope);
};
/**
* Property list for all local notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAll = function (callback, scope) {
this.exec('getAll', null, callback, scope);
};
/**
* Property list for given scheduled notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduled = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
ids = [ids];
}
if (!Array.isArray(ids)) {
this.exec('getSingleScheduled', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getScheduled', ids, callback, scope);
};
/**
* Property list for all scheduled notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllScheduled = function (callback, scope) {
this.exec('getScheduled', null, callback, scope);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggered = function () {
var args = Array.apply(null, arguments);
if (typeof args[0] == 'function') {
args.unshift([]);
}
var ids = args[0],
callback = args[1],
scope = args[2];
if (!Array.isArray(ids)) {
ids = [ids];
}
if (!Array.isArray(ids)) {
this.exec('getSingleTriggered', Number(ids), callback, scope);
return;
}
ids = this.convertIds(ids);
this.exec('getTriggered', ids, callback, scope);
};
/**
* Property list for all triggered notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllTriggered = function (callback, scope) {
this.exec('getTriggered', null, callback, scope);
};
/**
* Informs if the app has the permission to show notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.hasPermission = function (callback, scope) {
var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'hasPermission', []);
};
/**
* Register permission to show notifications if not already granted.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.registerPermission = function (callback, scope) {
var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'registerPermission', []);
};
/**********
* EVENTS *
**********/
/**
* Register callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
* @param {Object?} scope
* The callback function's scope
*/
exports.on = function (event, callback, scope) {
if (!this._listener[event]) {
this._listener[event] = [];
}
var item = [callback, scope || window];
this._listener[event].push(item);
};
/**
* Unregister callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
*/
exports.un = function (event, callback) {
var listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0];
if (fn == callback) {
listener.splice(i, 1);
break;
}
}
};
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
var exec = require('cordova/exec'),
channel = require('cordova/channel');
/***********
* MEMBERS *
***********/
// Default values
exports._defaults = {
text: '',
title: '',
sound: 'res://platform_default',
badge: 0,
id: 0,
data: undefined,
every: undefined,
at: undefined
};
// listener
exports._listener = {};
/********
* UTIL *
********/
/**
* Merge platform specific properties into the default ones.
*
* @return {Object}
* The default properties for the platform
*/
exports.applyPlatformSpecificOptions = function () {
var defaults = this._defaults;
switch (device.platform) {
case 'Android':
defaults.icon = 'res://icon';
defaults.smallIcon = 'res://ic_popup_reminder';
defaults.ongoing = false;
defaults.autoClear = true;
defaults.led = 'FFFFFF';
break;
}
return defaults;
};
/**
* Merge custom properties with the default values.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The merged property list
*/
exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults();
options.at = this.getValueFor(options, 'at', 'firstAt', 'date');
options.text = this.getValueFor(options, 'text', 'message');
options.data = this.getValueFor(options, 'data', 'json');
if (defaults.hasOwnProperty('autoClear')) {
options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel');
}
if (options.autoClear !== true && options.ongoing) {
options.autoClear = false;
}
if (options.at === undefined || options.at === null) {
options.at = new Date();
}
for (var key in defaults) {
if (options[key] === null || options[key] === undefined) {
if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
options[key] = undefined;
} else {
options[key] = defaults[key];
}
}
}
for (key in options) {
if (!defaults.hasOwnProperty(key)) {
delete options[key];
console.warn('Unknown property: ' + key);
}
}
return options;
};
/**
* Convert the passed values to their required type.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The converted property list
*/
exports.convertProperties = function (options) {
if (options.id) {
if (isNaN(options.id)) {
options.id = this.getDefaults().id;
console.warn('Id is not a number: ' + options.id);
} else {
options.id = Number(options.id);
}
}
if (options.title) {
options.title = options.title.toString();
}
if (options.text) {
options.text = options.text.toString();
}
if (options.badge) {
if (isNaN(options.badge)) {
options.badge = this.getDefaults().badge;
console.warn('Badge number is not a number: ' + options.id);
} else {
options.badge = Number(options.badge);
}
}
if (options.at) {
if (typeof options.at == 'object') {
options.at = options.at.getTime();
}
options.at = Math.round(options.at/1000);
}
if (typeof options.data == 'object') {
options.data = JSON.stringify(options.data);
}
return options;
};
/**
* Create callback, which will be executed within a specific scope.
*
* @param {Function} callbackFn
* The callback function
* @param {Object} scope
* The scope for the function
*
* @return {Function}
* The new callback function
*/
exports.createCallbackFn = function (callbackFn, scope) {
if (typeof callbackFn != 'function')
return;
return function () {
callbackFn.apply(scope || this, arguments);
};
};
/**
* Convert the IDs to numbers.
*
* @param {String/Number[]} ids
*
* @return Array of Numbers
*/
exports.convertIds = function (ids) {
var convertedIds = [];
for (var i = 0; i < ids.length; i++) {
convertedIds.push(Number(ids[i]));
}
return convertedIds;
};
/**
* First found value for the given keys.
*
* @param {Object} options
* Object with key-value properties
* @param {String[]} keys*
* Key list
*/
exports.getValueFor = function (options) {
var keys = Array.apply(null, arguments).slice(1);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (options.hasOwnProperty(key)) {
return options[key];
}
}
};
/**
* Fire event with given arguments.
*
* @param {String} event
* The event's name
* @param {args*}
* The callback's arguments
*/
exports.fireEvent = function (event) {
var args = Array.apply(null, arguments).slice(1),
listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0],
scope = listener[i][1];
fn.apply(scope, args);
}
};
/**
* Execute the native counterpart.
*
* @param {String} action
* The name of the action
* @param args[]
* Array of arguments
* @param {Function} callback
* The callback function
* @param {Object} scope
* The scope for the function
*/
exports.exec = function (action, args, callback, scope) {
var fn = this.createCallbackFn(callback, scope),
params = [];
if (Array.isArray(args)) {
params = args;
} else if (args) {
params.push(args);
}
exec(fn, null, 'LocalNotification', action, params);
};
/*********
* HOOKS *
*********/
// Called after 'deviceready' event
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// and all queued events can be executed.
exec(null, null, 'LocalNotification', 'deviceready', []);
});
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Device plugin is ready now
channel.onCordovaInfoReady.subscribe(function () {
// Merge platform specifics into defaults
exports.applyPlatformSpecificOptions();
});
});
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
/*************
* INTERFACE *
*************/
/**
* Returns the default settings.
*
* @return {Object}
*/
exports.getDefaults = function () {
return this.core.getDefaults();
};
/**
* Overwrite default settings.
*
* @param {Object} defaults
*/
exports.setDefaults = function (defaults) {
this.core.setDefaults(defaults);
};
/**
* Schedule a new local notification.
*
* @param {Object} opts
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.schedule = function (opts, callback, scope) {
this.core.schedule(opts, callback, scope);
};
/**
* Update existing notifications specified by IDs in options.
*
* @param {Object} options
* The notification properties to update
* @param {Function} callback
* A function to be called after the notification has been updated
* @param {Object?} scope
* The scope for the callback function
*/
exports.update = function (opts, callback, scope) {
this.core.update(opts, callback, scope);
};
/**
* Clear the specified notification.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clear = function (ids, callback, scope) {
this.core.clear(ids, callback, scope);
};
/**
* Clear all previously sheduled notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been cleared
* @param {Object?} scope
* The scope for the callback function
*/
exports.clearAll = function (callback, scope) {
this.core.clearAll(callback, scope);
};
/**
* Cancel the specified notifications.
*
* @param {String[]} ids
* The IDs of the notifications
* @param {Function} callback
* A function to be called after the notifications has been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancel = function (ids, callback, scope) {
this.core.cancel(ids, callback, scope);
};
/**
* Remove all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object?} scope
* The scope for the callback function
*/
exports.cancelAll = function (callback, scope) {
this.core.cancelAll(callback, scope);
};
/**
* Check if a notification with an ID is present.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isPresent = function (id, callback, scope) {
this.core.isPresent(id, callback, scope);
};
/**
* Check if a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isScheduled = function (id, callback, scope) {
this.core.isScheduled(id, callback, scope);
};
/**
* Check if a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.isTriggered = function (id, callback, scope) {
this.core.isTriggered(id, callback, scope);
};
/**
* List all local notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllIds = function (callback, scope) {
this.core.getAllIds(callback, scope);
};
/**
* Alias for `getAllIds`.
*/
exports.getIds = function () {
this.getAllIds.apply(this, arguments);
};
/**
* List all scheduled notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduledIds = function (callback, scope) {
this.core.getScheduledIds(callback, scope);
};
/**
* List all triggered notification IDs.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggeredIds = function (callback, scope) {
this.core.getTriggeredIds(callback, scope);
};
/**
* Property list for given local notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.get = function () {
this.core.get.apply(this.core, arguments);
};
/**
* Property list for all local notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAll = function (callback, scope) {
this.core.getAll(callback, scope);
};
/**
* Property list for given scheduled notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getScheduled = function () {
this.core.getScheduled.apply(this.core, arguments);
};
/**
* Property list for all scheduled notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllScheduled = function (callback, scope) {
this.core.getAllScheduled(callback, scope);
};
/**
* Property list for given triggered notifications.
* If called without IDs, all notification will be returned.
*
* @param {Number[]?} ids
* Set of notification IDs
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getTriggered = function () {
this.core.getTriggered.apply(this.core, arguments);
};
/**
* Property list for all triggered notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object?} scope
* The scope for the callback function
*/
exports.getAllTriggered = function (callback, scope) {
this.core.getAllTriggered(callback, scope);
};
/**
* Informs if the app has the permission to show notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.hasPermission = function (callback, scope) {
this.core.hasPermission(callback, scope);
};
/**
* Register permission to show notifications if not already granted.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
*/
exports.registerPermission = function (callback, scope) {
this.core.registerPermission(callback, scope);
};
/****************
* DEPRECATIONS *
****************/
/**
* Schedule a new local notification.
*/
exports.add = function () {
console.warn('Depreated: Please use `notification.local.schedule` instead.');
this.schedule.apply(this, arguments);
};
/**
* Register permission to show notifications
* if not already granted.
*/
exports.promptForPermission = function () {
console.warn('Depreated: Please use `notification.local.registerPermission` instead.');
this.registerPermission.apply(this, arguments);
};
/**********
* EVENTS *
**********/
/**
* Register callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
* @param {Object?} scope
* The callback function's scope
*/
exports.on = function (event, callback, scope) {
this.core.on(event, callback, scope);
};
/**
* Unregister callback for given event.
*
* @param {String} event
* The event's name
* @param {Function} callback
* The function to be exec as callback
*/
exports.un = function (event, callback) {
this.core.un(event, callback, scope);
};
});
{
"prepare_queue": {
"installed": [],
"uninstalled": []
},
"config_munge": {
"files": {}
},
"installed_plugins": {
"cordova-plugin-x-toast": {
"PACKAGE_NAME": "NotificationExample"
},
"cordova-android-support-v4": {
"PACKAGE_NAME": "NotificationExample"
},
"cordova-plugin-device": {
"PACKAGE_NAME": "NotificationExample"
},
"de.appplant.cordova.plugin.local-notification": {
"PACKAGE_NAME": "NotificationExample"
}
},
"dependent_plugins": {},
"modules": [
{
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-device/src/windows/DeviceProxy.js",
"id": "cordova-plugin-device.DeviceProxy",
"pluginId": "cordova-plugin-device",
"merges": [
""
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local",
"plugin.notification.local"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
"cordova.plugins.notification.local.core",
"plugin.notification.local.core"
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
""
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
""
]
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [
""
]
}
]
}
\ No newline at end of file
cordova.define('cordova/plugin_list', function(require, exports, module) { cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [ module.exports = [
{ {
"file": "plugins/nl.x-services.plugins.toast/www/Toast.js", "file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "nl.x-services.plugins.toast.Toast", "id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [ "clobbers": [
"window.plugins.toast" "window.plugins.toast"
] ]
}, },
{ {
"file": "plugins/nl.x-services.plugins.toast/test/tests.js", "file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "nl.x-services.plugins.toast.tests" "id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-device/src/windows/DeviceProxy.js",
"id": "cordova-plugin-device.DeviceProxy",
"pluginId": "cordova-plugin-device",
"merges": [
""
]
}, },
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [ "clobbers": [
"cordova.plugins.notification.local", "cordova.plugins.notification.local",
"plugin.notification.local" "plugin.notification.local"
...@@ -22,6 +41,7 @@ module.exports = [ ...@@ -22,6 +41,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"clobbers": [ "clobbers": [
"cordova.plugins.notification.local.core", "cordova.plugins.notification.local.core",
"plugin.notification.local.core" "plugin.notification.local.core"
...@@ -30,6 +50,7 @@ module.exports = [ ...@@ -30,6 +50,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [ "merges": [
"cordova.plugins.notification.local.core", "cordova.plugins.notification.local.core",
"plugin.notification.local.core" "plugin.notification.local.core"
...@@ -38,6 +59,7 @@ module.exports = [ ...@@ -38,6 +59,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [ "merges": [
"" ""
] ]
...@@ -45,6 +67,7 @@ module.exports = [ ...@@ -45,6 +67,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core",
"pluginId": "de.appplant.cordova.plugin.local-notification",
"merges": [ "merges": [
"" ""
] ]
...@@ -52,20 +75,7 @@ module.exports = [ ...@@ -52,20 +75,7 @@ module.exports = [
{ {
"file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util",
"merges": [ "pluginId": "de.appplant.cordova.plugin.local-notification",
""
]
},
{
"file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device",
"clobbers": [
"device"
]
},
{
"file": "plugins/cordova-plugin-device/src/windows/DeviceProxy.js",
"id": "cordova-plugin-device.DeviceProxy",
"merges": [ "merges": [
"" ""
] ]
...@@ -73,12 +83,6 @@ module.exports = [ ...@@ -73,12 +83,6 @@ module.exports = [
]; ];
module.exports.metadata = module.exports.metadata =
// TOP OF METADATA // TOP OF METADATA
{ {}
"android.support.v4": "21.0.1",
"de.appplant.cordova.common.registerusernotificationsettings": "1.0.1",
"nl.x-services.plugins.toast": "2.0.4",
"de.appplant.cordova.plugin.local-notification": "0.8.2-dev",
"cordova-plugin-device": "1.0.1"
}
// BOTTOM OF METADATA // BOTTOM OF METADATA
}); });
\ No newline at end of file
cordova.define("cordova-plugin-device.DeviceProxy", function(require, exports, module) { /* cordova.define("cordova-plugin-device.DeviceProxy", function(require, exports, module) { /*
* *
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
......
cordova.define("cordova-plugin-device.device", function(require, exports, module) { /* cordova.define("cordova-plugin-device.device", function(require, exports, module) { /*
* *
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
......
cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) {
expect(true).toBe(false);
done();
},
succeed = function (done) {
expect(true).toBe(true);
done();
};
describe('Plugin availability', function () {
it("window.plugins.toast should exist", function() {
expect(window.plugins.toast).toBeDefined();
});
});
describe('API functions', function () {
it("should define show", function() {
expect(window.plugins.toast.show).toBeDefined();
});
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined();
});
it("should define showShortCenter", function() {
expect(window.plugins.toast.showShortCenter).toBeDefined();
});
it("should define showShortBottom", function() {
expect(window.plugins.toast.showShortBottom).toBeDefined();
});
it("should define showLongTop", function() {
expect(window.plugins.toast.showLongTop).toBeDefined();
});
it("should define showLongCenter", function() {
expect(window.plugins.toast.showLongCenter).toBeDefined();
});
it("should define showLongBottom", function() {
expect(window.plugins.toast.showLongBottom).toBeDefined();
});
});
describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
});
};
});
cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) { function Toast() {
}
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
};
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
this.show(message, "short", "top", successCallback, errorCallback);
};
Toast.prototype.showShortCenter = function (message, successCallback, errorCallback) {
this.show(message, "short", "center", successCallback, errorCallback);
};
Toast.prototype.showShortBottom = function (message, successCallback, errorCallback) {
this.show(message, "short", "bottom", successCallback, errorCallback);
};
Toast.prototype.showLongTop = function (message, successCallback, errorCallback) {
this.show(message, "long", "top", successCallback, errorCallback);
};
Toast.prototype.showLongCenter = function (message, successCallback, errorCallback) {
this.show(message, "long", "center", successCallback, errorCallback);
};
Toast.prototype.showLongBottom = function (message, successCallback, errorCallback) {
this.show(message, "long", "bottom", successCallback, errorCallback);
};
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () {
if (!window.plugins) {
window.plugins = {};
}
window.plugins.toast = new Toast();
return window.plugins.toast;
};
cordova.addConstructor(Toast.install);
});
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core", function(require, exports, module) { /* cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Core", function(require, exports, module) { /*
Copyright 2013-2015 appPlant UG Copyright 2013-2015 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy", function(require, exports, module) { /* cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy", function(require, exports, module) { /*
Copyright 2013-2015 appPlant UG Copyright 2013-2015 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util", function(require, exports, module) { /* cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy.Util", function(require, exports, module) { /*
Copyright 2013-2015 appPlant UG Copyright 2013-2015 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { /* cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved. * Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
* *
* @APPPLANT_LICENSE_HEADER_START@ * @APPPLANT_LICENSE_HEADER_START@
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { /* cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved. * Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
* *
* @APPPLANT_LICENSE_HEADER_START@ * @APPPLANT_LICENSE_HEADER_START@
......
cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { /* cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved. * Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
* *
* @APPPLANT_LICENSE_HEADER_START@ * @APPPLANT_LICENSE_HEADER_START@
......
...@@ -70,13 +70,13 @@ ...@@ -70,13 +70,13 @@
} }
}, },
"installed_plugins": { "installed_plugins": {
"android.support.v4": { "de.appplant.cordova.common.registerusernotificationsettings": {
"PACKAGE_NAME": "de.appplant.localnotification.example" "PACKAGE_NAME": "de.appplant.localnotification.example"
}, },
"de.appplant.cordova.common.registerusernotificationsettings": { "cordova-plugin-x-toast": {
"PACKAGE_NAME": "de.appplant.localnotification.example" "PACKAGE_NAME": "de.appplant.localnotification.example"
}, },
"nl.x-services.plugins.toast": { "cordova-android-support-v4": {
"PACKAGE_NAME": "de.appplant.localnotification.example" "PACKAGE_NAME": "de.appplant.localnotification.example"
}, },
"de.appplant.cordova.plugin.local-notification": { "de.appplant.cordova.plugin.local-notification": {
......
# This is the official list of authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
# Names should be added to this file as:
# Name or Organization <email address>
# The email address is not required for organizations.
Google Inc.
# Contributing to this Repository
Thank you for your interest in contributing!
Unfortunately there are some legal hurdles. Sorry about that.
This repository is a Google open source project, and so we require contributors to sign Google's open source Contributor License Agreement.
It's easy to do, just click here to sign as an [individual](https://developers.google.com/open-source/cla/individual) or [corporation](https://developers.google.com/open-source/cla/corporate).
Individuals can sign electronically in seconds (see the bottom of the page); corporations will need to email a PDF, or mail.
We cannot accept PRs or patches larger than fixing typos and the like without a signed CLA.
If your Github account doesn't show the name your used to sign, please mention your name in your PR.
# People who have agreed to one of the CLAs and can contribute patches.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# https://developers.google.com/open-source/cla/individual
# https://developers.google.com/open-source/cla/corporate
#
# Names should be added to this file as:
# Name <email address>
Andrew Grieve <agrieve@google.com>
Max Woghiren <maxw@google.com>
Copyright (c) 2014 The Chromium Authors. 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 Google Inc. nor the names of its
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
OWNER 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.
This is a Cordova plugin that adds the Android Support v4 client library.
It is meant to be depended on by other plugins.
{
"version": "21.0.1",
"name": "android.support.v4",
"cordova_name": "Android Support v4",
"platforms": [
"android"
],
"engines": [
{
"name": "cordova",
"version": ">=3.0.0"
}
]
}
\ No newline at end of file
The MIT License (MIT)
Copyright (c) 2014 AppFeel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
cordova-plugin-android-support-v4
=================================
{
"name": "cordova-android-support-v4",
"version": "4.0.0",
"description": "cordova-android-support-v4 =================================",
"cordova": {
"id": "cordova-android-support-v4",
"platforms": [
"android"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/appfeel/cordova-plugin-android-support-v4.git"
},
"keywords": [
"ecosystem:cordova",
"cordova-android"
],
"engines": [
{
"name": "cordova",
"version": ">=3.0.0"
}
],
"author": "AppFeel",
"license": "MIT",
"bugs": {
"url": "https://github.com/appfeel/cordova-plugin-android-support-v4/issues"
},
"homepage": "https://github.com/appfeel/cordova-plugin-android-support-v4#readme"
}
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!-- <!--
Copyright (c) 2014 The Chromium Authors. All rights reserved. Copyright (c) 2014 AppFeel. All rights reserved.
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a MIT license that can be
found in the LICENSE file. found in the LICENSE file.
--> -->
<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" <plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" id="cordova-android-support-v4" version="4.0.0">
id="android.support.v4"
version="21.0.1">
<engines> <engines>
<engine name="cordova" version=">=3.0.0" /> <engine name="cordova" version=">=3.0.0" />
</engines> </engines>
<name>Android Support v4</name> <name>Android Support v4</name>
<platform name="android"> <platform name="android">
<source-file src="android-support-v4.jar" target-dir="libs" /> <lib-file src="android-support-v4.jar" />
</platform> </platform>
</plugin> </plugin>
\ No newline at end of file
...@@ -63,18 +63,19 @@ Toast is compatible with [Cordova Plugman](https://github.com/apache/cordova-plu ...@@ -63,18 +63,19 @@ Toast is compatible with [Cordova Plugman](https://github.com/apache/cordova-plu
Using the Cordova CLI and the [Cordova Plugin Registry](http://plugins.cordova.io) Using the Cordova CLI and the [Cordova Plugin Registry](http://plugins.cordova.io)
``` ```
$ cordova plugin add nl.x-services.plugins.toast $ cordova plugin add cordova-plugin-x-toast
$ cordova prepare $ cordova prepare
``` ```
Or using the phonegap CLI Or using the phonegap CLI
``` ```
$ phonegap local plugin add nl.x-services.plugins.toast $ phonegap local plugin add cordova-plugin-x-toast
``` ```
Toast.js is brought in automatically. There is no need to change or add anything in your html. Toast.js is brought in automatically. There is no need to change or add anything in your html.
### Manually ### Manually
You'd better use the CLI, but here goes:
1\. Add the following xml to your `config.xml` in the root directory of your `www` folder: 1\. Add the following xml to your `config.xml` in the root directory of your `www` folder:
```xml ```xml
...@@ -118,20 +119,18 @@ Toast works with PhoneGap build too, but only with PhoneGap 3.0 and up. ...@@ -118,20 +119,18 @@ Toast works with PhoneGap build too, but only with PhoneGap 3.0 and up.
Just add the following xml to your `config.xml` to always use the latest version of this plugin: Just add the following xml to your `config.xml` to always use the latest version of this plugin:
```xml ```xml
<gap:plugin name="nl.x-services.plugins.toast" /> <gap:plugin name="cordova-plugin-x-toast" source="npm" />
```
or to use this exact version:
```xml
<gap:plugin name="nl.x-services.plugins.toast" version="1.0" />
``` ```
Toast.js is brought in automatically. There is no need to change or add anything in your html. Toast.js is brought in automatically. There is no need to change or add anything in your html.
## 4. Usage ## 4. Usage
### Showing a Toast
You have two choices to make when showing a Toast: where to show it and for how long. You have two choices to make when showing a Toast: where to show it and for how long.
* show(message, duration, position) * show(message, duration, position)
* duration: 'short', 'long' * duration: 'short', 'long'
* position: 'top', 'center', 'bottom' * position: 'top', 'center', 'bottom'
You can also use any of these convenience methods: You can also use any of these convenience methods:
* showShortTop(message) * showShortTop(message)
...@@ -148,7 +147,34 @@ You can copy-paste these lines of code for a quick test: ...@@ -148,7 +147,34 @@ You can copy-paste these lines of code for a quick test:
<button onclick="window.plugins.toast.show('Hello there!', 'long', 'center', function(a){console.log('toast success: ' + a)}, function(b){alert('toast error: ' + b)})">Toast show long center</button> <button onclick="window.plugins.toast.show('Hello there!', 'long', 'center', function(a){console.log('toast success: ' + a)}, function(b){alert('toast error: ' + b)})">Toast show long center</button>
``` ```
### WP8 quircks #### Tweaking the vertical position
Since 2.1.0 you can add pixels to move the toast up or down.
Note that `showWithOptions` can be used instead of the functions above, but it's not useful unless you want to pass `addPixelsY`.
```js
function showTop() {
window.plugins.toast.showWithOptions(
{
message: "hey there",
duration: "short",
position: "bottom",
addPixelsY: -40 // added a negative value to move it up a bit (default 0)
},
onSuccess, // optional
onError // optional
);
}
```
### Hiding a Toast
In case you want to hide a Toast manually, call this:
```js
function hide() {
// this function takes an optional success callback, but you can do without just as well
window.plugins.toast.hide();
}
```
### WP8 quirks
The WP8 implementation needs a little more work, but it's perfectly useable when you keep this in mind: The WP8 implementation needs a little more work, but it's perfectly useable when you keep this in mind:
* You can't show two Toasts simultaneously. * You can't show two Toasts simultaneously.
* Wait until the first Toast is hidden before the second is shown, otherwise the second one will be hidden quickly. * Wait until the first Toast is hidden before the second is shown, otherwise the second one will be hidden quickly.
......
{
"name": "cordova-plugin-x-toast",
"version": "2.2.1",
"description": "This plugin allows you to show a Toast. A Toast is a little non intrusive buttonless popup which automatically disappears.",
"cordova": {
"id": "cordova-plugin-x-toast",
"platforms": [
"ios",
"android",
"wp8",
"blackberry10"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin.git"
},
"keywords": [
"Toast",
"Notification",
"Message",
"Alert",
"ecosystem:cordova",
"cordova-ios",
"cordova-android",
"cordova-wp8",
"cordova-blackberry10"
],
"engines": [
{
"name": "cordova",
"version": ">=3.0.0"
}
],
"author": "Eddy Verbruggen <eddyverbruggen@gmail.com> (https://github.com/EddyVerbruggen)",
"license": "MIT",
"bugs": {
"url": "https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin/issues"
},
"homepage": "https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin#readme"
}
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
id="nl.x-services.plugins.toast" id="cordova-plugin-x-toast"
version="2.0.4"> version="2.2.1">
<name>Toast</name> <name>Toast</name>
......
...@@ -5,6 +5,7 @@ import org.apache.cordova.CallbackContext; ...@@ -5,6 +5,7 @@ import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
/* /*
// TODO nice way for the Toast plugin to offer a longer delay than the default short and long options // TODO nice way for the Toast plugin to offer a longer delay than the default short and long options
...@@ -19,6 +20,7 @@ import org.json.JSONException; ...@@ -19,6 +20,7 @@ import org.json.JSONException;
public class Toast extends CordovaPlugin { public class Toast extends CordovaPlugin {
private static final String ACTION_SHOW_EVENT = "show"; private static final String ACTION_SHOW_EVENT = "show";
private static final String ACTION_HIDE_EVENT = "hide";
private android.widget.Toast mostRecentToast; private android.widget.Toast mostRecentToast;
...@@ -27,40 +29,44 @@ public class Toast extends CordovaPlugin { ...@@ -27,40 +29,44 @@ public class Toast extends CordovaPlugin {
@Override @Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if (ACTION_SHOW_EVENT.equals(action)) { if (ACTION_HIDE_EVENT.equals(action)) {
if (mostRecentToast != null) {
mostRecentToast.cancel();
}
callbackContext.success();
return true;
} else if (ACTION_SHOW_EVENT.equals(action)) {
if (this.isPaused) { if (this.isPaused) {
return true; return true;
} }
final String message = args.getString(0); final JSONObject options = args.getJSONObject(0);
final String duration = args.getString(1);
final String position = args.getString(2); final String message = options.getString("message");
final String duration = options.getString("duration");
final String position = options.getString("position");
final int addPixelsY = options.has("addPixelsY") ? options.getInt("addPixelsY") : 0;
cordova.getActivity().runOnUiThread(new Runnable() { cordova.getActivity().runOnUiThread(new Runnable() {
public void run() { public void run() {
android.widget.Toast toast = android.widget.Toast.makeText(webView.getContext(), message, 0); android.widget.Toast toast = android.widget.Toast.makeText(
cordova.getActivity().getApplicationContext(),
message,
"short".equals(duration) ? android.widget.Toast.LENGTH_SHORT : android.widget.Toast.LENGTH_LONG);
if ("top".equals(position)) { if ("top".equals(position)) {
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 20); toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 20 + addPixelsY);
} else if ("bottom".equals(position)) { } else if ("bottom".equals(position)) {
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 20); toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 20 - addPixelsY);
} else if ("center".equals(position)) { } else if ("center".equals(position)) {
toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0); toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, addPixelsY);
} else { } else {
callbackContext.error("invalid position. valid options are 'top', 'center' and 'bottom'"); callbackContext.error("invalid position. valid options are 'top', 'center' and 'bottom'");
return; return;
} }
if ("short".equals(duration)) {
toast.setDuration(android.widget.Toast.LENGTH_SHORT);
} else if ("long".equals(duration)) {
toast.setDuration(android.widget.Toast.LENGTH_LONG);
} else {
callbackContext.error("invalid duration. valid options are 'short' and 'long'");
return;
}
toast.show(); toast.show();
mostRecentToast = toast; mostRecentToast = toast;
callbackContext.success(); callbackContext.success();
...@@ -86,4 +92,4 @@ public class Toast extends CordovaPlugin { ...@@ -86,4 +92,4 @@ public class Toast extends CordovaPlugin {
public void onResume(boolean multitasking) { public void onResume(boolean multitasking) {
this.isPaused = false; this.isPaused = false;
} }
} }
\ No newline at end of file
var toast,
resultObjs = {},
threadCallback = null,
_utils = require("../../lib/utils");
module.exports = {
show: function (success, fail, args, env) {
var result = new PluginResult(args, env);
resultObjs[result.callbackId] = result;
var message = JSON.parse(decodeURIComponent(args[0])),
duration = JSON.parse(decodeURIComponent(args[1])),
position = JSON.parse(decodeURIComponent(args[2]));
toast.getInstance().show(result.callbackId, {message:message, duration:duration, position:position});
}
};
///////////////////////////////////////////////////////////////////
// JavaScript wrapper for JNEXT plugin for connection
///////////////////////////////////////////////////////////////////
JNEXT.Toast = function () {
var self = this,
hasInstance = false;
self.getId = function () {
return self.m_id;
};
self.init = function () {
if (!JNEXT.require("libToast")) {
return false;
}
self.m_id = JNEXT.createObject("libToast.Toast_JS");
if (self.m_id === "") {
return false;
}
JNEXT.registerEvents(self);
};
// calls into InvokeMethod(string command) in Toast_JS.cpp
self.show = function (callbackId, input) {
return JNEXT.invoke(self.m_id, "show " + callbackId + " " + JSON.stringify(input));
};
// Fired by the Event framework (used by asynchronous callbacks)
self.onEvent = function (strData) {
var arData = strData.split(" "),
callbackId = arData[0],
result = resultObjs[callbackId],
data = arData.slice(1, arData.length).join(" ");
if (result) {
if (callbackId != threadCallback) {
result.callbackOk(data, false);
delete resultObjs[callbackId];
} else {
result.callbackOk(data, true);
}
}
};
// ************************
// End of methods to edit
// ************************
self.m_id = "";
self.getInstance = function () {
if (!hasInstance) {
hasInstance = true;
self.init();
}
return self;
};
};
toast = new JNEXT.Toast();
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.debug.1877214659">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.debug.1877214659" moduleId="org.eclipse.cdt.core.settings" name="Device-Debug">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Device-Debug"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
<entry flags="RESOLVED" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" errorParsers="com.qnx.tools.ide.qde.core.QDELinkerErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser" id="com.qnx.qcc.configuration.sharedLib.debug.1877214659" name="Device-Debug" parent="com.qnx.qcc.configuration.sharedLib.debug" postannouncebuildStep="" postbuildStep="" preannouncebuildStep="" prebuildStep="">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.debug.1877214659." name="/" resourcePath="">
<toolChain errorParsers="" id="com.qnx.qcc.toolChain.sharedLib.debug.191768618" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<option id="com.qnx.qcc.option.cpu.1578303771" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.436831450" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Device-Debug}" errorParsers="" id="com.qnx.nto.606064165" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool command="qcc" commandLinePattern="${COMMAND} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}" errorParsers="org.eclipse.cdt.core.GCCErrorParser" id="com.qnx.qcc.tool.compiler.1879271926" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.1417199508" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.970212540" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.1460927572" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.2099952700" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtGlobal"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.1666296795" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.1549451068" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.710679926" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool command="qcc" commandLinePattern="${COMMAND} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}" errorParsers="" id="com.qnx.qcc.tool.assembler.646317396" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.1334708386" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.911447541" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool command="qcc" commandLinePattern="${COMMAND} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}" errorParsers="com.qnx.tools.ide.qde.core.QDELinkerErrorParser;org.eclipse.cdt.core.GLDErrorParser" id="com.qnx.qcc.tool.linker.1892404701" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.2066515291" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.935213389" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.2116373961" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.1764180006" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.227797113" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="Qt"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.1025464239" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.847297905" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.release.608922875">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.release.608922875" moduleId="org.eclipse.cdt.core.settings" name="Device-Release">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Device-Release"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
<entry flags="RESOLVED" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" id="com.qnx.qcc.configuration.sharedLib.release.608922875" name="Device-Release" parent="com.qnx.qcc.configuration.sharedLib.release">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.release.608922875." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.sharedLib.release.1688650878" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<option id="com.qnx.qcc.option.cpu.644399334" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.2097864805" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Device-Release}" id="com.qnx.nto.204940733" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.935907476" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.78720761" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.723931478" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compiler.includePath.471392157" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.1319958023" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.1396886030" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<option id="com.qnx.qcc.option.compiler.qccoptions.330490837" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
<listOptionValue builtIn="false" value="-frecord-gcc-switches"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.1724498438" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.748752433" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<inputType id="com.qnx.qcc.inputType.assembler.1895340354" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.1627058060" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.shared.1848469132" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.496307503" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.230783029" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.1387713775" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.1228510357" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.2037393321" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.profile.27502649">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.profile.27502649" moduleId="org.eclipse.cdt.core.settings" name="Device-Profile">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Device-Profile"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.profile,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="Build for Profiling" id="com.qnx.qcc.configuration.sharedLib.profile.27502649" name="Device-Profile" parent="com.qnx.qcc.configuration.sharedLib.profile">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.profile.27502649." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.sharedLib.profile.942439565" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<option id="com.qnx.qcc.option.cpu.2055455815" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1460803543" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Device-Profile}" id="com.qnx.nto.1317522383" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.445493654" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.1834537273" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.512579134" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.1314888503" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.profile2.1332239682" name="Build for Profiling (Function Instrumentation) (-finstrument-functions)" superClass="com.qnx.qcc.option.compiler.profile2" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.1232257233" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.304610370" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.961519137" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.139374714" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.84035750" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.964262814" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.136780888" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.1881786617" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.1401962234" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.profile2.1899497130" name="Build for Profiling (Function Instrumentation) (-lprofiling)" superClass="com.qnx.qcc.option.linker.profile2" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.1169741529" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.1458539142" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.1708860491" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.2086313169" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.802392274" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.2080729816" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.coverage.1806890017">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.coverage.1806890017" moduleId="org.eclipse.cdt.core.settings" name="Device-Coverage">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Device-Coverage"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.coverage,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="Build with Code Coverage" id="com.qnx.qcc.configuration.sharedLib.coverage.1806890017" name="Device-Coverage" parent="com.qnx.qcc.configuration.sharedLib.coverage">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.coverage.1806890017." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.sharedLib.coverage.1658857194" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<option id="com.qnx.qcc.option.cpu.1201722330" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.403898679" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Device-Coverage}" id="com.qnx.nto.1526448130" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.896107073" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.2016926234" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.571725797" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.2099523193" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.coverage.443259067" name="Build for Code Coverage (-Wc,-ftest-coverage -Wc,-fprofile-arcs)" superClass="com.qnx.qcc.option.compiler.coverage" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.78227312" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.1756697867" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.879955122" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.129340647" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.1895486171" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.1003882988" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.1882679870" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.1952361067" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.1165823345" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.coverage.1180137289" name="Build for Code Coverage (-ftest-coverage -fprofile-arcs)" superClass="com.qnx.qcc.option.linker.coverage" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.1237324749" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.1646505677" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.565853353" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.152967788" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.224554770" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.779497179" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.debug.193597202">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.debug.193597202" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Debug">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Simulator-Debug"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" id="com.qnx.qcc.configuration.sharedLib.debug.193597202" name="Simulator-Debug" parent="com.qnx.qcc.configuration.sharedLib.debug">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.debug.193597202." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.sharedLib.debug.716711966" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.929990965" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Simulator-Debug}" id="com.qnx.nto.9741914" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.138396159" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.1392174570" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.1178007212" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.2041326279" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.1182551175" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.442714629" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.154146404" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.2134230609" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.661085696" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.192626669" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.1605593885" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.1517116070" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.1252286694" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.1933218302" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.519768360" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.1272333045" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.1509711055" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.819355949" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.735761526" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.profile.941124085">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.profile.941124085" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Profile">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Simulator-Profile"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.profile,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="Build for Profiling" id="com.qnx.qcc.configuration.sharedLib.profile.941124085" name="Simulator-Profile" parent="com.qnx.qcc.configuration.sharedLib.profile">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.profile.941124085." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.sharedLib.profile.2039571511" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.2056186062" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Simulator-Profile}" id="com.qnx.nto.720646111" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.695327139" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.1333895577" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.1510595019" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.2062656374" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.profile2.310135966" name="Build for Profiling (Function Instrumentation) (-finstrument-functions)" superClass="com.qnx.qcc.option.compiler.profile2" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.1331825250" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.106473584" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.1623246779" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.445126053" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.2058477552" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.1334096638" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.1607661608" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.274526163" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.1372838850" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.profile2.1428522213" name="Build for Profiling (Function Instrumentation) (-lprofiling)" superClass="com.qnx.qcc.option.linker.profile2" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.1357475130" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.1309733103" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.1422840260" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.203659667" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.318181422" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.1706787374" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.coverage.537092296">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.coverage.537092296" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Coverage">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Toast/public"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Toast/Simulator-Coverage"/>
<entry flags="NONE" kind="libraryFile" name="Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.coverage,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="Build with Code Coverage" id="com.qnx.qcc.configuration.sharedLib.coverage.537092296" name="Simulator-Coverage" parent="com.qnx.qcc.configuration.sharedLib.coverage">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.coverage.537092296." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.sharedLib.coverage.1409700437" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.123435356" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Simulator-Coverage}" id="com.qnx.nto.540805157" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.595727552" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.1993375109" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.1636380900" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.249331101" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.coverage.641010958" name="Build for Code Coverage (-Wc,-ftest-coverage -Wc,-fprofile-arcs)" superClass="com.qnx.qcc.option.compiler.coverage" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.344574432" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.1921643665" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.453136796" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.622691546" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.1247332096" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.114306263" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.138220427" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.532570526" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.1125589493" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.coverage.158579585" name="Build for Code Coverage (-ftest-coverage -fprofile-arcs)" superClass="com.qnx.qcc.option.linker.coverage" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.1695519749" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.494101205" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.295270180" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.433937596" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.1536810093" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.493567756" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567" moduleId="org.eclipse.cdt.core.settings" name="device">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Cordova-Toast"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Cordova-Toast/device"/>
<entry flags="RESOLVED" kind="libraryFile" name="Cordova-Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567" name="device" parent="com.qnx.qcc.configuration.sharedLib.release">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.2215983" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<option id="com.qnx.qcc.option.cpu.315540759" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1359109141" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Device-Release}" id="com.qnx.nto.938326560" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.242697771" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.553244928" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.2070537906" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compiler.includePath.1483355415" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/Qt"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.9625963" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.872099896" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<option id="com.qnx.qcc.option.compiler.qccoptions.1015003128" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
<listOptionValue builtIn="false" value="-frecord-gcc-switches"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.1443568066" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.1996828008" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<inputType id="com.qnx.qcc.inputType.assembler.116798417" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.871546588" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.shared.915102752" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.1049529253" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${QNX_TARGET}/${CPUVARDIR}/usr/lib&quot;"/>
<listOptionValue builtIn="false" value="&quot;${QNX_TARGET}/${CPUVARDIR}/usr/lib/qt4/lib&quot;"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.1157664997" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.1316432206" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.1028572887" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.1781914947" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091" moduleId="org.eclipse.cdt.core.settings" name="simulator">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Cordova-Toast"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Cordova-Toast/simulator"/>
<entry flags="RESOLVED" kind="libraryFile" name="Cordova-Toast" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091" name="simulator" parent="com.qnx.qcc.configuration.sharedLib.debug">
<folderInfo id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091." name="/" resourcePath="">
<toolChain id="com.qnx.qcc.toolChain.688026907" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.469207190" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
<builder buildPath="${workspace_loc:/Toast/Simulator-Debug}" id="com.qnx.nto.2029800497" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
<tool id="com.qnx.qcc.tool.compiler.1028279123" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
<option id="com.qnx.qcc.option.compiler.shared.235893159" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.optlevel.1164238904" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
<option id="com.qnx.qcc.option.compile.debug.3716470" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.includePath.306305432" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/Qt"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb/system"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
</option>
<option id="com.qnx.qcc.option.compiler.security.1730007887" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.compiler.defines.1526896965" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
</option>
<inputType id="com.qnx.qcc.inputType.compiler.1881183122" superClass="com.qnx.qcc.inputType.compiler"/>
</tool>
<tool id="com.qnx.qcc.tool.assembler.312168125" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
<option id="com.qnx.qcc.option.assembler.debug.416544277" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
<inputType id="com.qnx.qcc.inputType.assembler.1722778407" superClass="com.qnx.qcc.inputType.assembler"/>
</tool>
<tool id="com.qnx.qcc.tool.linker.2130364088" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
<option id="com.qnx.qcc.option.linker.debug.1332880614" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.shared.1633267255" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraryPaths.565794953" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${QNX_TARGET}/${CPUVARDIR}/usr/lib&quot;"/>
<listOptionValue builtIn="false" value="&quot;${QNX_TARGET}/${CPUVARDIR}/usr/lib/qt4/lib&quot;"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
</option>
<option id="com.qnx.qcc.option.linker.security.9141791" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
<option id="com.qnx.qcc.option.linker.libraries.220836649" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
<listOptionValue builtIn="false" value="slog2"/>
<listOptionValue builtIn="false" value="bbsystem"/>
<listOptionValue builtIn="false" value="QtCore"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.167117375" superClass="com.qnx.qcc.inputType.linker">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.qnx.qcc.tool.archiver.489682882" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="???PROJECT_NAME???.null.138005006" name="???PROJECT_NAME???"/>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="1">
<resource resourceType="PROJECT" workspacePath="/Toast"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.debug.1877214659">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.debug.193597202">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.coverage.1806890017">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.release.608922875">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.coverage.537092296">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.profile.941124085">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.profile.27502649">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Toast</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/Toast/Device-Release}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>
</natures>
</projectDescription>
#ifndef JSON_AUTOLINK_H_INCLUDED
# define JSON_AUTOLINK_H_INCLUDED
# include "config.h"
# ifdef JSON_IN_CPPTL
# include <cpptl/cpptl_autolink.h>
# endif
# if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && !defined(JSON_IN_CPPTL)
# define CPPTL_AUTOLINK_NAME "json"
# undef CPPTL_AUTOLINK_DLL
# ifdef JSON_DLL
# define CPPTL_AUTOLINK_DLL
# endif
# include "autolink.h"
# endif
#endif // JSON_AUTOLINK_H_INCLUDED
#ifndef JSON_CONFIG_H_INCLUDED
# define JSON_CONFIG_H_INCLUDED
/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
/// If defined, indicates that json may leverage CppTL library
//# define JSON_USE_CPPTL 1
/// If defined, indicates that cpptl vector based map should be used instead of std::map
/// as Value container.
//# define JSON_USE_CPPTL_SMALLMAP 1
/// If defined, indicates that Json specific container should be used
/// (hash table & simple deque container with customizable allocator).
/// THIS FEATURE IS STILL EXPERIMENTAL!
//# define JSON_VALUE_USE_INTERNAL_MAP 1
/// Force usage of standard new/malloc based allocator instead of memory pool based allocator.
/// The memory pools allocator used optimization (initializing Value and ValueInternalLink
/// as if it was a POD) that may cause some validation tool to report errors.
/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined.
//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1
/// If defined, indicates that Json use exception to report invalid type manipulation
/// instead of C assert macro.
# define JSON_USE_EXCEPTION 1
# ifdef JSON_IN_CPPTL
# include <cpptl/config.h>
# ifndef JSON_USE_CPPTL
# define JSON_USE_CPPTL 1
# endif
# endif
# ifdef JSON_IN_CPPTL
# define JSON_API CPPTL_API
# elif defined(JSON_DLL_BUILD)
# define JSON_API __declspec(dllexport)
# elif defined(JSON_DLL)
# define JSON_API __declspec(dllimport)
# else
# define JSON_API
# endif
#endif // JSON_CONFIG_H_INCLUDED
#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
# define CPPTL_JSON_FEATURES_H_INCLUDED
# include "forwards.h"
namespace Json {
/** \brief Configuration passed to reader and writer.
* This configuration object can be used to force the Reader or Writer
* to behave in a standard conforming way.
*/
class JSON_API Features
{
public:
/** \brief A configuration that allows all features and assumes all strings are UTF-8.
* - C & C++ comments are allowed
* - Root object can be any JSON value
* - Assumes Value strings are encoded in UTF-8
*/
static Features all();
/** \brief A configuration that is strictly compatible with the JSON specification.
* - Comments are forbidden.
* - Root object must be either an array or an object value.
* - Assumes Value strings are encoded in UTF-8
*/
static Features strictMode();
/** \brief Initialize the configuration like JsonConfig::allFeatures;
*/
Features();
/// \c true if comments are allowed. Default: \c true.
bool allowComments_;
/// \c true if root must be either an array or an object value. Default: \c false.
bool strictRoot_;
};
} // namespace Json
#endif // CPPTL_JSON_FEATURES_H_INCLUDED
#ifndef JSON_FORWARDS_H_INCLUDED
# define JSON_FORWARDS_H_INCLUDED
# include "config.h"
namespace Json {
// writer.h
class FastWriter;
class StyledWriter;
// reader.h
class Reader;
// features.h
class Features;
// value.h
typedef int Int;
typedef unsigned int UInt;
class StaticString;
class Path;
class PathArgument;
class Value;
class ValueIteratorBase;
class ValueIterator;
class ValueConstIterator;
#ifdef JSON_VALUE_USE_INTERNAL_MAP
class ValueAllocator;
class ValueMapAllocator;
class ValueInternalLink;
class ValueInternalArray;
class ValueInternalMap;
#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
} // namespace Json
#endif // JSON_FORWARDS_H_INCLUDED
#ifndef JSON_JSON_H_INCLUDED
# define JSON_JSON_H_INCLUDED
# include "autolink.h"
# include "value.h"
# include "reader.h"
# include "writer.h"
# include "features.h"
#endif // JSON_JSON_H_INCLUDED
#ifndef CPPTL_JSON_READER_H_INCLUDED
# define CPPTL_JSON_READER_H_INCLUDED
# include "features.h"
# include "value.h"
# include <deque>
# include <stack>
# include <string>
# include <iostream>
namespace Json {
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
*
*/
class JSON_API Reader
{
public:
typedef char Char;
typedef const Char *Location;
/** \brief Constructs a Reader allowing all features
* for parsing.
*/
Reader();
/** \brief Constructs a Reader allowing the specified feature set
* for parsing.
*/
Reader( const Features &features );
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
* \param document UTF-8 encoded string containing the document to read.
* \param root [out] Contains the root value of the document if it was
* successfully parsed.
* \param collectComments \c true to collect comment and allow writing them back during
* serialization, \c false to discard comments.
* This parameter is ignored if Features::allowComments_
* is \c false.
* \return \c true if the document was successfully parsed, \c false if an error occurred.
*/
bool parse( const std::string &document,
Value &root,
bool collectComments = true );
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
* \param document UTF-8 encoded string containing the document to read.
* \param root [out] Contains the root value of the document if it was
* successfully parsed.
* \param collectComments \c true to collect comment and allow writing them back during
* serialization, \c false to discard comments.
* This parameter is ignored if Features::allowComments_
* is \c false.
* \return \c true if the document was successfully parsed, \c false if an error occurred.
*/
bool parse( const char *beginDoc, const char *endDoc,
Value &root,
bool collectComments = true );
/// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&).
bool parse( std::istream &is,
Value &root,
bool collectComments = true );
/** \brief Returns a user friendly string that list errors in the parsed document.
* \return Formatted error message with the list of errors with their location in
* the parsed document. An empty string is returned if no error occurred
* during parsing.
*/
std::string getFormatedErrorMessages() const;
private:
enum TokenType
{
tokenEndOfStream = 0,
tokenObjectBegin,
tokenObjectEnd,
tokenArrayBegin,
tokenArrayEnd,
tokenString,
tokenNumber,
tokenTrue,
tokenFalse,
tokenNull,
tokenArraySeparator,
tokenMemberSeparator,
tokenComment,
tokenError
};
class Token
{
public:
TokenType type_;
Location start_;
Location end_;
};
class ErrorInfo
{
public:
Token token_;
std::string message_;
Location extra_;
};
typedef std::deque<ErrorInfo> Errors;
bool expectToken( TokenType type, Token &token, const char *message );
bool readToken( Token &token );
void skipSpaces();
bool match( Location pattern,
int patternLength );
bool readComment();
bool readCStyleComment();
bool readCppStyleComment();
bool readString();
void readNumber();
bool readValue();
bool readObject( Token &token );
bool readArray( Token &token );
bool decodeNumber( Token &token );
bool decodeString( Token &token );
bool decodeString( Token &token, std::string &decoded );
bool decodeDouble( Token &token );
bool decodeUnicodeCodePoint( Token &token,
Location &current,
Location end,
unsigned int &unicode );
bool decodeUnicodeEscapeSequence( Token &token,
Location &current,
Location end,
unsigned int &unicode );
bool addError( const std::string &message,
Token &token,
Location extra = 0 );
bool recoverFromError( TokenType skipUntilToken );
bool addErrorAndRecover( const std::string &message,
Token &token,
TokenType skipUntilToken );
void skipUntilSpace();
Value &currentValue();
Char getNextChar();
void getLocationLineAndColumn( Location location,
int &line,
int &column ) const;
std::string getLocationLineAndColumn( Location location ) const;
void addComment( Location begin,
Location end,
CommentPlacement placement );
void skipCommentTokens( Token &token );
typedef std::stack<Value *> Nodes;
Nodes nodes_;
Errors errors_;
std::string document_;
Location begin_;
Location end_;
Location current_;
Location lastValueEnd_;
Value *lastValue_;
std::string commentsBefore_;
Features features_;
bool collectComments_;
};
/** \brief Read from 'sin' into 'root'.
Always keep comments from the input JSON.
This can be used to read a file into a particular sub-object.
For example:
\code
Json::Value root;
cin >> root["dir"]["file"];
cout << root;
\endcode
Result:
\verbatim
{
"dir": {
"file": {
// The input stream JSON would be nested here.
}
}
}
\endverbatim
\throw std::exception on parse error.
\see Json::operator<<()
*/
std::istream& operator>>( std::istream&, Value& );
} // namespace Json
#endif // CPPTL_JSON_READER_H_INCLUDED
#ifndef CPPTL_JSON_H_INCLUDED
# define CPPTL_JSON_H_INCLUDED
# include "forwards.h"
# include <string>
# include <vector>
# ifndef JSON_USE_CPPTL_SMALLMAP
# include <map>
# else
# include <cpptl/smallmap.h>
# endif
# ifdef JSON_USE_CPPTL
# include <cpptl/forwards.h>
# endif
/** \brief JSON (JavaScript Object Notation).
*/
namespace Json {
/** \brief Type of the value held by a Value object.
*/
enum ValueType
{
nullValue = 0, ///< 'null' value
intValue, ///< signed integer value
uintValue, ///< unsigned integer value
realValue, ///< double value
stringValue, ///< UTF-8 string value
booleanValue, ///< bool value
arrayValue, ///< array value (ordered list)
objectValue ///< object value (collection of name/value pairs).
};
enum CommentPlacement
{
commentBefore = 0, ///< a comment placed on the line before a value
commentAfterOnSameLine, ///< a comment just after a value on the same line
commentAfter, ///< a comment on the line after a value (only make sense for root value)
numberOfCommentPlacement
};
//# ifdef JSON_USE_CPPTL
// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
//# endif
/** \brief Lightweight wrapper to tag static string.
*
* Value constructor and objectValue member assignement takes advantage of the
* StaticString and avoid the cost of string duplication when storing the
* string or the member name.
*
* Example of usage:
* \code
* Json::Value aValue( StaticString("some text") );
* Json::Value object;
* static const StaticString code("code");
* object[code] = 1234;
* \endcode
*/
class JSON_API StaticString
{
public:
explicit StaticString( const char *czstring )
: str_( czstring )
{
}
operator const char *() const
{
return str_;
}
const char *c_str() const
{
return str_;
}
private:
const char *str_;
};
/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
*
* This class is a discriminated union wrapper that can represents a:
* - signed integer [range: Value::minInt - Value::maxInt]
* - unsigned integer (range: 0 - Value::maxUInt)
* - double
* - UTF-8 string
* - boolean
* - 'null'
* - an ordered list of Value
* - collection of name/value pairs (javascript object)
*
* The type of the held value is represented by a #ValueType and
* can be obtained using type().
*
* values of an #objectValue or #arrayValue can be accessed using operator[]() methods.
* Non const methods will automatically create the a #nullValue element
* if it does not exist.
* The sequence of an #arrayValue will be automatically resize and initialized
* with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
*
* The get() methods can be used to obtanis default value in the case the required element
* does not exist.
*
* It is possible to iterate over the list of a #objectValue values using
* the getMemberNames() method.
*/
class JSON_API Value
{
friend class ValueIteratorBase;
# ifdef JSON_VALUE_USE_INTERNAL_MAP
friend class ValueInternalLink;
friend class ValueInternalMap;
# endif
public:
typedef std::vector<std::string> Members;
typedef ValueIterator iterator;
typedef ValueConstIterator const_iterator;
typedef Json::UInt UInt;
typedef Json::Int Int;
typedef UInt ArrayIndex;
static const Value null;
static const Int minInt;
static const Int maxInt;
static const UInt maxUInt;
private:
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
# ifndef JSON_VALUE_USE_INTERNAL_MAP
class CZString
{
public:
enum DuplicationPolicy
{
noDuplication = 0,
duplicate,
duplicateOnCopy
};
CZString( int index );
CZString( const char *cstr, DuplicationPolicy allocate );
CZString( const CZString &other );
~CZString();
CZString &operator =( const CZString &other );
bool operator<( const CZString &other ) const;
bool operator==( const CZString &other ) const;
int index() const;
const char *c_str() const;
bool isStaticString() const;
private:
void swap( CZString &other );
const char *cstr_;
int index_;
};
public:
# ifndef JSON_USE_CPPTL_SMALLMAP
typedef std::map<CZString, Value> ObjectValues;
# else
typedef CppTL::SmallMap<CZString, Value> ObjectValues;
# endif // ifndef JSON_USE_CPPTL_SMALLMAP
# endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
public:
/** \brief Create a default Value of the given type.
This is a very useful constructor.
To create an empty array, pass arrayValue.
To create an empty object, pass objectValue.
Another Value can then be set to this one by assignment.
This is useful since clear() and resize() will not alter types.
Examples:
\code
Json::Value null_value; // null
Json::Value arr_value(Json::arrayValue); // []
Json::Value obj_value(Json::objectValue); // {}
\endcode
*/
Value( ValueType type = nullValue );
Value( Int value );
Value( UInt value );
Value( double value );
Value( const char *value );
Value( const char *beginValue, const char *endValue );
/** \brief Constructs a value from a static string.
* Like other value string constructor but do not duplicate the string for
* internal storage. The given string must remain alive after the call to this
* constructor.
* Example of usage:
* \code
* Json::Value aValue( StaticString("some text") );
* \endcode
*/
Value( const StaticString &value );
Value( const std::string &value );
# ifdef JSON_USE_CPPTL
Value( const CppTL::ConstString &value );
# endif
Value( bool value );
Value( const Value &other );
~Value();
Value &operator=( const Value &other );
/// Swap values.
/// \note Currently, comments are intentionally not swapped, for
/// both logic and efficiency.
void swap( Value &other );
ValueType type() const;
bool operator <( const Value &other ) const;
bool operator <=( const Value &other ) const;
bool operator >=( const Value &other ) const;
bool operator >( const Value &other ) const;
bool operator ==( const Value &other ) const;
bool operator !=( const Value &other ) const;
int compare( const Value &other );
const char *asCString() const;
std::string asString() const;
# ifdef JSON_USE_CPPTL
CppTL::ConstString asConstString() const;
# endif
Int asInt() const;
UInt asUInt() const;
double asDouble() const;
bool asBool() const;
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isUInt() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
bool isConvertibleTo( ValueType other ) const;
/// Number of values in array or object
UInt size() const;
/// \brief Return true if empty array, empty object, or null;
/// otherwise, false.
bool empty() const;
/// Return isNull()
bool operator!() const;
/// Remove all object members and array elements.
/// \pre type() is arrayValue, objectValue, or nullValue
/// \post type() is unchanged
void clear();
/// Resize the array to size elements.
/// New elements are initialized to null.
/// May only be called on nullValue or arrayValue.
/// \pre type() is arrayValue or nullValue
/// \post type() is arrayValue
void resize( UInt size );
/// Access an array element (zero based index ).
/// If the array contains less than index element, then null value are inserted
/// in the array so that its size is index+1.
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
Value &operator[]( UInt index );
/// Access an array element (zero based index )
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
const Value &operator[]( UInt index ) const;
/// If the array contains at least index+1 elements, returns the element value,
/// otherwise returns defaultValue.
Value get( UInt index,
const Value &defaultValue ) const;
/// Return true if index < size().
bool isValidIndex( UInt index ) const;
/// \brief Append value to array at the end.
///
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value &append( const Value &value );
/// Access an object value by name, create a null member if it does not exist.
Value &operator[]( const char *key );
/// Access an object value by name, returns null if there is no member with that name.
const Value &operator[]( const char *key ) const;
/// Access an object value by name, create a null member if it does not exist.
Value &operator[]( const std::string &key );
/// Access an object value by name, returns null if there is no member with that name.
const Value &operator[]( const std::string &key ) const;
/** \brief Access an object value by name, create a null member if it does not exist.
* If the object as no entry for that name, then the member name used to store
* the new entry is not duplicated.
* Example of use:
* \code
* Json::Value object;
* static const StaticString code("code");
* object[code] = 1234;
* \endcode
*/
Value &operator[]( const StaticString &key );
# ifdef JSON_USE_CPPTL
/// Access an object value by name, create a null member if it does not exist.
Value &operator[]( const CppTL::ConstString &key );
/// Access an object value by name, returns null if there is no member with that name.
const Value &operator[]( const CppTL::ConstString &key ) const;
# endif
/// Return the member named key if it exist, defaultValue otherwise.
Value get( const char *key,
const Value &defaultValue ) const;
/// Return the member named key if it exist, defaultValue otherwise.
Value get( const std::string &key,
const Value &defaultValue ) const;
# ifdef JSON_USE_CPPTL
/// Return the member named key if it exist, defaultValue otherwise.
Value get( const CppTL::ConstString &key,
const Value &defaultValue ) const;
# endif
/// \brief Remove and return the named member.
///
/// Do nothing if it did not exist.
/// \return the removed Value, or null.
/// \pre type() is objectValue or nullValue
/// \post type() is unchanged
Value removeMember( const char* key );
/// Same as removeMember(const char*)
Value removeMember( const std::string &key );
/// Return true if the object has a member named key.
bool isMember( const char *key ) const;
/// Return true if the object has a member named key.
bool isMember( const std::string &key ) const;
# ifdef JSON_USE_CPPTL
/// Return true if the object has a member named key.
bool isMember( const CppTL::ConstString &key ) const;
# endif
/// \brief Return a list of the member names.
///
/// If null, return an empty list.
/// \pre type() is objectValue or nullValue
/// \post if type() was nullValue, it remains nullValue
Members getMemberNames() const;
//# ifdef JSON_USE_CPPTL
// EnumMemberNames enumMemberNames() const;
// EnumValues enumValues() const;
//# endif
/// Comments must be //... or /* ... */
void setComment( const char *comment,
CommentPlacement placement );
/// Comments must be //... or /* ... */
void setComment( const std::string &comment,
CommentPlacement placement );
bool hasComment( CommentPlacement placement ) const;
/// Include delimiters and embedded newlines.
std::string getComment( CommentPlacement placement ) const;
std::string toStyledString() const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
private:
Value &resolveReference( const char *key,
bool isStatic );
# ifdef JSON_VALUE_USE_INTERNAL_MAP
inline bool isItemAvailable() const
{
return itemIsUsed_ == 0;
}
inline void setItemUsed( bool isUsed = true )
{
itemIsUsed_ = isUsed ? 1 : 0;
}
inline bool isMemberNameStatic() const
{
return memberNameIsStatic_ == 0;
}
inline void setMemberNameIsStatic( bool isStatic )
{
memberNameIsStatic_ = isStatic ? 1 : 0;
}
# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
private:
struct CommentInfo
{
CommentInfo();
~CommentInfo();
void setComment( const char *text );
char *comment_;
};
//struct MemberNamesTransform
//{
// typedef const char *result_type;
// const char *operator()( const CZString &name ) const
// {
// return name.c_str();
// }
//};
union ValueHolder
{
Int int_;
UInt uint_;
double real_;
bool bool_;
char *string_;
# ifdef JSON_VALUE_USE_INTERNAL_MAP
ValueInternalArray *array_;
ValueInternalMap *map_;
#else
ObjectValues *map_;
# endif
} value_;
ValueType type_ : 8;
int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
# ifdef JSON_VALUE_USE_INTERNAL_MAP
unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
# endif
CommentInfo *comments_;
};
/** \brief Experimental and untested: represents an element of the "path" to access a node.
*/
class PathArgument
{
public:
friend class Path;
PathArgument();
PathArgument( UInt index );
PathArgument( const char *key );
PathArgument( const std::string &key );
private:
enum Kind
{
kindNone = 0,
kindIndex,
kindKey
};
std::string key_;
UInt index_;
Kind kind_;
};
/** \brief Experimental and untested: represents a "path" to access a node.
*
* Syntax:
* - "." => root node
* - ".[n]" => elements at index 'n' of root node (an array value)
* - ".name" => member named 'name' of root node (an object value)
* - ".name1.name2.name3"
* - ".[0][1][2].name1[3]"
* - ".%" => member name is provided as parameter
* - ".[%]" => index is provied as parameter
*/
class Path
{
public:
Path( const std::string &path,
const PathArgument &a1 = PathArgument(),
const PathArgument &a2 = PathArgument(),
const PathArgument &a3 = PathArgument(),
const PathArgument &a4 = PathArgument(),
const PathArgument &a5 = PathArgument() );
const Value &resolve( const Value &root ) const;
Value resolve( const Value &root,
const Value &defaultValue ) const;
/// Creates the "path" to access the specified node and returns a reference on the node.
Value &make( Value &root ) const;
private:
typedef std::vector<const PathArgument *> InArgs;
typedef std::vector<PathArgument> Args;
void makePath( const std::string &path,
const InArgs &in );
void addPathInArg( const std::string &path,
const InArgs &in,
InArgs::const_iterator &itInArg,
PathArgument::Kind kind );
void invalidPath( const std::string &path,
int location );
Args args_;
};
/** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
*
* - makeMemberName() and releaseMemberName() are called to respectively duplicate and
* free an Json::objectValue member name.
* - duplicateStringValue() and releaseStringValue() are called similarly to
* duplicate and free a Json::stringValue value.
*/
class ValueAllocator
{
public:
enum { unknown = (unsigned)-1 };
virtual ~ValueAllocator();
virtual char *makeMemberName( const char *memberName ) = 0;
virtual void releaseMemberName( char *memberName ) = 0;
virtual char *duplicateStringValue( const char *value,
unsigned int length = unknown ) = 0;
virtual void releaseStringValue( char *value ) = 0;
};
#ifdef JSON_VALUE_USE_INTERNAL_MAP
/** \brief Allocator to customize Value internal map.
* Below is an example of a simple implementation (default implementation actually
* use memory pool for speed).
* \code
class DefaultValueMapAllocator : public ValueMapAllocator
{
public: // overridden from ValueMapAllocator
virtual ValueInternalMap *newMap()
{
return new ValueInternalMap();
}
virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
{
return new ValueInternalMap( other );
}
virtual void destructMap( ValueInternalMap *map )
{
delete map;
}
virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
{
return new ValueInternalLink[size];
}
virtual void releaseMapBuckets( ValueInternalLink *links )
{
delete [] links;
}
virtual ValueInternalLink *allocateMapLink()
{
return new ValueInternalLink();
}
virtual void releaseMapLink( ValueInternalLink *link )
{
delete link;
}
};
* \endcode
*/
class JSON_API ValueMapAllocator
{
public:
virtual ~ValueMapAllocator();
virtual ValueInternalMap *newMap() = 0;
virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
virtual void destructMap( ValueInternalMap *map ) = 0;
virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
virtual ValueInternalLink *allocateMapLink() = 0;
virtual void releaseMapLink( ValueInternalLink *link ) = 0;
};
/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
* \internal previous_ & next_ allows for bidirectional traversal.
*/
class JSON_API ValueInternalLink
{
public:
enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
enum InternalFlags {
flagAvailable = 0,
flagUsed = 1
};
ValueInternalLink();
~ValueInternalLink();
Value items_[itemPerLink];
char *keys_[itemPerLink];
ValueInternalLink *previous_;
ValueInternalLink *next_;
};
/** \brief A linked page based hash-table implementation used internally by Value.
* \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
* list in each bucket to handle collision. There is an addional twist in that
* each node of the collision linked list is a page containing a fixed amount of
* value. This provides a better compromise between memory usage and speed.
*
* Each bucket is made up of a chained list of ValueInternalLink. The last
* link of a given bucket can be found in the 'previous_' field of the following bucket.
* The last link of the last bucket is stored in tailLink_ as it has no following bucket.
* Only the last link of a bucket may contains 'available' item. The last link always
* contains at least one element unless is it the bucket one very first link.
*/
class JSON_API ValueInternalMap
{
friend class ValueIteratorBase;
friend class Value;
public:
typedef unsigned int HashKey;
typedef unsigned int BucketIndex;
# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
struct IteratorState
{
IteratorState()
: map_(0)
, link_(0)
, itemIndex_(0)
, bucketIndex_(0)
{
}
ValueInternalMap *map_;
ValueInternalLink *link_;
BucketIndex itemIndex_;
BucketIndex bucketIndex_;
};
# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
ValueInternalMap();
ValueInternalMap( const ValueInternalMap &other );
ValueInternalMap &operator =( const ValueInternalMap &other );
~ValueInternalMap();
void swap( ValueInternalMap &other );
BucketIndex size() const;
void clear();
bool reserveDelta( BucketIndex growth );
bool reserve( BucketIndex newItemCount );
const Value *find( const char *key ) const;
Value *find( const char *key );
Value &resolveReference( const char *key,
bool isStatic );
void remove( const char *key );
void doActualRemove( ValueInternalLink *link,
BucketIndex index,
BucketIndex bucketIndex );
ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
Value &setNewItem( const char *key,
bool isStatic,
ValueInternalLink *link,
BucketIndex index );
Value &unsafeAdd( const char *key,
bool isStatic,
HashKey hashedKey );
HashKey hash( const char *key ) const;
int compare( const ValueInternalMap &other ) const;
private:
void makeBeginIterator( IteratorState &it ) const;
void makeEndIterator( IteratorState &it ) const;
static bool equals( const IteratorState &x, const IteratorState &other );
static void increment( IteratorState &iterator );
static void incrementBucket( IteratorState &iterator );
static void decrement( IteratorState &iterator );
static const char *key( const IteratorState &iterator );
static const char *key( const IteratorState &iterator, bool &isStatic );
static Value &value( const IteratorState &iterator );
static int distance( const IteratorState &x, const IteratorState &y );
private:
ValueInternalLink *buckets_;
ValueInternalLink *tailLink_;
BucketIndex bucketsSize_;
BucketIndex itemCount_;
};
/** \brief A simplified deque implementation used internally by Value.
* \internal
* It is based on a list of fixed "page", each page contains a fixed number of items.
* Instead of using a linked-list, a array of pointer is used for fast item look-up.
* Look-up for an element is as follow:
* - compute page index: pageIndex = itemIndex / itemsPerPage
* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
*
* Insertion is amortized constant time (only the array containing the index of pointers
* need to be reallocated when items are appended).
*/
class JSON_API ValueInternalArray
{
friend class Value;
friend class ValueIteratorBase;
public:
enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
typedef Value::ArrayIndex ArrayIndex;
typedef unsigned int PageIndex;
# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
struct IteratorState // Must be a POD
{
IteratorState()
: array_(0)
, currentPageIndex_(0)
, currentItemIndex_(0)
{
}
ValueInternalArray *array_;
Value **currentPageIndex_;
unsigned int currentItemIndex_;
};
# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
ValueInternalArray();
ValueInternalArray( const ValueInternalArray &other );
ValueInternalArray &operator =( const ValueInternalArray &other );
~ValueInternalArray();
void swap( ValueInternalArray &other );
void clear();
void resize( ArrayIndex newSize );
Value &resolveReference( ArrayIndex index );
Value *find( ArrayIndex index ) const;
ArrayIndex size() const;
int compare( const ValueInternalArray &other ) const;
private:
static bool equals( const IteratorState &x, const IteratorState &other );
static void increment( IteratorState &iterator );
static void decrement( IteratorState &iterator );
static Value &dereference( const IteratorState &iterator );
static Value &unsafeDereference( const IteratorState &iterator );
static int distance( const IteratorState &x, const IteratorState &y );
static ArrayIndex indexOf( const IteratorState &iterator );
void makeBeginIterator( IteratorState &it ) const;
void makeEndIterator( IteratorState &it ) const;
void makeIterator( IteratorState &it, ArrayIndex index ) const;
void makeIndexValid( ArrayIndex index );
Value **pages_;
ArrayIndex size_;
PageIndex pageCount_;
};
/** \brief Experimental: do not use. Allocator to customize Value internal array.
* Below is an example of a simple implementation (actual implementation use
* memory pool).
\code
class DefaultValueArrayAllocator : public ValueArrayAllocator
{
public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator()
{
}
virtual ValueInternalArray *newArray()
{
return new ValueInternalArray();
}
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
{
return new ValueInternalArray( other );
}
virtual void destruct( ValueInternalArray *array )
{
delete array;
}
virtual void reallocateArrayPageIndex( Value **&indexes,
ValueInternalArray::PageIndex &indexCount,
ValueInternalArray::PageIndex minNewIndexCount )
{
ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
if ( minNewIndexCount > newIndexCount )
newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
if ( !newIndexes )
throw std::bad_alloc();
indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes );
}
virtual void releaseArrayPageIndex( Value **indexes,
ValueInternalArray::PageIndex indexCount )
{
if ( indexes )
free( indexes );
}
virtual Value *allocateArrayPage()
{
return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
}
virtual void releaseArrayPage( Value *value )
{
if ( value )
free( value );
}
};
\endcode
*/
class JSON_API ValueArrayAllocator
{
public:
virtual ~ValueArrayAllocator();
virtual ValueInternalArray *newArray() = 0;
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
virtual void destructArray( ValueInternalArray *array ) = 0;
/** \brief Reallocate array page index.
* Reallocates an array of pointer on each page.
* \param indexes [input] pointer on the current index. May be \c NULL.
* [output] pointer on the new index of at least
* \a minNewIndexCount pages.
* \param indexCount [input] current number of pages in the index.
* [output] number of page the reallocated index can handle.
* \b MUST be >= \a minNewIndexCount.
* \param minNewIndexCount Minimum number of page the new index must be able to
* handle.
*/
virtual void reallocateArrayPageIndex( Value **&indexes,
ValueInternalArray::PageIndex &indexCount,
ValueInternalArray::PageIndex minNewIndexCount ) = 0;
virtual void releaseArrayPageIndex( Value **indexes,
ValueInternalArray::PageIndex indexCount ) = 0;
virtual Value *allocateArrayPage() = 0;
virtual void releaseArrayPage( Value *value ) = 0;
};
#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
/** \brief base class for Value iterators.
*
*/
class ValueIteratorBase
{
public:
typedef unsigned int size_t;
typedef int difference_type;
typedef ValueIteratorBase SelfType;
ValueIteratorBase();
#ifndef JSON_VALUE_USE_INTERNAL_MAP
explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
#else
ValueIteratorBase( const ValueInternalArray::IteratorState &state );
ValueIteratorBase( const ValueInternalMap::IteratorState &state );
#endif
bool operator ==( const SelfType &other ) const
{
return isEqual( other );
}
bool operator !=( const SelfType &other ) const
{
return !isEqual( other );
}
difference_type operator -( const SelfType &other ) const
{
return computeDistance( other );
}
/// Return either the index or the member name of the referenced value as a Value.
Value key() const;
/// Return the index of the referenced Value. -1 if it is not an arrayValue.
UInt index() const;
/// Return the member name of the referenced Value. "" if it is not an objectValue.
const char *memberName() const;
protected:
Value &deref() const;
void increment();
void decrement();
difference_type computeDistance( const SelfType &other ) const;
bool isEqual( const SelfType &other ) const;
void copy( const SelfType &other );
private:
#ifndef JSON_VALUE_USE_INTERNAL_MAP
Value::ObjectValues::iterator current_;
// Indicates that iterator is for a null value.
bool isNull_;
#else
union
{
ValueInternalArray::IteratorState array_;
ValueInternalMap::IteratorState map_;
} iterator_;
bool isArray_;
#endif
};
/** \brief const iterator for object and array value.
*
*/
class ValueConstIterator : public ValueIteratorBase
{
friend class Value;
public:
typedef unsigned int size_t;
typedef int difference_type;
typedef const Value &reference;
typedef const Value *pointer;
typedef ValueConstIterator SelfType;
ValueConstIterator();
private:
/*! \internal Use by Value to create an iterator.
*/
#ifndef JSON_VALUE_USE_INTERNAL_MAP
explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
#else
ValueConstIterator( const ValueInternalArray::IteratorState &state );
ValueConstIterator( const ValueInternalMap::IteratorState &state );
#endif
public:
SelfType &operator =( const ValueIteratorBase &other );
SelfType operator++( int )
{
SelfType temp( *this );
++*this;
return temp;
}
SelfType operator--( int )
{
SelfType temp( *this );
--*this;
return temp;
}
SelfType &operator--()
{
decrement();
return *this;
}
SelfType &operator++()
{
increment();
return *this;
}
reference operator *() const
{
return deref();
}
};
/** \brief Iterator for object and array value.
*/
class ValueIterator : public ValueIteratorBase
{
friend class Value;
public:
typedef unsigned int size_t;
typedef int difference_type;
typedef Value &reference;
typedef Value *pointer;
typedef ValueIterator SelfType;
ValueIterator();
ValueIterator( const ValueConstIterator &other );
ValueIterator( const ValueIterator &other );
private:
/*! \internal Use by Value to create an iterator.
*/
#ifndef JSON_VALUE_USE_INTERNAL_MAP
explicit ValueIterator( const Value::ObjectValues::iterator &current );
#else
ValueIterator( const ValueInternalArray::IteratorState &state );
ValueIterator( const ValueInternalMap::IteratorState &state );
#endif
public:
SelfType &operator =( const SelfType &other );
SelfType operator++( int )
{
SelfType temp( *this );
++*this;
return temp;
}
SelfType operator--( int )
{
SelfType temp( *this );
--*this;
return temp;
}
SelfType &operator--()
{
decrement();
return *this;
}
SelfType &operator++()
{
increment();
return *this;
}
reference operator *() const
{
return deref();
}
};
} // namespace Json
#endif // CPPTL_JSON_H_INCLUDED
#ifndef JSON_WRITER_H_INCLUDED
# define JSON_WRITER_H_INCLUDED
# include "value.h"
# include <vector>
# include <string>
# include <iostream>
namespace Json {
class Value;
/** \brief Abstract class for writers.
*/
class JSON_API Writer
{
public:
virtual ~Writer();
virtual std::string write( const Value &root ) = 0;
};
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format without formatting (not human friendly).
*
* The JSON document is written in a single line. It is not intended for 'human' consumption,
* but may be usefull to support feature such as RPC where bandwith is limited.
* \sa Reader, Value
*/
class JSON_API FastWriter : public Writer
{
public:
FastWriter();
virtual ~FastWriter(){}
void enableYAMLCompatibility();
public: // overridden from Writer
virtual std::string write( const Value &root );
private:
void writeValue( const Value &value );
std::string document_;
bool yamlCompatiblityEnabled_;
};
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way.
*
* The rules for line break and indent are as follow:
* - Object value:
* - if empty then print {} without indent and line break
* - if not empty the print '{', line break & indent, print one value per line
* and then unindent and line break and print '}'.
* - Array value:
* - if empty then print [] without indent and line break
* - if the array contains no object value, empty array or some other value types,
* and all the values fit on one lines, then print the array on a single line.
* - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line.
*
* If the Value have comments then they are outputed according to their #CommentPlacement.
*
* \sa Reader, Value, Value::setComment()
*/
class JSON_API StyledWriter: public Writer
{
public:
StyledWriter();
virtual ~StyledWriter(){}
public: // overridden from Writer
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
* \param root Value to serialize.
* \return String containing the JSON document that represents the root value.
*/
virtual std::string write( const Value &root );
private:
void writeValue( const Value &value );
void writeArrayValue( const Value &value );
bool isMultineArray( const Value &value );
void pushValue( const std::string &value );
void writeIndent();
void writeWithIndent( const std::string &value );
void indent();
void unindent();
void writeCommentBeforeValue( const Value &root );
void writeCommentAfterValueOnSameLine( const Value &root );
bool hasCommentForValue( const Value &value );
static std::string normalizeEOL( const std::string &text );
typedef std::vector<std::string> ChildValues;
ChildValues childValues_;
std::string document_;
std::string indentString_;
int rightMargin_;
int indentSize_;
bool addChildValues_;
};
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way,
to a stream rather than to a string.
*
* The rules for line break and indent are as follow:
* - Object value:
* - if empty then print {} without indent and line break
* - if not empty the print '{', line break & indent, print one value per line
* and then unindent and line break and print '}'.
* - Array value:
* - if empty then print [] without indent and line break
* - if the array contains no object value, empty array or some other value types,
* and all the values fit on one lines, then print the array on a single line.
* - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line.
*
* If the Value have comments then they are outputed according to their #CommentPlacement.
*
* \param indentation Each level will be indented by this amount extra.
* \sa Reader, Value, Value::setComment()
*/
class JSON_API StyledStreamWriter
{
public:
StyledStreamWriter( std::string indentation="\t" );
~StyledStreamWriter(){}
public:
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
* \param out Stream to write to. (Can be ostringstream, e.g.)
* \param root Value to serialize.
* \note There is no point in deriving from Writer, since write() should not return a value.
*/
void write( std::ostream &out, const Value &root );
private:
void writeValue( const Value &value );
void writeArrayValue( const Value &value );
bool isMultineArray( const Value &value );
void pushValue( const std::string &value );
void writeIndent();
void writeWithIndent( const std::string &value );
void indent();
void unindent();
void writeCommentBeforeValue( const Value &root );
void writeCommentAfterValueOnSameLine( const Value &root );
bool hasCommentForValue( const Value &value );
static std::string normalizeEOL( const std::string &text );
typedef std::vector<std::string> ChildValues;
ChildValues childValues_;
std::ostream* document_;
std::string indentString_;
int rightMargin_;
std::string indentation_;
bool addChildValues_;
};
std::string JSON_API valueToString( Int value );
std::string JSON_API valueToString( UInt value );
std::string JSON_API valueToString( double value );
std::string JSON_API valueToString( bool value );
std::string JSON_API valueToQuotedString( const char *value );
/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
std::ostream& operator<<( std::ostream&, const Value &root );
} // namespace Json
#endif // JSON_WRITER_H_INCLUDED
#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
# define JSONCPP_BATCHALLOCATOR_H_INCLUDED
# include <stdlib.h>
# include <assert.h>
# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
namespace Json {
/* Fast memory allocator.
*
* This memory allocator allocates memory for a batch of object (specified by
* the page size, the number of object in each page).
*
* It does not allow the destruction of a single object. All the allocated objects
* can be destroyed at once. The memory can be either released or reused for future
* allocation.
*
* The in-place new operator must be used to construct the object using the pointer
* returned by allocate.
*/
template<typename AllocatedType
,const unsigned int objectPerAllocation>
class BatchAllocator
{
public:
typedef AllocatedType Type;
BatchAllocator( unsigned int objectsPerPage = 255 )
: freeHead_( 0 )
, objectsPerPage_( objectsPerPage )
{
// printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
assert( objectsPerPage >= 16 );
batches_ = allocateBatch( 0 ); // allocated a dummy page
currentBatch_ = batches_;
}
~BatchAllocator()
{
for ( BatchInfo *batch = batches_; batch; )
{
BatchInfo *nextBatch = batch->next_;
free( batch );
batch = nextBatch;
}
}
/// allocate space for an array of objectPerAllocation object.
/// @warning it is the responsability of the caller to call objects constructors.
AllocatedType *allocate()
{
if ( freeHead_ ) // returns node from free list.
{
AllocatedType *object = freeHead_;
freeHead_ = *(AllocatedType **)object;
return object;
}
if ( currentBatch_->used_ == currentBatch_->end_ )
{
currentBatch_ = currentBatch_->next_;
while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
currentBatch_ = currentBatch_->next_;
if ( !currentBatch_ ) // no free batch found, allocate a new one
{
currentBatch_ = allocateBatch( objectsPerPage_ );
currentBatch_->next_ = batches_; // insert at the head of the list
batches_ = currentBatch_;
}
}
AllocatedType *allocated = currentBatch_->used_;
currentBatch_->used_ += objectPerAllocation;
return allocated;
}
/// Release the object.
/// @warning it is the responsability of the caller to actually destruct the object.
void release( AllocatedType *object )
{
assert( object != 0 );
*(AllocatedType **)object = freeHead_;
freeHead_ = object;
}
private:
struct BatchInfo
{
BatchInfo *next_;
AllocatedType *used_;
AllocatedType *end_;
AllocatedType buffer_[objectPerAllocation];
};
// disabled copy constructor and assignement operator.
BatchAllocator( const BatchAllocator & );
void operator =( const BatchAllocator &);
static BatchInfo *allocateBatch( unsigned int objectsPerPage )
{
const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
+ sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
batch->next_ = 0;
batch->used_ = batch->buffer_;
batch->end_ = batch->buffer_ + objectsPerPage;
return batch;
}
BatchInfo *batches_;
BatchInfo *currentBatch_;
/// Head of a single linked list within the allocated space of freeed object
AllocatedType *freeHead_;
unsigned int objectsPerPage_;
};
} // namespace Json
# endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
// included by json_value.cpp
// everything is within Json namespace
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class ValueInternalArray
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
ValueArrayAllocator::~ValueArrayAllocator()
{
}
// //////////////////////////////////////////////////////////////////
// class DefaultValueArrayAllocator
// //////////////////////////////////////////////////////////////////
#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
class DefaultValueArrayAllocator : public ValueArrayAllocator
{
public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator()
{
}
virtual ValueInternalArray *newArray()
{
return new ValueInternalArray();
}
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
{
return new ValueInternalArray( other );
}
virtual void destructArray( ValueInternalArray *array )
{
delete array;
}
virtual void reallocateArrayPageIndex( Value **&indexes,
ValueInternalArray::PageIndex &indexCount,
ValueInternalArray::PageIndex minNewIndexCount )
{
ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
if ( minNewIndexCount > newIndexCount )
newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
if ( !newIndexes )
throw std::bad_alloc();
indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes );
}
virtual void releaseArrayPageIndex( Value **indexes,
ValueInternalArray::PageIndex indexCount )
{
if ( indexes )
free( indexes );
}
virtual Value *allocateArrayPage()
{
return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
}
virtual void releaseArrayPage( Value *value )
{
if ( value )
free( value );
}
};
#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
/// @todo make this thread-safe (lock when accessign batch allocator)
class DefaultValueArrayAllocator : public ValueArrayAllocator
{
public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator()
{
}
virtual ValueInternalArray *newArray()
{
ValueInternalArray *array = arraysAllocator_.allocate();
new (array) ValueInternalArray(); // placement new
return array;
}
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
{
ValueInternalArray *array = arraysAllocator_.allocate();
new (array) ValueInternalArray( other ); // placement new
return array;
}
virtual void destructArray( ValueInternalArray *array )
{
if ( array )
{
array->~ValueInternalArray();
arraysAllocator_.release( array );
}
}
virtual void reallocateArrayPageIndex( Value **&indexes,
ValueInternalArray::PageIndex &indexCount,
ValueInternalArray::PageIndex minNewIndexCount )
{
ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
if ( minNewIndexCount > newIndexCount )
newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
if ( !newIndexes )
throw std::bad_alloc();
indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes );
}
virtual void releaseArrayPageIndex( Value **indexes,
ValueInternalArray::PageIndex indexCount )
{
if ( indexes )
free( indexes );
}
virtual Value *allocateArrayPage()
{
return static_cast<Value *>( pagesAllocator_.allocate() );
}
virtual void releaseArrayPage( Value *value )
{
if ( value )
pagesAllocator_.release( value );
}
private:
BatchAllocator<ValueInternalArray,1> arraysAllocator_;
BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_;
};
#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
static ValueArrayAllocator *&arrayAllocator()
{
static DefaultValueArrayAllocator defaultAllocator;
static ValueArrayAllocator *arrayAllocator = &defaultAllocator;
return arrayAllocator;
}
static struct DummyArrayAllocatorInitializer {
DummyArrayAllocatorInitializer()
{
arrayAllocator(); // ensure arrayAllocator() statics are initialized before main().
}
} dummyArrayAllocatorInitializer;
// //////////////////////////////////////////////////////////////////
// class ValueInternalArray
// //////////////////////////////////////////////////////////////////
bool
ValueInternalArray::equals( const IteratorState &x,
const IteratorState &other )
{
return x.array_ == other.array_
&& x.currentItemIndex_ == other.currentItemIndex_
&& x.currentPageIndex_ == other.currentPageIndex_;
}
void
ValueInternalArray::increment( IteratorState &it )
{
JSON_ASSERT_MESSAGE( it.array_ &&
(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
!= it.array_->size_,
"ValueInternalArray::increment(): moving iterator beyond end" );
++(it.currentItemIndex_);
if ( it.currentItemIndex_ == itemsPerPage )
{
it.currentItemIndex_ = 0;
++(it.currentPageIndex_);
}
}
void
ValueInternalArray::decrement( IteratorState &it )
{
JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_
&& it.currentItemIndex_ == 0,
"ValueInternalArray::decrement(): moving iterator beyond end" );
if ( it.currentItemIndex_ == 0 )
{
it.currentItemIndex_ = itemsPerPage-1;
--(it.currentPageIndex_);
}
else
{
--(it.currentItemIndex_);
}
}
Value &
ValueInternalArray::unsafeDereference( const IteratorState &it )
{
return (*(it.currentPageIndex_))[it.currentItemIndex_];
}
Value &
ValueInternalArray::dereference( const IteratorState &it )
{
JSON_ASSERT_MESSAGE( it.array_ &&
(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
< it.array_->size_,
"ValueInternalArray::dereference(): dereferencing invalid iterator" );
return unsafeDereference( it );
}
void
ValueInternalArray::makeBeginIterator( IteratorState &it ) const
{
it.array_ = const_cast<ValueInternalArray *>( this );
it.currentItemIndex_ = 0;
it.currentPageIndex_ = pages_;
}
void
ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const
{
it.array_ = const_cast<ValueInternalArray *>( this );
it.currentItemIndex_ = index % itemsPerPage;
it.currentPageIndex_ = pages_ + index / itemsPerPage;
}
void
ValueInternalArray::makeEndIterator( IteratorState &it ) const
{
makeIterator( it, size_ );
}
ValueInternalArray::ValueInternalArray()
: pages_( 0 )
, size_( 0 )
, pageCount_( 0 )
{
}
ValueInternalArray::ValueInternalArray( const ValueInternalArray &other )
: pages_( 0 )
, pageCount_( 0 )
, size_( other.size_ )
{
PageIndex minNewPages = other.size_ / itemsPerPage;
arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation" );
IteratorState itOther;
other.makeBeginIterator( itOther );
Value *value;
for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) )
{
if ( index % itemsPerPage == 0 )
{
PageIndex pageIndex = index / itemsPerPage;
value = arrayAllocator()->allocateArrayPage();
pages_[pageIndex] = value;
}
new (value) Value( dereference( itOther ) );
}
}
ValueInternalArray &
ValueInternalArray::operator =( const ValueInternalArray &other )
{
ValueInternalArray temp( other );
swap( temp );
return *this;
}
ValueInternalArray::~ValueInternalArray()
{
// destroy all constructed items
IteratorState it;
IteratorState itEnd;
makeBeginIterator( it);
makeEndIterator( itEnd );
for ( ; !equals(it,itEnd); increment(it) )
{
Value *value = &dereference(it);
value->~Value();
}
// release all pages
PageIndex lastPageIndex = size_ / itemsPerPage;
for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )
arrayAllocator()->releaseArrayPage( pages_[pageIndex] );
// release pages index
arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ );
}
void
ValueInternalArray::swap( ValueInternalArray &other )
{
Value **tempPages = pages_;
pages_ = other.pages_;
other.pages_ = tempPages;
ArrayIndex tempSize = size_;
size_ = other.size_;
other.size_ = tempSize;
PageIndex tempPageCount = pageCount_;
pageCount_ = other.pageCount_;
other.pageCount_ = tempPageCount;
}
void
ValueInternalArray::clear()
{
ValueInternalArray dummy;
swap( dummy );
}
void
ValueInternalArray::resize( ArrayIndex newSize )
{
if ( newSize == 0 )
clear();
else if ( newSize < size_ )
{
IteratorState it;
IteratorState itEnd;
makeIterator( it, newSize );
makeIterator( itEnd, size_ );
for ( ; !equals(it,itEnd); increment(it) )
{
Value *value = &dereference(it);
value->~Value();
}
PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;
PageIndex lastPageIndex = size_ / itemsPerPage;
for ( ; pageIndex < lastPageIndex; ++pageIndex )
arrayAllocator()->releaseArrayPage( pages_[pageIndex] );
size_ = newSize;
}
else if ( newSize > size_ )
resolveReference( newSize );
}
void
ValueInternalArray::makeIndexValid( ArrayIndex index )
{
// Need to enlarge page index ?
if ( index >= pageCount_ * itemsPerPage )
{
PageIndex minNewPages = (index + 1) / itemsPerPage;
arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" );
}
// Need to allocate new pages ?
ArrayIndex nextPageIndex =
(size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage
: size_;
if ( nextPageIndex <= index )
{
PageIndex pageIndex = nextPageIndex / itemsPerPage;
PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
for ( ; pageToAllocate-- > 0; ++pageIndex )
pages_[pageIndex] = arrayAllocator()->allocateArrayPage();
}
// Initialize all new entries
IteratorState it;
IteratorState itEnd;
makeIterator( it, size_ );
size_ = index + 1;
makeIterator( itEnd, size_ );
for ( ; !equals(it,itEnd); increment(it) )
{
Value *value = &dereference(it);
new (value) Value(); // Construct a default value using placement new
}
}
Value &
ValueInternalArray::resolveReference( ArrayIndex index )
{
if ( index >= size_ )
makeIndexValid( index );
return pages_[index/itemsPerPage][index%itemsPerPage];
}
Value *
ValueInternalArray::find( ArrayIndex index ) const
{
if ( index >= size_ )
return 0;
return &(pages_[index/itemsPerPage][index%itemsPerPage]);
}
ValueInternalArray::ArrayIndex
ValueInternalArray::size() const
{
return size_;
}
int
ValueInternalArray::distance( const IteratorState &x, const IteratorState &y )
{
return indexOf(y) - indexOf(x);
}
ValueInternalArray::ArrayIndex
ValueInternalArray::indexOf( const IteratorState &iterator )
{
if ( !iterator.array_ )
return ArrayIndex(-1);
return ArrayIndex(
(iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage
+ iterator.currentItemIndex_ );
}
int
ValueInternalArray::compare( const ValueInternalArray &other ) const
{
int sizeDiff( size_ - other.size_ );
if ( sizeDiff != 0 )
return sizeDiff;
for ( ArrayIndex index =0; index < size_; ++index )
{
int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare(
other.pages_[index/itemsPerPage][index%itemsPerPage] );
if ( diff != 0 )
return diff;
}
return 0;
}
// included by json_value.cpp
// everything is within Json namespace
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class ValueInternalMap
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
/** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) );
* This optimization is used by the fast allocator.
*/
ValueInternalLink::ValueInternalLink()
: previous_( 0 )
, next_( 0 )
{
}
ValueInternalLink::~ValueInternalLink()
{
for ( int index =0; index < itemPerLink; ++index )
{
if ( !items_[index].isItemAvailable() )
{
if ( !items_[index].isMemberNameStatic() )
free( keys_[index] );
}
else
break;
}
}
ValueMapAllocator::~ValueMapAllocator()
{
}
#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
class DefaultValueMapAllocator : public ValueMapAllocator
{
public: // overridden from ValueMapAllocator
virtual ValueInternalMap *newMap()
{
return new ValueInternalMap();
}
virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
{
return new ValueInternalMap( other );
}
virtual void destructMap( ValueInternalMap *map )
{
delete map;
}
virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
{
return new ValueInternalLink[size];
}
virtual void releaseMapBuckets( ValueInternalLink *links )
{
delete [] links;
}
virtual ValueInternalLink *allocateMapLink()
{
return new ValueInternalLink();
}
virtual void releaseMapLink( ValueInternalLink *link )
{
delete link;
}
};
#else
/// @todo make this thread-safe (lock when accessign batch allocator)
class DefaultValueMapAllocator : public ValueMapAllocator
{
public: // overridden from ValueMapAllocator
virtual ValueInternalMap *newMap()
{
ValueInternalMap *map = mapsAllocator_.allocate();
new (map) ValueInternalMap(); // placement new
return map;
}
virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
{
ValueInternalMap *map = mapsAllocator_.allocate();
new (map) ValueInternalMap( other ); // placement new
return map;
}
virtual void destructMap( ValueInternalMap *map )
{
if ( map )
{
map->~ValueInternalMap();
mapsAllocator_.release( map );
}
}
virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
{
return new ValueInternalLink[size];
}
virtual void releaseMapBuckets( ValueInternalLink *links )
{
delete [] links;
}
virtual ValueInternalLink *allocateMapLink()
{
ValueInternalLink *link = linksAllocator_.allocate();
memset( link, 0, sizeof(ValueInternalLink) );
return link;
}
virtual void releaseMapLink( ValueInternalLink *link )
{
link->~ValueInternalLink();
linksAllocator_.release( link );
}
private:
BatchAllocator<ValueInternalMap,1> mapsAllocator_;
BatchAllocator<ValueInternalLink,1> linksAllocator_;
};
#endif
static ValueMapAllocator *&mapAllocator()
{
static DefaultValueMapAllocator defaultAllocator;
static ValueMapAllocator *mapAllocator = &defaultAllocator;
return mapAllocator;
}
static struct DummyMapAllocatorInitializer {
DummyMapAllocatorInitializer()
{
mapAllocator(); // ensure mapAllocator() statics are initialized before main().
}
} dummyMapAllocatorInitializer;
// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32.
/*
use linked list hash map.
buckets array is a container.
linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124)
value have extra state: valid, available, deleted
*/
ValueInternalMap::ValueInternalMap()
: buckets_( 0 )
, tailLink_( 0 )
, bucketsSize_( 0 )
, itemCount_( 0 )
{
}
ValueInternalMap::ValueInternalMap( const ValueInternalMap &other )
: buckets_( 0 )
, tailLink_( 0 )
, bucketsSize_( 0 )
, itemCount_( 0 )
{
reserve( other.itemCount_ );
IteratorState it;
IteratorState itEnd;
other.makeBeginIterator( it );
other.makeEndIterator( itEnd );
for ( ; !equals(it,itEnd); increment(it) )
{
bool isStatic;
const char *memberName = key( it, isStatic );
const Value &aValue = value( it );
resolveReference(memberName, isStatic) = aValue;
}
}
ValueInternalMap &
ValueInternalMap::operator =( const ValueInternalMap &other )
{
ValueInternalMap dummy( other );
swap( dummy );
return *this;
}
ValueInternalMap::~ValueInternalMap()
{
if ( buckets_ )
{
for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex )
{
ValueInternalLink *link = buckets_[bucketIndex].next_;
while ( link )
{
ValueInternalLink *linkToRelease = link;
link = link->next_;
mapAllocator()->releaseMapLink( linkToRelease );
}
}
mapAllocator()->releaseMapBuckets( buckets_ );
}
}
void
ValueInternalMap::swap( ValueInternalMap &other )
{
ValueInternalLink *tempBuckets = buckets_;
buckets_ = other.buckets_;
other.buckets_ = tempBuckets;
ValueInternalLink *tempTailLink = tailLink_;
tailLink_ = other.tailLink_;
other.tailLink_ = tempTailLink;
BucketIndex tempBucketsSize = bucketsSize_;
bucketsSize_ = other.bucketsSize_;
other.bucketsSize_ = tempBucketsSize;
BucketIndex tempItemCount = itemCount_;
itemCount_ = other.itemCount_;
other.itemCount_ = tempItemCount;
}
void
ValueInternalMap::clear()
{
ValueInternalMap dummy;
swap( dummy );
}
ValueInternalMap::BucketIndex
ValueInternalMap::size() const
{
return itemCount_;
}
bool
ValueInternalMap::reserveDelta( BucketIndex growth )
{
return reserve( itemCount_ + growth );
}
bool
ValueInternalMap::reserve( BucketIndex newItemCount )
{
if ( !buckets_ && newItemCount > 0 )
{
buckets_ = mapAllocator()->allocateMapBuckets( 1 );
bucketsSize_ = 1;
tailLink_ = &buckets_[0];
}
// BucketIndex idealBucketCount = (newItemCount + ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink;
return true;
}
const Value *
ValueInternalMap::find( const char *key ) const
{
if ( !bucketsSize_ )
return 0;
HashKey hashedKey = hash( key );
BucketIndex bucketIndex = hashedKey % bucketsSize_;
for ( const ValueInternalLink *current = &buckets_[bucketIndex];
current != 0;
current = current->next_ )
{
for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index )
{
if ( current->items_[index].isItemAvailable() )
return 0;
if ( strcmp( key, current->keys_[index] ) == 0 )
return &current->items_[index];
}
}
return 0;
}
Value *
ValueInternalMap::find( const char *key )
{
const ValueInternalMap *constThis = this;
return const_cast<Value *>( constThis->find( key ) );
}
Value &
ValueInternalMap::resolveReference( const char *key,
bool isStatic )
{
HashKey hashedKey = hash( key );
if ( bucketsSize_ )
{
BucketIndex bucketIndex = hashedKey % bucketsSize_;
ValueInternalLink **previous = 0;
BucketIndex index;
for ( ValueInternalLink *current = &buckets_[bucketIndex];
current != 0;
previous = &current->next_, current = current->next_ )
{
for ( index=0; index < ValueInternalLink::itemPerLink; ++index )
{
if ( current->items_[index].isItemAvailable() )
return setNewItem( key, isStatic, current, index );
if ( strcmp( key, current->keys_[index] ) == 0 )
return current->items_[index];
}
}
}
reserveDelta( 1 );
return unsafeAdd( key, isStatic, hashedKey );
}
void
ValueInternalMap::remove( const char *key )
{
HashKey hashedKey = hash( key );
if ( !bucketsSize_ )
return;
BucketIndex bucketIndex = hashedKey % bucketsSize_;
for ( ValueInternalLink *link = &buckets_[bucketIndex];
link != 0;
link = link->next_ )
{
BucketIndex index;
for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
{
if ( link->items_[index].isItemAvailable() )
return;
if ( strcmp( key, link->keys_[index] ) == 0 )
{
doActualRemove( link, index, bucketIndex );
return;
}
}
}
}
void
ValueInternalMap::doActualRemove( ValueInternalLink *link,
BucketIndex index,
BucketIndex bucketIndex )
{
// find last item of the bucket and swap it with the 'removed' one.
// set removed items flags to 'available'.
// if last page only contains 'available' items, then desallocate it (it's empty)
ValueInternalLink *&lastLink = getLastLinkInBucket( index );
BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1
for ( ;
lastItemIndex < ValueInternalLink::itemPerLink;
++lastItemIndex ) // may be optimized with dicotomic search
{
if ( lastLink->items_[lastItemIndex].isItemAvailable() )
break;
}
BucketIndex lastUsedIndex = lastItemIndex - 1;
Value *valueToDelete = &link->items_[index];
Value *valueToPreserve = &lastLink->items_[lastUsedIndex];
if ( valueToDelete != valueToPreserve )
valueToDelete->swap( *valueToPreserve );
if ( lastUsedIndex == 0 ) // page is now empty
{ // remove it from bucket linked list and delete it.
ValueInternalLink *linkPreviousToLast = lastLink->previous_;
if ( linkPreviousToLast != 0 ) // can not deleted bucket link.
{
mapAllocator()->releaseMapLink( lastLink );
linkPreviousToLast->next_ = 0;
lastLink = linkPreviousToLast;
}
}
else
{
Value dummy;
valueToPreserve->swap( dummy ); // restore deleted to default Value.
valueToPreserve->setItemUsed( false );
}
--itemCount_;
}
ValueInternalLink *&
ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex )
{
if ( bucketIndex == bucketsSize_ - 1 )
return tailLink_;
ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_;
if ( !previous )
previous = &buckets_[bucketIndex];
return previous;
}
Value &
ValueInternalMap::setNewItem( const char *key,
bool isStatic,
ValueInternalLink *link,
BucketIndex index )
{
char *duplicatedKey = valueAllocator()->makeMemberName( key );
++itemCount_;
link->keys_[index] = duplicatedKey;
link->items_[index].setItemUsed();
link->items_[index].setMemberNameIsStatic( isStatic );
return link->items_[index]; // items already default constructed.
}
Value &
ValueInternalMap::unsafeAdd( const char *key,
bool isStatic,
HashKey hashedKey )
{
JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." );
BucketIndex bucketIndex = hashedKey % bucketsSize_;
ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex );
ValueInternalLink *link = previousLink;
BucketIndex index;
for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
{
if ( link->items_[index].isItemAvailable() )
break;
}
if ( index == ValueInternalLink::itemPerLink ) // need to add a new page
{
ValueInternalLink *newLink = mapAllocator()->allocateMapLink();
index = 0;
link->next_ = newLink;
previousLink = newLink;
link = newLink;
}
return setNewItem( key, isStatic, link, index );
}
ValueInternalMap::HashKey
ValueInternalMap::hash( const char *key ) const
{
HashKey hash = 0;
while ( *key )
hash += *key++ * 37;
return hash;
}
int
ValueInternalMap::compare( const ValueInternalMap &other ) const
{
int sizeDiff( itemCount_ - other.itemCount_ );
if ( sizeDiff != 0 )
return sizeDiff;
// Strict order guaranty is required. Compare all keys FIRST, then compare values.
IteratorState it;
IteratorState itEnd;
makeBeginIterator( it );
makeEndIterator( itEnd );
for ( ; !equals(it,itEnd); increment(it) )
{
if ( !other.find( key( it ) ) )
return 1;
}
// All keys are equals, let's compare values
makeBeginIterator( it );
for ( ; !equals(it,itEnd); increment(it) )
{
const Value *otherValue = other.find( key( it ) );
int valueDiff = value(it).compare( *otherValue );
if ( valueDiff != 0 )
return valueDiff;
}
return 0;
}
void
ValueInternalMap::makeBeginIterator( IteratorState &it ) const
{
it.map_ = const_cast<ValueInternalMap *>( this );
it.bucketIndex_ = 0;
it.itemIndex_ = 0;
it.link_ = buckets_;
}
void
ValueInternalMap::makeEndIterator( IteratorState &it ) const
{
it.map_ = const_cast<ValueInternalMap *>( this );
it.bucketIndex_ = bucketsSize_;
it.itemIndex_ = 0;
it.link_ = 0;
}
bool
ValueInternalMap::equals( const IteratorState &x, const IteratorState &other )
{
return x.map_ == other.map_
&& x.bucketIndex_ == other.bucketIndex_
&& x.link_ == other.link_
&& x.itemIndex_ == other.itemIndex_;
}
void
ValueInternalMap::incrementBucket( IteratorState &iterator )
{
++iterator.bucketIndex_;
JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_,
"ValueInternalMap::increment(): attempting to iterate beyond end." );
if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ )
iterator.link_ = 0;
else
iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
iterator.itemIndex_ = 0;
}
void
ValueInternalMap::increment( IteratorState &iterator )
{
JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." );
++iterator.itemIndex_;
if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink )
{
JSON_ASSERT_MESSAGE( iterator.link_ != 0,
"ValueInternalMap::increment(): attempting to iterate beyond end." );
iterator.link_ = iterator.link_->next_;
if ( iterator.link_ == 0 )
incrementBucket( iterator );
}
else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() )
{
incrementBucket( iterator );
}
}
void
ValueInternalMap::decrement( IteratorState &iterator )
{
if ( iterator.itemIndex_ == 0 )
{
JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." );
if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] )
{
JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." );
--(iterator.bucketIndex_);
}
iterator.link_ = iterator.link_->previous_;
iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1;
}
}
const char *
ValueInternalMap::key( const IteratorState &iterator )
{
JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
return iterator.link_->keys_[iterator.itemIndex_];
}
const char *
ValueInternalMap::key( const IteratorState &iterator, bool &isStatic )
{
JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
return iterator.link_->keys_[iterator.itemIndex_];
}
Value &
ValueInternalMap::value( const IteratorState &iterator )
{
JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
return iterator.link_->items_[iterator.itemIndex_];
}
int
ValueInternalMap::distance( const IteratorState &x, const IteratorState &y )
{
int offset = 0;
IteratorState it = x;
while ( !equals( it, y ) )
increment( it );
return offset;
}
#include <json/reader.h>
#include <json/value.h>
#include <utility>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <stdexcept>
#if _MSC_VER >= 1400 // VC++ 8.0
#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
#endif
namespace Json {
// QNX is strict about declaring C symbols in the std namespace.
#ifdef __QNXNTO__
using std::memcpy;
using std::sprintf;
using std::sscanf;
#endif
// Implementation of class Features
// ////////////////////////////////
Features::Features()
: allowComments_( true )
, strictRoot_( false )
{
}
Features
Features::all()
{
return Features();
}
Features
Features::strictMode()
{
Features features;
features.allowComments_ = false;
features.strictRoot_ = true;
return features;
}
// Implementation of class Reader
// ////////////////////////////////
static inline bool
in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4 )
{
return c == c1 || c == c2 || c == c3 || c == c4;
}
static inline bool
in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4, Reader::Char c5 )
{
return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
}
static bool
containsNewLine( Reader::Location begin,
Reader::Location end )
{
for ( ;begin < end; ++begin )
if ( *begin == '\n' || *begin == '\r' )
return true;
return false;
}
static std::string codePointToUTF8(unsigned int cp)
{
std::string result;
// based on description from http://en.wikipedia.org/wiki/UTF-8
if (cp <= 0x7f)
{
result.resize(1);
result[0] = static_cast<char>(cp);
}
else if (cp <= 0x7FF)
{
result.resize(2);
result[1] = static_cast<char>(0x80 | (0x3f & cp));
result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
}
else if (cp <= 0xFFFF)
{
result.resize(3);
result[2] = static_cast<char>(0x80 | (0x3f & cp));
result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
}
else if (cp <= 0x10FFFF)
{
result.resize(4);
result[3] = static_cast<char>(0x80 | (0x3f & cp));
result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
}
return result;
}
// Class Reader
// //////////////////////////////////////////////////////////////////
Reader::Reader()
: features_( Features::all() )
{
}
Reader::Reader( const Features &features )
: features_( features )
{
}
bool
Reader::parse( const std::string &document,
Value &root,
bool collectComments )
{
document_ = document;
const char *begin = document_.c_str();
const char *end = begin + document_.length();
return parse( begin, end, root, collectComments );
}
bool
Reader::parse( std::istream& sin,
Value &root,
bool collectComments )
{
//std::istream_iterator<char> begin(sin);
//std::istream_iterator<char> end;
// Those would allow streamed input from a file, if parse() were a
// template function.
// Since std::string is reference-counted, this at least does not
// create an extra copy.
std::string doc;
std::getline(sin, doc, (char)EOF);
return parse( doc, root, collectComments );
}
bool
Reader::parse( const char *beginDoc, const char *endDoc,
Value &root,
bool collectComments )
{
if ( !features_.allowComments_ )
{
collectComments = false;
}
begin_ = beginDoc;
end_ = endDoc;
collectComments_ = collectComments;
current_ = begin_;
lastValueEnd_ = 0;
lastValue_ = 0;
commentsBefore_ = "";
errors_.clear();
while ( !nodes_.empty() )
nodes_.pop();
nodes_.push( &root );
bool successful = readValue();
Token token;
skipCommentTokens( token );
if ( collectComments_ && !commentsBefore_.empty() )
root.setComment( commentsBefore_, commentAfter );
if ( features_.strictRoot_ )
{
if ( !root.isArray() && !root.isObject() )
{
// Set error location to start of doc, ideally should be first token found in doc
token.type_ = tokenError;
token.start_ = beginDoc;
token.end_ = endDoc;
addError( "A valid JSON document must be either an array or an object value.",
token );
return false;
}
}
return successful;
}
bool
Reader::readValue()
{
Token token;
skipCommentTokens( token );
bool successful = true;
if ( collectComments_ && !commentsBefore_.empty() )
{
currentValue().setComment( commentsBefore_, commentBefore );
commentsBefore_ = "";
}
switch ( token.type_ )
{
case tokenObjectBegin:
successful = readObject( token );
break;
case tokenArrayBegin:
successful = readArray( token );
break;
case tokenNumber:
successful = decodeNumber( token );
break;
case tokenString:
successful = decodeString( token );
break;
case tokenTrue:
currentValue() = true;
break;
case tokenFalse:
currentValue() = false;
break;
case tokenNull:
currentValue() = Value();
break;
default:
return addError( "Syntax error: value, object or array expected.", token );
}
if ( collectComments_ )
{
lastValueEnd_ = current_;
lastValue_ = &currentValue();
}
return successful;
}
void
Reader::skipCommentTokens( Token &token )
{
if ( features_.allowComments_ )
{
do
{
readToken( token );
}
while ( token.type_ == tokenComment );
}
else
{
readToken( token );
}
}
bool
Reader::expectToken( TokenType type, Token &token, const char *message )
{
readToken( token );
if ( token.type_ != type )
return addError( message, token );
return true;
}
bool
Reader::readToken( Token &token )
{
skipSpaces();
token.start_ = current_;
Char c = getNextChar();
bool ok = true;
switch ( c )
{
case '{':
token.type_ = tokenObjectBegin;
break;
case '}':
token.type_ = tokenObjectEnd;
break;
case '[':
token.type_ = tokenArrayBegin;
break;
case ']':
token.type_ = tokenArrayEnd;
break;
case '"':
token.type_ = tokenString;
ok = readString();
break;
case '/':
token.type_ = tokenComment;
ok = readComment();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
token.type_ = tokenNumber;
readNumber();
break;
case 't':
token.type_ = tokenTrue;
ok = match( "rue", 3 );
break;
case 'f':
token.type_ = tokenFalse;
ok = match( "alse", 4 );
break;
case 'n':
token.type_ = tokenNull;
ok = match( "ull", 3 );
break;
case ',':
token.type_ = tokenArraySeparator;
break;
case ':':
token.type_ = tokenMemberSeparator;
break;
case 0:
token.type_ = tokenEndOfStream;
break;
default:
ok = false;
break;
}
if ( !ok )
token.type_ = tokenError;
token.end_ = current_;
return true;
}
void
Reader::skipSpaces()
{
while ( current_ != end_ )
{
Char c = *current_;
if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' )
++current_;
else
break;
}
}
bool
Reader::match( Location pattern,
int patternLength )
{
if ( end_ - current_ < patternLength )
return false;
int index = patternLength;
while ( index-- )
if ( current_[index] != pattern[index] )
return false;
current_ += patternLength;
return true;
}
bool
Reader::readComment()
{
Location commentBegin = current_ - 1;
Char c = getNextChar();
bool successful = false;
if ( c == '*' )
successful = readCStyleComment();
else if ( c == '/' )
successful = readCppStyleComment();
if ( !successful )
return false;
if ( collectComments_ )
{
CommentPlacement placement = commentBefore;
if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) )
{
if ( c != '*' || !containsNewLine( commentBegin, current_ ) )
placement = commentAfterOnSameLine;
}
addComment( commentBegin, current_, placement );
}
return true;
}
void
Reader::addComment( Location begin,
Location end,
CommentPlacement placement )
{
assert( collectComments_ );
if ( placement == commentAfterOnSameLine )
{
assert( lastValue_ != 0 );
lastValue_->setComment( std::string( begin, end ), placement );
}
else
{
if ( !commentsBefore_.empty() )
commentsBefore_ += "\n";
commentsBefore_ += std::string( begin, end );
}
}
bool
Reader::readCStyleComment()
{
while ( current_ != end_ )
{
Char c = getNextChar();
if ( c == '*' && *current_ == '/' )
break;
}
return getNextChar() == '/';
}
bool
Reader::readCppStyleComment()
{
while ( current_ != end_ )
{
Char c = getNextChar();
if ( c == '\r' || c == '\n' )
break;
}
return true;
}
void
Reader::readNumber()
{
while ( current_ != end_ )
{
if ( !(*current_ >= '0' && *current_ <= '9') &&
!in( *current_, '.', 'e', 'E', '+', '-' ) )
break;
++current_;
}
}
bool
Reader::readString()
{
Char c = 0;
while ( current_ != end_ )
{
c = getNextChar();
if ( c == '\\' )
getNextChar();
else if ( c == '"' )
break;
}
return c == '"';
}
bool
Reader::readObject( Token &tokenStart )
{
Token tokenName;
std::string name;
currentValue() = Value( objectValue );
while ( readToken( tokenName ) )
{
bool initialTokenOk = true;
while ( tokenName.type_ == tokenComment && initialTokenOk )
initialTokenOk = readToken( tokenName );
if ( !initialTokenOk )
break;
if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object
return true;
if ( tokenName.type_ != tokenString )
break;
name = "";
if ( !decodeString( tokenName, name ) )
return recoverFromError( tokenObjectEnd );
Token colon;
if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
{
return addErrorAndRecover( "Missing ':' after object member name",
colon,
tokenObjectEnd );
}
Value &value = currentValue()[ name ];
nodes_.push( &value );
bool ok = readValue();
nodes_.pop();
if ( !ok ) // error already set
return recoverFromError( tokenObjectEnd );
Token comma;
if ( !readToken( comma )
|| ( comma.type_ != tokenObjectEnd &&
comma.type_ != tokenArraySeparator &&
comma.type_ != tokenComment ) )
{
return addErrorAndRecover( "Missing ',' or '}' in object declaration",
comma,
tokenObjectEnd );
}
bool finalizeTokenOk = true;
while ( comma.type_ == tokenComment &&
finalizeTokenOk )
finalizeTokenOk = readToken( comma );
if ( comma.type_ == tokenObjectEnd )
return true;
}
return addErrorAndRecover( "Missing '}' or object member name",
tokenName,
tokenObjectEnd );
}
bool
Reader::readArray( Token &tokenStart )
{
currentValue() = Value( arrayValue );
skipSpaces();
if ( *current_ == ']' ) // empty array
{
Token endArray;
readToken( endArray );
return true;
}
int index = 0;
while ( true )
{
Value &value = currentValue()[ index++ ];
nodes_.push( &value );
bool ok = readValue();
nodes_.pop();
if ( !ok ) // error already set
return recoverFromError( tokenArrayEnd );
Token token;
// Accept Comment after last item in the array.
ok = readToken( token );
while ( token.type_ == tokenComment && ok )
{
ok = readToken( token );
}
bool badTokenType = ( token.type_ == tokenArraySeparator &&
token.type_ == tokenArrayEnd );
if ( !ok || badTokenType )
{
return addErrorAndRecover( "Missing ',' or ']' in array declaration",
token,
tokenArrayEnd );
}
if ( token.type_ == tokenArrayEnd )
break;
}
return true;
}
bool
Reader::decodeNumber( Token &token )
{
bool isDouble = false;
for ( Location inspect = token.start_; inspect != token.end_; ++inspect )
{
isDouble = isDouble
|| in( *inspect, '.', 'e', 'E', '+' )
|| ( *inspect == '-' && inspect != token.start_ );
}
if ( isDouble )
return decodeDouble( token );
Location current = token.start_;
bool isNegative = *current == '-';
if ( isNegative )
++current;
Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt)
: Value::maxUInt) / 10;
Value::UInt value = 0;
while ( current < token.end_ )
{
Char c = *current++;
if ( c < '0' || c > '9' )
return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
if ( value >= threshold )
return decodeDouble( token );
value = value * 10 + Value::UInt(c - '0');
}
if ( isNegative )
currentValue() = -Value::Int( value );
else if ( value <= Value::UInt(Value::maxInt) )
currentValue() = Value::Int( value );
else
currentValue() = value;
return true;
}
bool
Reader::decodeDouble( Token &token )
{
double value = 0;
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
if ( length <= bufferSize )
{
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );
buffer[length] = 0;
count = sscanf( buffer, "%lf", &value );
}
else
{
std::string buffer( token.start_, token.end_ );
count = sscanf( buffer.c_str(), "%lf", &value );
}
if ( count != 1 )
return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
currentValue() = value;
return true;
}
bool
Reader::decodeString( Token &token )
{
std::string decoded;
if ( !decodeString( token, decoded ) )
return false;
currentValue() = decoded;
return true;
}
bool
Reader::decodeString( Token &token, std::string &decoded )
{
decoded.reserve( token.end_ - token.start_ - 2 );
Location current = token.start_ + 1; // skip '"'
Location end = token.end_ - 1; // do not include '"'
while ( current != end )
{
Char c = *current++;
if ( c == '"' )
break;
else if ( c == '\\' )
{
if ( current == end )
return addError( "Empty escape sequence in string", token, current );
Char escape = *current++;
switch ( escape )
{
case '"': decoded += '"'; break;
case '/': decoded += '/'; break;
case '\\': decoded += '\\'; break;
case 'b': decoded += '\b'; break;
case 'f': decoded += '\f'; break;
case 'n': decoded += '\n'; break;
case 'r': decoded += '\r'; break;
case 't': decoded += '\t'; break;
case 'u':
{
unsigned int unicode;
if ( !decodeUnicodeCodePoint( token, current, end, unicode ) )
return false;
decoded += codePointToUTF8(unicode);
}
break;
default:
return addError( "Bad escape sequence in string", token, current );
}
}
else
{
decoded += c;
}
}
return true;
}
bool
Reader::decodeUnicodeCodePoint( Token &token,
Location &current,
Location end,
unsigned int &unicode )
{
if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) )
return false;
if (unicode >= 0xD800 && unicode <= 0xDBFF)
{
// surrogate pairs
if (end - current < 6)
return addError( "additional six characters expected to parse unicode surrogate pair.", token, current );
unsigned int surrogatePair;
if (*(current++) == '\\' && *(current++)== 'u')
{
if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair ))
{
unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
}
else
return false;
}
else
return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current );
}
return true;
}
bool
Reader::decodeUnicodeEscapeSequence( Token &token,
Location &current,
Location end,
unsigned int &unicode )
{
if ( end - current < 4 )
return addError( "Bad unicode escape sequence in string: four digits expected.", token, current );
unicode = 0;
for ( int index =0; index < 4; ++index )
{
Char c = *current++;
unicode *= 16;
if ( c >= '0' && c <= '9' )
unicode += c - '0';
else if ( c >= 'a' && c <= 'f' )
unicode += c - 'a' + 10;
else if ( c >= 'A' && c <= 'F' )
unicode += c - 'A' + 10;
else
return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
}
return true;
}
bool
Reader::addError( const std::string &message,
Token &token,
Location extra )
{
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = extra;
errors_.push_back( info );
return false;
}
bool
Reader::recoverFromError( TokenType skipUntilToken )
{
int errorCount = int(errors_.size());
Token skip;
while ( true )
{
if ( !readToken(skip) )
errors_.resize( errorCount ); // discard errors caused by recovery
if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream )
break;
}
errors_.resize( errorCount );
return false;
}
bool
Reader::addErrorAndRecover( const std::string &message,
Token &token,
TokenType skipUntilToken )
{
addError( message, token );
return recoverFromError( skipUntilToken );
}
Value &
Reader::currentValue()
{
return *(nodes_.top());
}
Reader::Char
Reader::getNextChar()
{
if ( current_ == end_ )
return 0;
return *current_++;
}
void
Reader::getLocationLineAndColumn( Location location,
int &line,
int &column ) const
{
Location current = begin_;
Location lastLineStart = current;
line = 0;
while ( current < location && current != end_ )
{
Char c = *current++;
if ( c == '\r' )
{
if ( *current == '\n' )
++current;
lastLineStart = current;
++line;
}
else if ( c == '\n' )
{
lastLineStart = current;
++line;
}
}
// column & line start at 1
column = int(location - lastLineStart) + 1;
++line;
}
std::string
Reader::getLocationLineAndColumn( Location location ) const
{
int line, column;
getLocationLineAndColumn( location, line, column );
char buffer[18+16+16+1];
sprintf( buffer, "Line %d, Column %d", line, column );
return buffer;
}
std::string
Reader::getFormatedErrorMessages() const
{
std::string formattedMessage;
for ( Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError )
{
const ErrorInfo &error = *itError;
formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n";
formattedMessage += " " + error.message_ + "\n";
if ( error.extra_ )
formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n";
}
return formattedMessage;
}
std::istream& operator>>( std::istream &sin, Value &root )
{
Json::Reader reader;
bool ok = reader.parse(sin, root, true);
//JSON_ASSERT( ok );
if (!ok) throw std::runtime_error(reader.getFormatedErrorMessages());
return sin;
}
} // namespace Json
#include <iostream>
#include <json/value.h>
#include <json/writer.h>
#include <utility>
#include <stdexcept>
#include <cstring>
#include <cassert>
#ifdef JSON_USE_CPPTL
# include <cpptl/conststring.h>
#endif
#include <cstddef> // size_t
#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
# include "json_batchallocator.h"
#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
#define JSON_ASSERT_UNREACHABLE assert( false )
#define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
#define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message );
namespace Json {
// QNX is strict about declaring C symbols in the std namespace.
#ifdef __QNXNTO__
using std::memcpy;
using std::strchr;
using std::strcmp;
using std::strlen;
#endif
const Value Value::null;
const Int Value::minInt = Int( ~(UInt(-1)/2) );
const Int Value::maxInt = Int( UInt(-1)/2 );
const UInt Value::maxUInt = UInt(-1);
// A "safe" implementation of strdup. Allow null pointer to be passed.
// Also avoid warning on msvc80.
//
//inline char *safeStringDup( const char *czstring )
//{
// if ( czstring )
// {
// const size_t length = (unsigned int)( strlen(czstring) + 1 );
// char *newString = static_cast<char *>( malloc( length ) );
// memcpy( newString, czstring, length );
// return newString;
// }
// return 0;
//}
//
//inline char *safeStringDup( const std::string &str )
//{
// if ( !str.empty() )
// {
// const size_t length = str.length();
// char *newString = static_cast<char *>( malloc( length + 1 ) );
// memcpy( newString, str.c_str(), length );
// newString[length] = 0;
// return newString;
// }
// return 0;
//}
ValueAllocator::~ValueAllocator()
{
}
class DefaultValueAllocator : public ValueAllocator
{
public:
virtual ~DefaultValueAllocator()
{
}
virtual char *makeMemberName( const char *memberName )
{
return duplicateStringValue( memberName );
}
virtual void releaseMemberName( char *memberName )
{
releaseStringValue( memberName );
}
virtual char *duplicateStringValue( const char *value,
unsigned int length = unknown )
{
//@todo invesgate this old optimization
//if ( !value || value[0] == 0 )
// return 0;
if ( length == unknown )
length = (unsigned int)strlen(value);
char *newString = static_cast<char *>( malloc( length + 1 ) );
memcpy( newString, value, length );
newString[length] = 0;
return newString;
}
virtual void releaseStringValue( char *value )
{
if ( value )
free( value );
}
};
static ValueAllocator *&valueAllocator()
{
static DefaultValueAllocator defaultAllocator;
static ValueAllocator *valueAllocator = &defaultAllocator;
return valueAllocator;
}
static struct DummyValueAllocatorInitializer {
DummyValueAllocatorInitializer()
{
valueAllocator(); // ensure valueAllocator() statics are initialized before main().
}
} dummyValueAllocatorInitializer;
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// ValueInternals...
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
#ifdef JSON_VALUE_USE_INTERNAL_MAP
# include "json_internalarray.inl"
# include "json_internalmap.inl"
#endif // JSON_VALUE_USE_INTERNAL_MAP
# include "json_valueiterator.inl"
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class Value::CommentInfo
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
Value::CommentInfo::CommentInfo()
: comment_( 0 )
{
}
Value::CommentInfo::~CommentInfo()
{
if ( comment_ )
valueAllocator()->releaseStringValue( comment_ );
}
void
Value::CommentInfo::setComment( const char *text )
{
if ( comment_ )
valueAllocator()->releaseStringValue( comment_ );
JSON_ASSERT( text );
JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
// It seems that /**/ style comments are acceptable as well.
comment_ = valueAllocator()->duplicateStringValue( text );
}
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class Value::CZString
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
# ifndef JSON_VALUE_USE_INTERNAL_MAP
// Notes: index_ indicates if the string was allocated when
// a string is stored.
Value::CZString::CZString( int index )
: cstr_( 0 )
, index_( index )
{
}
Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
: cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr)
: cstr )
, index_( allocate )
{
}
Value::CZString::CZString( const CZString &other )
: cstr_( other.index_ != noDuplication && other.cstr_ != 0
? valueAllocator()->makeMemberName( other.cstr_ )
: other.cstr_ )
, index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
: other.index_ )
{
}
Value::CZString::~CZString()
{
if ( cstr_ && index_ == duplicate )
valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) );
}
void
Value::CZString::swap( CZString &other )
{
std::swap( cstr_, other.cstr_ );
std::swap( index_, other.index_ );
}
Value::CZString &
Value::CZString::operator =( const CZString &other )
{
CZString temp( other );
swap( temp );
return *this;
}
bool
Value::CZString::operator<( const CZString &other ) const
{
if ( cstr_ )
return strcmp( cstr_, other.cstr_ ) < 0;
return index_ < other.index_;
}
bool
Value::CZString::operator==( const CZString &other ) const
{
if ( cstr_ )
return strcmp( cstr_, other.cstr_ ) == 0;
return index_ == other.index_;
}
int
Value::CZString::index() const
{
return index_;
}
const char *
Value::CZString::c_str() const
{
return cstr_;
}
bool
Value::CZString::isStaticString() const
{
return index_ == noDuplication;
}
#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class Value::Value
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
/*! \internal Default constructor initialization must be equivalent to:
* memset( this, 0, sizeof(Value) )
* This optimization is used in ValueInternalMap fast allocator.
*/
Value::Value( ValueType type )
: type_( type )
, allocated_( 0 )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
switch ( type )
{
case nullValue:
break;
case intValue:
case uintValue:
value_.int_ = 0;
break;
case realValue:
value_.real_ = 0.0;
break;
case stringValue:
value_.string_ = 0;
break;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
case objectValue:
value_.map_ = new ObjectValues();
break;
#else
case arrayValue:
value_.array_ = arrayAllocator()->newArray();
break;
case objectValue:
value_.map_ = mapAllocator()->newMap();
break;
#endif
case booleanValue:
value_.bool_ = false;
break;
default:
JSON_ASSERT_UNREACHABLE;
}
}
Value::Value( Int value )
: type_( intValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.int_ = value;
}
Value::Value( UInt value )
: type_( uintValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.uint_ = value;
}
Value::Value( double value )
: type_( realValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.real_ = value;
}
Value::Value( const char *value )
: type_( stringValue )
, allocated_( true )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.string_ = valueAllocator()->duplicateStringValue( value );
}
Value::Value( const char *beginValue,
const char *endValue )
: type_( stringValue )
, allocated_( true )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.string_ = valueAllocator()->duplicateStringValue( beginValue,
UInt(endValue - beginValue) );
}
Value::Value( const std::string &value )
: type_( stringValue )
, allocated_( true )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(),
(unsigned int)value.length() );
}
Value::Value( const StaticString &value )
: type_( stringValue )
, allocated_( false )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.string_ = const_cast<char *>( value.c_str() );
}
# ifdef JSON_USE_CPPTL
Value::Value( const CppTL::ConstString &value )
: type_( stringValue )
, allocated_( true )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() );
}
# endif
Value::Value( bool value )
: type_( booleanValue )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
value_.bool_ = value;
}
Value::Value( const Value &other )
: type_( other.type_ )
, comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
, itemIsUsed_( 0 )
#endif
{
switch ( type_ )
{
case nullValue:
case intValue:
case uintValue:
case realValue:
case booleanValue:
value_ = other.value_;
break;
case stringValue:
if ( other.value_.string_ )
{
value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ );
allocated_ = true;
}
else
value_.string_ = 0;
break;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
case objectValue:
value_.map_ = new ObjectValues( *other.value_.map_ );
break;
#else
case arrayValue:
value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
break;
case objectValue:
value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
break;
#endif
default:
JSON_ASSERT_UNREACHABLE;
}
if ( other.comments_ )
{
comments_ = new CommentInfo[numberOfCommentPlacement];
for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
{
const CommentInfo &otherComment = other.comments_[comment];
if ( otherComment.comment_ )
comments_[comment].setComment( otherComment.comment_ );
}
}
}
Value::~Value()
{
switch ( type_ )
{
case nullValue:
case intValue:
case uintValue:
case realValue:
case booleanValue:
break;
case stringValue:
if ( allocated_ )
valueAllocator()->releaseStringValue( value_.string_ );
break;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
case objectValue:
delete value_.map_;
break;
#else
case arrayValue:
arrayAllocator()->destructArray( value_.array_ );
break;
case objectValue:
mapAllocator()->destructMap( value_.map_ );
break;
#endif
default:
JSON_ASSERT_UNREACHABLE;
}
if ( comments_ )
delete[] comments_;
}
Value &
Value::operator=( const Value &other )
{
Value temp( other );
swap( temp );
return *this;
}
void
Value::swap( Value &other )
{
ValueType temp = type_;
type_ = other.type_;
other.type_ = temp;
std::swap( value_, other.value_ );
int temp2 = allocated_;
allocated_ = other.allocated_;
other.allocated_ = temp2;
}
ValueType
Value::type() const
{
return type_;
}
int
Value::compare( const Value &other )
{
/*
int typeDelta = other.type_ - type_;
switch ( type_ )
{
case nullValue:
return other.type_ == type_;
case intValue:
if ( other.type_.isNumeric()
case uintValue:
case realValue:
case booleanValue:
break;
case stringValue,
break;
case arrayValue:
delete value_.array_;
break;
case objectValue:
delete value_.map_;
default:
JSON_ASSERT_UNREACHABLE;
}
*/
return 0; // unreachable
}
bool
Value::operator <( const Value &other ) const
{
int typeDelta = type_ - other.type_;
if ( typeDelta )
return typeDelta < 0 ? true : false;
switch ( type_ )
{
case nullValue:
return false;
case intValue:
return value_.int_ < other.value_.int_;
case uintValue:
return value_.uint_ < other.value_.uint_;
case realValue:
return value_.real_ < other.value_.real_;
case booleanValue:
return value_.bool_ < other.value_.bool_;
case stringValue:
return ( value_.string_ == 0 && other.value_.string_ )
|| ( other.value_.string_
&& value_.string_
&& strcmp( value_.string_, other.value_.string_ ) < 0 );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
case objectValue:
{
int delta = int( value_.map_->size() - other.value_.map_->size() );
if ( delta )
return delta < 0;
return (*value_.map_) < (*other.value_.map_);
}
#else
case arrayValue:
return value_.array_->compare( *(other.value_.array_) ) < 0;
case objectValue:
return value_.map_->compare( *(other.value_.map_) ) < 0;
#endif
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable
}
bool
Value::operator <=( const Value &other ) const
{
return !(other > *this);
}
bool
Value::operator >=( const Value &other ) const
{
return !(*this < other);
}
bool
Value::operator >( const Value &other ) const
{
return other < *this;
}
bool
Value::operator ==( const Value &other ) const
{
//if ( type_ != other.type_ )
// GCC 2.95.3 says:
// attempt to take address of bit-field structure member `Json::Value::type_'
// Beats me, but a temp solves the problem.
int temp = other.type_;
if ( type_ != temp )
return false;
switch ( type_ )
{
case nullValue:
return true;
case intValue:
return value_.int_ == other.value_.int_;
case uintValue:
return value_.uint_ == other.value_.uint_;
case realValue:
return value_.real_ == other.value_.real_;
case booleanValue:
return value_.bool_ == other.value_.bool_;
case stringValue:
return ( value_.string_ == other.value_.string_ )
|| ( other.value_.string_
&& value_.string_
&& strcmp( value_.string_, other.value_.string_ ) == 0 );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
case objectValue:
return value_.map_->size() == other.value_.map_->size()
&& (*value_.map_) == (*other.value_.map_);
#else
case arrayValue:
return value_.array_->compare( *(other.value_.array_) ) == 0;
case objectValue:
return value_.map_->compare( *(other.value_.map_) ) == 0;
#endif
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable
}
bool
Value::operator !=( const Value &other ) const
{
return !( *this == other );
}
const char *
Value::asCString() const
{
JSON_ASSERT( type_ == stringValue );
return value_.string_;
}
std::string
Value::asString() const
{
switch ( type_ )
{
case nullValue:
return "";
case stringValue:
return value_.string_ ? value_.string_ : "";
case booleanValue:
return value_.bool_ ? "true" : "false";
case intValue:
case uintValue:
case realValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to string" );
default:
JSON_ASSERT_UNREACHABLE;
}
return ""; // unreachable
}
# ifdef JSON_USE_CPPTL
CppTL::ConstString
Value::asConstString() const
{
return CppTL::ConstString( asString().c_str() );
}
# endif
Value::Int
Value::asInt() const
{
switch ( type_ )
{
case nullValue:
return 0;
case intValue:
return value_.int_;
case uintValue:
JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" );
return value_.uint_;
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
return Int( value_.real_ );
case booleanValue:
return value_.bool_ ? 1 : 0;
case stringValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
Value::UInt
Value::asUInt() const
{
switch ( type_ )
{
case nullValue:
return 0;
case intValue:
JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
return value_.int_;
case uintValue:
return value_.uint_;
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
return UInt( value_.real_ );
case booleanValue:
return value_.bool_ ? 1 : 0;
case stringValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
double
Value::asDouble() const
{
switch ( type_ )
{
case nullValue:
return 0.0;
case intValue:
return value_.int_;
case uintValue:
return value_.uint_;
case realValue:
return value_.real_;
case booleanValue:
return value_.bool_ ? 1.0 : 0.0;
case stringValue:
case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE( false, "Type is not convertible to double" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
bool
Value::asBool() const
{
switch ( type_ )
{
case nullValue:
return false;
case intValue:
case uintValue:
return value_.int_ != 0;
case realValue:
return value_.real_ != 0.0;
case booleanValue:
return value_.bool_;
case stringValue:
return value_.string_ && value_.string_[0] != 0;
case arrayValue:
case objectValue:
return value_.map_->size() != 0;
default:
JSON_ASSERT_UNREACHABLE;
}
return false; // unreachable;
}
bool
Value::isConvertibleTo( ValueType other ) const
{
switch ( type_ )
{
case nullValue:
return true;
case intValue:
return ( other == nullValue && value_.int_ == 0 )
|| other == intValue
|| ( other == uintValue && value_.int_ >= 0 )
|| other == realValue
|| other == stringValue
|| other == booleanValue;
case uintValue:
return ( other == nullValue && value_.uint_ == 0 )
|| ( other == intValue && value_.uint_ <= (unsigned)maxInt )
|| other == uintValue
|| other == realValue
|| other == stringValue
|| other == booleanValue;
case realValue:
return ( other == nullValue && value_.real_ == 0.0 )
|| ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
|| ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
|| other == realValue
|| other == stringValue
|| other == booleanValue;
case booleanValue:
return ( other == nullValue && value_.bool_ == false )
|| other == intValue
|| other == uintValue
|| other == realValue
|| other == stringValue
|| other == booleanValue;
case stringValue:
return other == stringValue
|| ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
case arrayValue:
return other == arrayValue
|| ( other == nullValue && value_.map_->size() == 0 );
case objectValue:
return other == objectValue
|| ( other == nullValue && value_.map_->size() == 0 );
default:
JSON_ASSERT_UNREACHABLE;
}
return false; // unreachable;
}
/// Number of values in array or object
Value::UInt
Value::size() const
{
switch ( type_ )
{
case nullValue:
case intValue:
case uintValue:
case realValue:
case booleanValue:
case stringValue:
return 0;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue: // size of the array is highest index + 1
if ( !value_.map_->empty() )
{
ObjectValues::const_iterator itLast = value_.map_->end();
--itLast;
return (*itLast).first.index()+1;
}
return 0;
case objectValue:
return Int( value_.map_->size() );
#else
case arrayValue:
return Int( value_.array_->size() );
case objectValue:
return Int( value_.map_->size() );
#endif
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
bool
Value::empty() const
{
if ( isNull() || isArray() || isObject() )
return size() == 0u;
else
return false;
}
bool
Value::operator!() const
{
return isNull();
}
void
Value::clear()
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue );
switch ( type_ )
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
case objectValue:
value_.map_->clear();
break;
#else
case arrayValue:
value_.array_->clear();
break;
case objectValue:
value_.map_->clear();
break;
#endif
default:
break;
}
}
void
Value::resize( UInt newSize )
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
if ( type_ == nullValue )
*this = Value( arrayValue );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
UInt oldSize = size();
if ( newSize == 0 )
clear();
else if ( newSize > oldSize )
(*this)[ newSize - 1 ];
else
{
for ( UInt index = newSize; index < oldSize; ++index )
value_.map_->erase( index );
assert( size() == newSize );
}
#else
value_.array_->resize( newSize );
#endif
}
Value &
Value::operator[]( UInt index )
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
if ( type_ == nullValue )
*this = Value( arrayValue );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
CZString key( index );
ObjectValues::iterator it = value_.map_->lower_bound( key );
if ( it != value_.map_->end() && (*it).first == key )
return (*it).second;
ObjectValues::value_type defaultValue( key, null );
it = value_.map_->insert( it, defaultValue );
return (*it).second;
#else
return value_.array_->resolveReference( index );
#endif
}
const Value &
Value::operator[]( UInt index ) const
{
JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
if ( type_ == nullValue )
return null;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
CZString key( index );
ObjectValues::const_iterator it = value_.map_->find( key );
if ( it == value_.map_->end() )
return null;
return (*it).second;
#else
Value *value = value_.array_->find( index );
return value ? *value : null;
#endif
}
Value &
Value::operator[]( const char *key )
{
return resolveReference( key, false );
}
Value &
Value::resolveReference( const char *key,
bool isStatic )
{
JSON_ASSERT( type_ == nullValue || type_ == objectValue );
if ( type_ == nullValue )
*this = Value( objectValue );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
CZString actualKey( key, isStatic ? CZString::noDuplication
: CZString::duplicateOnCopy );
ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
if ( it != value_.map_->end() && (*it).first == actualKey )
return (*it).second;
ObjectValues::value_type defaultValue( actualKey, null );
it = value_.map_->insert( it, defaultValue );
Value &value = (*it).second;
return value;
#else
return value_.map_->resolveReference( key, isStatic );
#endif
}
Value
Value::get( UInt index,
const Value &defaultValue ) const
{
const Value *value = &((*this)[index]);
return value == &null ? defaultValue : *value;
}
bool
Value::isValidIndex( UInt index ) const
{
return index < size();
}
const Value &
Value::operator[]( const char *key ) const
{
JSON_ASSERT( type_ == nullValue || type_ == objectValue );
if ( type_ == nullValue )
return null;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
CZString actualKey( key, CZString::noDuplication );
ObjectValues::const_iterator it = value_.map_->find( actualKey );
if ( it == value_.map_->end() )
return null;
return (*it).second;
#else
const Value *value = value_.map_->find( key );
return value ? *value : null;
#endif
}
Value &
Value::operator[]( const std::string &key )
{
return (*this)[ key.c_str() ];
}
const Value &
Value::operator[]( const std::string &key ) const
{
return (*this)[ key.c_str() ];
}
Value &
Value::operator[]( const StaticString &key )
{
return resolveReference( key, true );
}
# ifdef JSON_USE_CPPTL
Value &
Value::operator[]( const CppTL::ConstString &key )
{
return (*this)[ key.c_str() ];
}
const Value &
Value::operator[]( const CppTL::ConstString &key ) const
{
return (*this)[ key.c_str() ];
}
# endif
Value &
Value::append( const Value &value )
{
return (*this)[size()] = value;
}
Value
Value::get( const char *key,
const Value &defaultValue ) const
{
const Value *value = &((*this)[key]);
return value == &null ? defaultValue : *value;
}
Value
Value::get( const std::string &key,
const Value &defaultValue ) const
{
return get( key.c_str(), defaultValue );
}
Value
Value::removeMember( const char* key )
{
JSON_ASSERT( type_ == nullValue || type_ == objectValue );
if ( type_ == nullValue )
return null;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
CZString actualKey( key, CZString::noDuplication );
ObjectValues::iterator it = value_.map_->find( actualKey );
if ( it == value_.map_->end() )
return null;
Value old(it->second);
value_.map_->erase(it);
return old;
#else
Value *value = value_.map_->find( key );
if (value){
Value old(*value);
value_.map_.remove( key );
return old;
} else {
return null;
}
#endif
}
Value
Value::removeMember( const std::string &key )
{
return removeMember( key.c_str() );
}
# ifdef JSON_USE_CPPTL
Value
Value::get( const CppTL::ConstString &key,
const Value &defaultValue ) const
{
return get( key.c_str(), defaultValue );
}
# endif
bool
Value::isMember( const char *key ) const
{
const Value *value = &((*this)[key]);
return value != &null;
}
bool
Value::isMember( const std::string &key ) const
{
return isMember( key.c_str() );
}
# ifdef JSON_USE_CPPTL
bool
Value::isMember( const CppTL::ConstString &key ) const
{
return isMember( key.c_str() );
}
#endif
Value::Members
Value::getMemberNames() const
{
JSON_ASSERT( type_ == nullValue || type_ == objectValue );
if ( type_ == nullValue )
return Value::Members();
Members members;
members.reserve( value_.map_->size() );
#ifndef JSON_VALUE_USE_INTERNAL_MAP
ObjectValues::const_iterator it = value_.map_->begin();
ObjectValues::const_iterator itEnd = value_.map_->end();
for ( ; it != itEnd; ++it )
members.push_back( std::string( (*it).first.c_str() ) );
#else
ValueInternalMap::IteratorState it;
ValueInternalMap::IteratorState itEnd;
value_.map_->makeBeginIterator( it );
value_.map_->makeEndIterator( itEnd );
for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
members.push_back( std::string( ValueInternalMap::key( it ) ) );
#endif
return members;
}
//
//# ifdef JSON_USE_CPPTL
//EnumMemberNames
//Value::enumMemberNames() const
//{
// if ( type_ == objectValue )
// {
// return CppTL::Enum::any( CppTL::Enum::transform(
// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
// MemberNamesTransform() ) );
// }
// return EnumMemberNames();
//}
//
//
//EnumValues
//Value::enumValues() const
//{
// if ( type_ == objectValue || type_ == arrayValue )
// return CppTL::Enum::anyValues( *(value_.map_),
// CppTL::Type<const Value &>() );
// return EnumValues();
//}
//
//# endif
bool
Value::isNull() const
{
return type_ == nullValue;
}
bool
Value::isBool() const
{
return type_ == booleanValue;
}
bool
Value::isInt() const
{
return type_ == intValue;
}
bool
Value::isUInt() const
{
return type_ == uintValue;
}
bool
Value::isIntegral() const
{
return type_ == intValue
|| type_ == uintValue
|| type_ == booleanValue;
}
bool
Value::isDouble() const
{
return type_ == realValue;
}
bool
Value::isNumeric() const
{
return isIntegral() || isDouble();
}
bool
Value::isString() const
{
return type_ == stringValue;
}
bool
Value::isArray() const
{
return type_ == nullValue || type_ == arrayValue;
}
bool
Value::isObject() const
{
return type_ == nullValue || type_ == objectValue;
}
void
Value::setComment( const char *comment,
CommentPlacement placement )
{
if ( !comments_ )
comments_ = new CommentInfo[numberOfCommentPlacement];
comments_[placement].setComment( comment );
}
void
Value::setComment( const std::string &comment,
CommentPlacement placement )
{
setComment( comment.c_str(), placement );
}
bool
Value::hasComment( CommentPlacement placement ) const
{
return comments_ != 0 && comments_[placement].comment_ != 0;
}
std::string
Value::getComment( CommentPlacement placement ) const
{
if ( hasComment(placement) )
return comments_[placement].comment_;
return "";
}
std::string
Value::toStyledString() const
{
StyledWriter writer;
return writer.write( *this );
}
Value::const_iterator
Value::begin() const
{
switch ( type_ )
{
#ifdef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
if ( value_.array_ )
{
ValueInternalArray::IteratorState it;
value_.array_->makeBeginIterator( it );
return const_iterator( it );
}
break;
case objectValue:
if ( value_.map_ )
{
ValueInternalMap::IteratorState it;
value_.map_->makeBeginIterator( it );
return const_iterator( it );
}
break;
#else
case arrayValue:
case objectValue:
if ( value_.map_ )
return const_iterator( value_.map_->begin() );
break;
#endif
default:
break;
}
return const_iterator();
}
Value::const_iterator
Value::end() const
{
switch ( type_ )
{
#ifdef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
if ( value_.array_ )
{
ValueInternalArray::IteratorState it;
value_.array_->makeEndIterator( it );
return const_iterator( it );
}
break;
case objectValue:
if ( value_.map_ )
{
ValueInternalMap::IteratorState it;
value_.map_->makeEndIterator( it );
return const_iterator( it );
}
break;
#else
case arrayValue:
case objectValue:
if ( value_.map_ )
return const_iterator( value_.map_->end() );
break;
#endif
default:
break;
}
return const_iterator();
}
Value::iterator
Value::begin()
{
switch ( type_ )
{
#ifdef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
if ( value_.array_ )
{
ValueInternalArray::IteratorState it;
value_.array_->makeBeginIterator( it );
return iterator( it );
}
break;
case objectValue:
if ( value_.map_ )
{
ValueInternalMap::IteratorState it;
value_.map_->makeBeginIterator( it );
return iterator( it );
}
break;
#else
case arrayValue:
case objectValue:
if ( value_.map_ )
return iterator( value_.map_->begin() );
break;
#endif
default:
break;
}
return iterator();
}
Value::iterator
Value::end()
{
switch ( type_ )
{
#ifdef JSON_VALUE_USE_INTERNAL_MAP
case arrayValue:
if ( value_.array_ )
{
ValueInternalArray::IteratorState it;
value_.array_->makeEndIterator( it );
return iterator( it );
}
break;
case objectValue:
if ( value_.map_ )
{
ValueInternalMap::IteratorState it;
value_.map_->makeEndIterator( it );
return iterator( it );
}
break;
#else
case arrayValue:
case objectValue:
if ( value_.map_ )
return iterator( value_.map_->end() );
break;
#endif
default:
break;
}
return iterator();
}
// class PathArgument
// //////////////////////////////////////////////////////////////////
PathArgument::PathArgument()
: kind_( kindNone )
{
}
PathArgument::PathArgument( Value::UInt index )
: index_( index )
, kind_( kindIndex )
{
}
PathArgument::PathArgument( const char *key )
: key_( key )
, kind_( kindKey )
{
}
PathArgument::PathArgument( const std::string &key )
: key_( key.c_str() )
, kind_( kindKey )
{
}
// class Path
// //////////////////////////////////////////////////////////////////
Path::Path( const std::string &path,
const PathArgument &a1,
const PathArgument &a2,
const PathArgument &a3,
const PathArgument &a4,
const PathArgument &a5 )
{
InArgs in;
in.push_back( &a1 );
in.push_back( &a2 );
in.push_back( &a3 );
in.push_back( &a4 );
in.push_back( &a5 );
makePath( path, in );
}
void
Path::makePath( const std::string &path,
const InArgs &in )
{
const char *current = path.c_str();
const char *end = current + path.length();
InArgs::const_iterator itInArg = in.begin();
while ( current != end )
{
if ( *current == '[' )
{
++current;
if ( *current == '%' )
addPathInArg( path, in, itInArg, PathArgument::kindIndex );
else
{
Value::UInt index = 0;
for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
index = index * 10 + Value::UInt(*current - '0');
args_.push_back( index );
}
if ( current == end || *current++ != ']' )
invalidPath( path, int(current - path.c_str()) );
}
else if ( *current == '%' )
{
addPathInArg( path, in, itInArg, PathArgument::kindKey );
++current;
}
else if ( *current == '.' )
{
++current;
}
else
{
const char *beginName = current;
while ( current != end && !strchr( "[.", *current ) )
++current;
args_.push_back( std::string( beginName, current ) );
}
}
}
void
Path::addPathInArg( const std::string &path,
const InArgs &in,
InArgs::const_iterator &itInArg,
PathArgument::Kind kind )
{
if ( itInArg == in.end() )
{
// Error: missing argument %d
}
else if ( (*itInArg)->kind_ != kind )
{
// Error: bad argument type
}
else
{
args_.push_back( **itInArg );
}
}
void
Path::invalidPath( const std::string &path,
int location )
{
// Error: invalid path.
}
const Value &
Path::resolve( const Value &root ) const
{
const Value *node = &root;
for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
{
const PathArgument &arg = *it;
if ( arg.kind_ == PathArgument::kindIndex )
{
if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
{
// Error: unable to resolve path (array value expected at position...
}
node = &((*node)[arg.index_]);
}
else if ( arg.kind_ == PathArgument::kindKey )
{
if ( !node->isObject() )
{
// Error: unable to resolve path (object value expected at position...)
}
node = &((*node)[arg.key_]);
if ( node == &Value::null )
{
// Error: unable to resolve path (object has no member named '' at position...)
}
}
}
return *node;
}
Value
Path::resolve( const Value &root,
const Value &defaultValue ) const
{
const Value *node = &root;
for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
{
const PathArgument &arg = *it;
if ( arg.kind_ == PathArgument::kindIndex )
{
if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
return defaultValue;
node = &((*node)[arg.index_]);
}
else if ( arg.kind_ == PathArgument::kindKey )
{
if ( !node->isObject() )
return defaultValue;
node = &((*node)[arg.key_]);
if ( node == &Value::null )
return defaultValue;
}
}
return *node;
}
Value &
Path::make( Value &root ) const
{
Value *node = &root;
for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
{
const PathArgument &arg = *it;
if ( arg.kind_ == PathArgument::kindIndex )
{
if ( !node->isArray() )
{
// Error: node is not an array at position ...
}
node = &((*node)[arg.index_]);
}
else if ( arg.kind_ == PathArgument::kindKey )
{
if ( !node->isObject() )
{
// Error: node is not an object at position...
}
node = &((*node)[arg.key_]);
}
}
return *node;
}
} // namespace Json
// included by json_value.cpp
// everything is within Json namespace
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class ValueIteratorBase
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
ValueIteratorBase::ValueIteratorBase()
#ifndef JSON_VALUE_USE_INTERNAL_MAP
: current_()
, isNull_( true )
{
}
#else
: isArray_( true )
, isNull_( true )
{
iterator_.array_ = ValueInternalArray::IteratorState();
}
#endif
#ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current )
: current_( current )
, isNull_( false )
{
}
#else
ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state )
: isArray_( true )
{
iterator_.array_ = state;
}
ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state )
: isArray_( false )
{
iterator_.map_ = state;
}
#endif
Value &
ValueIteratorBase::deref() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
return current_->second;
#else
if ( isArray_ )
return ValueInternalArray::dereference( iterator_.array_ );
return ValueInternalMap::value( iterator_.map_ );
#endif
}
void
ValueIteratorBase::increment()
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
++current_;
#else
if ( isArray_ )
ValueInternalArray::increment( iterator_.array_ );
ValueInternalMap::increment( iterator_.map_ );
#endif
}
void
ValueIteratorBase::decrement()
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
--current_;
#else
if ( isArray_ )
ValueInternalArray::decrement( iterator_.array_ );
ValueInternalMap::decrement( iterator_.map_ );
#endif
}
ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance( const SelfType &other ) const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
# ifdef JSON_USE_CPPTL_SMALLMAP
return current_ - other.current_;
# else
// Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default
// std::map::iterator. As begin() and end() are two instance
// of the default std::map::iterator, they can not be compared.
// To allow this, we handle this comparison specifically.
if ( isNull_ && other.isNull_ )
{
return 0;
}
// Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL,
// which is the one used by default).
// Using a portable hand-made version for non random iterator instead:
// return difference_type( std::distance( current_, other.current_ ) );
difference_type myDistance = 0;
for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it )
{
++myDistance;
}
return myDistance;
# endif
#else
if ( isArray_ )
return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ );
return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ );
#endif
}
bool
ValueIteratorBase::isEqual( const SelfType &other ) const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
if ( isNull_ )
{
return other.isNull_;
}
return current_ == other.current_;
#else
if ( isArray_ )
return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ );
return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ );
#endif
}
void
ValueIteratorBase::copy( const SelfType &other )
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
current_ = other.current_;
#else
if ( isArray_ )
iterator_.array_ = other.iterator_.array_;
iterator_.map_ = other.iterator_.map_;
#endif
}
Value
ValueIteratorBase::key() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
const Value::CZString czstring = (*current_).first;
if ( czstring.c_str() )
{
if ( czstring.isStaticString() )
return Value( StaticString( czstring.c_str() ) );
return Value( czstring.c_str() );
}
return Value( czstring.index() );
#else
if ( isArray_ )
return Value( ValueInternalArray::indexOf( iterator_.array_ ) );
bool isStatic;
const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic );
if ( isStatic )
return Value( StaticString( memberName ) );
return Value( memberName );
#endif
}
UInt
ValueIteratorBase::index() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
const Value::CZString czstring = (*current_).first;
if ( !czstring.c_str() )
return czstring.index();
return Value::UInt( -1 );
#else
if ( isArray_ )
return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) );
return Value::UInt( -1 );
#endif
}
const char *
ValueIteratorBase::memberName() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
const char *name = (*current_).first.c_str();
return name ? name : "";
#else
if ( !isArray_ )
return ValueInternalMap::key( iterator_.map_ );
return "";
#endif
}
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class ValueConstIterator
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
ValueConstIterator::ValueConstIterator()
{
}
#ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator &current )
: ValueIteratorBase( current )
{
}
#else
ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state )
: ValueIteratorBase( state )
{
}
ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state )
: ValueIteratorBase( state )
{
}
#endif
ValueConstIterator &
ValueConstIterator::operator =( const ValueIteratorBase &other )
{
copy( other );
return *this;
}
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// class ValueIterator
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
ValueIterator::ValueIterator()
{
}
#ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIterator::ValueIterator( const Value::ObjectValues::iterator &current )
: ValueIteratorBase( current )
{
}
#else
ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state )
: ValueIteratorBase( state )
{
}
ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state )
: ValueIteratorBase( state )
{
}
#endif
ValueIterator::ValueIterator( const ValueConstIterator &other )
: ValueIteratorBase( other )
{
}
ValueIterator::ValueIterator( const ValueIterator &other )
: ValueIteratorBase( other )
{
}
ValueIterator &
ValueIterator::operator =( const SelfType &other )
{
copy( other );
return *this;
}
#include <json/writer.h>
#include <utility>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#if _MSC_VER >= 1400 // VC++ 8.0
#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
#endif
namespace Json {
static bool isControlCharacter(char ch)
{
return ch > 0 && ch <= 0x1F;
}
static bool containsControlCharacter( const char* str )
{
while ( *str )
{
if ( isControlCharacter( *(str++) ) )
return true;
}
return false;
}
static void uintToString( unsigned int value,
char *&current )
{
*--current = 0;
do
{
*--current = (value % 10) + '0';
value /= 10;
}
while ( value != 0 );
}
std::string valueToString( Int value )
{
char buffer[32];
char *current = buffer + sizeof(buffer);
bool isNegative = value < 0;
if ( isNegative )
value = -value;
uintToString( UInt(value), current );
if ( isNegative )
*--current = '-';
assert( current >= buffer );
return current;
}
std::string valueToString( UInt value )
{
char buffer[32];
char *current = buffer + sizeof(buffer);
uintToString( value, current );
assert( current >= buffer );
return current;
}
std::string valueToString( double value )
{
char buffer[32];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
sprintf_s(buffer, sizeof(buffer), "%#.16g", value);
#else
sprintf(buffer, "%#.16g", value);
#endif
char* ch = buffer + strlen(buffer) - 1;
if (*ch != '0') return buffer; // nothing to truncate, so save time
while(ch > buffer && *ch == '0'){
--ch;
}
char* last_nonzero = ch;
while(ch >= buffer){
switch(*ch){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
--ch;
continue;
case '.':
// Truncate zeroes to save bytes in output, but keep one.
*(last_nonzero+2) = '\0';
return buffer;
default:
return buffer;
}
}
return buffer;
}
std::string valueToString( bool value )
{
return value ? "true" : "false";
}
std::string valueToQuotedString( const char *value )
{
// Not sure how to handle unicode...
if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value ))
return std::string("\"") + value + "\"";
// We have to walk value and escape any special characters.
// Appending to std::string is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
std::string result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
for (const char* c=value; *c != 0; ++c)
{
switch(*c)
{
case '\"':
result += "\\\"";
break;
case '\\':
result += "\\\\";
break;
case '\b':
result += "\\b";
break;
case '\f':
result += "\\f";
break;
case '\n':
result += "\\n";
break;
case '\r':
result += "\\r";
break;
case '\t':
result += "\\t";
break;
//case '/':
// Even though \/ is considered a legal escape in JSON, a bare
// slash is also legal, so I see no reason to escape it.
// (I hope I am not misunderstanding something.
// blep notes: actually escaping \/ may be useful in javascript to avoid </
// sequence.
// Should add a flag to allow this compatibility mode and prevent this
// sequence from occurring.
default:
if ( isControlCharacter( *c ) )
{
std::ostringstream oss;
oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c);
result += oss.str();
}
else
{
result += *c;
}
break;
}
}
result += "\"";
return result;
}
// Class Writer
// //////////////////////////////////////////////////////////////////
Writer::~Writer()
{
}
// Class FastWriter
// //////////////////////////////////////////////////////////////////
FastWriter::FastWriter()
: yamlCompatiblityEnabled_( false )
{
}
void
FastWriter::enableYAMLCompatibility()
{
yamlCompatiblityEnabled_ = true;
}
std::string
FastWriter::write( const Value &root )
{
document_ = "";
writeValue( root );
document_ += "\n";
return document_;
}
void
FastWriter::writeValue( const Value &value )
{
switch ( value.type() )
{
case nullValue:
document_ += "null";
break;
case intValue:
document_ += valueToString( value.asInt() );
break;
case uintValue:
document_ += valueToString( value.asUInt() );
break;
case realValue:
document_ += valueToString( value.asDouble() );
break;
case stringValue:
document_ += valueToQuotedString( value.asCString() );
break;
case booleanValue:
document_ += valueToString( value.asBool() );
break;
case arrayValue:
{
document_ += "[";
int size = value.size();
for ( int index =0; index < size; ++index )
{
if ( index > 0 )
document_ += ",";
writeValue( value[index] );
}
document_ += "]";
}
break;
case objectValue:
{
Value::Members members( value.getMemberNames() );
document_ += "{";
for ( Value::Members::iterator it = members.begin();
it != members.end();
++it )
{
const std::string &name = *it;
if ( it != members.begin() )
document_ += ",";
document_ += valueToQuotedString( name.c_str() );
document_ += yamlCompatiblityEnabled_ ? ": "
: ":";
writeValue( value[name] );
}
document_ += "}";
}
break;
}
}
// Class StyledWriter
// //////////////////////////////////////////////////////////////////
StyledWriter::StyledWriter()
: rightMargin_( 74 )
, indentSize_( 3 )
{
}
std::string
StyledWriter::write( const Value &root )
{
document_ = "";
addChildValues_ = false;
indentString_ = "";
writeCommentBeforeValue( root );
writeValue( root );
writeCommentAfterValueOnSameLine( root );
document_ += "\n";
return document_;
}
void
StyledWriter::writeValue( const Value &value )
{
switch ( value.type() )
{
case nullValue:
pushValue( "null" );
break;
case intValue:
pushValue( valueToString( value.asInt() ) );
break;
case uintValue:
pushValue( valueToString( value.asUInt() ) );
break;
case realValue:
pushValue( valueToString( value.asDouble() ) );
break;
case stringValue:
pushValue( valueToQuotedString( value.asCString() ) );
break;
case booleanValue:
pushValue( valueToString( value.asBool() ) );
break;
case arrayValue:
writeArrayValue( value);
break;
case objectValue:
{
Value::Members members( value.getMemberNames() );
if ( members.empty() )
pushValue( "{}" );
else
{
writeWithIndent( "{" );
indent();
Value::Members::iterator it = members.begin();
while ( true )
{
const std::string &name = *it;
const Value &childValue = value[name];
writeCommentBeforeValue( childValue );
writeWithIndent( valueToQuotedString( name.c_str() ) );
document_ += " : ";
writeValue( childValue );
if ( ++it == members.end() )
{
writeCommentAfterValueOnSameLine( childValue );
break;
}
document_ += ",";
writeCommentAfterValueOnSameLine( childValue );
}
unindent();
writeWithIndent( "}" );
}
}
break;
}
}
void
StyledWriter::writeArrayValue( const Value &value )
{
unsigned size = value.size();
if ( size == 0 )
pushValue( "[]" );
else
{
bool isArrayMultiLine = isMultineArray( value );
if ( isArrayMultiLine )
{
writeWithIndent( "[" );
indent();
bool hasChildValue = !childValues_.empty();
unsigned index =0;
while ( true )
{
const Value &childValue = value[index];
writeCommentBeforeValue( childValue );
if ( hasChildValue )
writeWithIndent( childValues_[index] );
else
{
writeIndent();
writeValue( childValue );
}
if ( ++index == size )
{
writeCommentAfterValueOnSameLine( childValue );
break;
}
document_ += ",";
writeCommentAfterValueOnSameLine( childValue );
}
unindent();
writeWithIndent( "]" );
}
else // output on a single line
{
assert( childValues_.size() == size );
document_ += "[ ";
for ( unsigned index =0; index < size; ++index )
{
if ( index > 0 )
document_ += ", ";
document_ += childValues_[index];
}
document_ += " ]";
}
}
}
bool
StyledWriter::isMultineArray( const Value &value )
{
int size = value.size();
bool isMultiLine = size*3 >= rightMargin_ ;
childValues_.clear();
for ( int index =0; index < size && !isMultiLine; ++index )
{
const Value &childValue = value[index];
isMultiLine = isMultiLine ||
( (childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0 );
}
if ( !isMultiLine ) // check if line length > max line length
{
childValues_.reserve( size );
addChildValues_ = true;
int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
for ( int index =0; index < size && !isMultiLine; ++index )
{
writeValue( value[index] );
lineLength += int( childValues_[index].length() );
isMultiLine = isMultiLine && hasCommentForValue( value[index] );
}
addChildValues_ = false;
isMultiLine = isMultiLine || lineLength >= rightMargin_;
}
return isMultiLine;
}
void
StyledWriter::pushValue( const std::string &value )
{
if ( addChildValues_ )
childValues_.push_back( value );
else
document_ += value;
}
void
StyledWriter::writeIndent()
{
if ( !document_.empty() )
{
char last = document_[document_.length()-1];
if ( last == ' ' ) // already indented
return;
if ( last != '\n' ) // Comments may add new-line
document_ += '\n';
}
document_ += indentString_;
}
void
StyledWriter::writeWithIndent( const std::string &value )
{
writeIndent();
document_ += value;
}
void
StyledWriter::indent()
{
indentString_ += std::string( indentSize_, ' ' );
}
void
StyledWriter::unindent()
{
assert( int(indentString_.size()) >= indentSize_ );
indentString_.resize( indentString_.size() - indentSize_ );
}
void
StyledWriter::writeCommentBeforeValue( const Value &root )
{
if ( !root.hasComment( commentBefore ) )
return;
document_ += normalizeEOL( root.getComment( commentBefore ) );
document_ += "\n";
}
void
StyledWriter::writeCommentAfterValueOnSameLine( const Value &root )
{
if ( root.hasComment( commentAfterOnSameLine ) )
document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
if ( root.hasComment( commentAfter ) )
{
document_ += "\n";
document_ += normalizeEOL( root.getComment( commentAfter ) );
document_ += "\n";
}
}
bool
StyledWriter::hasCommentForValue( const Value &value )
{
return value.hasComment( commentBefore )
|| value.hasComment( commentAfterOnSameLine )
|| value.hasComment( commentAfter );
}
std::string
StyledWriter::normalizeEOL( const std::string &text )
{
std::string normalized;
normalized.reserve( text.length() );
const char *begin = text.c_str();
const char *end = begin + text.length();
const char *current = begin;
while ( current != end )
{
char c = *current++;
if ( c == '\r' ) // mac or dos EOL
{
if ( *current == '\n' ) // convert dos EOL
++current;
normalized += '\n';
}
else // handle unix EOL & other char
normalized += c;
}
return normalized;
}
// Class StyledStreamWriter
// //////////////////////////////////////////////////////////////////
StyledStreamWriter::StyledStreamWriter( std::string indentation )
: document_(NULL)
, rightMargin_( 74 )
, indentation_( indentation )
{
}
void
StyledStreamWriter::write( std::ostream &out, const Value &root )
{
document_ = &out;
addChildValues_ = false;
indentString_ = "";
writeCommentBeforeValue( root );
writeValue( root );
writeCommentAfterValueOnSameLine( root );
*document_ << "\n";
document_ = NULL; // Forget the stream, for safety.
}
void
StyledStreamWriter::writeValue( const Value &value )
{
switch ( value.type() )
{
case nullValue:
pushValue( "null" );
break;
case intValue:
pushValue( valueToString( value.asInt() ) );
break;
case uintValue:
pushValue( valueToString( value.asUInt() ) );
break;
case realValue:
pushValue( valueToString( value.asDouble() ) );
break;
case stringValue:
pushValue( valueToQuotedString( value.asCString() ) );
break;
case booleanValue:
pushValue( valueToString( value.asBool() ) );
break;
case arrayValue:
writeArrayValue( value);
break;
case objectValue:
{
Value::Members members( value.getMemberNames() );
if ( members.empty() )
pushValue( "{}" );
else
{
writeWithIndent( "{" );
indent();
Value::Members::iterator it = members.begin();
while ( true )
{
const std::string &name = *it;
const Value &childValue = value[name];
writeCommentBeforeValue( childValue );
writeWithIndent( valueToQuotedString( name.c_str() ) );
*document_ << " : ";
writeValue( childValue );
if ( ++it == members.end() )
{
writeCommentAfterValueOnSameLine( childValue );
break;
}
*document_ << ",";
writeCommentAfterValueOnSameLine( childValue );
}
unindent();
writeWithIndent( "}" );
}
}
break;
}
}
void
StyledStreamWriter::writeArrayValue( const Value &value )
{
unsigned size = value.size();
if ( size == 0 )
pushValue( "[]" );
else
{
bool isArrayMultiLine = isMultineArray( value );
if ( isArrayMultiLine )
{
writeWithIndent( "[" );
indent();
bool hasChildValue = !childValues_.empty();
unsigned index =0;
while ( true )
{
const Value &childValue = value[index];
writeCommentBeforeValue( childValue );
if ( hasChildValue )
writeWithIndent( childValues_[index] );
else
{
writeIndent();
writeValue( childValue );
}
if ( ++index == size )
{
writeCommentAfterValueOnSameLine( childValue );
break;
}
*document_ << ",";
writeCommentAfterValueOnSameLine( childValue );
}
unindent();
writeWithIndent( "]" );
}
else // output on a single line
{
assert( childValues_.size() == size );
*document_ << "[ ";
for ( unsigned index =0; index < size; ++index )
{
if ( index > 0 )
*document_ << ", ";
*document_ << childValues_[index];
}
*document_ << " ]";
}
}
}
bool
StyledStreamWriter::isMultineArray( const Value &value )
{
int size = value.size();
bool isMultiLine = size*3 >= rightMargin_ ;
childValues_.clear();
for ( int index =0; index < size && !isMultiLine; ++index )
{
const Value &childValue = value[index];
isMultiLine = isMultiLine ||
( (childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0 );
}
if ( !isMultiLine ) // check if line length > max line length
{
childValues_.reserve( size );
addChildValues_ = true;
int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
for ( int index =0; index < size && !isMultiLine; ++index )
{
writeValue( value[index] );
lineLength += int( childValues_[index].length() );
isMultiLine = isMultiLine && hasCommentForValue( value[index] );
}
addChildValues_ = false;
isMultiLine = isMultiLine || lineLength >= rightMargin_;
}
return isMultiLine;
}
void
StyledStreamWriter::pushValue( const std::string &value )
{
if ( addChildValues_ )
childValues_.push_back( value );
else
*document_ << value;
}
void
StyledStreamWriter::writeIndent()
{
/*
Some comments in this method would have been nice. ;-)
if ( !document_.empty() )
{
char last = document_[document_.length()-1];
if ( last == ' ' ) // already indented
return;
if ( last != '\n' ) // Comments may add new-line
*document_ << '\n';
}
*/
*document_ << '\n' << indentString_;
}
void
StyledStreamWriter::writeWithIndent( const std::string &value )
{
writeIndent();
*document_ << value;
}
void
StyledStreamWriter::indent()
{
indentString_ += indentation_;
}
void
StyledStreamWriter::unindent()
{
assert( indentString_.size() >= indentation_.size() );
indentString_.resize( indentString_.size() - indentation_.size() );
}
void
StyledStreamWriter::writeCommentBeforeValue( const Value &root )
{
if ( !root.hasComment( commentBefore ) )
return;
*document_ << normalizeEOL( root.getComment( commentBefore ) );
*document_ << "\n";
}
void
StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root )
{
if ( root.hasComment( commentAfterOnSameLine ) )
*document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
if ( root.hasComment( commentAfter ) )
{
*document_ << "\n";
*document_ << normalizeEOL( root.getComment( commentAfter ) );
*document_ << "\n";
}
}
bool
StyledStreamWriter::hasCommentForValue( const Value &value )
{
return value.hasComment( commentBefore )
|| value.hasComment( commentAfterOnSameLine )
|| value.hasComment( commentAfter );
}
std::string
StyledStreamWriter::normalizeEOL( const std::string &text )
{
std::string normalized;
normalized.reserve( text.length() );
const char *begin = text.c_str();
const char *end = begin + text.length();
const char *current = begin;
while ( current != end )
{
char c = *current++;
if ( c == '\r' ) // mac or dos EOL
{
if ( *current == '\n' ) // convert dos EOL
++current;
normalized += '\n';
}
else // handle unix EOL & other char
normalized += c;
}
return normalized;
}
std::ostream& operator<<( std::ostream &sout, const Value &root )
{
Json::StyledStreamWriter writer;
writer.write(sout, root);
return sout;
}
} // namespace Json
#include "plugin.h"
#include "tokenizer.h"
#ifdef _WINDOWS
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}
#else
#include <errno.h>
#include <string.h>
extern int errno;
#endif
SendPluginEv SendPluginEvent;
string g_GetSysErrMsg( void )
{
string strError = "Unknown";
// Problem loading
#ifdef _WINDOWS
int nErrorCode = GetLastError();
LPTSTR s;
if ( ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, nErrorCode, 0, ( LPTSTR ) &s, 0, NULL ) )
{
strError = s;
}
else
{
char szBuf[ 20 ];
_snprintf_s( szBuf, _countof(szBuf), 19, "%d", nErrorCode );
strError = szBuf;
}
#else
char szError[80];
if ( strerror_r( errno, szError, sizeof(szError) ) )
{
strError = "no description found";
}
else
{
strError = szError;
}
#endif
return strError;
}
void g_sleep( unsigned int mseconds )
{
#ifdef _WINDOWS
Sleep( mseconds );
#else
usleep( mseconds * 1000 );
#endif
}
string& g_trim( string& str )
{
// Whitespace characters
char whspc[] = " \t\r\n\v\f";
// Whack off first part
size_t pos = str.find_first_not_of( whspc );
if ( pos != string::npos )
str.replace( 0, pos, "" );
// Whack off trailing stuff
pos = str.find_last_not_of( whspc );
if ( pos != string::npos )
str.replace( pos + 1, str.length() - pos, "" );
return str;
}
void g_tokenize( const string& str, const string& delimiters, vector<string>& tokens )
{
tokenize( str, tokens, delimiters );
}
char* SetEventFunc( SendPluginEv funcPtr )
{
static char * szObjList = onGetObjList();
SendPluginEvent = funcPtr;
return szObjList;
}
const int nMAXSIZE = 512;
char* g_pszRetVal = NULL;
//-----------------------------------------------------------
// Map from an object Id to an object instance
//-----------------------------------------------------------
typedef std::map<string, JSExt*> StringToJExt_T;
//-----------------------------------------------------------
// Map from a browser context to an id mapping
//-----------------------------------------------------------
typedef std::map<void*, StringToJExt_T*> VoidToMap_T;
VoidToMap_T g_context2Map;
class GlobalSharedModule
{
public:
GlobalSharedModule( void )
{
g_pszRetVal = new char[ nMAXSIZE ];
}
~GlobalSharedModule()
{
delete [] g_pszRetVal;
VoidToMap_T::iterator posMaps;
for ( posMaps = g_context2Map.begin(); posMaps != g_context2Map.end(); ++posMaps )
{
StringToJExt_T& id2Obj = *posMaps->second;
StringToJExt_T::iterator posMap;
for ( posMap = id2Obj.begin(); posMap != id2Obj.end(); ++posMap )
{
JSExt* pJSExt = posMap->second;
if ( pJSExt->CanDelete() )
{
delete pJSExt;
}
}
id2Obj.erase( id2Obj.begin(), id2Obj.end() );
}
g_context2Map.erase( g_context2Map.begin(), g_context2Map.end() );
}
};
GlobalSharedModule g_sharedModule;
char* g_str2global( const string& strRetVal )
{
int nLen = strRetVal.size();
if ( nLen >= nMAXSIZE )
{
delete [] g_pszRetVal;
g_pszRetVal = new char[ nLen + 1 ];
}
else
{
// To minimaize the number of memory reallocations, the assumption
// is that in most times this will be the case
delete [] g_pszRetVal;
g_pszRetVal = new char[ nMAXSIZE ];
}
strcpy( g_pszRetVal, strRetVal.c_str() );
return g_pszRetVal;
}
bool g_unregisterObject( const string& strObjId, void* pContext )
{
// Called by the plugin extension implementation
// if the extension handles the deletion of its object
StringToJExt_T * pID2Obj = NULL;
VoidToMap_T::iterator iter = g_context2Map.find( pContext );
if ( iter != g_context2Map.end() )
{
pID2Obj = iter->second;
}
else
{
return false;
}
StringToJExt_T& mapID2Obj = *pID2Obj;
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r == mapID2Obj.end() )
{
return false;
}
mapID2Obj.erase( strObjId );
return true;
}
char* InvokeFunction( const char* szCommand, void* pContext )
{
StringToJExt_T * pID2Obj = NULL;
VoidToMap_T::iterator iter = g_context2Map.find( pContext );
if ( iter != g_context2Map.end() )
{
pID2Obj = iter->second;
}
else
{
pID2Obj = new StringToJExt_T;
g_context2Map[ pContext ] = pID2Obj;
}
StringToJExt_T& mapID2Obj = *pID2Obj;
string strFullCommand = szCommand;
vector<string> arParams;
g_tokenize( strFullCommand, " ", arParams );
string strCommand = arParams[ 0 ];
string strRetVal = szERROR;
if ( strCommand == szCREATE )
{
string strClassName = arParams[ 1 ];
string strObjId = arParams[ 2 ];
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r != mapID2Obj.end() )
{
strRetVal += strObjId;
strRetVal += " :Object already exists.";
return g_str2global( strRetVal );
}
JSExt* pJSExt = onCreateObject( strClassName, strObjId );
if ( pJSExt == NULL )
{
strRetVal += strObjId;
strRetVal += " :Unknown object type ";
strRetVal += strClassName;
return g_str2global( strRetVal );
}
pJSExt->m_pContext = pContext;
mapID2Obj[ strObjId ] = pJSExt;
strRetVal = szOK;
strRetVal += strObjId;
return g_str2global( strRetVal );
}
else
if ( strCommand == szINVOKE )
{
string strObjId = arParams[ 1 ];
string strMethod = arParams[ 2 ];
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r == mapID2Obj.end() )
{
strRetVal += strObjId;
strRetVal += " :No object found for id.";
return g_str2global( strRetVal );
}
JSExt* pJSExt = r->second;
size_t nLoc = strFullCommand.find( strObjId );
if ( nLoc == string::npos )
{
strRetVal += strObjId;
strRetVal += " :Internal InvokeMethod error.";
return g_str2global( strRetVal );
}
if ( strMethod == szDISPOSE )
{
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r == mapID2Obj.end() )
{
strRetVal = szERROR;
strRetVal += strObjId;
return g_str2global( strRetVal );
}
JSExt * pJSExt = mapID2Obj[ strObjId ];
if ( pJSExt->CanDelete() )
{
delete pJSExt;
}
mapID2Obj.erase( strObjId );
strRetVal = szOK;
strRetVal += strObjId;
return g_str2global( strRetVal );
}
size_t nSuffixLoc = nLoc + strObjId.size();
string strInvoke = strFullCommand.substr( nSuffixLoc );
strInvoke = g_trim( strInvoke );
strRetVal = pJSExt->InvokeMethod( strInvoke );
return g_str2global( strRetVal );
}
strRetVal += " :Unknown command ";
strRetVal += strCommand;
return g_str2global( strRetVal );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#ifndef _PLUGIN_H
#define _PLUGIN_H
#include <map>
#include <string>
#include <vector>
#include <unistd.h>
//#include "tokenizer.h"
using namespace std;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%% Functions exported by this DLL
//%% Should always be only SetEventFunc and InvokeFunction
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// g++ requires extern "C" otherwise the names of SetEventFunc and InvokeFunction
// are mangled C++ style. MS Visual Studio doesn't seem to care though.
extern "C"
{
typedef void (*SendPluginEv)( const char* szEvent, void* pContext );
char* SetEventFunc(SendPluginEv funcPtr);
char* InvokeFunction( const char* szCommand, void* pContext );
}
// JNEXT Framework function of the form:
// typedef void (*SendPluginEv)( const char* szEvent );
// used to notify JavaScript of an asynchronous event
extern SendPluginEv SendPluginEvent;
/////////////////////////////////////////////////////////////////////////
// Constants and methods common to all JNEXT extensions types
/////////////////////////////////////////////////////////////////////////
#define szERROR "Error "
#define szOK "Ok "
#define szDISPOSE "Dispose"
#define szINVOKE "InvokeMethod"
#define szCREATE "CreateObj"
/////////////////////////////////////////////////////////////////////////
// Utility functions
/////////////////////////////////////////////////////////////////////////
string& g_trim( string& str );
void g_tokenize(const string& str,const string& delimiters, vector<string>& tokens);
char* g_str2static( const string& strRetVal );
void g_sleep( unsigned int mseconds );
bool g_unregisterObject( const string& strObjId, void* pContext );
/////////////////////////////////////////////////////////////////////////
// Abstract extension object
/////////////////////////////////////////////////////////////////////////
class JSExt
{
public:
virtual ~JSExt() {};
virtual string InvokeMethod( const string& strCommand ) = 0;
virtual bool CanDelete( void ) = 0;
virtual void TryDelete( void ) {}
public:
void* m_pContext;
};
/////////////////////////////////////////////////////////////////////////
// Callback functions to be implemented by the plugin implementation
/////////////////////////////////////////////////////////////////////////
extern char* onGetObjList( void );
extern JSExt* onCreateObject( const string& strClassName, const string& strObjId );
#endif
/************************************************************************
The zlib/libpng License
Copyright (c) 2006 Joerg Wiedenmann
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from
the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
***********************************************************************/
/********************************************************************
created: 2006-01-28
filename: tokenizer.cpp
author: Jörg Wiedenmann
purpose: A tokenizer function which provides a very
customizable way of breaking up strings.
history: 2006-01-28, Original version
2006-03-04, Fixed a small parsing bug, thanks Elias.
*********************************************************************/
#include "tokenizer.h"
using namespace std;
void tokenize ( const string& str, vector<string>& result,
const string& delimiters, const string& delimiters_preserve,
const string& quote, const string& esc )
{
// clear the vector
if ( false == result.empty() )
{
result.clear();
}
string::size_type pos = 0; // the current position (char) in the string
char ch = 0; // buffer for the current character
char delimiter = 0; // the buffer for the delimiter char which
// will be added to the tokens if the delimiter
// is preserved
char current_quote = 0; // the char of the current open quote
bool quoted = false; // indicator if there is an open quote
string token; // string buffer for the token
bool token_complete = false; // indicates if the current token is
// read to be added to the result vector
string::size_type len = str.length(); // length of the input-string
// for every char in the input-string
while ( len > pos )
{
// get the character of the string and reset the delimiter buffer
ch = str.at(pos);
delimiter = 0;
// assume ch isn't a delimiter
bool add_char = true;
// check ...
// ... if the delimiter is an escaped character
bool escaped = false; // indicates if the next char is protected
if ( false == esc.empty() ) // check if esc-chars are provided
{
if ( string::npos != esc.find_first_of(ch) )
{
// get the escaped char
++pos;
if ( pos < len ) // if there are more chars left
{
// get the next one
ch = str.at(pos);
// add the escaped character to the token
add_char = true;
}
else // cannot get any more characters
{
// don't add the esc-char
add_char = false;
}
// ignore the remaining delimiter checks
escaped = true;
}
}
// ... if the delimiter is a quote
if ( false == quote.empty() && false == escaped )
{
// if quote chars are provided and the char isn't protected
if ( string::npos != quote.find_first_of(ch) )
{
// if not quoted, set state to open quote and set
// the quote character
if ( false == quoted )
{
quoted = true;
current_quote = ch;
// don't add the quote-char to the token
add_char = false;
}
else // if quote is open already
{
// check if it is the matching character to close it
if ( current_quote == ch )
{
// close quote and reset the quote character
quoted = false;
current_quote = 0;
// don't add the quote-char to the token
add_char = false;
}
} // else
}
}
// ... if the delimiter isn't preserved
if ( false == delimiters.empty() && false == escaped &&
false == quoted )
{
// if a delimiter is provided and the char isn't protected by
// quote or escape char
if ( string::npos != delimiters.find_first_of(ch) )
{
// if ch is a delimiter and the token string isn't empty
// the token is complete
if ( false == token.empty() ) // BUGFIX: 2006-03-04
{
token_complete = true;
}
// don't add the delimiter to the token
add_char = false;
}
}
// ... if the delimiter is preserved - add it as a token
bool add_delimiter = false;
if ( false == delimiters_preserve.empty() && false == escaped &&
false == quoted )
{
// if a delimiter which will be preserved is provided and the
// char isn't protected by quote or escape char
if ( string::npos != delimiters_preserve.find_first_of(ch) )
{
// if ch is a delimiter and the token string isn't empty
// the token is complete
if ( false == token.empty() ) // BUGFIX: 2006-03-04
{
token_complete = true;
}
// don't add the delimiter to the token
add_char = false;
// add the delimiter
delimiter = ch;
add_delimiter = true;
}
}
// add the character to the token
if ( true == add_char )
{
// add the current char
token.push_back( ch );
}
// add the token if it is complete
if ( true == token_complete && false == token.empty() )
{
// add the token string
result.push_back( token );
// clear the contents
token.clear();
// build the next token
token_complete = false;
}
// add the delimiter
if ( true == add_delimiter )
{
// the next token is the delimiter
string delim_token;
delim_token.push_back( delimiter );
result.push_back( delim_token );
// REMOVED: 2006-03-04, Bugfix
}
// repeat for the next character
++pos;
} // while
// add the final token
if ( false == token.empty() )
{
result.push_back( token );
}
}
/************************************************************************
The zlib/libpng License
Copyright (c) 2006 Joerg Wiedenmann
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from
the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
***********************************************************************/
/********************************************************************
created: 2006-01-28
filename: tokenizer.cpp
author: Jörg Wiedenmann
purpose: A tokenizer function which provides a very
customizable way of breaking up strings.
*********************************************************************/
#include <vector>
#include <string>
using namespace std;
// Function to break up a string into tokens
//
// Parameters:
//-----------
// str = the input string that will be tokenized
// result = the tokens for str
// delimiters = the delimiter characters
// delimiters preserve = same as above, but the delimiter characters
// will be put into the result as a token
// quote = characters to protect the enclosed characters
// esc = characters to protect a single character
//
void tokenize ( const string& str, vector<string>& result,
const string& delimiters, const string& delimiters_preserve = "",
const string& quote = "\"", const string& esc = "\\" );
/*
* Copyright (c) 2013 BlackBerry 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.
*/
#include "Logger.hpp"
#include "toast_js.hpp"
#include <slog2.h>
namespace webworks {
Logger::Logger(const char* name, Toast_JS *parent): m_pParent(parent) {
buffer_config.buffer_set_name = name;
buffer_config.num_buffers = 2;
buffer_config.verbosity_level = SLOG2_DEBUG1;
/* Configure the first buffer, using 7 x 4KB pages. This larger buffer will be used for
very chatty logging. Our goal is to have 30-60 seconds of history at any given time,
so we will want to log at a rate of around one log line with a string of 16 bytes
long every 150 milliseconds.
*/
buffer_config.buffer_config[0].buffer_name = "low_priority";
buffer_config.buffer_config[0].num_pages = 7;
/* Configure the second buffer, which we will use for high level info logging that is very
infrequent, but we want a longer history (hours or maybe even over a day or two). This
buffer uses 1 x 4KB.
*/
buffer_config.buffer_config[1].buffer_name = "high_priority";
buffer_config.buffer_config[1].num_pages = 1;
/* Register the buffer set. */
if( -1 == slog2_register( &buffer_config, buffer_handle, 0 ) ) {
fprintf( stderr, "Error registering slogger2 buffer!\n" );
} else {
info("Created slogger2 buffers");
}
}
Logger::~Logger() {
critical("slogger2 buffers reset");
slog2_reset();
}
int Logger::log(slog2_buffer_t buffer, _Uint8t severity, const char* message) {
return slog2c(buffer, 0, severity, message);
}
int Logger::debug(const char* message) {
return log(lowPriorityBuffer(), SLOG2_DEBUG1, message);
}
int Logger::info(const char* message) {
return log(lowPriorityBuffer(), SLOG2_INFO, message);
}
int Logger::notice(const char* message) {
return log(lowPriorityBuffer(), SLOG2_NOTICE, message);
}
int Logger::warn(const char* message) {
return log(lowPriorityBuffer(), SLOG2_WARNING, message);
}
int Logger::error(const char* message) {
return log(hiPriorityBuffer(), SLOG2_ERROR, message);
}
int Logger::critical(const char* message) {
return log(hiPriorityBuffer(), SLOG2_CRITICAL, message);
}
int Logger::setVerbosity(_Uint8t verbosity) {
return slog2_set_verbosity(buffer_handle[0], verbosity);
}
_Uint8t Logger::getVerbosity() {
return slog2_get_verbosity(buffer_handle[0]);
}
slog2_buffer_t Logger::hiPriorityBuffer() {
return buffer_handle[1];
}
slog2_buffer_t Logger::lowPriorityBuffer() {
return buffer_handle[0];
}
} /* namespace webworks */
/*
* Copyright (c) 2013 BlackBerry 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.
*/
#ifndef LOGGER_HPP_
#define LOGGER_HPP_
#include <string>
#include <slog2.h>
class Toast_JS;
namespace webworks {
class Logger {
public:
explicit Logger(const char* name, Toast_JS *parent = NULL);
virtual ~Logger();
int debug(const char* message);
int info(const char* message);
int notice(const char* message);
int warn(const char* message);
int error(const char* message);
int critical(const char* message);
int setVerbosity(_Uint8t verbosity);
_Uint8t getVerbosity();
slog2_buffer_t hiPriorityBuffer();
slog2_buffer_t lowPriorityBuffer();
private:
Toast_JS *m_pParent;
slog2_buffer_set_config_t buffer_config;
slog2_buffer_t buffer_handle[2];
int log(slog2_buffer_t buffer, _Uint8t severity, const char* message);
};
} /* namespace webworks */
#endif /* LOGGER_HPP_ */
/*
* Copyright (c) 2013 BlackBerry 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.
*/
#include <string>
#include "../public/tokenizer.h"
#include "toast_js.hpp"
#include "toast_ndk.hpp"
#include <json/reader.h>
#include <json/writer.h>
using namespace std;
/**
* Default constructor.
*/
Toast_JS::Toast_JS(const std::string& id) :
m_id(id)
{
m_pLogger = new webworks::Logger("Toast_JS", this);
m_pToastController = new webworks::Toast_NDK(this);
}
/**
* Toast_JS destructor.
*/
Toast_JS::~Toast_JS()
{
if (m_pToastController)
delete m_pToastController;
if (m_pLogger)
delete m_pLogger;
}
webworks::Logger* Toast_JS::getLog()
{
return m_pLogger;
}
/**
* This method returns the list of objects implemented by this native
* extension.
*/
char* onGetObjList()
{
static char name[] = "Toast_JS";
return name;
}
/**
* This method is used by JNext to instantiate the Toast_JS object when
* an object is created on the JavaScript server side.
*/
JSExt* onCreateObject(const string& className, const string& id)
{
if (className == "Toast_JS")
{
return new Toast_JS(id);
}
return NULL;
}
/**
* Method used by JNext to determine if the object can be deleted.
*/
bool Toast_JS::CanDelete()
{
return true;
}
/**
* It will be called from JNext JavaScript side with passed string.
* This method implements the interface for the JavaScript to native binding
* for invoking native code. This method is triggered when JNext.invoke is
* called on the JavaScript side with this native objects id.
*/
string Toast_JS::InvokeMethod(const string& command)
{
m_pLogger->debug("Toast invoked");
// format must be: "command callbackId params"
size_t commandIndex = command.find_first_of(" ");
std::string strCommand = command.substr(0, commandIndex);
size_t callbackIndex = command.find_first_of(" ", commandIndex + 1);
std::string callbackId = command.substr(commandIndex + 1, callbackIndex - commandIndex - 1);
std::string arg = command.substr(callbackIndex + 1, command.length());
m_pLogger->debug(command.c_str());
m_pLogger->debug(arg.c_str());
Json::FastWriter writer;
Json::Reader reader;
Json::Value root;
bool parse = reader.parse(arg, root);
if (!parse)
{
m_pLogger->error("Parse Error");
Json::Value error;
error["result"] = "Cannot parse JSON object";
NotifyEvent(callbackId + " error " + writer.write(error));
} else
{
if (strCommand == "show")
{
m_pToastController->toast(root["message"].asString(), root["duration"].asString(), root["position"].asString(), callbackId);
}
}
strCommand.append(";");
strCommand.append(command);
return strCommand;
}
// Notifies JavaScript of an event
void Toast_JS::NotifyEvent(const std::string& event)
{
std::string eventString = m_id + " ";
eventString.append(event);
SendPluginEvent(eventString.c_str(), m_pContext);
}
/*
* Copyright (c) 2013 BlackBerry 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.
*/
#ifndef toast_JS_HPP_
#define toast_JS_HPP_
#include <string>
#include "../public/plugin.h"
#include "toast_ndk.hpp"
#include "Logger.hpp"
class Toast_JS: public JSExt {
public:
explicit Toast_JS(const std::string& id);
virtual ~Toast_JS();
virtual bool CanDelete();
virtual std::string InvokeMethod(const std::string& command);
void NotifyEvent(const std::string& event);
webworks::Logger* getLog();
private:
std::string m_id;
// Definition of a pointer to the actual native extension code
webworks::Toast_NDK *m_pToastController;
webworks::Logger *m_pLogger;
};
#endif /* toast_JS_HPP_ */
/*
* Copyright (c) 2013 BlackBerry 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.
*/
#include <string>
#include "toast_ndk.hpp"
#include "toast_js.hpp"
#include <bb/system/SystemToast>
#include <bb/system/SystemUiPosition>
using namespace bb::system;
namespace webworks
{
Toast_NDK::Toast_NDK(Toast_JS *parent) :
m_pParent(parent)
{
}
Toast_NDK::~Toast_NDK()
{
}
void Toast_NDK::toast(const std::string& message, const std::string& duration,
const std::string& position, const std::string callbackId)
{
SystemToast* m_toast;
m_toast = new SystemToast();
m_toast->setBody(message.c_str());
if (position == "top")
{
m_toast->setPosition(SystemUiPosition::TopCenter);
} else if (position == "bottom")
{
m_toast->setPosition(SystemUiPosition::BottomCenter);
} else
{
m_toast->setPosition(SystemUiPosition::MiddleCenter);
}
m_toast->show();
m_pParent->NotifyEvent(callbackId);
}
} /* namespace webworks */
/*
* Copyright (c) 2013 BlackBerry 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.
*/
#ifndef toast_NDK_HPP_
#define toast_NDK_HPP_
#include <string>
#include <pthread.h>
class Toast_JS;
namespace webworks {
class Toast_NDK {
public:
explicit Toast_NDK(Toast_JS *parent = NULL);
virtual ~Toast_NDK();
void toast(const std::string& message, const std::string& duration, const std::string& position, const std::string callbackId);
private:
Toast_JS *m_pParent;
};
} // namespace webworks
#endif /* toast_NDK_HPP_ */
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
// each makeToast method creates a view and displays it as toast // each makeToast method creates a view and displays it as toast
- (void)makeToast:(NSString *)message; - (void)makeToast:(NSString *)message;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position addPixelsY:(int)addPixelsY;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position image:(UIImage *)image; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position image:(UIImage *)image;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title image:(UIImage *)image; - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title image:(UIImage *)image;
- (void)hideToast;
// displays toast with an activity spinner // displays toast with an activity spinner
- (void)makeToastActivity; - (void)makeToastActivity;
- (void)makeToastActivity:(id)position; - (void)makeToastActivity:(id)position;
...@@ -16,6 +19,7 @@ ...@@ -16,6 +19,7 @@
// the showToast methods display any view as toast // the showToast methods display any view as toast
- (void)showToast:(UIView *)toast; - (void)showToast:(UIView *)toast;
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point; - (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point ;
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point addedPixelsY:(int)addPixelsY;
@end @end
...@@ -12,7 +12,7 @@ static const CGFloat CSToastMaxWidth = 0.8; // 80% of parent vie ...@@ -12,7 +12,7 @@ static const CGFloat CSToastMaxWidth = 0.8; // 80% of parent vie
static const CGFloat CSToastMaxHeight = 0.8; // 80% of parent view height static const CGFloat CSToastMaxHeight = 0.8; // 80% of parent view height
static const CGFloat CSToastHorizontalPadding = 16.0; static const CGFloat CSToastHorizontalPadding = 16.0;
static const CGFloat CSToastVerticalPadding = 12.0; static const CGFloat CSToastVerticalPadding = 12.0;
static const CGFloat CSToastTopBottomOffset = 10.0; static const CGFloat CSToastTopBottomOffset = 20.0;
static const CGFloat CSToastCornerRadius = 20.0; static const CGFloat CSToastCornerRadius = 20.0;
static const CGFloat CSToastOpacity = 0.8; static const CGFloat CSToastOpacity = 0.8;
static const CGFloat CSToastFontSize = 13.0; static const CGFloat CSToastFontSize = 13.0;
...@@ -53,7 +53,7 @@ static UIView *prevToast = NULL; ...@@ -53,7 +53,7 @@ static UIView *prevToast = NULL;
- (void)hideToast:(UIView *)toast; - (void)hideToast:(UIView *)toast;
- (void)toastTimerDidFinish:(NSTimer *)timer; - (void)toastTimerDidFinish:(NSTimer *)timer;
- (void)handleToastTapped:(UITapGestureRecognizer *)recognizer; - (void)handleToastTapped:(UITapGestureRecognizer *)recognizer;
- (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast; - (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast withAddedPixelsY:(int) addPixelsY;
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image; - (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
- (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode; - (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode;
...@@ -70,22 +70,27 @@ static UIView *prevToast = NULL; ...@@ -70,22 +70,27 @@ static UIView *prevToast = NULL;
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position {
UIView *toast = [self viewForMessage:message title:nil image:nil]; UIView *toast = [self viewForMessage:message title:nil image:nil];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
}
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position addPixelsY:(int)addPixelsY {
UIView *toast = [self viewForMessage:message title:nil image:nil];
[self showToast:toast duration:duration position:position addedPixelsY:addPixelsY];
} }
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title {
UIView *toast = [self viewForMessage:message title:title image:nil]; UIView *toast = [self viewForMessage:message title:title image:nil];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
} }
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position image:(UIImage *)image { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position image:(UIImage *)image {
UIView *toast = [self viewForMessage:message title:nil image:image]; UIView *toast = [self viewForMessage:message title:nil image:image];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
} }
- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image { - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image {
UIView *toast = [self viewForMessage:message title:title image:image]; UIView *toast = [self viewForMessage:message title:title image:image];
[self showToast:toast duration:duration position:position]; [self showToast:toast duration:duration position:position];
} }
- (void)showToast:(UIView *)toast { - (void)showToast:(UIView *)toast {
...@@ -93,22 +98,27 @@ static UIView *prevToast = NULL; ...@@ -93,22 +98,27 @@ static UIView *prevToast = NULL;
} }
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point { - (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point {
if(prevToast){ [self showToast:toast duration:CSToastDefaultDuration position:CSToastDefaultPosition addedPixelsY:0];
[self hideToast:prevToast]; }
}
- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point addedPixelsY:(int) addPixelsY {
[self hideToast];
prevToast = toast; prevToast = toast;
toast.center = [self centerPointForPosition:point withToast:toast]; toast.center = [self centerPointForPosition:point withToast:toast withAddedPixelsY:addPixelsY];
toast.alpha = 0.0; toast.alpha = 0.0;
if (CSToastHidesOnTap) { if (CSToastHidesOnTap) {
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:toast action:@selector(handleToastTapped:)]; UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:toast action:@selector(handleToastTapped:)];
[toast addGestureRecognizer:recognizer]; [toast addGestureRecognizer:recognizer];
toast.userInteractionEnabled = YES; toast.userInteractionEnabled = YES;
toast.exclusiveTouch = YES; toast.exclusiveTouch = YES;
} }
[self addSubview:toast]; // make sure that if InAppBrowser is active, we're still showing Toasts on top of it
UIViewController *vc = [self getTopMostViewController];
UIView *v = [vc view];
[v addSubview:toast];
[UIView animateWithDuration:CSToastFadeDuration [UIView animateWithDuration:CSToastFadeDuration
delay:0.0 delay:0.0
options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction) options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction)
...@@ -119,7 +129,21 @@ static UIView *prevToast = NULL; ...@@ -119,7 +129,21 @@ static UIView *prevToast = NULL;
// associate the timer with the toast view // associate the timer with the toast view
objc_setAssociatedObject (toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject (toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}]; }];
}
- (UIViewController*) getTopMostViewController {
UIViewController *presentingViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (presentingViewController.presentedViewController != nil) {
presentingViewController = presentingViewController.presentedViewController;
}
return presentingViewController;
}
- (void)hideToast {
if (prevToast){
[self hideToast:prevToast];
}
} }
- (void)hideToast:(UIView *)toast { - (void)hideToast:(UIView *)toast {
...@@ -142,7 +166,7 @@ static UIView *prevToast = NULL; ...@@ -142,7 +166,7 @@ static UIView *prevToast = NULL;
- (void)handleToastTapped:(UITapGestureRecognizer *)recognizer { - (void)handleToastTapped:(UITapGestureRecognizer *)recognizer {
NSTimer *timer = (NSTimer *)objc_getAssociatedObject(self, &CSToastTimerKey); NSTimer *timer = (NSTimer *)objc_getAssociatedObject(self, &CSToastTimerKey);
[timer invalidate]; [timer invalidate];
[self hideToast:recognizer.view]; [self hideToast:recognizer.view];
} }
...@@ -156,31 +180,31 @@ static UIView *prevToast = NULL; ...@@ -156,31 +180,31 @@ static UIView *prevToast = NULL;
// sanity // sanity
UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
if (existingActivityView != nil) return; if (existingActivityView != nil) return;
UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CSToastActivityWidth, CSToastActivityHeight)]; UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CSToastActivityWidth, CSToastActivityHeight)];
activityView.center = [self centerPointForPosition:position withToast:activityView]; activityView.center = [self centerPointForPosition:position withToast:activityView withAddedPixelsY:0];
activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity]; activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity];
activityView.alpha = 0.0; activityView.alpha = 0.0;
activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
activityView.layer.cornerRadius = CSToastCornerRadius; activityView.layer.cornerRadius = CSToastCornerRadius;
if (CSToastDisplayShadow) { if (CSToastDisplayShadow) {
activityView.layer.shadowColor = [UIColor blackColor].CGColor; activityView.layer.shadowColor = [UIColor blackColor].CGColor;
activityView.layer.shadowOpacity = CSToastShadowOpacity; activityView.layer.shadowOpacity = CSToastShadowOpacity;
activityView.layer.shadowRadius = CSToastShadowRadius; activityView.layer.shadowRadius = CSToastShadowRadius;
activityView.layer.shadowOffset = CSToastShadowOffset; activityView.layer.shadowOffset = CSToastShadowOffset;
} }
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2); activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2);
[activityView addSubview:activityIndicatorView]; [activityView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating]; [activityIndicatorView startAnimating];
// associate the activity view with self // associate the activity view with self
objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addSubview:activityView]; [self addSubview:activityView];
[UIView animateWithDuration:CSToastFadeDuration [UIView animateWithDuration:CSToastFadeDuration
delay:0.0 delay:0.0
options:UIViewAnimationOptionCurveEaseOut options:UIViewAnimationOptionCurveEaseOut
...@@ -206,22 +230,22 @@ static UIView *prevToast = NULL; ...@@ -206,22 +230,22 @@ static UIView *prevToast = NULL;
#pragma mark - Helpers #pragma mark - Helpers
- (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast { - (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast withAddedPixelsY:(int) addPixelsY {
if([point isKindOfClass:[NSString class]]) { if([point isKindOfClass:[NSString class]]) {
// convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint // convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint
if([point caseInsensitiveCompare:@"top"] == NSOrderedSame) { if([point caseInsensitiveCompare:@"top"] == NSOrderedSame) {
return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + CSToastVerticalPadding + CSToastTopBottomOffset); return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + addPixelsY + CSToastVerticalPadding + CSToastTopBottomOffset);
} else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) { } else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) {
return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding - CSToastTopBottomOffset); return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding - CSToastTopBottomOffset + addPixelsY);
} else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) { } else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) {
return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); return CGPointMake(self.bounds.size.width / 2, (self.bounds.size.height / 2) + addPixelsY);
} }
} else if ([point isKindOfClass:[NSValue class]]) { } else if ([point isKindOfClass:[NSValue class]]) {
return [point CGPointValue]; return [point CGPointValue];
} }
NSLog(@"Warning: Invalid position for toast."); NSLog(@"Warning: Invalid position for toast.");
return [self centerPointForPosition:CSToastDefaultPosition withToast:toast]; return [self centerPointForPosition:CSToastDefaultPosition withToast:toast withAddedPixelsY:addPixelsY];
} }
- (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode { - (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode {
...@@ -233,7 +257,10 @@ static UIView *prevToast = NULL; ...@@ -233,7 +257,10 @@ static UIView *prevToast = NULL;
return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height)); return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height));
} }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [string sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:lineBreakMode]; return [string sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:lineBreakMode];
#pragma clang diagnostic pop
} }
- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image { - (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
......
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
@interface Toast : CDVPlugin @interface Toast : CDVPlugin
- (void)show:(CDVInvokedUrlCommand*)command; - (void)show:(CDVInvokedUrlCommand*)command;
- (void)hide:(CDVInvokedUrlCommand*)command;
@end @end
\ No newline at end of file
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
- (void)show:(CDVInvokedUrlCommand*)command { - (void)show:(CDVInvokedUrlCommand*)command {
NSString *message = [command.arguments objectAtIndex:0]; NSDictionary* options = [command.arguments objectAtIndex:0];
NSString *duration = [command.arguments objectAtIndex:1];
NSString *position = [command.arguments objectAtIndex:2]; NSString *message = [options objectForKey:@"message"];
NSString *duration = [options objectForKey:@"duration"];
NSString *position = [options objectForKey:@"position"];
NSNumber *addPixelsY = [options objectForKey:@"addPixelsY"];
if (![position isEqual: @"top"] && ![position isEqual: @"center"] && ![position isEqual: @"bottom"]) { if (![position isEqual: @"top"] && ![position isEqual: @"center"] && ![position isEqual: @"bottom"]) {
CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"invalid position. valid options are 'top', 'center' and 'bottom'"]; CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"invalid position. valid options are 'top', 'center' and 'bottom'"];
...@@ -27,7 +30,14 @@ ...@@ -27,7 +30,14 @@
return; return;
} }
[self.webView makeToast:message duration:durationInt position:position]; [self.webView makeToast:message duration:durationInt position:position addPixelsY:addPixelsY == nil ? 0 : [addPixelsY intValue]];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
- (void)hide:(CDVInvokedUrlCommand*)command {
[self.webView hideToast];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
......
using System;
using System.Runtime.Serialization;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
...@@ -26,13 +28,44 @@ namespace WPCordovaClassLib.Cordova.Commands ...@@ -26,13 +28,44 @@ namespace WPCordovaClassLib.Cordova.Commands
} }
} }
[DataContract]
public class ToastOptions
{
[DataMember(IsRequired = true, Name = "message")]
public string message { get; set; }
[DataMember(IsRequired = true, Name = "duration")]
public string duration { get; set; }
[DataMember(IsRequired = true, Name = "position")]
public string position { get; set; }
[DataMember(IsRequired = false, Name = "addPixelsY")]
public int addPixelsY { get; set; }
}
public void show(string options) public void show(string options)
{ {
ToastOptions toastOptions;
string[] args = JSON.JsonHelper.Deserialize<string[]>(options); string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
var message = args[0]; String jsonOptions = args[0];
var duration = args[1];
var position = args[2]; try
string aliasCurrentCommandCallbackId = args[3]; {
toastOptions = JSON.JsonHelper.Deserialize<ToastOptions>(jsonOptions);
}
catch (Exception)
{
DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
return;
}
var message = toastOptions.message;
var duration = toastOptions.duration;
var position = toastOptions.position;
int addPixelsY = toastOptions.addPixelsY;
string aliasCurrentCommandCallbackId = args[1];
Deployment.Current.Dispatcher.BeginInvoke(() => Deployment.Current.Dispatcher.BeginInvoke(() =>
{ {
...@@ -75,17 +108,17 @@ namespace WPCordovaClassLib.Cordova.Commands ...@@ -75,17 +108,17 @@ namespace WPCordovaClassLib.Cordova.Commands
if ("top".Equals(position)) if ("top".Equals(position))
{ {
popup.VerticalAlignment = VerticalAlignment.Top; popup.VerticalAlignment = VerticalAlignment.Top;
popup.VerticalOffset = 20; popup.VerticalOffset = 20 + addPixelsY;
} }
else if ("bottom".Equals(position)) else if ("bottom".Equals(position))
{ {
popup.VerticalAlignment = VerticalAlignment.Bottom; popup.VerticalAlignment = VerticalAlignment.Bottom;
popup.VerticalOffset = -100; // TODO can do better popup.VerticalOffset = -100 + addPixelsY; // TODO can do better
} }
else if ("center".Equals(position)) else if ("center".Equals(position))
{ {
popup.VerticalAlignment = VerticalAlignment.Center; popup.VerticalAlignment = VerticalAlignment.Center;
popup.VerticalOffset = -50; // TODO can do way better popup.VerticalOffset = -50 + addPixelsY; // TODO can do way better
} }
else else
{ {
...@@ -116,6 +149,17 @@ namespace WPCordovaClassLib.Cordova.Commands ...@@ -116,6 +149,17 @@ namespace WPCordovaClassLib.Cordova.Commands
}); });
} }
public void hide(string options)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (popup != null && popup.IsOpen)
{
popup.IsOpen = false;
}
});
}
private async void hidePopup(int delay) private async void hidePopup(int delay)
{ {
await Task.Delay(delay); await Task.Delay(delay);
......
exports.defineAutoTests = function() { exports.defineAutoTests = function() {
var fail = function (done) { var fail = function (done) {
expect(true).toBe(false); expect(true).toBe(false);
done(); done();
...@@ -20,6 +20,14 @@ exports.defineAutoTests = function() { ...@@ -20,6 +20,14 @@ exports.defineAutoTests = function() {
expect(window.plugins.toast.show).toBeDefined(); expect(window.plugins.toast.show).toBeDefined();
}); });
it("should define showWithOptions", function() {
expect(window.plugins.toast.showWithOptions).toBeDefined();
});
it("should define optionsBuilder", function() {
expect(window.plugins.toast.optionsBuilder).toBeDefined();
});
it("should define showShortTop", function() { it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined(); expect(window.plugins.toast.showShortTop).toBeDefined();
}); });
...@@ -47,11 +55,7 @@ exports.defineAutoTests = function() { ...@@ -47,11 +55,7 @@ exports.defineAutoTests = function() {
describe('Invalid usage', function () { describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) { it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done)); window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
it("should fail due to an invalid duration", function(done) {
window.plugins.toast.show('hi', 'medium', 'top', fail.bind(null, done), succeed.bind(null, done));
}); });
}); });
}; };
function Toast() { function Toast() {
} }
Toast.prototype.optionsBuilder = function () {
// defaults
var message = null;
var duration = "short";
var position = "center";
var addPixelsY = 0;
return {
withMessage: function(m) {
message = m;
return this;
},
withDuration: function(d) {
duration = d;
return this;
},
withPosition: function(p) {
position = p;
return this;
},
withAddPixelsY: function(y) {
addPixelsY = y;
return this;
},
build: function() {
return {
message: message,
duration: duration,
position: position,
addPixelsY: addPixelsY
}
}
}
};
Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
};
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) { Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [message, duration, position]); this.showWithOptions(
this.optionsBuilder()
.withMessage(message)
.withDuration(duration)
.withPosition(position)
.build(),
successCallback,
errorCallback);
}; };
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) { Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba ...@@ -29,6 +81,10 @@ Toast.prototype.showLongBottom = function (message, successCallback, errorCallba
this.show(message, "long", "bottom", successCallback, errorCallback); this.show(message, "long", "bottom", successCallback, errorCallback);
}; };
Toast.prototype.hide = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
};
Toast.install = function () { Toast.install = function () {
if (!window.plugins) { if (!window.plugins) {
window.plugins = {}; window.plugins = {};
......
...@@ -13,12 +13,6 @@ ...@@ -13,12 +13,6 @@
"path": "../cordova-plugin-email-composer" "path": "../cordova-plugin-email-composer"
} }
}, },
"android.support.v4": {
"source": {
"type": "registry",
"id": "android.support.v4"
}
},
"de.appplant.cordova.common.RegisterUserNotificationSettings": { "de.appplant.cordova.common.RegisterUserNotificationSettings": {
"source": { "source": {
"type": "git", "type": "git",
...@@ -44,14 +38,6 @@ ...@@ -44,14 +38,6 @@
"id": "de.appplant.cordova.plugin.hidden-statusbar-overlay" "id": "de.appplant.cordova.plugin.hidden-statusbar-overlay"
} }
}, },
"nl.x-services.plugins.toast": {
"source": {
"type": "registry",
"id": "nl.x-services.plugins.toast"
},
"is_top_level": true,
"variables": {}
},
"cordova-plugin-device": { "cordova-plugin-device": {
"source": { "source": {
"type": "registry", "type": "registry",
...@@ -68,6 +54,22 @@ ...@@ -68,6 +54,22 @@
"is_top_level": false, "is_top_level": false,
"variables": {} "variables": {}
}, },
"cordova-plugin-x-toast": {
"source": {
"type": "registry",
"id": "cordova-plugin-x-toast"
},
"is_top_level": true,
"variables": {}
},
"cordova-android-support-v4": {
"source": {
"type": "registry",
"id": "cordova-android-support-v4"
},
"is_top_level": true,
"variables": {}
},
"de.appplant.cordova.plugin.local-notification": { "de.appplant.cordova.plugin.local-notification": {
"source": { "source": {
"type": "local", "type": "local",
......
...@@ -4,54 +4,24 @@ ...@@ -4,54 +4,24 @@
"uninstalled": [] "uninstalled": []
}, },
"config_munge": { "config_munge": {
"files": { "files": {}
"framework": {
"parents": {
"QuartzCore.framework": [
{
"xml": false,
"count": 1
}
]
}
},
"config.xml": {
"parents": {
"/*": [
{
"xml": "<feature name=\"Toast\"><param name=\"ios-package\" value=\"Toast\" /></feature>",
"count": 1
},
{
"xml": "<feature name=\"Device\"><param name=\"ios-package\" value=\"CDVDevice\" /></feature>",
"count": 1
},
{
"xml": "<feature name=\"LocalNotification\"><param name=\"ios-package\" onload=\"true\" value=\"APPLocalNotification\" /><param name=\"onload\" value=\"true\" /></feature>",
"count": 1
}
]
}
}
}
}, },
"installed_plugins": { "installed_plugins": {
"android.support.v4": { "cordova-android-support-v4": {
"PACKAGE_NAME": "de.appplant.localnotification.example" "PACKAGE_NAME": "de.appplant.localnotification.example"
}, },
"de.appplant.cordova.common.registerusernotificationsettings": { "cordova-plugin-device": {
"PACKAGE_NAME": "de.appplant.localnotification.example" "PACKAGE_NAME": "de.appplant.localnotification.example"
}, },
"nl.x-services.plugins.toast": { "cordova-plugin-x-toast": {
"PACKAGE_NAME": "de.appplant.localnotification.example"
},
"de.appplant.cordova.common.registerusernotificationsettings": {
"PACKAGE_NAME": "de.appplant.localnotification.example" "PACKAGE_NAME": "de.appplant.localnotification.example"
}, },
"de.appplant.cordova.plugin.local-notification": { "de.appplant.cordova.plugin.local-notification": {
"PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)" "PACKAGE_NAME": "de.appplant.localnotification.example"
} }
}, },
"dependent_plugins": { "dependent_plugins": {}
"cordova-plugin-device": {
"PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
}
}
} }
\ No newline at end of file
...@@ -7,13 +7,13 @@ ...@@ -7,13 +7,13 @@
"files": {} "files": {}
}, },
"installed_plugins": { "installed_plugins": {
"android.support.v4": { "de.appplant.cordova.common.registerusernotificationsettings": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
}, },
"de.appplant.cordova.common.registerusernotificationsettings": { "cordova-plugin-x-toast": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
}, },
"nl.x-services.plugins.toast": { "cordova-android-support-v4": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
}, },
"de.appplant.cordova.plugin.local-notification": { "de.appplant.cordova.plugin.local-notification": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment