You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2013/06/19 02:17:42 UTC
[01/50] [abbrv] git commit: Oops, misplaced a \
Updated Branches:
refs/heads/2.9.x 3503e453d -> d1ecfbcc9
Oops, misplaced a \
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/6c3badc7
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/6c3badc7
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/6c3badc7
Branch: refs/heads/2.9.x
Commit: 6c3badc71d83f010262c7b44f8a57a49765302f9
Parents: 43a181d
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 11:22:38 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 11:23:40 2013 -0700
----------------------------------------------------------------------
wp7/tooling/scripts/createTemplates.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/6c3badc7/wp7/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp7/tooling/scripts/createTemplates.js b/wp7/tooling/scripts/createTemplates.js
index 73f0ec7..b8755cc 100644
--- a/wp7/tooling/scripts/createTemplates.js
+++ b/wp7/tooling/scripts/createTemplates.js
@@ -34,7 +34,7 @@ var templatePath = '\\template';
//Get version number
var versionNum ='0.0.0';
-var platformRoot = WScript.ScriptFullName.split('\\tooling\\', 1);\
+var platformRoot = WScript.ScriptFullName.split('\\tooling\\', 1);
// set with the -install switch, default false
var addToVS = false;
[19/50] [abbrv] moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/www/cordova.js
----------------------------------------------------------------------
diff --git a/wp7/template/www/cordova.js b/wp7/template/www/cordova.js
deleted file mode 100644
index 9ec380f..0000000
--- a/wp7/template/www/cordova.js
+++ /dev/null
@@ -1,6722 +0,0 @@
-// Platform: windowsphone
-// 2.8.0-0-g6208c95
-/*
- 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.
-*/
-;(function() {
-var CORDOVA_JS_BUILD_LABEL = '2.8.0-0-g6208c95';
-// file: lib\scripts\require.js
-
-var require,
- define;
-
-(function () {
- var modules = {},
- // Stack of moduleIds currently being built.
- requireStack = [],
- // Map of module ID -> index into requireStack of modules currently being built.
- inProgressModules = {},
- SEPERATOR = ".";
-
-
-
- function build(module) {
- var factory = module.factory,
- localRequire = function (id) {
- var resultantId = id;
- //Its a relative path, so lop off the last portion and add the id (minus "./")
- if (id.charAt(0) === ".") {
- resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
- }
- return require(resultantId);
- };
- module.exports = {};
- delete module.factory;
- factory(localRequire, module.exports, module);
- return module.exports;
- }
-
- require = function (id) {
- if (!modules[id]) {
- throw "module " + id + " not found";
- } else if (id in inProgressModules) {
- var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
- throw "Cycle in require graph: " + cycle;
- }
- if (modules[id].factory) {
- try {
- inProgressModules[id] = requireStack.length;
- requireStack.push(id);
- return build(modules[id]);
- } finally {
- delete inProgressModules[id];
- requireStack.pop();
- }
- }
- return modules[id].exports;
- };
-
- define = function (id, factory) {
- if (modules[id]) {
- throw "module " + id + " already defined";
- }
-
- modules[id] = {
- id: id,
- factory: factory
- };
- };
-
- define.remove = function (id) {
- delete modules[id];
- };
-
- define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
- module.exports.require = require;
- module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-
-/**
- * Listen for DOMContentLoaded and notify our channel subscribers.
- */
-document.addEventListener('DOMContentLoaded', function() {
- channel.onDOMContentLoaded.fire();
-}, false);
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
- channel.onDOMContentLoaded.fire();
-}
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
- windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof documentEventHandlers[e] != 'undefined') {
- documentEventHandlers[e].subscribe(handler);
- } else {
- m_document_addEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof windowEventHandlers[e] != 'undefined') {
- windowEventHandlers[e].subscribe(handler);
- } else {
- m_window_addEventListener.call(window, evt, handler, capture);
- }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubscribing from an event that is handled by a plugin
- if (typeof documentEventHandlers[e] != "undefined") {
- documentEventHandlers[e].unsubscribe(handler);
- } else {
- m_document_removeEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubscribing from an event that is handled by a plugin
- if (typeof windowEventHandlers[e] != "undefined") {
- windowEventHandlers[e].unsubscribe(handler);
- } else {
- m_window_removeEventListener.call(window, evt, handler, capture);
- }
-};
-
-function createEvent(type, data) {
- var event = document.createEvent('Events');
- event.initEvent(type, false, false);
- if (data) {
- for (var i in data) {
- if (data.hasOwnProperty(i)) {
- event[i] = data[i];
- }
- }
- }
- return event;
-}
-
-if(typeof window.console === "undefined") {
- window.console = {
- log:function(){}
- };
-}
-
-var cordova = {
- define:define,
- require:require,
- /**
- * Methods to add/remove your own addEventListener hijacking on document + window.
- */
- addWindowEventHandler:function(event) {
- return (windowEventHandlers[event] = channel.create(event));
- },
- addStickyDocumentEventHandler:function(event) {
- return (documentEventHandlers[event] = channel.createSticky(event));
- },
- addDocumentEventHandler:function(event) {
- return (documentEventHandlers[event] = channel.create(event));
- },
- removeWindowEventHandler:function(event) {
- delete windowEventHandlers[event];
- },
- removeDocumentEventHandler:function(event) {
- delete documentEventHandlers[event];
- },
- /**
- * Retrieve original event handlers that were replaced by Cordova
- *
- * @return object
- */
- getOriginalHandlers: function() {
- return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
- 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
- },
- /**
- * Method to fire event from native code
- * bNoDetach is required for events which cause an exception which needs to be caught in native code
- */
- fireDocumentEvent: function(type, data, bNoDetach) {
- var evt = createEvent(type, data);
- if (typeof documentEventHandlers[type] != 'undefined') {
- if( bNoDetach ) {
- documentEventHandlers[type].fire(evt);
- }
- else {
- setTimeout(function() {
- // Fire deviceready on listeners that were registered before cordova.js was loaded.
- if (type == 'deviceready') {
- document.dispatchEvent(evt);
- }
- documentEventHandlers[type].fire(evt);
- }, 0);
- }
- } else {
- document.dispatchEvent(evt);
- }
- },
- fireWindowEvent: function(type, data) {
- var evt = createEvent(type,data);
- if (typeof windowEventHandlers[type] != 'undefined') {
- setTimeout(function() {
- windowEventHandlers[type].fire(evt);
- }, 0);
- } else {
- window.dispatchEvent(evt);
- }
- },
-
- /**
- * Plugin callback mechanism.
- */
- // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
- // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
- callbackId: Math.floor(Math.random() * 2000000000),
- callbacks: {},
- callbackStatus: {
- NO_RESULT: 0,
- OK: 1,
- CLASS_NOT_FOUND_EXCEPTION: 2,
- ILLEGAL_ACCESS_EXCEPTION: 3,
- INSTANTIATION_EXCEPTION: 4,
- MALFORMED_URL_EXCEPTION: 5,
- IO_EXCEPTION: 6,
- INVALID_ACTION: 7,
- JSON_EXCEPTION: 8,
- ERROR: 9
- },
-
- /**
- * Called by native code when returning successful result from an action.
- */
- callbackSuccess: function(callbackId, args) {
- try {
- cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
- } catch (e) {
- console.log("Error in error callback: " + callbackId + " = "+e);
- }
- },
-
- /**
- * Called by native code when returning error result from an action.
- */
- callbackError: function(callbackId, args) {
- // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
- // Derive success from status.
- try {
- cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
- } catch (e) {
- console.log("Error in error callback: " + callbackId + " = "+e);
- }
- },
-
- /**
- * Called by native code when returning the result from an action.
- */
- callbackFromNative: function(callbackId, success, status, args, keepCallback) {
- var callback = cordova.callbacks[callbackId];
- if (callback) {
- if (success && status == cordova.callbackStatus.OK) {
- callback.success && callback.success.apply(null, args);
- } else if (!success) {
- callback.fail && callback.fail.apply(null, args);
- }
-
- // Clear callback if not expecting any more results
- if (!keepCallback) {
- delete cordova.callbacks[callbackId];
- }
- }
- },
- addConstructor: function(func) {
- channel.onCordovaReady.subscribe(function() {
- try {
- func();
- } catch(e) {
- console.log("Failed to run constructor: " + e);
- }
- });
- }
-};
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-module.exports = cordova;
-
-});
-
-// file: lib\common\argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
- 'A': 'Array',
- 'D': 'Date',
- 'N': 'Number',
- 'S': 'String',
- 'F': 'Function',
- 'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
- return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
- if (!moduleExports.enableChecks) {
- return;
- }
- var errMsg = null;
- var typeName;
- for (var i = 0; i < spec.length; ++i) {
- var c = spec.charAt(i),
- cUpper = c.toUpperCase(),
- arg = args[i];
- // Asterix means allow anything.
- if (c == '*') {
- continue;
- }
- typeName = utils.typeName(arg);
- if ((arg === null || arg === undefined) && c == cUpper) {
- continue;
- }
- if (typeName != typeMap[cUpper]) {
- errMsg = 'Expected ' + typeMap[cUpper];
- break;
- }
- }
- if (errMsg) {
- errMsg += ', but got ' + typeName + '.';
- errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
- // Don't log when running jake test.
- if (typeof jasmine == 'undefined') {
- console.error(errMsg);
- }
- throw TypeError(errMsg);
- }
-}
-
-function getValue(value, defaultValue) {
- return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// file: lib\common\builder.js
-define("cordova/builder", function(require, exports, module) {
-
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
- for (var prop in objects) {
- if (objects.hasOwnProperty(prop)) {
- func.apply(context, [objects[prop], prop]);
- }
- }
-}
-
-function clobber(obj, key, value) {
- exports.replaceHookForTesting(obj, key);
- obj[key] = value;
- // Getters can only be overridden by getters.
- if (obj[key] !== value) {
- utils.defineGetter(obj, key, function() {
- return value;
- });
- }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
- if (message) {
- utils.defineGetter(obj, key, function() {
- console.log(message);
- delete obj[key];
- clobber(obj, key, value);
- return value;
- });
- } else {
- clobber(obj, key, value);
- }
-}
-
-function include(parent, objects, clobber, merge) {
- each(objects, function (obj, key) {
- try {
- var result = obj.path ? require(obj.path) : {};
-
- if (clobber) {
- // Clobber if it doesn't exist.
- if (typeof parent[key] === 'undefined') {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- } else if (typeof obj.path !== 'undefined') {
- // If merging, merge properties onto parent, otherwise, clobber.
- if (merge) {
- recursiveMerge(parent[key], result);
- } else {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- }
- }
- result = parent[key];
- } else {
- // Overwrite if not currently defined.
- if (typeof parent[key] == 'undefined') {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- } else {
- // Set result to what already exists, so we can build children into it if they exist.
- result = parent[key];
- }
- }
-
- if (obj.children) {
- include(result, obj.children, clobber, merge);
- }
- } catch(e) {
- utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
- }
- });
-}
-
-/**
- * Merge properties from one object onto another recursively. Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
- for (var prop in src) {
- if (src.hasOwnProperty(prop)) {
- if (target.prototype && target.prototype.constructor === target) {
- // If the target object is a constructor override off prototype.
- clobber(target.prototype, prop, src[prop]);
- } else {
- if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
- recursiveMerge(target[prop], src[prop]);
- } else {
- clobber(target, prop, src[prop]);
- }
- }
- }
- }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
- include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
- include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
- include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib\common\channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
- nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
- * onNativeReady* Internal event that indicates the Cordova native side is ready.
- * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
- * onCordovaInfoReady* Internal event fired when device properties are available.
- * onCordovaConnectionReady* Internal event fired when the connection property has been set.
- * onDeviceReady* User event fired to indicate that Cordova is ready
- * onResume User event fired to indicate a start/resume lifecycle event
- * onPause User event fired to indicate a pause lifecycle event
- * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
- * pause App has moved to background
- * resume App has returned to foreground
- *
- * Listeners can be registered as:
- * document.addEventListener("deviceready", myDeviceReadyListener, false);
- * document.addEventListener("resume", myResumeListener, false);
- * document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- * window.onload
- * window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type String the channel name
- */
-var Channel = function(type, sticky) {
- this.type = type;
- // Map of guid -> function.
- this.handlers = {};
- // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
- this.state = sticky ? 1 : 0;
- // Used in sticky mode to remember args passed to fire().
- this.fireArgs = null;
- // Used by onHasSubscribersChange to know if there are any listeners.
- this.numHandlers = 0;
- // Function that is called when the first listener is subscribed, or when
- // the last listener is unsubscribed.
- this.onHasSubscribersChange = null;
-},
- channel = {
- /**
- * Calls the provided function only after all of the channels specified
- * have been fired. All channels must be sticky channels.
- */
- join: function(h, c) {
- var len = c.length,
- i = len,
- f = function() {
- if (!(--i)) h();
- };
- for (var j=0; j<len; j++) {
- if (c[j].state === 0) {
- throw Error('Can only use join with sticky channels.');
- }
- c[j].subscribe(f);
- }
- if (!len) h();
- },
- create: function(type) {
- return channel[type] = new Channel(type, false);
- },
- createSticky: function(type) {
- return channel[type] = new Channel(type, true);
- },
-
- /**
- * cordova Channels that must fire before "deviceready" is fired.
- */
- deviceReadyChannelsArray: [],
- deviceReadyChannelsMap: {},
-
- /**
- * Indicate that a feature needs to be initialized before it is ready to be used.
- * This holds up Cordova's "deviceready" event until the feature has been initialized
- * and Cordova.initComplete(feature) is called.
- *
- * @param feature {String} The unique feature name
- */
- waitForInitialization: function(feature) {
- if (feature) {
- var c = channel[feature] || this.createSticky(feature);
- this.deviceReadyChannelsMap[feature] = c;
- this.deviceReadyChannelsArray.push(c);
- }
- },
-
- /**
- * Indicate that initialization code has completed and the feature is ready to be used.
- *
- * @param feature {String} The unique feature name
- */
- initializationComplete: function(feature) {
- var c = this.deviceReadyChannelsMap[feature];
- if (c) {
- c.fire();
- }
- }
- };
-
-function forceFunction(f) {
- if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
- // need a function to call
- forceFunction(f);
- if (this.state == 2) {
- f.apply(c || this, this.fireArgs);
- return;
- }
-
- var func = f,
- guid = f.observer_guid;
- if (typeof c == "object") { func = utils.close(c, f); }
-
- if (!guid) {
- // first time any channel has seen this subscriber
- guid = '' + nextGuid++;
- }
- func.observer_guid = guid;
- f.observer_guid = guid;
-
- // Don't add the same handler more than once.
- if (!this.handlers[guid]) {
- this.handlers[guid] = func;
- this.numHandlers++;
- if (this.numHandlers == 1) {
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
- // need a function to unsubscribe
- forceFunction(f);
-
- var guid = f.observer_guid,
- handler = this.handlers[guid];
- if (handler) {
- delete this.handlers[guid];
- this.numHandlers--;
- if (this.numHandlers === 0) {
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
- var fail = false,
- fireArgs = Array.prototype.slice.call(arguments);
- // Apply stickiness.
- if (this.state == 1) {
- this.state = 2;
- this.fireArgs = fireArgs;
- }
- if (this.numHandlers) {
- // Copy the values first so that it is safe to modify it from within
- // callbacks.
- var toCall = [];
- for (var item in this.handlers) {
- toCall.push(this.handlers[item]);
- }
- for (var i = 0; i < toCall.length; ++i) {
- toCall[i].apply(this, fireArgs);
- }
- if (this.state == 2 && this.numHandlers) {
- this.numHandlers = 0;
- this.handlers = {};
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that device properties are available
-channel.createSticky('onCordovaInfoReady');
-
-// Event to indicate that the connection property has been set.
-channel.createSticky('onCordovaConnectionReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onCordovaConnectionReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib\common\commandProxy.js
-define("cordova/commandProxy", function(require, exports, module) {
-
-
-// internal map of proxy function
-var CommandProxyMap = {};
-
-module.exports = {
-
- // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
- add:function(id,proxyObj) {
- console.log("adding proxy for " + id);
- CommandProxyMap[id] = proxyObj;
- return proxyObj;
- },
-
- // cordova.commandProxy.remove("Accelerometer");
- remove:function(id) {
- var proxy = CommandProxyMap[id];
- delete CommandProxyMap[id];
- CommandProxyMap[id] = null;
- return proxy;
- },
-
- get:function(service,action) {
- return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
- }
-};
-});
-
-// file: lib\windowsphone\exec.js
-define("cordova/exec", function(require, exports, module) {
-
-var cordova = require('cordova');
-
-/**
- * Execute a cordova command. It is up to the native side whether this action
- * is synchronous or asynchronous. The native side can return:
- * Synchronous: PluginResult object as a JSON string
- * Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success The success callback
- * @param {Function} fail The fail callback
- * @param {String} service The name of the service to use
- * @param {String} action Action to be run in cordova
- * @param {String[]} [args] Zero or more arguments to pass to the method
-
- */
-
-module.exports = function(success, fail, service, action, args) {
-
- var callbackId = service + cordova.callbackId++;
- if (typeof success == "function" || typeof fail == "function") {
- cordova.callbacks[callbackId] = {success:success, fail:fail};
- }
- // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
- for(var n = 0; n < args.length; n++)
- {
- if(typeof args[n] !== "string")
- {
- args[n] = JSON.stringify(args[n]);
- }
- }
- var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
- // pass it on to Notify
- try {
- if(window.external) {
- window.external.Notify(command);
- }
- else {
- console.log("window.external not available :: command=" + command);
- }
- }
- catch(e) {
- console.log("Exception calling native with command :: " + command + " :: exception=" + e);
- }
-};
-
-
-});
-
-// file: lib\common\modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
- moduleMap = define.moduleMap,
- symbolList,
- deprecationMap;
-
-exports.reset = function() {
- symbolList = [];
- deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
- if (!(moduleName in moduleMap)) {
- throw new Error('Module ' + moduleName + ' does not exist.');
- }
- 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);
-};
-
-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 symbolPath = symbolList[i + 2];
- var lastDot = symbolPath.lastIndexOf('.');
- var namespace = symbolPath.substr(0, lastDot);
- var lastName = symbolPath.substr(lastDot + 1);
-
- var module = require(moduleName);
- 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.loadMatchingModules = function(matchingRegExp) {
- for (var k in moduleMap) {
- if (matchingRegExp.exec(k)) {
- require(k);
- }
- }
-};
-
-exports.reset();
-
-
-});
-
-// file: lib\windowsphone\platform.js
-define("cordova/platform", function(require, exports, module) {
-
-var cordova = require('cordova'),
- exec = require('cordova/exec');
-
-module.exports = {
- id: "windowsphone",
- initialize:function() {
- var modulemapper = require('cordova/modulemapper');
-
- modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
-
- modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
-
- modulemapper.mapModules(window);
-
- // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
- var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
- backButtonChannel.onHasSubscribersChange = function() {
- exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
- };
- }
-};
-
-});
-
-// file: lib\common\plugin\Acceleration.js
-define("cordova/plugin/Acceleration", function(require, exports, module) {
-
-var Acceleration = function(x, y, z, timestamp) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.timestamp = timestamp || (new Date()).getTime();
-};
-
-module.exports = Acceleration;
-
-});
-
-// file: lib\common\plugin\Camera.js
-define("cordova/plugin/Camera", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- Camera = require('cordova/plugin/CameraConstants'),
- CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
-
-var cameraExport = {};
-
-// Tack on the Camera Constants to the base camera plugin.
-for (var key in Camera) {
- cameraExport[key] = Camera[key];
-}
-
-/**
- * Gets a picture from source defined by "options.sourceType", and returns the
- * image as defined by the "options.destinationType" option.
-
- * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
- *
- * @param {Function} successCallback
- * @param {Function} errorCallback
- * @param {Object} options
- */
-cameraExport.getPicture = function(successCallback, errorCallback, options) {
- argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
- options = options || {};
- var getValue = argscheck.getValue;
-
- var quality = getValue(options.quality, 50);
- var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
- var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
- var targetWidth = getValue(options.targetWidth, -1);
- var targetHeight = getValue(options.targetHeight, -1);
- var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
- var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
- var allowEdit = !!options.allowEdit;
- var correctOrientation = !!options.correctOrientation;
- var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
- var popoverOptions = getValue(options.popoverOptions, null);
- var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
-
- var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
-
- exec(successCallback, errorCallback, "Camera", "takePicture", args);
- return new CameraPopoverHandle();
-};
-
-cameraExport.cleanup = function(successCallback, errorCallback) {
- exec(successCallback, errorCallback, "Camera", "cleanup", []);
-};
-
-module.exports = cameraExport;
-
-});
-
-// file: lib\common\plugin\CameraConstants.js
-define("cordova/plugin/CameraConstants", function(require, exports, module) {
-
-module.exports = {
- DestinationType:{
- DATA_URL: 0, // Return base64 encoded string
- FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
- NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
- },
- EncodingType:{
- JPEG: 0, // Return JPEG encoded image
- PNG: 1 // Return PNG encoded image
- },
- MediaType:{
- PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
- VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
- ALLMEDIA : 2 // allow selection from all media types
- },
- PictureSourceType:{
- PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
- CAMERA : 1, // Take picture from camera
- SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
- },
- PopoverArrowDirection:{
- ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
- ARROW_DOWN : 2,
- ARROW_LEFT : 4,
- ARROW_RIGHT : 8,
- ARROW_ANY : 15
- },
- Direction:{
- BACK: 0,
- FRONT: 1
- }
-};
-
-});
-
-// file: lib\common\plugin\CameraPopoverHandle.js
-define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-/**
- * A handle to an image picker popover.
- */
-var CameraPopoverHandle = function() {
- this.setPosition = function(popoverOptions) {
- console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
- };
-};
-
-module.exports = CameraPopoverHandle;
-
-});
-
-// file: lib\common\plugin\CameraPopoverOptions.js
-define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
-
-var Camera = require('cordova/plugin/CameraConstants');
-
-/**
- * Encapsulates options for iOS Popover image picker
- */
-var CameraPopoverOptions = function(x,y,width,height,arrowDir){
- // information of rectangle that popover should be anchored to
- this.x = x || 0;
- this.y = y || 32;
- this.width = width || 320;
- this.height = height || 480;
- // The direction of the popover arrow
- this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
-};
-
-module.exports = CameraPopoverOptions;
-
-});
-
-// file: lib\common\plugin\CaptureAudioOptions.js
-define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all audio capture operation configuration options.
- */
-var CaptureAudioOptions = function(){
- // Upper limit of sound clips user can record. Value must be equal or greater than 1.
- this.limit = 1;
- // Maximum duration of a single sound clip in seconds.
- this.duration = 0;
-};
-
-module.exports = CaptureAudioOptions;
-
-});
-
-// file: lib\common\plugin\CaptureError.js
-define("cordova/plugin/CaptureError", function(require, exports, module) {
-
-/**
- * The CaptureError interface encapsulates all errors in the Capture API.
- */
-var CaptureError = function(c) {
- this.code = c || null;
-};
-
-// Camera or microphone failed to capture image or sound.
-CaptureError.CAPTURE_INTERNAL_ERR = 0;
-// Camera application or audio capture application is currently serving other capture request.
-CaptureError.CAPTURE_APPLICATION_BUSY = 1;
-// Invalid use of the API (e.g. limit parameter has value less than one).
-CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
-// User exited camera application or audio capture application before capturing anything.
-CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
-// The requested capture operation is not supported.
-CaptureError.CAPTURE_NOT_SUPPORTED = 20;
-
-module.exports = CaptureError;
-
-});
-
-// file: lib\common\plugin\CaptureImageOptions.js
-define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all image capture operation configuration options.
- */
-var CaptureImageOptions = function(){
- // Upper limit of images user can take. Value must be equal or greater than 1.
- this.limit = 1;
-};
-
-module.exports = CaptureImageOptions;
-
-});
-
-// file: lib\common\plugin\CaptureVideoOptions.js
-define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all video capture operation configuration options.
- */
-var CaptureVideoOptions = function(){
- // Upper limit of videos user can record. Value must be equal or greater than 1.
- this.limit = 1;
- // Maximum duration of a single video clip in seconds.
- this.duration = 0;
-};
-
-module.exports = CaptureVideoOptions;
-
-});
-
-// file: lib\common\plugin\CompassError.js
-define("cordova/plugin/CompassError", function(require, exports, module) {
-
-/**
- * CompassError.
- * An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var CompassError = function(err) {
- this.code = (err !== undefined ? err : null);
-};
-
-CompassError.COMPASS_INTERNAL_ERR = 0;
-CompassError.COMPASS_NOT_SUPPORTED = 20;
-
-module.exports = CompassError;
-
-});
-
-// file: lib\common\plugin\CompassHeading.js
-define("cordova/plugin/CompassHeading", function(require, exports, module) {
-
-var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
- this.magneticHeading = magneticHeading;
- this.trueHeading = trueHeading;
- this.headingAccuracy = headingAccuracy;
- this.timestamp = timestamp || new Date().getTime();
-};
-
-module.exports = CompassHeading;
-
-});
-
-// file: lib\common\plugin\ConfigurationData.js
-define("cordova/plugin/ConfigurationData", function(require, exports, module) {
-
-/**
- * Encapsulates a set of parameters that the capture device supports.
- */
-function ConfigurationData() {
- // The ASCII-encoded string in lower case representing the media type.
- this.type = null;
- // The height attribute represents height of the image or video in pixels.
- // In the case of a sound clip this attribute has value 0.
- this.height = 0;
- // The width attribute represents width of the image or video in pixels.
- // In the case of a sound clip this attribute has value 0
- this.width = 0;
-}
-
-module.exports = ConfigurationData;
-
-});
-
-// file: lib\common\plugin\Connection.js
-define("cordova/plugin/Connection", function(require, exports, module) {
-
-/**
- * Network status
- */
-module.exports = {
- UNKNOWN: "unknown",
- ETHERNET: "ethernet",
- WIFI: "wifi",
- CELL_2G: "2g",
- CELL_3G: "3g",
- CELL_4G: "4g",
- CELL:"cellular",
- NONE: "none"
-};
-
-});
-
-// file: lib\common\plugin\Contact.js
-define("cordova/plugin/Contact", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- ContactError = require('cordova/plugin/ContactError'),
- utils = require('cordova/utils');
-
-/**
-* Converts primitives into Complex Object
-* Currently only used for Date fields
-*/
-function convertIn(contact) {
- var value = contact.birthday;
- try {
- contact.birthday = new Date(parseFloat(value));
- } catch (exception){
- console.log("Cordova Contact convertIn error: exception creating date.");
- }
- return contact;
-}
-
-/**
-* Converts Complex objects into primitives
-* Only conversion at present is for Dates.
-**/
-
-function convertOut(contact) {
- var value = contact.birthday;
- if (value !== null) {
- // try to make it a Date object if it is not already
- if (!utils.isDate(value)){
- try {
- value = new Date(value);
- } catch(exception){
- value = null;
- }
- }
- if (utils.isDate(value)){
- value = value.valueOf(); // convert to milliseconds
- }
- contact.birthday = value;
- }
- return contact;
-}
-
-/**
-* Contains information about a single contact.
-* @constructor
-* @param {DOMString} id unique identifier
-* @param {DOMString} displayName
-* @param {ContactName} name
-* @param {DOMString} nickname
-* @param {Array.<ContactField>} phoneNumbers array of phone numbers
-* @param {Array.<ContactField>} emails array of email addresses
-* @param {Array.<ContactAddress>} addresses array of addresses
-* @param {Array.<ContactField>} ims instant messaging user ids
-* @param {Array.<ContactOrganization>} organizations
-* @param {DOMString} birthday contact's birthday
-* @param {DOMString} note user notes about contact
-* @param {Array.<ContactField>} photos
-* @param {Array.<ContactField>} categories
-* @param {Array.<ContactField>} urls contact's web sites
-*/
-var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
- ims, organizations, birthday, note, photos, categories, urls) {
- this.id = id || null;
- this.rawId = null;
- this.displayName = displayName || null;
- this.name = name || null; // ContactName
- this.nickname = nickname || null;
- this.phoneNumbers = phoneNumbers || null; // ContactField[]
- this.emails = emails || null; // ContactField[]
- this.addresses = addresses || null; // ContactAddress[]
- this.ims = ims || null; // ContactField[]
- this.organizations = organizations || null; // ContactOrganization[]
- this.birthday = birthday || null;
- this.note = note || null;
- this.photos = photos || null; // ContactField[]
- this.categories = categories || null; // ContactField[]
- this.urls = urls || null; // ContactField[]
-};
-
-/**
-* Removes contact from device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.remove = function(successCB, errorCB) {
- argscheck.checkArgs('FF', 'Contact.remove', arguments);
- var fail = errorCB && function(code) {
- errorCB(new ContactError(code));
- };
- if (this.id === null) {
- fail(ContactError.UNKNOWN_ERROR);
- }
- else {
- exec(successCB, fail, "Contacts", "remove", [this.id]);
- }
-};
-
-/**
-* Creates a deep copy of this Contact.
-* With the contact ID set to null.
-* @return copy of this Contact
-*/
-Contact.prototype.clone = function() {
- var clonedContact = utils.clone(this);
- clonedContact.id = null;
- clonedContact.rawId = null;
-
- function nullIds(arr) {
- if (arr) {
- for (var i = 0; i < arr.length; ++i) {
- arr[i].id = null;
- }
- }
- }
-
- // Loop through and clear out any id's in phones, emails, etc.
- nullIds(clonedContact.phoneNumbers);
- nullIds(clonedContact.emails);
- nullIds(clonedContact.addresses);
- nullIds(clonedContact.ims);
- nullIds(clonedContact.organizations);
- nullIds(clonedContact.categories);
- nullIds(clonedContact.photos);
- nullIds(clonedContact.urls);
- return clonedContact;
-};
-
-/**
-* Persists contact to device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.save = function(successCB, errorCB) {
- argscheck.checkArgs('FFO', 'Contact.save', arguments);
- var fail = errorCB && function(code) {
- errorCB(new ContactError(code));
- };
- var success = function(result) {
- if (result) {
- if (successCB) {
- var fullContact = require('cordova/plugin/contacts').create(result);
- successCB(convertIn(fullContact));
- }
- }
- else {
- // no Entry object returned
- fail(ContactError.UNKNOWN_ERROR);
- }
- };
- var dupContact = convertOut(utils.clone(this));
- exec(success, fail, "Contacts", "save", [dupContact]);
-};
-
-
-module.exports = Contact;
-
-});
-
-// file: lib\common\plugin\ContactAddress.js
-define("cordova/plugin/ContactAddress", function(require, exports, module) {
-
-/**
-* Contact address.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code
-* @param formatted // NOTE: not a W3C standard
-* @param streetAddress
-* @param locality
-* @param region
-* @param postalCode
-* @param country
-*/
-
-var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.formatted = formatted || null;
- this.streetAddress = streetAddress || null;
- this.locality = locality || null;
- this.region = region || null;
- this.postalCode = postalCode || null;
- this.country = country || null;
-};
-
-module.exports = ContactAddress;
-
-});
-
-// file: lib\common\plugin\ContactError.js
-define("cordova/plugin/ContactError", function(require, exports, module) {
-
-/**
- * ContactError.
- * An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var ContactError = function(err) {
- this.code = (typeof err != 'undefined' ? err : null);
-};
-
-/**
- * Error codes
- */
-ContactError.UNKNOWN_ERROR = 0;
-ContactError.INVALID_ARGUMENT_ERROR = 1;
-ContactError.TIMEOUT_ERROR = 2;
-ContactError.PENDING_OPERATION_ERROR = 3;
-ContactError.IO_ERROR = 4;
-ContactError.NOT_SUPPORTED_ERROR = 5;
-ContactError.PERMISSION_DENIED_ERROR = 20;
-
-module.exports = ContactError;
-
-});
-
-// file: lib\common\plugin\ContactField.js
-define("cordova/plugin/ContactField", function(require, exports, module) {
-
-/**
-* Generic contact field.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param type
-* @param value
-* @param pref
-*/
-var ContactField = function(type, value, pref) {
- this.id = null;
- this.type = (type && type.toString()) || null;
- this.value = (value && value.toString()) || null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
-};
-
-module.exports = ContactField;
-
-});
-
-// file: lib\common\plugin\ContactFindOptions.js
-define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
-
-/**
- * ContactFindOptions.
- * @constructor
- * @param filter used to match contacts against
- * @param multiple boolean used to determine if more than one contact should be returned
- */
-
-var ContactFindOptions = function(filter, multiple) {
- this.filter = filter || '';
- this.multiple = (typeof multiple != 'undefined' ? multiple : false);
-};
-
-module.exports = ContactFindOptions;
-
-});
-
-// file: lib\common\plugin\ContactName.js
-define("cordova/plugin/ContactName", function(require, exports, module) {
-
-/**
-* Contact name.
-* @constructor
-* @param formatted // NOTE: not part of W3C standard
-* @param familyName
-* @param givenName
-* @param middle
-* @param prefix
-* @param suffix
-*/
-var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
- this.formatted = formatted || null;
- this.familyName = familyName || null;
- this.givenName = givenName || null;
- this.middleName = middle || null;
- this.honorificPrefix = prefix || null;
- this.honorificSuffix = suffix || null;
-};
-
-module.exports = ContactName;
-
-});
-
-// file: lib\common\plugin\ContactOrganization.js
-define("cordova/plugin/ContactOrganization", function(require, exports, module) {
-
-/**
-* Contact organization.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param name
-* @param dept
-* @param title
-* @param startDate
-* @param endDate
-* @param location
-* @param desc
-*/
-
-var ContactOrganization = function(pref, type, name, dept, title) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.name = name || null;
- this.department = dept || null;
- this.title = title || null;
-};
-
-module.exports = ContactOrganization;
-
-});
-
-// file: lib\common\plugin\Coordinates.js
-define("cordova/plugin/Coordinates", function(require, exports, module) {
-
-/**
- * This class contains position information.
- * @param {Object} lat
- * @param {Object} lng
- * @param {Object} alt
- * @param {Object} acc
- * @param {Object} head
- * @param {Object} vel
- * @param {Object} altacc
- * @constructor
- */
-var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
- /**
- * The latitude of the position.
- */
- this.latitude = lat;
- /**
- * The longitude of the position,
- */
- this.longitude = lng;
- /**
- * The accuracy of the position.
- */
- this.accuracy = acc;
- /**
- * The altitude of the position.
- */
- this.altitude = (alt !== undefined ? alt : null);
- /**
- * The direction the device is moving at the position.
- */
- this.heading = (head !== undefined ? head : null);
- /**
- * The velocity with which the device is moving at the position.
- */
- this.speed = (vel !== undefined ? vel : null);
-
- if (this.speed === 0 || this.speed === null) {
- this.heading = NaN;
- }
-
- /**
- * The altitude accuracy of the position.
- */
- this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
-};
-
-module.exports = Coordinates;
-
-});
-
-// file: lib\common\plugin\DirectoryEntry.js
-define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileError = require('cordova/plugin/FileError'),
- DirectoryReader = require('cordova/plugin/DirectoryReader');
-
-/**
- * An interface representing a directory on the file system.
- *
- * {boolean} isFile always false (readonly)
- * {boolean} isDirectory always true (readonly)
- * {DOMString} name of the directory, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the directory (readonly)
- * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
- */
-var DirectoryEntry = function(name, fullPath) {
- DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
-};
-
-utils.extend(DirectoryEntry, Entry);
-
-/**
- * Creates a new DirectoryReader to read entries from this directory
- */
-DirectoryEntry.prototype.createReader = function() {
- return new DirectoryReader(this.fullPath);
-};
-
-/**
- * Creates or looks up a directory
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
- * @param {Flags} options to create or exclusively create the directory
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
- argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
- var win = successCallback && function(result) {
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
-};
-
-/**
- * Deletes a directory and all of it's contents
- *
- * @param {Function} successCallback is called with no parameters
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
-};
-
-/**
- * Creates or looks up a file
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
- * @param {Flags} options to create or exclusively create the file
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
- argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
- var win = successCallback && function(result) {
- var FileEntry = require('cordova/plugin/FileEntry');
- var entry = new FileEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
-};
-
-module.exports = DirectoryEntry;
-
-});
-
-// file: lib\common\plugin\DirectoryReader.js
-define("cordova/plugin/DirectoryReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError') ;
-
-/**
- * An interface that lists the files and directories in a directory.
- */
-function DirectoryReader(path) {
- this.path = path || null;
-}
-
-/**
- * Returns a list of entries from a directory.
- *
- * @param {Function} successCallback is called with a list of entries
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
- var win = typeof successCallback !== 'function' ? null : function(result) {
- var retVal = [];
- for (var i=0; i<result.length; i++) {
- var entry = null;
- if (result[i].isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result[i].isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result[i].isDirectory;
- entry.isFile = result[i].isFile;
- entry.name = result[i].name;
- entry.fullPath = result[i].fullPath;
- retVal.push(entry);
- }
- successCallback(retVal);
- };
- var fail = typeof errorCallback !== 'function' ? null : function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "readEntries", [this.path]);
-};
-
-module.exports = DirectoryReader;
-
-});
-
-// file: lib\common\plugin\Entry.js
-define("cordova/plugin/Entry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError'),
- Metadata = require('cordova/plugin/Metadata');
-
-/**
- * Represents a file or directory on the local file system.
- *
- * @param isFile
- * {boolean} true if Entry is a file (readonly)
- * @param isDirectory
- * {boolean} true if Entry is a directory (readonly)
- * @param name
- * {DOMString} name of the file or directory, excluding the path
- * leading to it (readonly)
- * @param fullPath
- * {DOMString} the absolute full path to the file or directory
- * (readonly)
- */
-function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
- this.isFile = !!isFile;
- this.isDirectory = !!isDirectory;
- this.name = name || '';
- this.fullPath = fullPath || '';
- this.filesystem = fileSystem || null;
-}
-
-/**
- * Look up the metadata of the entry.
- *
- * @param successCallback
- * {Function} is called with a Metadata object
- * @param errorCallback
- * {Function} is called with a FileError
- */
-Entry.prototype.getMetadata = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
- var success = successCallback && function(lastModified) {
- var metadata = new Metadata(lastModified);
- successCallback(metadata);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
-
- exec(success, fail, "File", "getMetadata", [this.fullPath]);
-};
-
-/**
- * Set the metadata of the entry.
- *
- * @param successCallback
- * {Function} is called with a Metadata object
- * @param errorCallback
- * {Function} is called with a FileError
- * @param metadataObject
- * {Object} keys and values to set
- */
-Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
- argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
- exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
-};
-
-/**
- * Move a file or directory to a new location.
- *
- * @param parent
- * {DirectoryEntry} the directory to which to move this entry
- * @param newName
- * {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- * {Function} called with the new DirectoryEntry object
- * @param errorCallback
- * {Function} called with a FileError
- */
-Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
- argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- // source path
- var srcPath = this.fullPath,
- // entry name
- name = newName || this.name,
- success = function(entry) {
- if (entry) {
- if (successCallback) {
- // create appropriate Entry object
- var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
- successCallback(result);
- }
- }
- else {
- // no Entry object returned
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- // copy
- exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Copy a directory to a different location.
- *
- * @param parent
- * {DirectoryEntry} the directory to which to copy the entry
- * @param newName
- * {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- * {Function} called with the new Entry object
- * @param errorCallback
- * {Function} called with a FileError
- */
-Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
- argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
-
- // source path
- var srcPath = this.fullPath,
- // entry name
- name = newName || this.name,
- // success callback
- success = function(entry) {
- if (entry) {
- if (successCallback) {
- // create appropriate Entry object
- var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
- successCallback(result);
- }
- }
- else {
- // no Entry object returned
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- // copy
- exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Return a URL that can be used to identify this entry.
- */
-Entry.prototype.toURL = function() {
- // fullPath attribute contains the full URL
- return this.fullPath;
-};
-
-/**
- * Returns a URI that can be used to identify this entry.
- *
- * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
- * @return uri
- */
-Entry.prototype.toURI = function(mimeType) {
- console.log("DEPRECATED: Update your code to use 'toURL'");
- // fullPath attribute contains the full URI
- return this.toURL();
-};
-
-/**
- * Remove a file or directory. It is an error to attempt to delete a
- * directory that is not empty. It is an error to attempt to delete a
- * root directory of a file system.
- *
- * @param successCallback {Function} called with no parameters
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.remove = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.remove', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "remove", [this.fullPath]);
-};
-
-/**
- * Look up the parent DirectoryEntry of this entry.
- *
- * @param successCallback {Function} called with the parent DirectoryEntry object
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.getParent = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.getParent', arguments);
- var win = successCallback && function(result) {
- var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getParent", [this.fullPath]);
-};
-
-module.exports = Entry;
-
-});
-
-// file: lib\common\plugin\File.js
-define("cordova/plugin/File", function(require, exports, module) {
-
-/**
- * Constructor.
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-
-var File = function(name, fullPath, type, lastModifiedDate, size){
- this.name = name || '';
- this.fullPath = fullPath || null;
- this.type = type || null;
- this.lastModifiedDate = lastModifiedDate || null;
- this.size = size || 0;
-
- // These store the absolute start and end for slicing the file.
- this.start = 0;
- this.end = this.size;
-};
-
-/**
- * Returns a "slice" of the file. Since Cordova Files don't contain the actual
- * content, this really returns a File with adjusted start and end.
- * Slices of slices are supported.
- * start {Number} The index at which to start the slice (inclusive).
- * end {Number} The index at which to end the slice (exclusive).
- */
-File.prototype.slice = function(start, end) {
- var size = this.end - this.start;
- var newStart = 0;
- var newEnd = size;
- if (arguments.length) {
- if (start < 0) {
- newStart = Math.max(size + start, 0);
- } else {
- newStart = Math.min(size, start);
- }
- }
-
- if (arguments.length >= 2) {
- if (end < 0) {
- newEnd = Math.max(size + end, 0);
- } else {
- newEnd = Math.min(end, size);
- }
- }
-
- var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
- newFile.start = this.start + newStart;
- newFile.end = this.start + newEnd;
- return newFile;
-};
-
-
-module.exports = File;
-
-});
-
-// file: lib\common\plugin\FileEntry.js
-define("cordova/plugin/FileEntry", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileWriter = require('cordova/plugin/FileWriter'),
- File = require('cordova/plugin/File'),
- FileError = require('cordova/plugin/FileError');
-
-/**
- * An interface representing a file on the file system.
- *
- * {boolean} isFile always true (readonly)
- * {boolean} isDirectory always false (readonly)
- * {DOMString} name of the file, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the file (readonly)
- * {FileSystem} filesystem on which the file resides (readonly)
- */
-var FileEntry = function(name, fullPath) {
- FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
-};
-
-utils.extend(FileEntry, Entry);
-
-/**
- * Creates a new FileWriter associated with the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new FileWriter
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
- this.file(function(filePointer) {
- var writer = new FileWriter(filePointer);
-
- if (writer.fileName === null || writer.fileName === "") {
- errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
- } else {
- successCallback && successCallback(writer);
- }
- }, errorCallback);
-};
-
-/**
- * Returns a File that represents the current state of the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new File object
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.file = function(successCallback, errorCallback) {
- var win = successCallback && function(f) {
- var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
- successCallback(file);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
-};
-
-
-module.exports = FileEntry;
-
-});
-
-// file: lib\common\plugin\FileError.js
-define("cordova/plugin/FileError", function(require, exports, module) {
-
-/**
- * FileError
- */
-function FileError(error) {
- this.code = error || null;
-}
-
-// File error codes
-// Found in DOMException
-FileError.NOT_FOUND_ERR = 1;
-FileError.SECURITY_ERR = 2;
-FileError.ABORT_ERR = 3;
-
-// Added by File API specification
-FileError.NOT_READABLE_ERR = 4;
-FileError.ENCODING_ERR = 5;
-FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
-FileError.INVALID_STATE_ERR = 7;
-FileError.SYNTAX_ERR = 8;
-FileError.INVALID_MODIFICATION_ERR = 9;
-FileError.QUOTA_EXCEEDED_ERR = 10;
-FileError.TYPE_MISMATCH_ERR = 11;
-FileError.PATH_EXISTS_ERR = 12;
-
-module.exports = FileError;
-
-});
-
-// file: lib\common\plugin\FileReader.js
-define("cordova/plugin/FileReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
- modulemapper = require('cordova/modulemapper'),
- utils = require('cordova/utils'),
- File = require('cordova/plugin/File'),
- FileError = require('cordova/plugin/FileError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent'),
- origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
-
-/**
- * This class reads the mobile device file system.
- *
- * For Android:
- * The root directory is the root of the file system.
- * To read from the SD card, the file name is "sdcard/my_file.txt"
- * @constructor
- */
-var FileReader = function() {
- this._readyState = 0;
- this._error = null;
- this._result = null;
- this._fileName = '';
- this._realReader = origFileReader ? new origFileReader() : {};
-};
-
-// States
-FileReader.EMPTY = 0;
-FileReader.LOADING = 1;
-FileReader.DONE = 2;
-
-utils.defineGetter(FileReader.prototype, 'readyState', function() {
- return this._fileName ? this._readyState : this._realReader.readyState;
-});
-
-utils.defineGetter(FileReader.prototype, 'error', function() {
- return this._fileName ? this._error: this._realReader.error;
-});
-
-utils.defineGetter(FileReader.prototype, 'result', function() {
- return this._fileName ? this._result: this._realReader.result;
-});
-
-function defineEvent(eventName) {
- utils.defineGetterSetter(FileReader.prototype, eventName, function() {
- return this._realReader[eventName] || null;
- }, function(value) {
- this._realReader[eventName] = value;
- });
-}
-defineEvent('onloadstart'); // When the read starts.
-defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
-defineEvent('onload'); // When the read has successfully completed.
-defineEvent('onerror'); // When the read has failed (see errors).
-defineEvent('onloadend'); // When the request has completed (either in success or failure).
-defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
-
-function initRead(reader, file) {
- // Already loading something
- if (reader.readyState == FileReader.LOADING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- reader._result = null;
- reader._error = null;
- reader._readyState = FileReader.LOADING;
-
- if (typeof file.fullPath == 'string') {
- reader._fileName = file.fullPath;
- } else {
- reader._fileName = '';
- return true;
- }
-
- reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
-}
-
-/**
- * Abort reading file.
- */
-FileReader.prototype.abort = function() {
- if (origFileReader && !this._fileName) {
- return this._realReader.abort();
- }
- this._result = null;
-
- if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
- return;
- }
-
- this._readyState = FileReader.DONE;
-
- // If abort callback
- if (typeof this.onabort === 'function') {
- this.onabort(new ProgressEvent('abort', {target:this}));
- }
- // If load end callback
- if (typeof this.onloadend === 'function') {
- this.onloadend(new ProgressEvent('loadend', {target:this}));
- }
-};
-
-/**
- * Read text file.
- *
- * @param file {File} File object containing file properties
- * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
- */
-FileReader.prototype.readAsText = function(file, encoding) {
- if (initRead(this, file)) {
- return this._realReader.readAsText(file, encoding);
- }
-
- // Default encoding is UTF-8
- var enc = encoding ? encoding : "UTF-8";
- var me = this;
- var execArgs = [this._fileName, enc, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // Save result
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // null result
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsText", execArgs);
-};
-
-
-/**
- * Read file and return data as a base64 encoded data url.
- * A data url is of the form:
- * data:[<mediatype>][;base64],<data>
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsDataURL = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsDataURL(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // Save result
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsDataURL", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsBinaryString = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsBinaryString(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsBinaryString", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsArrayBuffer = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsArrayBuffer(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsArrayBuffer", execArgs);
-};
-
-module.exports = FileReader;
-
-});
-
-// file: lib\common\plugin\FileSystem.js
-define("cordova/plugin/FileSystem", function(require, exports, module) {
-
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-
-/**
- * An interface representing a file system
- *
- * @constructor
- * {DOMString} name the unique name of the file system (readonly)
- * {DirectoryEntry} root directory of the file system (readonly)
- */
-var FileSystem = function(name, root) {
- this.name = name || null;
- if (root) {
- this.root = new DirectoryEntry(root.name, root.fullPath);
- }
-};
-
-module.exports = FileSystem;
-
-});
-
-// file: lib\common\plugin\FileTransfer.js
-define("cordova/plugin/FileTransfer", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- FileTransferError = require('cordova/plugin/FileTransferError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-function newProgressEvent(result) {
- var pe = new ProgressEvent();
- pe.lengthComputable = result.lengthComputable;
- pe.loaded = result.loaded;
- pe.total = result.total;
- return pe;
-}
-
-function getBasicAuthHeader(urlString) {
- var header = null;
-
- if (window.btoa) {
- // parse the url using the Location object
- var url = document.createElement('a');
- url.href = urlString;
-
- var credentials = null;
- var protocol = url.protocol + "//";
- var origin = protocol + url.host;
-
- // check whether there are the username:password credentials in the url
- if (url.href.indexOf(origin) !== 0) { // credentials found
- var atIndex = url.href.indexOf("@");
- credentials = url.href.substring(protocol.length, atIndex);
- }
-
- if (credentials) {
- var authHeader = "Authorization";
- var authHeaderValue = "Basic " + window.btoa(credentials);
-
- header = {
- name : authHeader,
- value : authHeaderValue
- };
- }
- }
-
- return header;
-}
-
-var idCounter = 0;
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {
- this._id = ++idCounter;
- this.onprogress = null; // optional callback
-};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String} Full path of the file on the device
-* @param server {String} URL of the server to receive the file
-* @param successCallback (Function} Callback to be invoked when upload has completed
-* @param errorCallback {Function} Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
- argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
- // check for options
- var fileKey = null;
- var fileName = null;
- var mimeType = null;
- var params = null;
- var chunkedMode = true;
- var headers = null;
- var httpMethod = null;
- var basicAuthHeader = getBasicAuthHeader(server);
- if (basicAuthHeader) {
- options = options || {};
- options.headers = options.headers || {};
- options.headers[basicAuthHeader.name] = basicAuthHeader.value;
- }
-
- if (options) {
- fileKey = options.fileKey;
- fileName = options.fileName;
- mimeType = options.mimeType;
- headers = options.headers;
- httpMethod = options.httpMethod || "POST";
- if (httpMethod.toUpperCase() == "PUT"){
- httpMethod = "PUT";
- } else {
- httpMethod = "POST";
- }
- if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
- chunkedMode = options.chunkedMode;
- }
- if (options.params) {
- params = options.params;
- }
- else {
- params = {};
- }
- }
-
- var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
- errorCallback(error);
- };
-
- var self = this;
- var win = function(result) {
- if (typeof result.lengthComputable != "undefined") {
- if (self.onprogress) {
- self.onprogress(newProgressEvent(result));
- }
- } else {
- successCallback && successCallback(result);
- }
- };
- exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String} URL of the server to receive the file
- * @param target {String} Full path of the file on the device
- * @param successCallback (Function} Callback to be invoked when upload has completed
- * @param errorCallback {Function} Callback to be invoked upon error
- * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
- * @param options {FileDownloadOptions} Optional parameters such as headers
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
- argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
- var self = this;
-
- var basicAuthHeader = getBasicAuthHeader(source);
- if (basicAuthHeader) {
- options = options || {};
- options.headers = options.headers || {};
- options.headers[basicAuthHeader.name] = basicAuthHeader.value;
- }
-
- var headers = null;
- if (options) {
- headers = options.headers || null;
- }
-
- var win = function(result) {
- if (typeof result.lengthComputable != "undefined") {
- if (self.onprogress) {
- return self.onprogress(newProgressEvent(result));
- }
- } else if (successCallback) {
- var entry = null;
- if (result.isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result.isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result.isDirectory;
- entry.isFile = result.isFile;
- entry.name = result.name;
- entry.fullPath = result.fullPath;
- successCallback(entry);
- }
- };
-
- var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
- errorCallback(error);
- };
-
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
-};
-
-/**
- * Aborts the ongoing file transfer on this object. The original error
- * callback for the file transfer will be called if necessary.
- */
-FileTransfer.prototype.abort = function() {
- exec(null, null, 'FileTransfer', 'abort', [this._id]);
-};
-
-module.exports = FileTransfer;
-
-});
-
-// file: lib\common\plugin\FileTransferError.js
-define("cordova/plugin/FileTransferError", function(require, exports, modul
<TRUNCATED>
[34/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/www/css/index.css
----------------------------------------------------------------------
diff --git a/common/www/css/index.css b/common/www/css/index.css
new file mode 100644
index 0000000..f1f9d76
--- /dev/null
+++ b/common/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+* {
+ -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
+ -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
+ -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+ -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
+}
+
+body {
+ background-color:#E4E4E4;
+ background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ color-stop(0, #A7A7A7),
+ color-stop(0.51, #E4E4E4)
+ );
+ background-attachment:fixed;
+ font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+ font-size:12px;
+ height:100%;
+ margin:0px;
+ padding:0px;
+ text-transform:uppercase;
+ width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+ background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+ position:absolute; /* position in the center of the screen */
+ left:50%;
+ top:50%;
+ height:50px; /* text area height */
+ width:225px; /* text area width */
+ text-align:center;
+ padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
+ margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
+ /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+ .app {
+ background-position:left center;
+ padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
+ margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
+ /* offset horizontal: half of image width and text area width */
+ }
+}
+
+h1 {
+ font-size:24px;
+ font-weight:normal;
+ margin:0px;
+ overflow:visible;
+ padding:0px;
+ text-align:center;
+}
+
+.event {
+ border-radius:4px;
+ -webkit-border-radius:4px;
+ color:#FFFFFF;
+ font-size:12px;
+ margin:0px 30px;
+ padding:2px 0px;
+}
+
+.event.listening {
+ background-color:#333333;
+ display:block;
+}
+
+.event.received {
+ background-color:#4B946A;
+ display:none;
+}
+
+@keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+@-webkit-keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+.blink {
+ animation:fade 3000ms infinite;
+ -webkit-animation:fade 3000ms infinite;
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/www/img/logo.png
----------------------------------------------------------------------
diff --git a/common/www/img/logo.png b/common/www/img/logo.png
new file mode 100644
index 0000000..9519e7d
Binary files /dev/null and b/common/www/img/logo.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/www/index.html
----------------------------------------------------------------------
diff --git a/common/www/index.html b/common/www/index.html
new file mode 100644
index 0000000..842b364
--- /dev/null
+++ b/common/www/index.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="format-detection" content="telephone=no" />
+ <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+ <link rel="stylesheet" type="text/css" href="css/index.css" />
+ <title>Hello World</title>
+ </head>
+ <body>
+ <div class="app">
+ <h1>Apache Cordova</h1>
+ <div id="deviceready" class="blink">
+ <p class="event listening">Connecting to Device</p>
+ <p class="event received">Device is Ready</p>
+ </div>
+ </div>
+ <script type="text/javascript" src="cordova.js"></script>
+ <script type="text/javascript" src="js/index.js"></script>
+ <script type="text/javascript">
+ app.initialize();
+ </script>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/www/js/index.js
----------------------------------------------------------------------
diff --git a/common/www/js/index.js b/common/www/js/index.js
new file mode 100644
index 0000000..3b75d3f
--- /dev/null
+++ b/common/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * 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 app = {
+ // Application Constructor
+ initialize: function() {
+ this.bindEvents();
+ },
+ // Bind Event Listeners
+ //
+ // Bind any events that are required on startup. Common events are:
+ // `load`, `deviceready`, `offline`, and `online`.
+ bindEvents: function() {
+ document.addEventListener('deviceready', this.onDeviceReady, false);
+ },
+ // deviceready Event Handler
+ //
+ // The scope of `this` is the event. In order to call the `receivedEvent`
+ // function, we must explicity call `app.receivedEvent(...);`
+ onDeviceReady: function() {
+ app.receivedEvent('deviceready');
+ },
+ // Update DOM on a Received Event
+ receivedEvent: function(id) {
+ var parentElement = document.getElementById(id);
+ var listeningElement = parentElement.querySelector('.listening');
+ var receivedElement = parentElement.querySelector('.received');
+
+ listeningElement.setAttribute('style', 'display:none;');
+ receivedElement.setAttribute('style', 'display:block;');
+
+ console.log('Received Event: ' + id);
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/wp7/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp7/tooling/scripts/createTemplates.js b/wp7/tooling/scripts/createTemplates.js
index b24a94b..afe3785 100644
--- a/wp7/tooling/scripts/createTemplates.js
+++ b/wp7/tooling/scripts/createTemplates.js
@@ -74,7 +74,6 @@ var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
// returns the contents of a file
function read(filename) {
- WScript.Echo('Reading in ' + filename);
if(fso.FileExists(filename))
{
var f=fso.OpenTextFile(filename, 1,2);
@@ -84,7 +83,7 @@ function read(filename) {
}
else
{
- WScript.StdErr.WriteLine('Cannot read non-existant file : ' + filename);
+ Log('Cannot read non-existant file : ' + filename,true);
WScript.Quit(1);
}
return null;
@@ -99,15 +98,12 @@ function write(filename, contents) {
// replaces the matches of regexp with replacement
function replaceInFile(filename, regexp, replacement) {
- //WScript.Echo("Replaceing with "+replacement+ " in:");
var text = read(filename).replace(regexp,replacement);
- //WScript.Echo(text);
write(filename,text);
}
// executes a commmand in the shell
function exec(command) {
- Log("exec:" + command);
var oShell=wscript_shell.Exec(command);
var maxTime = 5000;
while (oShell.Status === 0) {
@@ -148,7 +144,7 @@ function copyFile(src,dest) {
}
function copyCommonItemsToTemplate() {
- var srcPath = repoRoot + '\\common-items';
+ var srcPath = repoRoot + '\\common';
var destPath = platformRoot + templatePath;
var folder = fso.GetFolder(srcPath);
@@ -159,7 +155,7 @@ function copyCommonItemsToTemplate() {
}
// iterate over the child folders in the folder
for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
- Log("Folder: " + srcPath + "\\" + subFlds.item().name);
+ //Log("Folder: " + srcPath + "\\" + subFlds.item().name);
exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " "
+ destPath + "\\" + subFlds.item().name);
}
@@ -167,7 +163,7 @@ function copyCommonItemsToTemplate() {
// delete desination items
function removeCommonItems() {
- var srcPath = repoRoot + '\\common-items';
+ var srcPath = repoRoot + '\\common';
var destPath = platformRoot + templatePath;
var folder = fso.GetFolder(srcPath);
// iterate over the files in the folder
@@ -185,7 +181,7 @@ function removeCommonItems() {
function package_templates()
{
- Log("Creating template .zip files ...");
+ Log("Creating template .zip files for wp7");
var templateOutFilename = repoRoot + '\\CordovaWP7_' + versionNum.replace(/\./g, '_') + '.zip';
// clear the destination
@@ -218,7 +214,6 @@ function package_templates()
var template_dir = wscript_shell.ExpandEnvironmentStrings("%USERPROFILE%") + '\\Documents\\Visual Studio 2012\\Templates\\ProjectTemplates\\Testing';
if(fso.FolderExists(template_dir ))
{
- Log("template_dir = " + template_dir);
dest = shell.NameSpace(template_dir);
dest.CopyHere(templateOutFilename, 4|20);
}
@@ -243,15 +238,12 @@ function zip_project(zip_path, project_path) {
// open .zip folder and copy contents of project_path to zip_path
var zipFolder = shell.NameSpace(zip_path);
- Log("zip_path = " + zip_path);
- Log("zipFolder = " + zipFolder);
- Log("project_path = " + project_path);
var sourceItems = shell.NameSpace(project_path).items();
if (zipFolder !== null) {
zipFolder.CopyHere(sourceItems, 4|16|512|1024);
var maxTime = 5000;
- Log("sourceItems.Count = " + sourceItems.Count);
+ //Log("sourceItems.Count = " + sourceItems.Count);
while(zipFolder.items().Count < sourceItems.Count)
{
maxTime -= 100;
@@ -263,7 +255,7 @@ function zip_project(zip_path, project_path) {
break;
}
}
- Log("zipFolder.items().Count = " + zipFolder.items().Count);
+ //Log("zipFolder.items().Count = " + zipFolder.items().Count);
}
else {
Log('Failed to create .zip file.', true);
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/wp8/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp8/tooling/scripts/createTemplates.js b/wp8/tooling/scripts/createTemplates.js
index ea31195..2061af2 100644
--- a/wp8/tooling/scripts/createTemplates.js
+++ b/wp8/tooling/scripts/createTemplates.js
@@ -74,7 +74,6 @@ var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
// returns the contents of a file
function read(filename) {
- WScript.Echo('Reading in ' + filename);
if(fso.FileExists(filename))
{
var f=fso.OpenTextFile(filename, 1,2);
@@ -84,7 +83,7 @@ function read(filename) {
}
else
{
- WScript.StdErr.WriteLine('Cannot read non-existant file : ' + filename);
+ Log('Cannot read non-existant file : ' + filename,true);
WScript.Quit(1);
}
return null;
@@ -99,15 +98,12 @@ function write(filename, contents) {
// replaces the matches of regexp with replacement
function replaceInFile(filename, regexp, replacement) {
- //WScript.Echo("Replaceing with "+replacement+ " in:");
var text = read(filename).replace(regexp,replacement);
- //WScript.Echo(text);
write(filename,text);
}
// executes a commmand in the shell
function exec(command) {
- Log("exec:" + command);
var oShell=wscript_shell.Exec(command);
var maxTime = 5000;
while (oShell.Status === 0) {
@@ -130,8 +126,7 @@ function exec_verbose(command) {
WScript.sleep(100);
//Print any stdout output from the script
if(!oShell.StdOut.AtEndOfStream) {
- var line = oShell.StdOut.ReadLine();
- Log(line);
+ Log(oShell.StdOut.ReadLine());
}
}
//Check to make sure our scripts did not encounter an error
@@ -148,7 +143,7 @@ function copyFile(src,dest) {
}
function copyCommonItemsToTemplate() {
- var srcPath = repoRoot + '\\common-items';
+ var srcPath = repoRoot + '\\common';
var destPath = platformRoot + templatePath;
var folder = fso.GetFolder(srcPath);
@@ -159,7 +154,7 @@ function copyCommonItemsToTemplate() {
}
// iterate over the child folders in the folder
for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
- Log("Folder: " + srcPath + "\\" + subFlds.item().name);
+ //Log("Folder: " + srcPath + "\\" + subFlds.item().name);
exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " "
+ destPath + "\\" + subFlds.item().name);
}
@@ -167,7 +162,7 @@ function copyCommonItemsToTemplate() {
// delete desination items
function removeCommonItems() {
- var srcPath = repoRoot + '\\common-items';
+ var srcPath = repoRoot + '\\common';
var destPath = platformRoot + templatePath;
var folder = fso.GetFolder(srcPath);
// iterate over the files in the folder
@@ -183,7 +178,7 @@ function removeCommonItems() {
// packages templates into .zip
function package_templates()
{
- Log("Creating template .zip files ...");
+ Log("Creating template .zip files for wp8");
var templateOutFilename = repoRoot + '\\CordovaWP8_' + versionNum.replace(/\./g, '_') + '.zip';
// clear the destination
@@ -216,7 +211,6 @@ function package_templates()
var template_dir = wscript_shell.ExpandEnvironmentStrings("%USERPROFILE%") + '\\Documents\\Visual Studio 2012\\Templates\\ProjectTemplates\\Testing';
if(fso.FolderExists(template_dir ))
{
- Log("template_dir = " + template_dir);
dest = shell.NameSpace(template_dir);
dest.CopyHere(templateOutFilename, 4|20);
}
@@ -240,15 +234,12 @@ function zip_project(zip_path, project_path) {
// open .zip folder and copy contents of project_path to zip_path
var zipFolder = shell.NameSpace(zip_path);
- Log("zip_path = " + zip_path);
- Log("zipFolder = " + zipFolder);
- Log("project_path = " + project_path);
var sourceItems = shell.NameSpace(project_path).items();
if (zipFolder !== null) {
zipFolder.CopyHere(sourceItems, 4|16|512|1024);
var maxTime = 5000;
- Log("sourceItems.Count = " + sourceItems.Count);
+ //Log("sourceItems.Count = " + sourceItems.Count);
while(zipFolder.items().Count < sourceItems.Count)
{
maxTime -= 100;
@@ -260,7 +251,7 @@ function zip_project(zip_path, project_path) {
break;
}
}
- Log("zipFolder.items().Count = " + zipFolder.items().Count);
+ //Log("zipFolder.items().Count = " + zipFolder.items().Count);
}
else {
Log('Failed to create .zip file.', true);
[47/50] [abbrv] merge issues
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/90097ba2/common/www/cordova.js
----------------------------------------------------------------------
diff --cc common/www/cordova.js
index 0d763d9,0000000..3e70492
mode 100644,000000..100644
--- a/common/www/cordova.js
+++ b/common/www/cordova.js
@@@ -1,6723 -1,0 +1,6720 @@@
- // Platform: windowsphone
++// Platform: windowsphone
+// 2.8.0rc1-0-g22bc4d8
+/*
+ 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.
+*/
+;(function() {
+var CORDOVA_JS_BUILD_LABEL = '2.8.0rc1-0-g22bc4d8';
+// file: lib/scripts/require.js
+
+var require,
+ define;
+
+(function () {
+ var modules = {},
+ // Stack of moduleIds currently being built.
+ requireStack = [],
+ // Map of module ID -> index into requireStack of modules currently being built.
+ inProgressModules = {},
+ SEPERATOR = ".";
+
+
+
+ function build(module) {
+ var factory = module.factory,
+ localRequire = function (id) {
+ var resultantId = id;
+ //Its a relative path, so lop off the last portion and add the id (minus "./")
+ if (id.charAt(0) === ".") {
+ resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
+ }
+ return require(resultantId);
+ };
+ module.exports = {};
+ delete module.factory;
+ factory(localRequire, module.exports, module);
+ return module.exports;
+ }
+
+ require = function (id) {
+ if (!modules[id]) {
+ throw "module " + id + " not found";
+ } else if (id in inProgressModules) {
+ var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+ throw "Cycle in require graph: " + cycle;
+ }
+ if (modules[id].factory) {
+ try {
+ inProgressModules[id] = requireStack.length;
+ requireStack.push(id);
+ return build(modules[id]);
+ } finally {
+ delete inProgressModules[id];
+ requireStack.pop();
+ }
+ }
+ return modules[id].exports;
+ };
+
+ define = function (id, factory) {
+ if (modules[id]) {
+ throw "module " + id + " already defined";
+ }
+
+ modules[id] = {
+ id: id,
+ factory: factory
+ };
+ };
+
+ define.remove = function (id) {
+ delete modules[id];
+ };
+
+ define.moduleMap = modules;
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+ module.exports.require = require;
+ module.exports.define = define;
+}
+
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+
+
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+ channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+ channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+ windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ if (typeof documentEventHandlers[e] != 'undefined') {
+ documentEventHandlers[e].subscribe(handler);
+ } else {
+ m_document_addEventListener.call(document, evt, handler, capture);
+ }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ if (typeof windowEventHandlers[e] != 'undefined') {
+ windowEventHandlers[e].subscribe(handler);
+ } else {
+ m_window_addEventListener.call(window, evt, handler, capture);
+ }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ // If unsubscribing from an event that is handled by a plugin
+ if (typeof documentEventHandlers[e] != "undefined") {
+ documentEventHandlers[e].unsubscribe(handler);
+ } else {
+ m_document_removeEventListener.call(document, evt, handler, capture);
+ }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ // If unsubscribing from an event that is handled by a plugin
+ if (typeof windowEventHandlers[e] != "undefined") {
+ windowEventHandlers[e].unsubscribe(handler);
+ } else {
+ m_window_removeEventListener.call(window, evt, handler, capture);
+ }
+};
+
+function createEvent(type, data) {
+ var event = document.createEvent('Events');
+ event.initEvent(type, false, false);
+ if (data) {
+ for (var i in data) {
+ if (data.hasOwnProperty(i)) {
+ event[i] = data[i];
+ }
+ }
+ }
+ return event;
+}
+
+if(typeof window.console === "undefined") {
+ window.console = {
+ log:function(){}
+ };
+}
+
+var cordova = {
+ define:define,
+ require:require,
+ /**
+ * Methods to add/remove your own addEventListener hijacking on document + window.
+ */
+ addWindowEventHandler:function(event) {
+ return (windowEventHandlers[event] = channel.create(event));
+ },
+ addStickyDocumentEventHandler:function(event) {
+ return (documentEventHandlers[event] = channel.createSticky(event));
+ },
+ addDocumentEventHandler:function(event) {
+ return (documentEventHandlers[event] = channel.create(event));
+ },
+ removeWindowEventHandler:function(event) {
+ delete windowEventHandlers[event];
+ },
+ removeDocumentEventHandler:function(event) {
+ delete documentEventHandlers[event];
+ },
+ /**
+ * Retrieve original event handlers that were replaced by Cordova
+ *
+ * @return object
+ */
+ getOriginalHandlers: function() {
+ return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+ 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+ },
+ /**
+ * Method to fire event from native code
+ * bNoDetach is required for events which cause an exception which needs to be caught in native code
+ */
+ fireDocumentEvent: function(type, data, bNoDetach) {
+ var evt = createEvent(type, data);
+ if (typeof documentEventHandlers[type] != 'undefined') {
+ if( bNoDetach ) {
+ documentEventHandlers[type].fire(evt);
+ }
+ else {
+ setTimeout(function() {
+ // Fire deviceready on listeners that were registered before cordova.js was loaded.
+ if (type == 'deviceready') {
+ document.dispatchEvent(evt);
+ }
+ documentEventHandlers[type].fire(evt);
+ }, 0);
+ }
+ } else {
+ document.dispatchEvent(evt);
+ }
+ },
+ fireWindowEvent: function(type, data) {
+ var evt = createEvent(type,data);
+ if (typeof windowEventHandlers[type] != 'undefined') {
+ setTimeout(function() {
+ windowEventHandlers[type].fire(evt);
+ }, 0);
+ } else {
+ window.dispatchEvent(evt);
+ }
+ },
+
+ /**
+ * Plugin callback mechanism.
+ */
+ // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+ // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+ callbackId: Math.floor(Math.random() * 2000000000),
+ callbacks: {},
+ callbackStatus: {
+ NO_RESULT: 0,
+ OK: 1,
+ CLASS_NOT_FOUND_EXCEPTION: 2,
+ ILLEGAL_ACCESS_EXCEPTION: 3,
+ INSTANTIATION_EXCEPTION: 4,
+ MALFORMED_URL_EXCEPTION: 5,
+ IO_EXCEPTION: 6,
+ INVALID_ACTION: 7,
+ JSON_EXCEPTION: 8,
+ ERROR: 9
+ },
+
+ /**
+ * Called by native code when returning successful result from an action.
+ */
+ callbackSuccess: function(callbackId, args) {
+ try {
+ cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
+ } catch (e) {
+ console.log("Error in error callback: " + callbackId + " = "+e);
+ }
+ },
+
+ /**
+ * Called by native code when returning error result from an action.
+ */
+ callbackError: function(callbackId, args) {
+ // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+ // Derive success from status.
+ try {
+ cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
+ } catch (e) {
+ console.log("Error in error callback: " + callbackId + " = "+e);
+ }
+ },
+
+ /**
+ * Called by native code when returning the result from an action.
+ */
+ callbackFromNative: function(callbackId, success, status, args, keepCallback) {
+ var callback = cordova.callbacks[callbackId];
+ if (callback) {
+ if (success && status == cordova.callbackStatus.OK) {
+ callback.success && callback.success.apply(null, args);
+ } else if (!success) {
+ callback.fail && callback.fail.apply(null, args);
+ }
+
+ // Clear callback if not expecting any more results
+ if (!keepCallback) {
+ delete cordova.callbacks[callbackId];
+ }
+ }
+ },
+ addConstructor: function(func) {
+ channel.onCordovaReady.subscribe(function() {
+ try {
+ func();
+ } catch(e) {
+ console.log("Failed to run constructor: " + e);
+ }
+ });
+ }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/argscheck.js
+define("cordova/argscheck", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+ 'A': 'Array',
+ 'D': 'Date',
+ 'N': 'Number',
+ 'S': 'String',
+ 'F': 'Function',
+ 'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+ return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+ if (!moduleExports.enableChecks) {
+ return;
+ }
+ var errMsg = null;
+ var typeName;
+ for (var i = 0; i < spec.length; ++i) {
+ var c = spec.charAt(i),
+ cUpper = c.toUpperCase(),
+ arg = args[i];
+ // Asterix means allow anything.
+ if (c == '*') {
+ continue;
+ }
+ typeName = utils.typeName(arg);
+ if ((arg === null || arg === undefined) && c == cUpper) {
+ continue;
+ }
+ if (typeName != typeMap[cUpper]) {
+ errMsg = 'Expected ' + typeMap[cUpper];
+ break;
+ }
+ }
+ if (errMsg) {
+ errMsg += ', but got ' + typeName + '.';
+ errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+ // Don't log when running jake test.
+ if (typeof jasmine == 'undefined') {
+ console.error(errMsg);
+ }
+ throw TypeError(errMsg);
+ }
+}
+
+function getValue(value, defaultValue) {
+ return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+ for (var prop in objects) {
+ if (objects.hasOwnProperty(prop)) {
+ func.apply(context, [objects[prop], prop]);
+ }
+ }
+}
+
+function clobber(obj, key, value) {
+ exports.replaceHookForTesting(obj, key);
+ obj[key] = value;
+ // Getters can only be overridden by getters.
+ if (obj[key] !== value) {
+ utils.defineGetter(obj, key, function() {
+ return value;
+ });
+ }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+ if (message) {
+ utils.defineGetter(obj, key, function() {
+ console.log(message);
+ delete obj[key];
+ clobber(obj, key, value);
+ return value;
+ });
+ } else {
+ clobber(obj, key, value);
+ }
+}
+
+function include(parent, objects, clobber, merge) {
+ each(objects, function (obj, key) {
+ try {
+ var result = obj.path ? require(obj.path) : {};
+
+ if (clobber) {
+ // Clobber if it doesn't exist.
+ if (typeof parent[key] === 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else if (typeof obj.path !== 'undefined') {
+ // If merging, merge properties onto parent, otherwise, clobber.
+ if (merge) {
+ recursiveMerge(parent[key], result);
+ } else {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ }
+ }
+ result = parent[key];
+ } else {
+ // Overwrite if not currently defined.
+ if (typeof parent[key] == 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else {
+ // Set result to what already exists, so we can build children into it if they exist.
+ result = parent[key];
+ }
+ }
+
+ if (obj.children) {
+ include(result, obj.children, clobber, merge);
+ }
+ } catch(e) {
+ utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+ }
+ });
+}
+
+/**
+ * Merge properties from one object onto another recursively. Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+ for (var prop in src) {
+ if (src.hasOwnProperty(prop)) {
+ if (target.prototype && target.prototype.constructor === target) {
+ // If the target object is a constructor override off prototype.
+ clobber(target.prototype, prop, src[prop]);
+ } else {
+ if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+ recursiveMerge(target[prop], src[prop]);
+ } else {
+ clobber(target, prop, src[prop]);
+ }
+ }
+ }
+ }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+ include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+ include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+ include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+ nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady* Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady* Internal event fired when device properties are available.
+ * onCordovaConnectionReady* Internal event fired when the connection property has been set.
+ * onDeviceReady* User event fired to indicate that Cordova is ready
+ * onResume User event fired to indicate a start/resume lifecycle event
+ * onPause User event fired to indicate a pause lifecycle event
+ * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ * pause App has moved to background
+ * resume App has returned to foreground
+ *
+ * Listeners can be registered as:
+ * document.addEventListener("deviceready", myDeviceReadyListener, false);
+ * document.addEventListener("resume", myResumeListener, false);
+ * document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ * window.onload
+ * window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type String the channel name
+ */
+var Channel = function(type, sticky) {
+ this.type = type;
+ // Map of guid -> function.
+ this.handlers = {};
+ // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+ this.state = sticky ? 1 : 0;
+ // Used in sticky mode to remember args passed to fire().
+ this.fireArgs = null;
+ // Used by onHasSubscribersChange to know if there are any listeners.
+ this.numHandlers = 0;
+ // Function that is called when the first listener is subscribed, or when
+ // the last listener is unsubscribed.
+ this.onHasSubscribersChange = null;
+},
+ channel = {
+ /**
+ * Calls the provided function only after all of the channels specified
+ * have been fired. All channels must be sticky channels.
+ */
+ join: function(h, c) {
+ var len = c.length,
+ i = len,
+ f = function() {
+ if (!(--i)) h();
+ };
+ for (var j=0; j<len; j++) {
+ if (c[j].state === 0) {
+ throw Error('Can only use join with sticky channels.');
+ }
+ c[j].subscribe(f);
+ }
+ if (!len) h();
+ },
+ create: function(type) {
+ return channel[type] = new Channel(type, false);
+ },
+ createSticky: function(type) {
+ return channel[type] = new Channel(type, true);
+ },
+
+ /**
+ * cordova Channels that must fire before "deviceready" is fired.
+ */
+ deviceReadyChannelsArray: [],
+ deviceReadyChannelsMap: {},
+
+ /**
+ * Indicate that a feature needs to be initialized before it is ready to be used.
+ * This holds up Cordova's "deviceready" event until the feature has been initialized
+ * and Cordova.initComplete(feature) is called.
+ *
+ * @param feature {String} The unique feature name
+ */
+ waitForInitialization: function(feature) {
+ if (feature) {
+ var c = channel[feature] || this.createSticky(feature);
+ this.deviceReadyChannelsMap[feature] = c;
+ this.deviceReadyChannelsArray.push(c);
+ }
+ },
+
+ /**
+ * Indicate that initialization code has completed and the feature is ready to be used.
+ *
+ * @param feature {String} The unique feature name
+ */
+ initializationComplete: function(feature) {
+ var c = this.deviceReadyChannelsMap[feature];
+ if (c) {
+ c.fire();
+ }
+ }
+ };
+
+function forceFunction(f) {
+ if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+ // need a function to call
+ forceFunction(f);
+ if (this.state == 2) {
+ f.apply(c || this, this.fireArgs);
+ return;
+ }
+
+ var func = f,
+ guid = f.observer_guid;
+ if (typeof c == "object") { func = utils.close(c, f); }
+
+ if (!guid) {
+ // first time any channel has seen this subscriber
+ guid = '' + nextGuid++;
+ }
+ func.observer_guid = guid;
+ f.observer_guid = guid;
+
+ // Don't add the same handler more than once.
+ if (!this.handlers[guid]) {
+ this.handlers[guid] = func;
+ this.numHandlers++;
+ if (this.numHandlers == 1) {
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+ // need a function to unsubscribe
+ forceFunction(f);
+
+ var guid = f.observer_guid,
+ handler = this.handlers[guid];
+ if (handler) {
+ delete this.handlers[guid];
+ this.numHandlers--;
+ if (this.numHandlers === 0) {
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+ var fail = false,
+ fireArgs = Array.prototype.slice.call(arguments);
+ // Apply stickiness.
+ if (this.state == 1) {
+ this.state = 2;
+ this.fireArgs = fireArgs;
+ }
+ if (this.numHandlers) {
+ // Copy the values first so that it is safe to modify it from within
+ // callbacks.
+ var toCall = [];
+ for (var item in this.handlers) {
+ toCall.push(this.handlers[item]);
+ }
+ for (var i = 0; i < toCall.length; ++i) {
+ toCall[i].apply(this, fireArgs);
+ }
+ if (this.state == 2 && this.numHandlers) {
+ this.numHandlers = 0;
+ this.handlers = {};
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.createSticky('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.createSticky('onCordovaConnectionReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/commandProxy.js
+define("cordova/commandProxy", function(require, exports, module) {
+
+
+// internal map of proxy function
+var CommandProxyMap = {};
+
+module.exports = {
+
+ // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
+ add:function(id,proxyObj) {
+ console.log("adding proxy for " + id);
+ CommandProxyMap[id] = proxyObj;
+ return proxyObj;
+ },
+
+ // cordova.commandProxy.remove("Accelerometer");
+ remove:function(id) {
+ var proxy = CommandProxyMap[id];
+ delete CommandProxyMap[id];
+ CommandProxyMap[id] = null;
+ return proxy;
+ },
+
+ get:function(service,action) {
+ return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
+ }
+};
+});
+
+// file: lib/windowsphone/exec.js
+define("cordova/exec", function(require, exports, module) {
+
+var cordova = require('cordova');
+
+/**
+ * Execute a cordova command. It is up to the native side whether this action
+ * is synchronous or asynchronous. The native side can return:
+ * Synchronous: PluginResult object as a JSON string
+ * Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success The success callback
+ * @param {Function} fail The fail callback
+ * @param {String} service The name of the service to use
+ * @param {String} action Action to be run in cordova
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+
+ */
+
+module.exports = function(success, fail, service, action, args) {
+
+ var callbackId = service + cordova.callbackId++;
+ if (typeof success == "function" || typeof fail == "function") {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+ // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
+ for(var n = 0; n < args.length; n++)
+ {
+ if(typeof args[n] !== "string")
+ {
+ args[n] = JSON.stringify(args[n]);
+ }
+ }
+ var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
+ // pass it on to Notify
+ try {
+ if(window.external) {
+ window.external.Notify(command);
+ }
+ else {
+ console.log("window.external not available :: command=" + command);
+ }
+ }
+ catch(e) {
+ console.log("Exception calling native with command :: " + command + " :: exception=" + e);
+ }
+};
+
+
+});
+
+// file: lib/common/modulemapper.js
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+ moduleMap = define.moduleMap,
+ symbolList,
+ deprecationMap;
+
+exports.reset = function() {
+ symbolList = [];
+ deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+ if (!(moduleName in moduleMap)) {
+ throw new Error('Module ' + moduleName + ' does not exist.');
+ }
+ 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);
+};
+
+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 symbolPath = symbolList[i + 2];
+ var lastDot = symbolPath.lastIndexOf('.');
+ var namespace = symbolPath.substr(0, lastDot);
+ var lastName = symbolPath.substr(lastDot + 1);
+
+ var module = require(moduleName);
+ 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.loadMatchingModules = function(matchingRegExp) {
+ for (var k in moduleMap) {
+ if (matchingRegExp.exec(k)) {
+ require(k);
+ }
+ }
+};
+
+exports.reset();
+
+
+});
+
+// file: lib/windowsphone/platform.js
+define("cordova/platform", function(require, exports, module) {
+
+var cordova = require('cordova'),
+ exec = require('cordova/exec');
+
+module.exports = {
+ id: "windowsphone",
+ initialize:function() {
+ var modulemapper = require('cordova/modulemapper');
+
+ modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
+
+ modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
+
+ modulemapper.mapModules(window);
+
+ // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
+ var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+ backButtonChannel.onHasSubscribersChange = function() {
+ exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
+ };
+ }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+
+var Acceleration = function(x, y, z, timestamp) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ Camera = require('cordova/plugin/CameraConstants'),
+ CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+ cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+ argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
+ options = options || {};
+ var getValue = argscheck.getValue;
+
+ var quality = getValue(options.quality, 50);
+ var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
+ var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
+ var targetWidth = getValue(options.targetWidth, -1);
+ var targetHeight = getValue(options.targetHeight, -1);
+ var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
+ var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
+ var allowEdit = !!options.allowEdit;
+ var correctOrientation = !!options.correctOrientation;
+ var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
+ var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
+
+ var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
+
+ exec(successCallback, errorCallback, "Camera", "takePicture", args);
+ return new CameraPopoverHandle();
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+ exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+
+module.exports = {
+ DestinationType:{
+ DATA_URL: 0, // Return base64 encoded string
+ FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
+ NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
+ },
+ EncodingType:{
+ JPEG: 0, // Return JPEG encoded image
+ PNG: 1 // Return PNG encoded image
+ },
+ MediaType:{
+ PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+ VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
+ ALLMEDIA : 2 // allow selection from all media types
+ },
+ PictureSourceType:{
+ PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+ CAMERA : 1, // Take picture from camera
+ SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
+ },
+ PopoverArrowDirection:{
+ ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+ ARROW_DOWN : 2,
+ ARROW_LEFT : 4,
+ ARROW_RIGHT : 8,
+ ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
+ }
+};
+
+});
+
+// file: lib/common/plugin/CameraPopoverHandle.js
+define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+/**
+ * A handle to an image picker popover.
+ */
+var CameraPopoverHandle = function() {
+ this.setPosition = function(popoverOptions) {
+ console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
+ };
+};
+
+module.exports = CameraPopoverHandle;
+
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+ // information of rectangle that popover should be anchored to
+ this.x = x || 0;
+ this.y = y || 32;
+ this.width = width || 320;
+ this.height = height || 480;
+ // The direction of the popover arrow
+ this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+ // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+ this.limit = 1;
+ // Maximum duration of a single sound clip in seconds.
+ this.duration = 0;
+};
+
+module.exports = CaptureAudioOptions;
+
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+ this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+ // Upper limit of images user can take. Value must be equal or greater than 1.
+ this.limit = 1;
+};
+
+module.exports = CaptureImageOptions;
+
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+ // Upper limit of videos user can record. Value must be equal or greater than 1.
+ this.limit = 1;
+ // Maximum duration of a single video clip in seconds.
+ this.duration = 0;
+};
+
+module.exports = CaptureVideoOptions;
+
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+
+/**
+ * CompassError.
+ * An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var CompassError = function(err) {
+ this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+ this.magneticHeading = magneticHeading;
+ this.trueHeading = trueHeading;
+ this.headingAccuracy = headingAccuracy;
+ this.timestamp = timestamp || new Date().getTime();
+};
+
+module.exports = CompassHeading;
+
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+ // The ASCII-encoded string in lower case representing the media type.
+ this.type = null;
+ // The height attribute represents height of the image or video in pixels.
+ // In the case of a sound clip this attribute has value 0.
+ this.height = 0;
+ // The width attribute represents width of the image or video in pixels.
+ // In the case of a sound clip this attribute has value 0
+ this.width = 0;
+}
+
+module.exports = ConfigurationData;
+
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+
+/**
+ * Network status
+ */
+module.exports = {
+ UNKNOWN: "unknown",
+ ETHERNET: "ethernet",
+ WIFI: "wifi",
+ CELL_2G: "2g",
+ CELL_3G: "3g",
+ CELL_4G: "4g",
+ CELL:"cellular",
+ NONE: "none"
+};
+
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ ContactError = require('cordova/plugin/ContactError'),
+ utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+ var value = contact.birthday;
+ try {
+ contact.birthday = new Date(parseFloat(value));
+ } catch (exception){
+ console.log("Cordova Contact convertIn error: exception creating date.");
+ }
+ return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+ var value = contact.birthday;
+ if (value !== null) {
+ // try to make it a Date object if it is not already
+ if (!utils.isDate(value)){
+ try {
+ value = new Date(value);
+ } catch(exception){
+ value = null;
+ }
+ }
+ if (utils.isDate(value)){
+ value = value.valueOf(); // convert to milliseconds
+ }
+ contact.birthday = value;
+ }
+ return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+ ims, organizations, birthday, note, photos, categories, urls) {
+ this.id = id || null;
+ this.rawId = null;
+ this.displayName = displayName || null;
+ this.name = name || null; // ContactName
+ this.nickname = nickname || null;
+ this.phoneNumbers = phoneNumbers || null; // ContactField[]
+ this.emails = emails || null; // ContactField[]
+ this.addresses = addresses || null; // ContactAddress[]
+ this.ims = ims || null; // ContactField[]
+ this.organizations = organizations || null; // ContactOrganization[]
+ this.birthday = birthday || null;
+ this.note = note || null;
+ this.photos = photos || null; // ContactField[]
+ this.categories = categories || null; // ContactField[]
+ this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+ argscheck.checkArgs('FF', 'Contact.remove', arguments);
+ var fail = errorCB && function(code) {
+ errorCB(new ContactError(code));
+ };
+ if (this.id === null) {
+ fail(ContactError.UNKNOWN_ERROR);
+ }
+ else {
+ exec(successCB, fail, "Contacts", "remove", [this.id]);
+ }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+ var clonedContact = utils.clone(this);
+ clonedContact.id = null;
+ clonedContact.rawId = null;
+
+ function nullIds(arr) {
+ if (arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ arr[i].id = null;
+ }
+ }
+ }
+
+ // Loop through and clear out any id's in phones, emails, etc.
+ nullIds(clonedContact.phoneNumbers);
+ nullIds(clonedContact.emails);
+ nullIds(clonedContact.addresses);
+ nullIds(clonedContact.ims);
+ nullIds(clonedContact.organizations);
+ nullIds(clonedContact.categories);
+ nullIds(clonedContact.photos);
+ nullIds(clonedContact.urls);
+ return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+ argscheck.checkArgs('FFO', 'Contact.save', arguments);
+ var fail = errorCB && function(code) {
+ errorCB(new ContactError(code));
+ };
+ var success = function(result) {
+ if (result) {
+ if (successCB) {
+ var fullContact = require('cordova/plugin/contacts').create(result);
+ successCB(convertIn(fullContact));
+ }
+ }
+ else {
+ // no Entry object returned
+ fail(ContactError.UNKNOWN_ERROR);
+ }
+ };
+ var dupContact = convertOut(utils.clone(this));
+ exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+ this.id = null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+ this.type = type || null;
+ this.formatted = formatted || null;
+ this.streetAddress = streetAddress || null;
+ this.locality = locality || null;
+ this.region = region || null;
+ this.postalCode = postalCode || null;
+ this.country = country || null;
+};
+
+module.exports = ContactAddress;
+
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+
+/**
+ * ContactError.
+ * An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var ContactError = function(err) {
+ this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+ this.id = null;
+ this.type = (type && type.toString()) || null;
+ this.value = (value && value.toString()) || null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+ this.filter = filter || '';
+ this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+ this.formatted = formatted || null;
+ this.familyName = familyName || null;
+ this.givenName = givenName || null;
+ this.middleName = middle || null;
+ this.honorificPrefix = prefix || null;
+ this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+ this.id = null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+ this.type = type || null;
+ this.name = name || null;
+ this.department = dept || null;
+ this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+ /**
+ * The latitude of the position.
+ */
+ this.latitude = lat;
+ /**
+ * The longitude of the position,
+ */
+ this.longitude = lng;
+ /**
+ * The accuracy of the position.
+ */
+ this.accuracy = acc;
+ /**
+ * The altitude of the position.
+ */
+ this.altitude = (alt !== undefined ? alt : null);
+ /**
+ * The direction the device is moving at the position.
+ */
+ this.heading = (head !== undefined ? head : null);
+ /**
+ * The velocity with which the device is moving at the position.
+ */
+ this.speed = (vel !== undefined ? vel : null);
+
+ if (this.speed === 0 || this.speed === null) {
+ this.heading = NaN;
+ }
+
+ /**
+ * The altitude accuracy of the position.
+ */
+ this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ Entry = require('cordova/plugin/Entry'),
+ FileError = require('cordova/plugin/FileError'),
+ DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+ DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+ return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or exclusively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+ argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
+ var win = successCallback && function(result) {
+ var entry = new DirectoryEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or exclusively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+ argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
+ var win = successCallback && function(result) {
+ var FileEntry = require('cordova/plugin/FileEntry');
+ var entry = new FileEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+ this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+ var win = typeof successCallback !== 'function' ? null : function(result) {
+ var retVal = [];
+ for (var i=0; i<result.length; i++) {
+ var entry = null;
+ if (result[i].isDirectory) {
+ entry = new (require('cordova/plugin/DirectoryEntry'))();
+ }
+ else if (result[i].isFile) {
+ entry = new (require('cordova/plugin/FileEntry'))();
+ }
+ entry.isDirectory = result[i].isDirectory;
+ entry.isFile = result[i].isFile;
+ entry.name = result[i].name;
+ entry.fullPath = result[i].fullPath;
+ retVal.push(entry);
+ }
+ successCallback(retVal);
+ };
+ var fail = typeof errorCallback !== 'function' ? null : function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError'),
+ Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ * {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ * {boolean} true if Entry is a directory (readonly)
+ * @param name
+ * {DOMString} name of the file or directory, excluding the path
+ * leading to it (readonly)
+ * @param fullPath
+ * {DOMString} the absolute full path to the file or directory
+ * (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+ this.isFile = !!isFile;
+ this.isDirectory = !!isDirectory;
+ this.name = name || '';
+ this.fullPath = fullPath || '';
+ this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ * {Function} is called with a Metadata object
+ * @param errorCallback
+ * {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
+ var success = successCallback && function(lastModified) {
+ var metadata = new Metadata(lastModified);
+ successCallback(metadata);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+
+ exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ * {Function} is called with a Metadata object
+ * @param errorCallback
+ * {Function} is called with a FileError
+ * @param metadataObject
+ * {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+ argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
+ exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ * {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ * {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ * {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+ argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ // source path
+ var srcPath = this.fullPath,
+ // entry name
+ name = newName || this.name,
+ success = function(entry) {
+ if (entry) {
+ if (successCallback) {
+ // create appropriate Entry object
+ var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+ successCallback(result);
+ }
+ }
+ else {
+ // no Entry object returned
+ fail && fail(FileError.NOT_FOUND_ERR);
+ }
+ };
+
+ // copy
+ exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ * {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ * {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ * {Function} called with the new Entry object
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+ argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+
+ // source path
+ var srcPath = this.fullPath,
+ // entry name
+ name = newName || this.name,
+ // success callback
+ success = function(entry) {
+ if (entry) {
+ if (successCallback) {
+ // create appropriate Entry object
+ var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+ successCallback(result);
+ }
+ }
+ else {
+ // no Entry object returned
+ fail && fail(FileError.NOT_FOUND_ERR);
+ }
+ };
+
+ // copy
+ exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+ // fullPath attribute contains the full URL
+ return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+ console.log("DEPRECATED: Update your code to use 'toURL'");
+ // fullPath attribute contains the full URI
+ return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.remove', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.getParent', arguments);
+ var win = successCallback && function(result) {
+ var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+ var entry = new DirectoryEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+ this.name = name || '';
+ this.fullPath = fullPath || null;
+ this.type = type || null;
+ this.lastModifiedDate = lastModifiedDate || null;
+ this.size = size || 0;
+
+ // These store the absolute start and end for slicing the file.
+ this.start = 0;
+ this.end = this.size;
+};
+
+/**
+ * Returns a "slice" of the file. Since Cordova Files don't contain the actual
+ * content, this really returns a File with adjusted start and end.
+ * Slices of slices are supported.
+ * start {Number} The index at which to start the slice (inclusive).
+ * end {Number} The index at which to end the slice (exclusive).
+ */
+File.prototype.slice = function(start, end) {
+ var size = this.end - this.start;
+ var newStart = 0;
+ var newEnd = size;
+ if (arguments.length) {
+ if (start < 0) {
+ newStart = Math.max(size + start, 0);
+ } else {
+ newStart = Math.min(size, start);
+ }
+ }
+
+ if (arguments.length >= 2) {
+ if (end < 0) {
+ newEnd = Math.max(size + end, 0);
+ } else {
+ newEnd = Math.min(end, size);
+ }
+ }
+
+ var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
+ newFile.start = this.start + newStart;
+ newFile.end = this.start + newEnd;
+ return newFile;
+};
+
+
+module.exports = File;
+
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ Entry = require('cordova/plugin/Entry'),
+ FileWriter = require('cordova/plugin/FileWriter'),
+ File = require('cordova/plugin/File'),
+ FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+ FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+ this.file(function(filePointer) {
+ var writer = new FileWriter(filePointer);
+
+ if (writer.fileName === null || writer.fileName === "") {
+ errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+ } else {
+ successCallback && successCallback(writer);
+ }
+ }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+ var win = successCallback && function(f) {
+ var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+ successCallback(file);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+
+/**
+ * FileError
+ */
+function FileError(error) {
+ this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+ modulemapper = require('cordova/modulemapper'),
+ utils = require('cordova/utils'),
+ File = require('cordova/plugin/File'),
+ FileError = require('cordova/plugin/FileError'),
+ ProgressEvent = require('cordova/plugin/ProgressEvent'),
+ origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ * The root directory is the root of the file system.
+ * To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+ this._readyState = 0;
+ this._error = null;
+ this._result = null;
+ this._fileName = '';
+ this._realReader = origFileReader ? new origFileReader() : {};
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+utils.defineGetter(FileReader.prototype, 'readyState', function() {
+ return this._fileName ? this._readyState : this._realReader.readyState;
+});
+
+utils.defineGetter(FileReader.prototype, 'error', function() {
+ return this._fileName ? this._error: this._realReader.error;
+});
+
+utils.defineGetter(FileReader.prototype, 'result', function() {
+ return this._fileName ? this._result: this._realReader.result;
+});
+
+function defineEvent(eventName) {
+ utils.defineGetterSetter(FileReader.prototype, eventName, function() {
+ return this._realReader[eventName] || null;
+ }, function(value) {
+ this._realReader[eventName] = value;
+ });
+}
+defineEvent('onloadstart'); // When the read starts.
+defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
+defineEvent('onload'); // When the read has successfully completed.
+defineEvent('onerror'); // When the read has failed (see errors).
+defineEvent('onloadend'); // When the request has completed (either in success or failure).
+defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
+
+function initRead(reader, file) {
+ // Already loading something
+ if (reader.readyState == FileReader.LOADING) {
+ throw new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ reader._result = null;
+ reader._error = null;
+ reader._readyState = FileReader.LOADING;
+
+ if (typeof file == 'string') {
+ // Deprecated in Cordova 2.4.
+ console.warn('Using a string argument with FileReader.readAs functions is deprecated.');
+ reader._fileName = file;
+ } else if (typeof file.fullPath == 'string') {
+ reader._fileName = file.fullPath;
+ } else {
+ reader._fileName = '';
+ return true;
+ }
+
+ reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
+}
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+ if (origFileReader && !this._fileName) {
+ return this._realReader.abort();
+ }
+ this._result = null;
+
+ if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
+ return;
+ }
+
+ this._readyState = FileReader.DONE;
+
+ // If abort callback
+ if (typeof this.onabort === 'function') {
+ this.onabort(new ProgressEvent('abort', {target:this}));
+ }
+ // If load end callback
+ if (typeof this.onloadend === 'function') {
+ this.onloadend(new ProgressEvent('loadend', {target:this}));
+ }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file {File} File object containing file properties
+ * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsText(file, encoding);
+ }
+
+ // Default encoding is UTF-8
+ var enc = encoding ? encoding : "UTF-8";
+ var me = this;
+ var execArgs = [this._fileName, enc, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // Save result
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // null result
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsText", execArgs);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ * data:[<mediatype>][;base64],<data>
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsDataURL(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // Save result
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsDataURL", execArgs);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsBinaryString(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsArrayBuffer(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
+};
+
+module.exports = FileReader;
+
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+ this.name = name || null;
+ if (root) {
+ this.root = new DirectoryEntry(root.name, root.fullPath);
+ }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ FileTransferError = require('cordova/plugin/FileTransferError'),
+ ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+function newProgressEvent(result) {
+ var pe = new ProgressEvent();
+ pe.lengthComputable = result.lengthComputable;
+ pe.loaded = result.loaded;
+ pe.total = result.total;
+ return pe;
+}
+
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) !== 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
+var idCounter = 0;
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {
+ this._id = ++idCounter;
+ this.onprogress = null; // optional callback
+};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String} Full path of the file on the device
+* @param server {String} URL of the server to receive the file
+* @param successCallback (Function} Callback to be invoked when upload has completed
+* @param errorCallback {Function} Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+ argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
+ // check for options
+ var fileKey = null;
+ var fileName = null;
+ var mimeType = null;
+ var params = null;
+ var chunkedMode = true;
+ var headers = null;
+ var httpMethod = null;
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ if (options) {
+ fileKey = options.fileKey;
+ fileName = options.fileName;
+ mimeType = options.mimeType;
+ headers = options.headers;
+ httpMethod = options.httpMethod || "POST";
+ if (httpMethod.toUpperCase() == "PUT"){
+ httpMethod = "PUT";
+ } else {
+ httpMethod = "POST";
+ }
+ if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+ chunkedMode = options.chunkedMode;
+ }
+ if (options.params) {
+ params = options.params;
+ }
+ else {
+ params = {};
+ }
+ }
+
+ var fail = errorCallback && function(e) {
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
+ errorCallback(error);
+ };
+
+ var self = this;
+ var win = function(result) {
+ if (typeof result.lengthComputable != "undefined") {
+ if (self.onprogress) {
+ self.onprogress(newProgressEvent(result));
+ }
+
<TRUNCATED>
[30/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Globalization.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Globalization.cs b/common-items/Plugins/Globalization.cs
new file mode 100644
index 0000000..2c2f468
--- /dev/null
+++ b/common-items/Plugins/Globalization.cs
@@ -0,0 +1,1177 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides information about system locale, culture settings, number formats, ect.
+ /// </summary>
+ public class Globalization : BaseCommand
+ {
+
+ #region Globalization errors
+
+ /// <summary>
+ /// Globalization error codes.
+ /// </summary>
+ public enum ErrorCode : int
+ {
+ UnknownError = 0,
+ FormattingError = 1,
+ ParsingError = 2,
+ PatternError = 3
+ }
+
+ /// <summary>
+ /// Represents globalization error object.
+ /// </summary>
+ [DataContract]
+ public class GlobalizationError
+ {
+ #region Error messages
+ /// <summary>
+ /// Error messages
+ /// </summary>
+ public const string UnknownError = "UNKNOWN_ERROR";
+ public const string FormattingError = "FORMATTIN_ERROR";
+ public const string ParsingError = "PARSING_ERROR";
+ public const string PatternError = "PATTERN_ERROR";
+
+ #endregion
+
+ /// <summary>
+ /// Error code
+ /// </summary>
+ [DataMember(Name = "code", IsRequired = false)]
+ public ErrorCode Code { get; set; }
+
+ /// <summary>
+ /// Error message
+ /// </summary>
+ [DataMember(Name = "message", IsRequired = false)]
+ public string Message { get; set; }
+
+ /// <summary>
+ /// Default constructor
+ /// </summary>
+ public GlobalizationError()
+ {
+ this.Code = ErrorCode.UnknownError;
+ this.Message = UnknownError;
+ }
+
+ /// <summary>
+ /// Constructor setting error code
+ /// </summary>
+ public GlobalizationError(ErrorCode error)
+ {
+ this.Code = error;
+
+ switch (error)
+ {
+ case ErrorCode.ParsingError:
+ {
+ this.Message = ParsingError;
+ break;
+ }
+ case ErrorCode.FormattingError:
+ {
+ this.Message = FormattingError;
+ break;
+ }
+ case ErrorCode.PatternError:
+ {
+ this.Message = PatternError;
+ break;
+ }
+ default:
+ {
+ this.Message = UnknownError;
+ break;
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Globalization options
+
+ /// <summary>
+ /// Represents globalization options.
+ /// </summary>
+ [DataContract]
+ public class GlobalizationOptions
+ {
+ #region available option values
+ /// <summary>
+ /// Number pattern types.
+ /// </summary>
+ public const string Percent = "percent";
+ public const string Currency = "currency";
+ public const string Decimal = "decimal";
+
+ /// <summary>
+ /// Format length types
+ /// </summary>
+ public const string Short = "short";
+ public const string Medium = "medium";
+ public const string Long = "long";
+ public const string Full = "full";
+
+ /// <summary>
+ /// Selector types
+ /// </summary>
+ public const string TimeSelector = "time";
+ public const string DateSelector = "date";
+ public const string DateAndTimeSelector = "date and time";
+
+ /// <summary>
+ /// Date name types
+ /// </summary>
+ public const string Narrow = "narrow";
+ public const string Wide = "wide";
+
+ /// <summary>
+ /// Date name items
+ /// </summary>
+ public const string Months = "months";
+ public const string Days = "days";
+
+ #endregion
+
+ /// <summary>
+ /// Additional options
+ /// </summary>
+ [DataMember(Name = "options", IsRequired = false)]
+ public Options AdditionalOptions { get; set; }
+
+ /// <summary>
+ /// Date to convert
+ /// </summary>
+ [DataMember(Name = "date", IsRequired = false)]
+ public long Date { get; set; }
+
+ /// <summary>
+ /// Date as stirng
+ /// </summary>
+ [DataMember(Name = "dateString", IsRequired = false)]
+ public string DateString { get; set; }
+
+ /// <summary>
+ /// Currency code
+ /// </summary>
+ [DataMember(Name = "currencyCode", IsRequired = false)]
+ public string CurrencyCode { get; set; }
+
+ /// <summary>
+ /// Number as string
+ /// </summary>
+ [DataMember(Name = "numberString", IsRequired = false)]
+ public string NumberString { get; set; }
+
+ /// <summary>
+ /// Number to convert
+ /// </summary>
+ [DataMember(Name = "number", IsRequired = false)]
+ public double Number { get; set; }
+ }
+
+ /// <summary>
+ /// Represents additional options
+ /// </summary>
+ [DataContract]
+ public class Options
+ {
+ /// <summary>
+ /// Pattern type
+ /// </summary>
+ [DataMember(Name = "type", IsRequired = false)]
+ public string Type { get; set; }
+
+ /// <summary>
+ /// Format length
+ /// </summary>
+ [DataMember(Name = "formatLength", IsRequired = false)]
+ public string FormatLength { get; set; }
+
+ /// <summary>
+ /// Selector
+ /// </summary>
+ [DataMember(Name = "selector", IsRequired = false)]
+ public string Selector { get; set; }
+
+ /// <summary>
+ /// Date name item
+ /// </summary>
+ [DataMember(Name = "item", IsRequired = false)]
+ public string Item { get; set; }
+ }
+
+ #endregion
+
+ #region returned objects
+
+ #region Number pattern object
+
+ /// <summary>
+ /// Represents number pattern
+ /// </summary>
+ [DataContract]
+ public class NumberPattern
+ {
+ /// <summary>
+ /// Pattern
+ /// </summary>
+ [DataMember(Name = "pattern", IsRequired = false)]
+ public string Pattern { get; set; }
+
+ /// <summary>
+ /// Symbol
+ /// </summary>
+ [DataMember(Name = "symbol", IsRequired = false)]
+ public string Symbol { get; set; }
+
+ /// <summary>
+ /// Fraction
+ /// </summary>
+ [DataMember(Name = "fraction", IsRequired = false)]
+ public int Fraction { get; set; }
+
+ /// <summary>
+ /// Positive
+ /// </summary>
+ [DataMember(Name = "positive", IsRequired = false)]
+ public string Positive { get; set; }
+
+ /// <summary>
+ /// Negative
+ /// </summary>
+ [DataMember(Name = "negative", IsRequired = false)]
+ public string Negative { get; set; }
+
+ /// <summary>
+ /// Rounding
+ /// </summary>
+ [DataMember(Name = "rounding", IsRequired = false)]
+ public int Rounding { get; set; }
+
+ /// <summary>
+ /// Decimal
+ /// </summary>
+ [DataMember(Name = "decimal", IsRequired = false)]
+ public string Decimal { get; set; }
+
+ /// <summary>
+ /// Grouping
+ /// </summary>
+ [DataMember(Name = "grouping", IsRequired = false)]
+ public string Grouping { get; set; }
+
+ /// <summary>
+ /// Constructor of the class
+ /// </summary>
+ /// <param name="pattern"></param>
+ /// <param name="symbol"></param>
+ /// <param name="fraction"></param>
+ /// <param name="positive"></param>
+ /// <param name="negative"></param>
+ /// <param name="rounding"></param>
+ /// <param name="dec"></param>
+ /// <param name="grouping"></param>
+ public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
+ {
+ this.Pattern = pattern;
+ this.Symbol = symbol;
+ this.Fraction = fraction;
+ this.Positive = positive;
+ this.Negative = negative;
+ this.Rounding = rounding;
+ this.Decimal = dec;
+ this.Grouping = grouping;
+ }
+ }
+ #endregion
+
+ #region Date format object
+
+ /// <summary>
+ /// Represents date format
+ /// </summary>
+ [DataContract]
+ public class DateFormat
+ {
+ /// <summary>
+ /// Year
+ /// </summary>
+ [DataMember(Name = "year", IsRequired = false)]
+ public int Year { get; set; }
+
+ /// <summary>
+ /// Month
+ /// </summary>
+ [DataMember(Name = "month", IsRequired = false)]
+ public int Month { get; set; }
+
+ /// <summary>
+ /// Day
+ /// </summary>
+ [DataMember(Name = "day", IsRequired = false)]
+ public int Day { get; set; }
+
+ /// <summary>
+ /// Hour
+ /// </summary>
+ [DataMember(Name = "hour", IsRequired = false)]
+ public int Hour { get; set; }
+
+ /// <summary>
+ /// Minute
+ /// </summary>
+ [DataMember(Name = "minute", IsRequired = false)]
+ public int Minute { get; set; }
+
+ /// <summary>
+ /// Second
+ /// </summary>
+ [DataMember(Name = "second", IsRequired = false)]
+ public int Second { get; set; }
+
+ /// <summary>
+ /// Millisecond
+ /// </summary>
+ [DataMember(Name = "millisecond", IsRequired = false)]
+ public int Millisecond { get; set; }
+
+ public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
+ {
+ this.Year = year;
+ this.Month = month;
+ this.Day = day;
+ this.Hour = hour;
+ this.Minute = minute;
+ this.Millisecond = millisecond;
+ }
+
+ }
+ #endregion
+
+ #region Date pattern object
+
+ /// <summary>
+ /// Represents date pattern object
+ /// </summary>
+ [DataContract]
+ public class DatePattern
+ {
+
+ /// <summary>
+ /// Date pattern
+ /// </summary>
+ [DataMember(Name = "pattern", IsRequired = false)]
+ public string Pattern { get; set; }
+
+ /// <summary>
+ /// TimeZone
+ /// </summary>
+ [DataMember(Name = "timezone", IsRequired = false)]
+ public string TimeZone { get; set; }
+
+ /// <summary>
+ /// UTC offset
+ /// </summary>
+ [DataMember(Name = "utc_offset", IsRequired = false)]
+ public double UtcOffset { get; set; }
+
+ /// <summary>
+ /// Dst offset
+ /// </summary>
+ [DataMember(Name = "dst_offset", IsRequired = false)]
+ public double DstOffset { get; set; }
+
+ /// <summary>
+ /// Constructor of the class
+ /// </summary>
+ /// <param name="pattern"></param>
+ /// <param name="timezone"></param>
+ /// <param name="utcOffset"></param>
+ /// <param name="dstOffset"></param>
+ public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
+ {
+ this.Pattern = pattern;
+ this.TimeZone = timezone;
+ this.UtcOffset = utcOffset;
+ this.DstOffset = dstOffset;
+ }
+
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Locale info
+
+ /// <summary>
+ /// Gets the string identifier for the client's current locale setting.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getLocaleName(string options)
+ {
+ try
+ {
+ var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
+ this.DispatchCommandResult(result);
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ /// <summary>
+ /// Gets the string identifier for the client's current language.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getPreferredLanguage(string options)
+ {
+ try
+ {
+ var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
+ this.DispatchCommandResult(result);
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ #endregion
+
+ #region Date and time info
+
+ /// <summary>
+ /// Gets whether daylight savings time is in effect for a given date using the client's
+ /// time zone and calendar.
+ /// </summary>
+ /// <param name="opitons">Date to daylight savings check.</param>
+ public void isDayLightSavingsTime(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
+ TimeZoneInfo localZone = TimeZoneInfo.Local;
+ bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ /// <summary>
+ /// Gets the first day of the week according to the client's user preferences and calendar.
+ /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getFirstDayOfWeek(string options)
+ {
+ try
+ {
+ // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
+ var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
+ this.DispatchCommandResult(result);
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ #endregion
+
+ #region Formatting
+
+ /// <summary>
+ /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client.
+ /// </summary>
+ /// <param name="options"></param>
+ public void dateToString(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
+
+ string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
+ int formatLength = 0; //default format
+ int selector = 0; //default selector
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.FormatLength != null)
+ {
+ string t = globalOptions.AdditionalOptions.FormatLength;
+
+ if (t.Equals(GlobalizationOptions.Full))
+ {
+ formatLength++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Selector != null)
+ {
+ string t = globalOptions.AdditionalOptions.Selector;
+
+ if (t.Equals(GlobalizationOptions.DateSelector))
+ {
+ selector += 10;
+ }
+ else if (t.Equals(GlobalizationOptions.TimeSelector))
+ {
+ selector += 20;
+ }
+ }
+
+ //determine return value
+ int method = formatLength + selector;
+
+ switch (method)
+ {
+ case 1: // full datetime
+ {
+ format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
+ break;
+ }
+ case 10: // short date
+ {
+ format = "{0:d}";
+ break;
+ }
+ case 11: // full date
+ {
+ format = "{0:D}";
+ break;
+ }
+ case 20: // short time
+ {
+ format = "{0:t}";
+ break;
+ }
+ case 21: // full time
+ {
+ format = "{0:T}";
+ break;
+ }
+ default: // short datetime
+ {
+ format = "{0:M/dd/yy H:m:s}";
+ break;
+ }
+ }
+ }
+
+ string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
+ }
+ }
+
+ /// <summary>
+ /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
+ /// </summary>
+ /// <param name="options"></param>
+ public void stringToDate(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ if (string.IsNullOrEmpty(globalOptions.DateString))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ string format = "M/dd/yy H:m:s"; // short datetime by default
+ int formatLength = 0; //default format
+ int selector = 0; //default selector
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.FormatLength != null)
+ {
+ string t = globalOptions.AdditionalOptions.FormatLength;
+
+ if (t.Equals(GlobalizationOptions.Full))
+ {
+ formatLength++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Selector != null)
+ {
+ string t = globalOptions.AdditionalOptions.Selector;
+
+ if (t.Equals(GlobalizationOptions.DateSelector))
+ {
+ selector += 10;
+ }
+ else if (t.Equals(GlobalizationOptions.TimeSelector))
+ {
+ selector += 20;
+ }
+ }
+
+ //determine return value
+ int method = formatLength + selector;
+
+ switch (method)
+ {
+ case 1: // full datetime
+ {
+ format = "MMMM/dddd/yyyy HH:mm:ss tt";
+ break;
+ }
+ case 10: // short date
+ {
+ format = "d";
+ break;
+ }
+ case 11: // full date
+ {
+ format = "D";
+ break;
+ }
+ case 20: // short time
+ {
+ format = "t";
+ break;
+ }
+ case 21: // full time
+ {
+ format = "T";
+ break;
+ }
+ default: // short datetime
+ {
+ format = "M/dd/yy H:m:s";
+ break;
+ }
+ }
+ }
+
+ DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
+ DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
+
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getDatePattern(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
+ string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
+ int formatLength = 0; //default format
+ int selector = 0; //default selector
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.FormatLength != null)
+ {
+ string t = globalOptions.AdditionalOptions.FormatLength;
+
+ if (t.Equals(GlobalizationOptions.Full))
+ {
+ formatLength++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Selector != null)
+ {
+ string t = globalOptions.AdditionalOptions.Selector;
+
+ if (t.Equals(GlobalizationOptions.DateSelector))
+ {
+ selector += 10;
+ }
+ else if (t.Equals(GlobalizationOptions.TimeSelector))
+ {
+ selector += 20;
+ }
+ }
+
+ //determine return value
+ int method = formatLength + selector;
+
+ switch (method)
+ {
+ case 1: // full datetime
+ {
+ pattern = dateFormatInfo.FullDateTimePattern;
+ break;
+ }
+ case 10: // short date
+ {
+ pattern = dateFormatInfo.ShortDatePattern;
+ break;
+ }
+ case 11: // full date
+ {
+ pattern = dateFormatInfo.LongDatePattern;
+ break;
+ }
+ case 20: // short time
+ {
+ pattern = dateFormatInfo.ShortTimePattern;
+ break;
+ }
+ case 21: // full time
+ {
+ pattern = dateFormatInfo.LongTimePattern;
+ break;
+ }
+ default: // short datetime
+ {
+ // Seems like C# doesn't support short datetime pattern so we use full format
+ // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
+ pattern = dateFormatInfo.FullDateTimePattern;
+ break;
+ }
+ }
+ }
+
+ TimeZoneInfo localZone = TimeZoneInfo.Local;
+ DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getDateNames(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ int type = 0; //default wide
+ int item = 0; //default months
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.Type != null)
+ {
+ string t = globalOptions.AdditionalOptions.Type;
+
+ if (t.Equals(GlobalizationOptions.Narrow))
+ {
+ type++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Item != null)
+ {
+ string t = globalOptions.AdditionalOptions.Item;
+
+ if (t.Equals(GlobalizationOptions.Days))
+ {
+ item += 10;
+ }
+ }
+ }
+
+ //determine return value
+ int method = item + type;
+ string[] namesArray;
+ CultureInfo currentCulture = CultureInfo.CurrentCulture;
+
+ if (method == 1) //months and narrow
+ {
+ namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
+ }
+ else if (method == 10) //days and wide
+ {
+ namesArray = currentCulture.DateTimeFormat.DayNames;
+ }
+ else if (method == 11) //days and narrow
+ {
+ namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
+ }
+ else //default: months and wide
+ {
+ namesArray = currentCulture.DateTimeFormat.MonthNames;
+ }
+
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ /// <summary>
+ /// Gets a number formatted as a string according to the client's user preferences.
+ /// </summary>
+ /// <param name="options"></param>
+ public void numberToString(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ string format = string.Empty;
+ string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
+ GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
+
+ switch (numberFormatType)
+ {
+ case GlobalizationOptions.Percent:
+ {
+ format = "{0:p}";
+ break;
+ }
+
+ case GlobalizationOptions.Currency:
+ {
+ format = "{0:c}";
+ break;
+ }
+
+ default:
+ {
+ format = "{0:f}";
+ break;
+ }
+ }
+
+ string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
+
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
+ /// </summary>
+ /// <param name="options"></param>
+ public void stringToNumber(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ if (string.IsNullOrEmpty(globalOptions.NumberString))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ string numberString = globalOptions.NumberString;
+ string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
+ GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
+
+ NumberStyles numberStyle;
+
+ switch (numberFormatType)
+ {
+ case GlobalizationOptions.Percent:
+ {
+ numberStyle = NumberStyles.Any;
+ numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
+ break;
+ }
+
+ case GlobalizationOptions.Currency:
+ {
+ numberStyle = NumberStyles.Currency;
+ break;
+ }
+
+ default:
+ {
+ numberStyle = NumberStyles.Number;
+ break;
+ }
+ }
+
+ double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
+
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
+ }
+ }
+
+
+ /// <summary>
+ /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getNumberPattern(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ CultureInfo cultureInfo = CultureInfo.CurrentCulture;
+ NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
+ string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
+ GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
+ NumberPattern pattern = null;
+ string symbol;
+
+ // TODO find out how to get format pattern and the number of fraction digits
+ switch (numberFormatType)
+ {
+ case GlobalizationOptions.Percent:
+ {
+ symbol = formatInfo.PercentSymbol;
+ pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
+ break;
+ }
+ case GlobalizationOptions.Currency:
+ {
+ symbol = formatInfo.CurrencySymbol;
+ pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
+ break;
+ }
+ default:
+ {
+ symbol = formatInfo.NumberDecimalSeparator;
+ pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
+ break;
+ }
+ }
+
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getCurrencyPattern(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ string currencyCode = globalOptions.CurrencyCode;
+
+ // temporary not supported via lack of api required
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
+ return;
+
+ // TODO find the way to get currency info from currency code
+ // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
+ // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
+ // CultureInfo cultureInfo = new CultureInfo(currencyCode);
+ // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
+ }
+ }
+
+ #endregion
+
+ #region private methods
+
+ /// <summary>
+ /// Wraps data into JSON format
+ /// </summary>
+ /// <param name="data">data</param>
+ /// <returns>data formatted as JSON object</returns>
+ private string WrapIntoJSON<T>(T data, string keyName = "value")
+ {
+ string param = "{0}";
+ string stringifiedData = data.ToString();
+
+ if (data.GetType() == typeof(string))
+ {
+ param = "\"" + param + "\"";
+ }
+
+ if (data.GetType() == typeof(bool))
+ {
+ stringifiedData = stringifiedData.ToLower();
+ }
+
+ if (data.GetType() == typeof(string[]))
+ {
+ stringifiedData = JSON.JsonHelper.Serialize(data);
+ }
+
+ var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
+ formattedData = "{" + formattedData + "}";
+
+ return formattedData;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/ImageExifHelper.cs b/common-items/Plugins/ImageExifHelper.cs
new file mode 100644
index 0000000..68ddf87
--- /dev/null
+++ b/common-items/Plugins/ImageExifHelper.cs
@@ -0,0 +1,209 @@
+/*
+ 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.
+
+*/
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Windows.Media.Imaging;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class ImageExifOrientation
+ {
+ public const int Portrait = 1;
+ public const int PortraitUpsideDown = 3;
+ public const int LandscapeLeft = 6;
+ public const int LandscapeRight = 8;
+ }
+
+ public class ImageExifHelper
+ {
+
+ public static Stream RotateStream(Stream stream, int angle)
+ {
+ stream.Position = 0;
+ if (angle % 90 != 0 || angle < 0)
+ {
+ throw new ArgumentException();
+ }
+ if (angle % 360 == 0)
+ {
+ return stream;
+ }
+
+ angle = angle % 360;
+
+ BitmapImage bitmap = new BitmapImage();
+ bitmap.SetSource(stream);
+ WriteableBitmap wbSource = new WriteableBitmap(bitmap);
+
+ WriteableBitmap wbTarget = null;
+
+ int srcPixelWidth = wbSource.PixelWidth;
+ int srcPixelHeight = wbSource.PixelHeight;
+
+ if (angle % 180 == 0)
+ {
+ wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
+ }
+ else
+ {
+ wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
+ }
+
+ int destPixelWidth = wbTarget.PixelWidth;
+ int[] srcPxls = wbSource.Pixels;
+ int[] destPxls = wbTarget.Pixels;
+
+ // this ugly if/else is to avoid a conditional check for every pixel
+ if (angle == 90)
+ {
+ for (int x = 0; x < srcPixelWidth; x++)
+ {
+ for (int y = 0; y < srcPixelHeight; y++)
+ {
+ destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
+ }
+ }
+ }
+ else if (angle == 180)
+ {
+ for (int x = 0; x < srcPixelWidth; x++)
+ {
+ for (int y = 0; y < srcPixelHeight; y++)
+ {
+ destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
+ }
+ }
+ }
+ else if (angle == 270)
+ {
+ for (int x = 0; x < srcPixelWidth; x++)
+ {
+ for (int y = 0; y < srcPixelHeight; y++)
+ {
+ destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
+ }
+ }
+ }
+
+ MemoryStream targetStream = new MemoryStream();
+ wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
+ return targetStream;
+ }
+
+ public static int getImageOrientationFromStream(Stream imgStream)
+ {
+
+ // 0xFFD8 : jpgHeader
+ // 0xFFE1 :
+ // 0x???? : length of exif data
+ // 0x????, 0x???? : Chars 'E','x','i','f'
+ // 0x0000 : 2 empty bytes
+ // <== mark beginning of tags SIZE:ID:VALUE
+ // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determins littleEndian-ness
+ // 0x002A : marker value
+ // 0x???? : offset to the Image File Data
+
+ // XXXX possible space before actual tag data ... we skip to mark + offset
+
+ // 0x???? number of exif tags present
+
+ // make sure we are at the begining
+ imgStream.Seek(0, SeekOrigin.Begin);
+ BinaryReader reader = new BinaryReader(imgStream);
+
+ byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
+
+ byte start = reader.ReadByte(); // 0xFF
+ byte index = reader.ReadByte(); // 0xE1
+
+ while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
+ {
+ // Get the data length
+ ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ // skip along
+ reader.ReadBytes(dLen - 2);
+ start = reader.ReadByte();
+ index = reader.ReadByte();
+ }
+
+ // It's only success if we found the 0xFFE1 marker
+ if (start != 0xFF || index != 0xE1)
+ {
+ // throw new Exception("Could not find Exif data block");
+ Debug.WriteLine("Did not find EXIF data");
+ return 0;
+ }
+
+ // read 2 byte length of EXIF data
+ ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ String exif = ""; // build the string
+ for (var n = 0; n < 4; n++)
+ {
+ exif += reader.ReadChar();
+ }
+ if (exif != "Exif")
+ {
+ // did not find exif data ...
+ Debug.WriteLine("Did not find EXIF data");
+ return 0;
+ }
+
+ // read 2 empty bytes
+ //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ reader.ReadBytes(2);
+
+ long headerMark = reader.BaseStream.Position; // where are we now <==
+
+ //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
+ reader.ReadBytes(2); // 'II' or 'MM', but we don't care
+
+ if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
+ {
+ Debug.WriteLine("Error in data != 0x002A");
+ return 0;
+ }
+
+ // Get the offset to the IFD (image file directory)
+ ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+
+ imgStream.Position = headerMark + imgOffset;
+ ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ for (ushort x = 0; x < tagCount; x++)
+ {
+ // Orientation = 0x112, aka 274
+ if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
+ {
+ ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ // don't care ..
+ uint comps = reader.ReadUInt32();
+ byte[] tagData = reader.ReadBytes(4);
+ int orientation = (int)tagData[0];
+ Debug.WriteLine("orientation = " + orientation.ToString());
+ return orientation;
+ // 6 means rotate clockwise 90 deg
+ // 8 means rotate counter-clockwise 90 deg
+ // 1 means all is good
+ // 3 means flip vertical
+ }
+ // skip to the next item, 12 bytes each
+ reader.BaseStream.Seek(10, SeekOrigin.Current);
+ }
+ return 0;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/InAppBrowser.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/InAppBrowser.cs b/common-items/Plugins/InAppBrowser.cs
new file mode 100644
index 0000000..2741355
--- /dev/null
+++ b/common-items/Plugins/InAppBrowser.cs
@@ -0,0 +1,271 @@
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Controls;
+using System.Diagnostics;
+using System.Runtime.Serialization;
+using WPCordovaClassLib.Cordova;
+using WPCordovaClassLib.Cordova.Commands;
+using WPCordovaClassLib.Cordova.JSON;
+using Microsoft.Phone.Shell;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ [DataContract]
+ public class BrowserOptions
+ {
+ [DataMember]
+ public string url;
+
+ [DataMember]
+ public bool isGeolocationEnabled;
+ }
+
+ public class InAppBrowser : BaseCommand
+ {
+
+ private static WebBrowser browser;
+ private static ApplicationBarIconButton backButton;
+ private static ApplicationBarIconButton fwdButton;
+
+ public void open(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
+ string urlLoc = args[0];
+ string target = args[1];
+ /*
+ _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
+ _blank - always open in the InAppBrowser
+ _system - always open in the system web browser
+ */
+ switch (target)
+ {
+ case "_blank":
+ ShowInAppBrowser(urlLoc);
+ break;
+ case "_self":
+ ShowCordovaBrowser(urlLoc);
+ break;
+ case "_system":
+ ShowSystemBrowser(urlLoc);
+ break;
+ }
+
+
+ }
+
+ private void ShowCordovaBrowser(string url)
+ {
+ Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ CordovaView cView = page.FindName("CordovaView") as CordovaView;
+ if (cView != null)
+ {
+ WebBrowser br = cView.Browser;
+ br.Navigate(loc);
+ }
+ }
+
+ }
+ });
+ }
+
+ private void ShowSystemBrowser(string url)
+ {
+ WebBrowserTask webBrowserTask = new WebBrowserTask();
+ webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
+ webBrowserTask.Show();
+ }
+
+
+ private void ShowInAppBrowser(string url)
+ {
+ Uri loc = new Uri(url);
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ if (browser != null)
+ {
+ //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
+ browser.Navigate(loc);
+ }
+ else
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+
+ string baseImageUrl = "Images/";
+
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ browser = new WebBrowser();
+ browser.IsScriptEnabled = true;
+ browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
+
+ browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
+ browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
+ browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
+ browser.Navigate(loc);
+ //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
+ grid.Children.Add(browser);
+ }
+
+ ApplicationBar bar = new ApplicationBar();
+ bar.BackgroundColor = Colors.Gray;
+ bar.IsMenuEnabled = false;
+
+ backButton = new ApplicationBarIconButton();
+ backButton.Text = "Back";
+
+ backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
+ backButton.Click += new EventHandler(backButton_Click);
+ backButton.IsEnabled = false;
+ bar.Buttons.Add(backButton);
+
+
+ fwdButton = new ApplicationBarIconButton();
+ fwdButton.Text = "Forward";
+ fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
+ fwdButton.Click += new EventHandler(fwdButton_Click);
+ fwdButton.IsEnabled = false;
+ bar.Buttons.Add(fwdButton);
+
+ ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
+ closeBtn.Text = "Close";
+ closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
+ closeBtn.Click += new EventHandler(closeBtn_Click);
+ bar.Buttons.Add(closeBtn);
+
+ page.ApplicationBar = bar;
+ }
+
+ }
+ }
+ });
+ }
+
+ void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+
+ }
+
+ void fwdButton_Click(object sender, EventArgs e)
+ {
+ if (browser != null)
+ {
+ try
+ {
+ browser.GoForward();
+ //browser.InvokeScript("execScript", "history.forward();");
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ void backButton_Click(object sender, EventArgs e)
+ {
+ if (browser != null)
+ {
+ try
+ {
+ browser.GoBack();
+ //browser.InvokeScript("execScript", "history.back();");
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ void closeBtn_Click(object sender, EventArgs e)
+ {
+ this.close();
+ }
+
+
+ public void close(string options = "")
+ {
+ if (browser != null)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(browser);
+ }
+ page.ApplicationBar = null;
+ }
+ }
+ browser = null;
+ string message = "{\"type\":\"exit\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.OK, message);
+ result.KeepCallback = false;
+ this.DispatchCommandResult(result);
+ });
+ }
+ }
+
+ void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (browser != null)
+ {
+ backButton.IsEnabled = browser.CanGoBack;
+ fwdButton.IsEnabled = browser.CanGoForward;
+
+ }
+ string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.OK, message);
+ result.KeepCallback = true;
+ this.DispatchCommandResult(result);
+ }
+
+ void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
+ {
+ string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
+ result.KeepCallback = true;
+ this.DispatchCommandResult(result);
+ }
+
+ void browser_Navigating(object sender, NavigatingEventArgs e)
+ {
+ string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.OK, message);
+ result.KeepCallback = true;
+ this.DispatchCommandResult(result);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Media.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Media.cs b/common-items/Plugins/Media.cs
new file mode 100644
index 0000000..5de4884
--- /dev/null
+++ b/common-items/Plugins/Media.cs
@@ -0,0 +1,547 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Windows;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides the ability to record and play back audio files on a device.
+ /// </summary>
+ public class Media : BaseCommand
+ {
+ /// <summary>
+ /// Audio player objects
+ /// </summary>
+ private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
+
+ /// <summary>
+ /// Represents Media action options.
+ /// </summary>
+ [DataContract]
+ public class MediaOptions
+ {
+ /// <summary>
+ /// Audio id
+ /// </summary>
+ [DataMember(Name = "id", IsRequired = true)]
+ public string Id { get; set; }
+
+ /// <summary>
+ /// Path to audio file
+ /// </summary>
+ [DataMember(Name = "src")]
+ public string Src { get; set; }
+
+ /// <summary>
+ /// New track position
+ /// </summary>
+ [DataMember(Name = "milliseconds")]
+ public int Milliseconds { get; set; }
+ }
+
+ /// <summary>
+ /// Releases the audio player instance to save memory.
+ /// </summary>
+ public void release(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ if (!Media.players.ContainsKey(mediaOptions.Id))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
+ return;
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ AudioPlayer audio = Media.players[mediaOptions.Id];
+ Media.players.Remove(mediaOptions.Id);
+ audio.Dispose();
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Starts recording and save the specified file
+ /// </summary>
+ public void startRecordingAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ mediaOptions.Src = optionsString[1];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ if (mediaOptions != null)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ AudioPlayer audio;
+ if (!Media.players.ContainsKey(mediaOptions.Id))
+ {
+ audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ }
+ else
+ {
+ audio = Media.players[mediaOptions.Id];
+ }
+
+ if (audio != null)
+ {
+ audio.startRecording(mediaOptions.Src);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+
+ });
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Stops recording and save to the file specified when recording started
+ /// </summary>
+ public void stopRecordingAudio(string options)
+ {
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ audio.stopRecording();
+ Media.players.Remove(mediaId);
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+ }
+
+ public void setVolume(string options) // id,volume
+ {
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ string id = optionsString[0];
+ double volume = double.Parse(optionsString[1]);
+
+ if (Media.players.ContainsKey(id))
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ AudioPlayer player = Media.players[id];
+ player.setVolume(volume);
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
+ return;
+ }
+ }
+
+ // Some Audio Notes:
+ // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
+ // While playing, a MediaElement stops all other media playback on the phone.
+ // Multiple MediaElement controls are NOT supported
+
+ // Called when you create a new Media('blah') object in JS.
+ public void create(string options)
+ {
+ // Debug.WriteLine("Creating Audio :: " + options);
+ try
+ {
+ MediaOptions mediaOptions;
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ mediaOptions.Src = optionsString[1];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
+ return;
+ }
+
+ AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Starts or resume playing audio file
+ /// </summary>
+ public void startPlayingAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ mediaOptions.Src = optionsString[1];
+ if (optionsString.Length > 2 && optionsString[2] != null)
+ {
+ mediaOptions.Milliseconds = int.Parse(optionsString[2]);
+ }
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ AudioPlayer audio;
+
+ if (!Media.players.ContainsKey(mediaOptions.Id))
+ {
+ audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ }
+ else
+ {
+ //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
+ audio = Media.players[mediaOptions.Id];
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ audio.startPlaying(mediaOptions.Src);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+
+ /// <summary>
+ /// Seeks to a location
+ /// </summary>
+ public void seekToAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ if (optionsString.Length > 1 && optionsString[1] != null)
+ {
+ mediaOptions.Milliseconds = int.Parse(optionsString[1]);
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaOptions.Id))
+ {
+ AudioPlayer audio = Media.players[mediaOptions.Id];
+ audio.seekToPlaying(mediaOptions.Milliseconds);
+ }
+ else
+ {
+ Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Pauses playing
+ /// </summary>
+ public void pausePlayingAudio(string options)
+ {
+
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ audio.pausePlaying();
+ }
+ else
+ {
+ Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+
+
+ }
+
+
+ /// <summary>
+ /// Stops playing the audio file
+ /// </summary>
+ public void stopPlayingAudio(String options)
+ {
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ audio.stopPlaying();
+ }
+ else
+ {
+ Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+ }
+
+ /// <summary>
+ /// Gets current position of playback
+ /// </summary>
+ public void getCurrentPositionAudio(string options)
+ {
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
+ }
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+ }
+
+
+ /// <summary>
+ /// Gets the duration of the audio file
+ /// </summary>
+
+ [Obsolete("This method will be removed shortly")]
+ public void getDurationAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ AudioPlayer audio;
+ if (Media.players.ContainsKey(mediaOptions.Id))
+ {
+ audio = Media.players[mediaOptions.Id];
+ }
+ else
+ {
+ Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
+ audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+ }
+}
[29/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/MimeTypeMapper.cs b/common-items/Plugins/MimeTypeMapper.cs
new file mode 100644
index 0000000..a2794f5
--- /dev/null
+++ b/common-items/Plugins/MimeTypeMapper.cs
@@ -0,0 +1,101 @@
+/*
+ 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.
+*/
+
+using System.Collections.Generic;
+using System.IO;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Represents file extension to mime type mapper.
+ /// </summary>
+ public static class MimeTypeMapper
+ {
+ /// <summary>
+ /// For unknown type it is recommended to use 'application/octet-stream'
+ /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
+ /// </summary>
+ private static string DefaultMimeType = "application/octet-stream";
+
+ /// <summary>
+ /// Stores mime type for all necessary extension
+ /// </summary>
+ private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
+ {
+ {"avi", "video/x-msvideo"},
+ {"bmp", "image/bmp"},
+ {"gif", "image/gif"},
+ {"html","text/html"},
+ {"jpe", "image/jpeg"},
+ {"jpeg", "image/jpeg"},
+ {"jpg", "image/jpeg"},
+ {"js","text/javascript"},
+ {"mov", "video/quicktime"},
+ {"mp2", "audio/mpeg"},
+ {"mp3", "audio/mpeg"},
+ {"mp4", "video/mp4"},
+ {"mpe", "video/mpeg"},
+ {"mpeg", "video/mpeg"},
+ {"mpg", "video/mpeg"},
+ {"mpga", "audio/mpeg"},
+ {"pbm", "image/x-portable-bitmap"},
+ {"pcm", "audio/x-pcm"},
+ {"pct", "image/pict"},
+ {"pgm", "image/x-portable-graymap"},
+ {"pic", "image/pict"},
+ {"pict", "image/pict"},
+ {"png", "image/png"},
+ {"pnm", "image/x-portable-anymap"},
+ {"pnt", "image/x-macpaint"},
+ {"pntg", "image/x-macpaint"},
+ {"ppm", "image/x-portable-pixmap"},
+ {"qt", "video/quicktime"},
+ {"ra", "audio/x-pn-realaudio"},
+ {"ram", "audio/x-pn-realaudio"},
+ {"ras", "image/x-cmu-raster"},
+ {"rgb", "image/x-rgb"},
+ {"snd", "audio/basic"},
+ {"txt", "text/plain"},
+ {"tif", "image/tiff"},
+ {"tiff", "image/tiff"},
+ {"wav", "audio/x-wav"},
+ {"wbmp", "image/vnd.wap.wbmp"},
+
+ };
+ /// <summary>
+ /// Gets mime type by file extension
+ /// </summary>
+ /// <param name="fileName">file name to extract extension</param>
+ /// <returns>mime type</returns>
+ public static string GetMimeType(string fileName)
+ {
+ string ext = Path.GetExtension(fileName);
+
+ // invalid extension
+ if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
+ {
+ return DefaultMimeType;
+ }
+
+ ext = ext.Remove(0, 1);
+
+ if (MIMETypesDictionary.ContainsKey(ext))
+ {
+ return MIMETypesDictionary[ext];
+ }
+
+ return DefaultMimeType;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/NetworkStatus.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/NetworkStatus.cs b/common-items/Plugins/NetworkStatus.cs
new file mode 100644
index 0000000..12eb061
--- /dev/null
+++ b/common-items/Plugins/NetworkStatus.cs
@@ -0,0 +1,129 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Diagnostics;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Net.NetworkInformation;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+ // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
+ // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
+
+ public class NetworkStatus : BaseCommand
+ {
+ const string UNKNOWN = "unknown";
+ const string ETHERNET = "ethernet";
+ const string WIFI = "wifi";
+ const string CELL_2G = "2g";
+ const string CELL_3G = "3g";
+ const string CELL_4G = "4g";
+ const string NONE = "none";
+ const string CELL = "cellular";
+
+ private bool HasCallback = false;
+
+ public NetworkStatus()
+ {
+ DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
+ }
+
+ public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
+ {
+ this.getConnectionInfo("");
+ }
+
+ public void getConnectionInfo(string empty)
+ {
+ HasCallback = true;
+ updateConnectionType(checkConnectionType());
+ }
+
+ private string checkConnectionType()
+ {
+ if (DeviceNetworkInformation.IsNetworkAvailable)
+ {
+ if (DeviceNetworkInformation.IsWiFiEnabled)
+ {
+ return WIFI;
+ }
+ else
+ {
+ return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
+ }
+ }
+ return NONE;
+ }
+
+ private string checkConnectionType(NetworkInterfaceSubType type)
+ {
+ switch (type)
+ {
+ case NetworkInterfaceSubType.Cellular_1XRTT: //cell
+ case NetworkInterfaceSubType.Cellular_GPRS: //cell
+ return CELL;
+ case NetworkInterfaceSubType.Cellular_EDGE: //2
+ return CELL_2G;
+ case NetworkInterfaceSubType.Cellular_3G:
+ case NetworkInterfaceSubType.Cellular_EVDO: //3
+ case NetworkInterfaceSubType.Cellular_EVDV: //3
+ case NetworkInterfaceSubType.Cellular_HSPA: //3
+ return CELL_3G;
+ case NetworkInterfaceSubType.WiFi:
+ return WIFI;
+ case NetworkInterfaceSubType.Unknown:
+ case NetworkInterfaceSubType.Desktop_PassThru:
+ default:
+ return UNKNOWN;
+ }
+ }
+
+ void ChangeDetected(object sender, NetworkNotificationEventArgs e)
+ {
+ switch (e.NotificationType)
+ {
+ case NetworkNotificationType.InterfaceConnected:
+ updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
+ break;
+ case NetworkNotificationType.InterfaceDisconnected:
+ updateConnectionType(NONE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void updateConnectionType(string type)
+ {
+ // This should also implicitly fire offline/online events as that is handled on the JS side
+ if (this.HasCallback)
+ {
+ PluginResult result = new PluginResult(PluginResult.Status.OK, type);
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Notification.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Notification.cs b/common-items/Plugins/Notification.cs
new file mode 100644
index 0000000..0759c72
--- /dev/null
+++ b/common-items/Plugins/Notification.cs
@@ -0,0 +1,361 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using Microsoft.Devices;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Windows.Resources;
+using Microsoft.Phone.Controls;
+using Microsoft.Xna.Framework.Audio;
+using WPCordovaClassLib.Cordova.UI;
+using System.Diagnostics;
+
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Notification : BaseCommand
+ {
+ static ProgressBar progressBar = null;
+ const int DEFAULT_DURATION = 5;
+
+ private NotificationBox notifyBox;
+
+ private PhoneApplicationPage Page
+ {
+ get
+ {
+ PhoneApplicationPage page = null;
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ page = frame.Content as PhoneApplicationPage;
+ }
+ return page;
+ }
+ }
+
+ // blink api - doesn't look like there is an equivalent api we can use...
+
+ [DataContract]
+ public class AlertOptions
+ {
+ [OnDeserializing]
+ public void OnDeserializing(StreamingContext context)
+ {
+ // set defaults
+ this.message = "message";
+ this.title = "Alert";
+ this.buttonLabel = "ok";
+ }
+
+ /// <summary>
+ /// message to display in the alert box
+ /// </summary>
+ [DataMember]
+ public string message;
+
+ /// <summary>
+ /// title displayed on the alert window
+ /// </summary>
+ [DataMember]
+ public string title;
+
+ /// <summary>
+ /// text to display on the button
+ /// </summary>
+ [DataMember]
+ public string buttonLabel;
+ }
+
+ public void alert(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ AlertOptions alertOpts = new AlertOptions();
+ alertOpts.message = args[0];
+ alertOpts.title = args[1];
+ alertOpts.buttonLabel = args[2];
+ string aliasCurrentCommandCallbackId = args[3];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = alertOpts.title;
+ notifyBox.SubTitle.Text = alertOpts.message;
+ Button btnOK = new Button();
+ btnOK.Content = alertOpts.buttonLabel;
+ btnOK.Click += new RoutedEventHandler(btnOK_Click);
+ btnOK.Tag = 1;
+ notifyBox.ButtonPanel.Children.Add(btnOK);
+ grid.Children.Add(notifyBox);
+
+ if (previous == null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ public void confirm(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ AlertOptions alertOpts = new AlertOptions();
+ alertOpts.message = args[0];
+ alertOpts.title = args[1];
+ alertOpts.buttonLabel = args[2];
+ string aliasCurrentCommandCallbackId = args[3];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = alertOpts.title;
+ notifyBox.SubTitle.Text = alertOpts.message;
+
+ string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
+
+ if (labels == null)
+ {
+ labels = alertOpts.buttonLabel.Split(',');
+ }
+
+ for (int n = 0; n < labels.Length; n++)
+ {
+ Button btn = new Button();
+ btn.Content = labels[n];
+ btn.Tag = n;
+ btn.Click += new RoutedEventHandler(btnOK_Click);
+ notifyBox.ButtonPanel.Children.Add(btn);
+ }
+
+ grid.Children.Add(notifyBox);
+ if (previous == null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ PhoneApplicationPage page = sender as PhoneApplicationPage;
+ string callbackId = "";
+ if (page != null && notifyBox != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(notifyBox);
+ dynamic notifBoxData = notifyBox.Tag;
+ notifyBox = notifBoxData.previous as NotificationBox;
+ callbackId = notifBoxData.callbackId as string;
+ }
+ if (notifyBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ e.Cancel = true;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
+ }
+
+ void btnOK_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ FrameworkElement notifBoxParent = null;
+ int retVal = 0;
+ string callbackId = "";
+ if (btn != null)
+ {
+ retVal = (int)btn.Tag + 1;
+
+ notifBoxParent = btn.Parent as FrameworkElement;
+ while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
+ !(notifBoxParent is NotificationBox)) ;
+ }
+ if (notifBoxParent != null)
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(notifBoxParent);
+ }
+
+ dynamic notifBoxData = notifBoxParent.Tag;
+ notifyBox = notifBoxData.previous as NotificationBox;
+ callbackId = notifBoxData.callbackId as string;
+
+ if (notifyBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ }
+
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
+ }
+
+
+
+ public void beep(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ int times = int.Parse(args[0]);
+
+ string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
+
+ StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
+
+ if (sri != null)
+ {
+ SoundEffect effect = SoundEffect.FromStream(sri.Stream);
+ SoundEffectInstance inst = effect.CreateInstance();
+ ThreadPool.QueueUserWorkItem((o) =>
+ {
+ // cannot interact with UI !!
+ do
+ {
+ inst.Play();
+ Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
+ }
+ while (--times > 0);
+
+ });
+
+ }
+
+ // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
+ DispatchCommandResult();
+ }
+
+ // Display an indeterminate progress indicator
+ public void activityStart(string unused)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+
+ if (page != null)
+ {
+ var temp = page.FindName("LayoutRoot");
+ Grid grid = temp as Grid;
+ if (grid != null)
+ {
+ if (progressBar != null)
+ {
+ grid.Children.Remove(progressBar);
+ }
+ progressBar = new ProgressBar();
+ progressBar.IsIndeterminate = true;
+ progressBar.IsEnabled = true;
+
+ grid.Children.Add(progressBar);
+ }
+ }
+ }
+ });
+ }
+
+
+ // Remove our indeterminate progress indicator
+ public void activityStop(string unused)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ if (progressBar != null)
+ {
+ progressBar.IsEnabled = false;
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(progressBar);
+ }
+ }
+ }
+ progressBar = null;
+ }
+ });
+ }
+
+ public void vibrate(string vibrateDuration)
+ {
+
+ int msecs = 200; // set default
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
+
+ msecs = int.Parse(args[0]);
+ if (msecs < 1)
+ {
+ msecs = 1;
+ }
+ }
+ catch (FormatException)
+ {
+
+ }
+
+ VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
+
+ // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
+ DispatchCommandResult();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/AudioCaptureTask.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/AudioCaptureTask.cs b/common-items/Plugins/UI/AudioCaptureTask.cs
new file mode 100644
index 0000000..3d7d60f
--- /dev/null
+++ b/common-items/Plugins/UI/AudioCaptureTask.cs
@@ -0,0 +1,107 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.Windows;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ /// <summary>
+ /// Allows an application to launch the Audio Recording application.
+ /// Use this to allow users to record audio from your application.
+ /// </summary>
+ public class AudioCaptureTask
+ {
+ /// <summary>
+ /// Represents recorded audio returned from a call to the Show method of
+ /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
+ /// </summary>
+ public class AudioResult : TaskEventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the AudioResult class.
+ /// </summary>
+ public AudioResult()
+ { }
+
+ /// <summary>
+ /// Initializes a new instance of the AudioResult class
+ /// with the specified Microsoft.Phone.Tasks.TaskResult.
+ /// </summary>
+ /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
+ public AudioResult(TaskResult taskResult)
+ : base(taskResult)
+ { }
+
+ /// <summary>
+ /// Gets the file name of the recorded audio.
+ /// </summary>
+ public Stream AudioFile { get; internal set; }
+
+ /// <summary>
+ /// Gets the stream containing the data for the recorded audio.
+ /// </summary>
+ public string AudioFileName { get; internal set; }
+ }
+
+ /// <summary>
+ /// Occurs when a audio recording task is completed.
+ /// </summary>
+ public event EventHandler<AudioResult> Completed;
+
+ /// <summary>
+ /// Shows Audio Recording application
+ /// </summary>
+ public void Show()
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ var root = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
+
+ string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
+ // dummy parameter is used to always open a fresh version
+ root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
+
+ });
+ }
+
+ /// <summary>
+ /// Performs additional configuration of the recording application.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (!(e.Content is AudioRecorder)) return;
+
+ (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
+
+ AudioRecorder audioRecorder = (AudioRecorder)e.Content;
+
+ if (audioRecorder != null)
+ {
+ audioRecorder.Completed += this.Completed;
+ }
+ else if (this.Completed != null)
+ {
+ this.Completed(this, new AudioResult(TaskResult.Cancel));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/AudioRecorder.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/AudioRecorder.xaml b/common-items/Plugins/UI/AudioRecorder.xaml
new file mode 100644
index 0000000..0fd26ab
--- /dev/null
+++ b/common-items/Plugins/UI/AudioRecorder.xaml
@@ -0,0 +1,66 @@
+<!--
+ 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.
+-->
+<phone:PhoneApplicationPage
+ x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
+ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ SupportedOrientations="Portrait" Orientation="Portrait"
+ mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
+ shell:SystemTray.IsVisible="True">
+
+ <!--LayoutRoot is the root grid where all page content is placed-->
+ <Grid x:Name="LayoutRoot" Background="Transparent">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ <!--TitlePanel contains the name of the application and page title-->
+ <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
+ <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
+ </StackPanel>
+
+ <!--ContentPanel - place additional content here-->
+ <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
+ <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0" VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
+ <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
+ <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
+ </Grid>
+ </Grid>
+
+ <!--Sample code showing usage of ApplicationBar-->
+ <!--<phone:PhoneApplicationPage.ApplicationBar>
+ <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
+ <shell:ApplicationBar.MenuItems>
+ <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
+ <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
+ </shell:ApplicationBar.MenuItems>
+ </shell:ApplicationBar>
+ </phone:PhoneApplicationPage.ApplicationBar>-->
+
+</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/AudioRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/AudioRecorder.xaml.cs b/common-items/Plugins/UI/AudioRecorder.xaml.cs
new file mode 100644
index 0000000..01a0832
--- /dev/null
+++ b/common-items/Plugins/UI/AudioRecorder.xaml.cs
@@ -0,0 +1,307 @@
+/*
+ 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.
+*/
+
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows;
+using System.Windows.Threading;
+using WPCordovaClassLib.Cordova.Commands;
+using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ /// <summary>
+ /// Implements Audio Recording application
+ /// </summary>
+ public partial class AudioRecorder : PhoneApplicationPage
+ {
+
+ #region Constants
+
+ private const string RecordingStartCaption = "Start";
+ private const string RecordingStopCaption = "Stop";
+
+ private const string LocalFolderName = "AudioCache";
+ private const string FileNameFormat = "Audio-{0}.wav";
+
+ #endregion
+
+ #region Callbacks
+
+ /// <summary>
+ /// Occurs when a audio recording task is completed.
+ /// </summary>
+ public event EventHandler<AudioResult> Completed;
+
+ #endregion
+
+ #region Fields
+
+ /// <summary>
+ /// Audio source
+ /// </summary>
+ private Microphone microphone;
+
+ /// <summary>
+ /// Temporary buffer to store audio chunk
+ /// </summary>
+ private byte[] buffer;
+
+ /// <summary>
+ /// Recording duration
+ /// </summary>
+ private TimeSpan duration;
+
+ /// <summary>
+ /// Output buffer
+ /// </summary>
+ private MemoryStream memoryStream;
+
+ /// <summary>
+ /// Xna game loop dispatcher
+ /// </summary>
+ DispatcherTimer dtXna;
+
+ /// <summary>
+ /// Recording result, dispatched back when recording page is closed
+ /// </summary>
+ private AudioResult result = new AudioResult(TaskResult.Cancel);
+
+ /// <summary>
+ /// Whether we are recording audio now
+ /// </summary>
+ private bool IsRecording
+ {
+ get
+ {
+ return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Creates new instance of the AudioRecorder class.
+ /// </summary>
+ public AudioRecorder()
+ {
+
+ this.InitializeXnaGameLoop();
+
+ // microphone requires special XNA initialization to work
+ InitializeComponent();
+ }
+
+ /// <summary>
+ /// Starts recording, data is stored in memory
+ /// </summary>
+ private void StartRecording()
+ {
+ this.microphone = Microphone.Default;
+ this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
+
+ this.btnTake.IsEnabled = false;
+ this.btnStartStop.Content = RecordingStopCaption;
+
+ this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
+ this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
+
+ this.memoryStream = new MemoryStream();
+ this.memoryStream.InitializeWavStream(this.microphone.SampleRate);
+
+ this.duration = new TimeSpan(0);
+
+ this.microphone.Start();
+ }
+
+ /// <summary>
+ /// Stops recording
+ /// </summary>
+ private void StopRecording()
+ {
+ this.microphone.Stop();
+
+ this.microphone.BufferReady -= MicrophoneBufferReady;
+
+ this.microphone = null;
+
+ btnStartStop.Content = RecordingStartCaption;
+
+ // check there is some data
+ this.btnTake.IsEnabled = true;
+ }
+
+ /// <summary>
+ /// Handles Start/Stop events
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void btnStartStop_Click(object sender, RoutedEventArgs e)
+ {
+
+ if (this.IsRecording)
+ {
+ this.StopRecording();
+ }
+ else
+ {
+ this.StartRecording();
+ }
+ }
+
+ /// <summary>
+ /// Handles Take button click
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void btnTake_Click(object sender, RoutedEventArgs e)
+ {
+ this.result = this.SaveAudioClipToLocalStorage();
+
+ if (Completed != null)
+ {
+ Completed(this, result);
+ }
+
+ if (this.NavigationService.CanGoBack)
+ {
+ this.NavigationService.GoBack();
+ }
+ }
+
+ /// <summary>
+ /// Handles page closing event, stops recording if needed and dispatches results.
+ /// </summary>
+ /// <param name="e"></param>
+ protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (IsRecording)
+ {
+ StopRecording();
+ }
+
+ this.FinalizeXnaGameLoop();
+
+ base.OnNavigatedFrom(e);
+ }
+
+ /// <summary>
+ /// Copies data from microphone to memory storages and updates recording state
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void MicrophoneBufferReady(object sender, EventArgs e)
+ {
+ this.microphone.GetData(this.buffer);
+ this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
+ TimeSpan bufferDuration = this.microphone.BufferDuration;
+
+ this.Dispatcher.BeginInvoke(() =>
+ {
+ this.duration += bufferDuration;
+
+ this.txtDuration.Text = "Duration: " +
+ this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
+ this.duration.Seconds.ToString().PadLeft(2, '0');
+ });
+
+ }
+
+ /// <summary>
+ /// Writes audio data from memory to isolated storage
+ /// </summary>
+ /// <returns></returns>
+ private AudioResult SaveAudioClipToLocalStorage()
+ {
+ if (this.memoryStream == null || this.memoryStream.Length <= 0)
+ {
+ return new AudioResult(TaskResult.Cancel);
+ }
+
+ this.memoryStream.UpdateWavStream();
+
+ // save audio data to local isolated storage
+
+ string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+
+ if (!isoFile.DirectoryExists(LocalFolderName))
+ {
+ isoFile.CreateDirectory(LocalFolderName);
+ }
+
+ string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
+
+ this.memoryStream.Seek(0, SeekOrigin.Begin);
+
+ using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
+ {
+
+ this.memoryStream.CopyTo(fileStream);
+ }
+
+ AudioResult result = new AudioResult(TaskResult.OK);
+ result.AudioFileName = filePath;
+
+ result.AudioFile = this.memoryStream;
+ result.AudioFile.Seek(0, SeekOrigin.Begin);
+
+ return result;
+ }
+
+
+
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Special initialization required for the microphone: XNA game loop
+ /// </summary>
+ private void InitializeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ this.dtXna = new DispatcherTimer();
+ this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
+ this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
+ this.dtXna.Start();
+ }
+ /// <summary>
+ /// Finalizes XNA game loop for microphone
+ /// </summary>
+ private void FinalizeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ if (dtXna != null)
+ {
+ dtXna.Stop();
+ dtXna = null;
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/ImageCapture.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/ImageCapture.xaml b/common-items/Plugins/UI/ImageCapture.xaml
new file mode 100644
index 0000000..a7eee21
--- /dev/null
+++ b/common-items/Plugins/UI/ImageCapture.xaml
@@ -0,0 +1,26 @@
+<phone:PhoneApplicationPage
+ x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
+ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
+ mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
+ shell:SystemTray.IsVisible="True">
+
+ <!--LayoutRoot is the root grid where all page content is placed-->
+ <Grid x:Name="LayoutRoot" Background="Yellow">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ </Grid>
+
+
+</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/ImageCapture.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/ImageCapture.xaml.cs b/common-items/Plugins/UI/ImageCapture.xaml.cs
new file mode 100644
index 0000000..234b444
--- /dev/null
+++ b/common-items/Plugins/UI/ImageCapture.xaml.cs
@@ -0,0 +1,109 @@
+/*
+ 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.
+*/
+
+
+using System;
+using System.IO;
+using System.Windows;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class ImageCapture : PhoneApplicationPage
+ {
+ public ImageCapture()
+ {
+ InitializeComponent();
+ }
+ }
+
+ public class ImageCaptureTask
+ {
+ /// <summary>
+ /// Represents an image returned from a call to the Show method of
+ /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
+ /// </summary>
+ //public class AudioResult : TaskEventArgs
+ //{
+ // /// <summary>
+ // /// Initializes a new instance of the AudioResult class.
+ // /// </summary>
+ // public AudioResult()
+ // { }
+
+ // /// <summary>
+ // /// Initializes a new instance of the AudioResult class
+ // /// with the specified Microsoft.Phone.Tasks.TaskResult.
+ // /// </summary>
+ // /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
+ // public AudioResult(TaskResult taskResult)
+ // : base(taskResult)
+ // { }
+
+ // /// <summary>
+ // /// Gets the file name of the recorded audio.
+ // /// </summary>
+ // public Stream AudioFile { get; internal set; }
+
+ // /// <summary>
+ // /// Gets the stream containing the data for the recorded audio.
+ // /// </summary>
+ // public string AudioFileName { get; internal set; }
+ //}
+
+ ///// <summary>
+ ///// Occurs when a audio recording task is completed.
+ ///// </summary>
+ //public event EventHandler<AudioResult> Completed;
+
+ /// <summary>
+ /// Shows Audio Recording application
+ /// </summary>
+ public void Show()
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ var root = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
+
+ string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
+
+ // dummy parameter is used to always open a fresh version
+ root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
+ });
+ }
+
+ /// <summary>
+ /// Performs additional configuration of the recording application.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ ImageCapture imageCapture = e.Content as ImageCapture;
+ if (imageCapture != null)
+ {
+ (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
+
+ //imageCapture.Completed += this.Completed;
+ //else if (this.Completed != null)
+ //{
+ // this.Completed(this, new AudioResult(TaskResult.Cancel));
+ //}
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/NotificationBox.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/NotificationBox.xaml b/common-items/Plugins/UI/NotificationBox.xaml
new file mode 100644
index 0000000..1ca5d5f
--- /dev/null
+++ b/common-items/Plugins/UI/NotificationBox.xaml
@@ -0,0 +1,62 @@
+<!--
+ 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.
+-->
+<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
+
+ <Grid x:Name="LayoutRoot"
+ Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+
+ <!--TitlePanel contains the name of the application and page title-->
+ <StackPanel x:Name="TitlePanel"
+ Grid.Row="0"
+ Background="{StaticResource PhoneSemitransparentBrush}">
+ <TextBlock x:Name="PageTitle"
+ Text="Title"
+ Margin="10,10"
+ Style="{StaticResource PhoneTextTitle2Style}"/>
+
+ <TextBlock x:Name="SubTitle"
+ Text="Subtitle"
+ TextWrapping="Wrap"
+ Margin="10,10"
+ Style="{StaticResource PhoneTextTitle3Style}"/>
+
+ <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
+ <StackPanel x:Name="ButtonPanel"
+ Margin="10,10"
+ Orientation="Horizontal"/>
+ </ScrollViewer>
+
+ </StackPanel>
+ </Grid>
+</UserControl>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/NotificationBox.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/NotificationBox.xaml.cs b/common-items/Plugins/UI/NotificationBox.xaml.cs
new file mode 100644
index 0000000..50b2f2a
--- /dev/null
+++ b/common-items/Plugins/UI/NotificationBox.xaml.cs
@@ -0,0 +1,41 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class NotificationBox : UserControl
+ {
+ public NotificationBox()
+ {
+ InitializeComponent();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/VideoCaptureTask.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/VideoCaptureTask.cs b/common-items/Plugins/UI/VideoCaptureTask.cs
new file mode 100644
index 0000000..958c05c
--- /dev/null
+++ b/common-items/Plugins/UI/VideoCaptureTask.cs
@@ -0,0 +1,105 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.Windows;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ /// <summary>
+ /// Allows an application to launch the Video Recording application.
+ /// Use this to allow users to record video from your application.
+ /// </summary>
+ public class VideoCaptureTask
+ {
+ /// <summary>
+ /// Represents recorded video returned from a call to the Show method of
+ /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
+ /// </summary>
+ public class VideoResult : TaskEventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the VideoResult class.
+ /// </summary>
+ public VideoResult()
+ { }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoResult class
+ /// with the specified Microsoft.Phone.Tasks.TaskResult.
+ /// </summary>
+ /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
+ public VideoResult(TaskResult taskResult)
+ : base(taskResult)
+ { }
+
+ /// <summary>
+ /// Gets the file name of the recorded Video.
+ /// </summary>
+ public Stream VideoFile { get; internal set; }
+
+ /// <summary>
+ /// Gets the stream containing the data for the recorded Video.
+ /// </summary>
+ public string VideoFileName { get; internal set; }
+ }
+
+ /// <summary>
+ /// Occurs when a Video recording task is completed.
+ /// </summary>
+ public event EventHandler<VideoResult> Completed;
+
+ /// <summary>
+ /// Shows Video Recording application
+ /// </summary>
+ public void Show()
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ var root = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
+
+ string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
+ // dummy parameter is used to always open a fresh version
+ root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
+ });
+ }
+
+ /// <summary>
+ /// Performs additional configuration of the recording application.
+ /// </summary>
+ private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (!(e.Content is VideoRecorder)) return;
+
+ (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
+
+ VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
+
+ if (VideoRecorder != null)
+ {
+ VideoRecorder.Completed += this.Completed;
+ }
+ else if (this.Completed != null)
+ {
+ this.Completed(this, new VideoResult(TaskResult.Cancel));
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/VideoRecorder.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/VideoRecorder.xaml b/common-items/Plugins/UI/VideoRecorder.xaml
new file mode 100644
index 0000000..c78fdb0
--- /dev/null
+++ b/common-items/Plugins/UI/VideoRecorder.xaml
@@ -0,0 +1,52 @@
+<!--
+ 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.
+-->
+<phone:PhoneApplicationPage
+ x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
+ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ SupportedOrientations="Landscape" Orientation="LandscapeLeft"
+ shell:SystemTray.IsVisible="False">
+
+ <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
+
+ <Rectangle
+ x:Name="viewfinderRectangle"
+ Width="640"
+ Height="480"
+ HorizontalAlignment="Left"
+ Canvas.Left="80"/>
+
+ </Canvas>
+
+ <phone:PhoneApplicationPage.ApplicationBar>
+ <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record" x:Name="btnStartRecording" Click="StartRecording_Click" />
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>
+ </shell:ApplicationBar>
+ </phone:PhoneApplicationPage.ApplicationBar>
+
+</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/UI/VideoRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/VideoRecorder.xaml.cs b/common-items/Plugins/UI/VideoRecorder.xaml.cs
new file mode 100644
index 0000000..6ab1cc3
--- /dev/null
+++ b/common-items/Plugins/UI/VideoRecorder.xaml.cs
@@ -0,0 +1,405 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows.Media;
+using System.Windows.Navigation;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Shell;
+using Microsoft.Phone.Tasks;
+using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class VideoRecorder : PhoneApplicationPage
+ {
+
+ #region Constants
+
+ /// <summary>
+ /// Caption for record button in ready state
+ /// </summary>
+ private const string RecordingStartCaption = "Record";
+
+ /// <summary>
+ /// Caption for record button in recording state
+ /// </summary>
+ private const string RecordingStopCaption = "Stop";
+
+ /// <summary>
+ /// Start record icon URI
+ /// </summary>
+ private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
+
+ /// <summary>
+ /// Stop record icon URI
+ /// </summary>
+ private const string StopIconUri = "/Images/appbar.stop.rest.png";
+
+ /// <summary>
+ /// Folder to save video clips
+ /// </summary>
+ private const string LocalFolderName = "VideoCache";
+
+ /// <summary>
+ /// File name format
+ /// </summary>
+ private const string FileNameFormat = "Video-{0}.mp4";
+
+ /// <summary>
+ /// Temporary file name
+ /// </summary>
+ private const string defaultFileName = "NewVideoFile.mp4";
+
+ #endregion
+
+ #region Callbacks
+ /// <summary>
+ /// Occurs when a video recording task is completed.
+ /// </summary>
+ public event EventHandler<VideoResult> Completed;
+
+ #endregion
+
+ #region Fields
+
+ /// <summary>
+ /// Viewfinder for capturing video
+ /// </summary>
+ private VideoBrush videoRecorderBrush;
+
+ /// <summary>
+ /// Path to save video clip
+ /// </summary>
+ private string filePath;
+
+ /// <summary>
+ /// Source for capturing video.
+ /// </summary>
+ private CaptureSource captureSource;
+
+ /// <summary>
+ /// Video device
+ /// </summary>
+ private VideoCaptureDevice videoCaptureDevice;
+
+ /// <summary>
+ /// File sink so save recording video in Isolated Storage
+ /// </summary>
+ private FileSink fileSink;
+
+ /// <summary>
+ /// For managing button and application state
+ /// </summary>
+ private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
+
+ /// <summary>
+ /// Current video state
+ /// </summary>
+ private VideoState currentVideoState;
+
+ /// <summary>
+ /// Stream to return result
+ /// </summary>
+ private MemoryStream memoryStream;
+
+ /// <summary>
+ /// Recording result, dispatched back when recording page is closed
+ /// </summary>
+ private VideoResult result = new VideoResult(TaskResult.Cancel);
+
+ #endregion
+
+ /// <summary>
+ /// Initializes components
+ /// </summary>
+ public VideoRecorder()
+ {
+ InitializeComponent();
+
+ PhoneAppBar = (ApplicationBar)ApplicationBar;
+ PhoneAppBar.IsVisible = true;
+ btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
+ btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
+ }
+
+ /// <summary>
+ /// Initializes the video recorder then page is loading
+ /// </summary>
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ base.OnNavigatedTo(e);
+ this.InitializeVideoRecorder();
+ }
+
+ /// <summary>
+ /// Disposes camera and media objects then leave the page
+ /// </summary>
+ protected override void OnNavigatedFrom(NavigationEventArgs e)
+ {
+ this.DisposeVideoRecorder();
+
+ if (this.Completed != null)
+ {
+ this.Completed(this, result);
+ }
+ base.OnNavigatedFrom(e);
+ }
+
+ /// <summary>
+ /// Handles TakeVideo button click
+ /// </summary>
+ private void TakeVideo_Click(object sender, EventArgs e)
+ {
+ this.result = this.SaveVideoClip();
+ this.NavigateBack();
+ }
+
+ private void NavigateBack()
+ {
+ if (this.NavigationService.CanGoBack)
+ {
+ this.NavigationService.GoBack();
+ }
+ }
+
+ /// <summary>
+ /// Resaves video clip from temporary directory to persistent
+ /// </summary>
+ private VideoResult SaveVideoClip()
+ {
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
+ {
+ return new VideoResult(TaskResult.Cancel);
+ }
+
+ string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
+ string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
+ isoFile.CopyFile(filePath, newPath);
+ isoFile.DeleteFile(filePath);
+
+ memoryStream = new MemoryStream();
+ using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
+ {
+ fileStream.CopyTo(memoryStream);
+ }
+
+ VideoResult result = new VideoResult(TaskResult.OK);
+ result.VideoFileName = newPath;
+ result.VideoFile = this.memoryStream;
+ result.VideoFile.Seek(0, SeekOrigin.Begin);
+ return result;
+ }
+
+ }
+ catch (Exception)
+ {
+ return new VideoResult(TaskResult.None);
+ }
+ }
+
+ /// <summary>
+ /// Updates the buttons on the UI thread based on current state.
+ /// </summary>
+ /// <param name="currentState">current UI state</param>
+ private void UpdateUI(VideoState currentState)
+ {
+ Dispatcher.BeginInvoke(delegate
+ {
+ switch (currentState)
+ {
+ case VideoState.CameraNotSupported:
+ btnStartRecording.IsEnabled = false;
+ btnTakeVideo.IsEnabled = false;
+ break;
+
+ case VideoState.Initialized:
+ btnStartRecording.Text = RecordingStartCaption;
+ btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
+ btnTakeVideo.IsEnabled = false;
+ break;
+
+ case VideoState.Ready:
+ btnStartRecording.Text = RecordingStartCaption;
+ btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
+ btnTakeVideo.IsEnabled = true;
+ break;
+
+ case VideoState.Recording:
+ btnStartRecording.Text = RecordingStopCaption;
+ btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
+ btnTakeVideo.IsEnabled = false;
+ break;
+
+ default:
+ break;
+ }
+ currentVideoState = currentState;
+ });
+ }
+
+ /// <summary>
+ /// Initializes VideoRecorder
+ /// </summary>
+ public void InitializeVideoRecorder()
+ {
+ if (captureSource == null)
+ {
+ captureSource = new CaptureSource();
+ fileSink = new FileSink();
+ videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
+
+ if (videoCaptureDevice != null)
+ {
+ videoRecorderBrush = new VideoBrush();
+ videoRecorderBrush.SetSource(captureSource);
+ viewfinderRectangle.Fill = videoRecorderBrush;
+ captureSource.Start();
+ this.UpdateUI(VideoState.Initialized);
+ }
+ else
+ {
+ this.UpdateUI(VideoState.CameraNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets recording state: start recording
+ /// </summary>
+ private void StartVideoRecording()
+ {
+ try
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
+ {
+ captureSource.Stop();
+ fileSink.CaptureSource = captureSource;
+ filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.DirectoryExists(LocalFolderName))
+ {
+ isoFile.CreateDirectory(LocalFolderName);
+ }
+
+ if (isoFile.FileExists(filePath))
+ {
+ isoFile.DeleteFile(filePath);
+ }
+ }
+
+ fileSink.IsolatedStorageFileName = filePath;
+ }
+
+ if (captureSource.VideoCaptureDevice != null
+ && captureSource.State == CaptureState.Stopped)
+ {
+ captureSource.Start();
+ }
+ this.UpdateUI(VideoState.Recording);
+ }
+ catch (Exception)
+ {
+ this.result = new VideoResult(TaskResult.None);
+ this.NavigateBack();
+ }
+ }
+
+ /// <summary>
+ /// Sets the recording state: stop recording
+ /// </summary>
+ private void StopVideoRecording()
+ {
+ try
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
+ {
+ captureSource.Stop();
+ fileSink.CaptureSource = null;
+ fileSink.IsolatedStorageFileName = null;
+ this.StartVideoPreview();
+ }
+ }
+ catch (Exception)
+ {
+ this.result = new VideoResult(TaskResult.None);
+ this.NavigateBack();
+ }
+ }
+
+ /// <summary>
+ /// Sets the recording state: display the video on the viewfinder.
+ /// </summary>
+ private void StartVideoPreview()
+ {
+ try
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
+ {
+ videoRecorderBrush.SetSource(captureSource);
+ viewfinderRectangle.Fill = videoRecorderBrush;
+ captureSource.Start();
+ this.UpdateUI(VideoState.Ready);
+ }
+ }
+ catch (Exception)
+ {
+ this.result = new VideoResult(TaskResult.None);
+ this.NavigateBack();
+ }
+ }
+
+ /// <summary>
+ /// Starts video recording
+ /// </summary>
+ private void StartRecording_Click(object sender, EventArgs e)
+ {
+ if (currentVideoState == VideoState.Recording)
+ {
+ this.StopVideoRecording();
+ }
+ else
+ {
+ this.StartVideoRecording();
+ }
+ }
+
+ /// <summary>
+ /// Releases resources
+ /// </summary>
+ private void DisposeVideoRecorder()
+ {
+ if (captureSource != null)
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
+ {
+ captureSource.Stop();
+ }
+ captureSource = null;
+ videoCaptureDevice = null;
+ fileSink = null;
+ videoRecorderBrush = null;
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Accelerometer.cs
----------------------------------------------------------------------
diff --git a/plugins/Accelerometer.cs b/plugins/Accelerometer.cs
deleted file mode 100644
index cba911c..0000000
--- a/plugins/Accelerometer.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Captures device motion in the x, y, and z direction.
- /// </summary>
- public class Accelerometer : BaseCommand
- {
- #region AccelerometerOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class AccelerometerOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public AccelerometerOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Frequency = 10000;
- }
- }
-
- #endregion
-
- #region Status codes and Constants
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 3;
-
- public const double gConstant = -9.81;
-
- #endregion
-
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Accelerometer
- /// </summary>
- private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
-
- private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
-
- #endregion
-
- /// <summary>
- /// Sensor listener event
- /// </summary>
- private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
- {
- this.SetStatus(Running);
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- /// <summary>
- /// Starts listening for acceleration sensor
- /// </summary>
- /// <returns>status of listener</returns>
- public void start(string options)
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return;
- }
- try
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
- accelerometer.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- public void stop(string options)
- {
- if (currentStatus == Running)
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
- accelerometer.Stop();
- this.SetStatus(Stopped);
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetCurrentAccelerationFormatted()
- {
- // convert to unix timestamp
- // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
- // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
- // this resolves an issue with inconsistencies between JS dates and Native DateTime
- string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
- (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
- return "{" + resultCoordinates + "}";
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/AudioFormatsHelper.cs
----------------------------------------------------------------------
diff --git a/plugins/AudioFormatsHelper.cs b/plugins/AudioFormatsHelper.cs
deleted file mode 100644
index dca7ee6..0000000
--- a/plugins/AudioFormatsHelper.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- 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.
-
- */
-
-using System;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides extra functionality to support different audio formats.
- /// </summary>
- public static class AudioFormatsHelper
- {
- #region Wav
- /// <summary>
- /// Adds wav file format header to the stream
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">The stream</param>
- /// <param name="sampleRate">Sample Rate</param>
- public static void InitializeWavStream(this Stream stream, int sampleRate)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- int numBits = 16;
- int numBytes = numBits / 8;
-
- stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
- stream.Write(BitConverter.GetBytes(16), 0, 4);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
- stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
- stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
- stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- }
-
- /// <summary>
- /// Updates wav file format header
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">Wav stream</param>
- public static void UpdateWavStream(this Stream stream)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- var position = stream.Position;
-
- stream.Seek(4, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
- stream.Seek(40, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
- stream.Seek(position, SeekOrigin.Begin);
- }
-
- #endregion
- }
-}
[22/50] [abbrv] git commit: moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
moved all common app stuff to own folder, template builder copies it over
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/22118ac7
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/22118ac7
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/22118ac7
Branch: refs/heads/2.9.x
Commit: 22118ac72dc70df944780249ee0c5772a0c0eae1
Parents: a2476e7
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 13:39:10 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 13:39:10 2013 -0700
----------------------------------------------------------------------
common-items/ApplicationIcon.png | Bin 0 -> 4951 bytes
common-items/Background.png | Bin 0 -> 10259 bytes
common-items/Images/appbar.back.rest.png | Bin 0 -> 375 bytes
common-items/Images/appbar.close.rest.png | Bin 0 -> 359 bytes
.../Images/appbar.feature.video.rest.png | Bin 0 -> 433 bytes
common-items/Images/appbar.next.rest.png | Bin 0 -> 388 bytes
common-items/Images/appbar.save.rest.png | Bin 0 -> 297 bytes
common-items/Images/appbar.stop.rest.png | Bin 0 -> 350 bytes
common-items/SplashScreenImage.jpg | Bin 0 -> 33248 bytes
common-items/__PreviewImage.jpg | Bin 0 -> 25875 bytes
common-items/__TemplateIcon.png | Bin 0 -> 6546 bytes
common-items/resources/notification-beep.wav | Bin 0 -> 16630 bytes
common-items/www/cordova.js | 6723 ++++++++++++++++++
common-items/www/css/index.css | 115 +
common-items/www/img/logo.png | Bin 0 -> 21814 bytes
common-items/www/index.html | 42 +
common-items/www/js/index.js | 49 +
wp7/template/ApplicationIcon.png | Bin 4951 -> 0 bytes
wp7/template/Background.png | Bin 10259 -> 0 bytes
wp7/template/Images/appbar.back.rest.png | Bin 375 -> 0 bytes
wp7/template/Images/appbar.close.rest.png | Bin 359 -> 0 bytes
.../Images/appbar.feature.video.rest.png | Bin 433 -> 0 bytes
wp7/template/Images/appbar.next.rest.png | Bin 388 -> 0 bytes
wp7/template/Images/appbar.save.rest.png | Bin 297 -> 0 bytes
wp7/template/Images/appbar.stop.rest.png | Bin 350 -> 0 bytes
wp7/template/MyTemplate.vstemplate | 10 +-
wp7/template/SplashScreenImage.jpg | Bin 33248 -> 0 bytes
wp7/template/VERSION | 1 -
wp7/template/__PreviewImage.jpg | Bin 25875 -> 0 bytes
wp7/template/__TemplateIcon.png | Bin 6546 -> 0 bytes
wp7/template/resources/notification-beep.wav | Bin 16630 -> 0 bytes
wp7/template/www/cordova.js | 6722 -----------------
wp7/template/www/css/index.css | 115 -
wp7/template/www/img/logo.png | Bin 21814 -> 0 bytes
wp7/template/www/index.html | 42 -
wp7/template/www/js/index.js | 49 -
wp7/tooling/scripts/createTemplates.js | 44 +-
wp8/template/ApplicationIcon.png | Bin 4951 -> 0 bytes
wp8/template/Background.png | Bin 10259 -> 0 bytes
wp8/template/Images/appbar.back.rest.png | Bin 375 -> 0 bytes
wp8/template/Images/appbar.close.rest.png | Bin 359 -> 0 bytes
.../Images/appbar.feature.video.rest.png | Bin 433 -> 0 bytes
wp8/template/Images/appbar.next.rest.png | Bin 388 -> 0 bytes
wp8/template/Images/appbar.save.rest.png | Bin 297 -> 0 bytes
wp8/template/Images/appbar.stop.rest.png | Bin 350 -> 0 bytes
wp8/template/SplashScreenImage.jpg | Bin 33248 -> 0 bytes
wp8/template/__PreviewImage.jpg | Bin 25875 -> 0 bytes
wp8/template/__TemplateIcon.png | Bin 6546 -> 0 bytes
wp8/template/resources/notification-beep.wav | Bin 16630 -> 0 bytes
wp8/template/www/cordova.js | 6723 ------------------
wp8/template/www/css/index.css | 115 -
wp8/template/www/img/logo.png | Bin 21814 -> 0 bytes
wp8/template/www/index.html | 42 -
wp8/template/www/js/index.js | 49 -
wp8/tooling/scripts/createTemplates.js | 39 +-
55 files changed, 7017 insertions(+), 13863 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/ApplicationIcon.png
----------------------------------------------------------------------
diff --git a/common-items/ApplicationIcon.png b/common-items/ApplicationIcon.png
new file mode 100644
index 0000000..6b69046
Binary files /dev/null and b/common-items/ApplicationIcon.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Background.png
----------------------------------------------------------------------
diff --git a/common-items/Background.png b/common-items/Background.png
new file mode 100644
index 0000000..2667df4
Binary files /dev/null and b/common-items/Background.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Images/appbar.back.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.back.rest.png b/common-items/Images/appbar.back.rest.png
new file mode 100644
index 0000000..4bc2b92
Binary files /dev/null and b/common-items/Images/appbar.back.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Images/appbar.close.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.close.rest.png b/common-items/Images/appbar.close.rest.png
new file mode 100644
index 0000000..8166a1c
Binary files /dev/null and b/common-items/Images/appbar.close.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Images/appbar.feature.video.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.feature.video.rest.png b/common-items/Images/appbar.feature.video.rest.png
new file mode 100644
index 0000000..baff565
Binary files /dev/null and b/common-items/Images/appbar.feature.video.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Images/appbar.next.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.next.rest.png b/common-items/Images/appbar.next.rest.png
new file mode 100644
index 0000000..ed577d7
Binary files /dev/null and b/common-items/Images/appbar.next.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Images/appbar.save.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.save.rest.png b/common-items/Images/appbar.save.rest.png
new file mode 100644
index 0000000..d49940e
Binary files /dev/null and b/common-items/Images/appbar.save.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/Images/appbar.stop.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.stop.rest.png b/common-items/Images/appbar.stop.rest.png
new file mode 100644
index 0000000..4dd724f
Binary files /dev/null and b/common-items/Images/appbar.stop.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/SplashScreenImage.jpg
----------------------------------------------------------------------
diff --git a/common-items/SplashScreenImage.jpg b/common-items/SplashScreenImage.jpg
new file mode 100644
index 0000000..d35501d
Binary files /dev/null and b/common-items/SplashScreenImage.jpg differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/__PreviewImage.jpg
----------------------------------------------------------------------
diff --git a/common-items/__PreviewImage.jpg b/common-items/__PreviewImage.jpg
new file mode 100644
index 0000000..1d72941
Binary files /dev/null and b/common-items/__PreviewImage.jpg differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/__TemplateIcon.png
----------------------------------------------------------------------
diff --git a/common-items/__TemplateIcon.png b/common-items/__TemplateIcon.png
new file mode 100644
index 0000000..75c17c7
Binary files /dev/null and b/common-items/__TemplateIcon.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/resources/notification-beep.wav
----------------------------------------------------------------------
diff --git a/common-items/resources/notification-beep.wav b/common-items/resources/notification-beep.wav
new file mode 100644
index 0000000..d0ad085
Binary files /dev/null and b/common-items/resources/notification-beep.wav differ
[48/50] [abbrv] git commit: merge issues
Posted by pu...@apache.org.
merge issues
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/90097ba2
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/90097ba2
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/90097ba2
Branch: refs/heads/2.9.x
Commit: 90097ba2e6c6fbede3743b9da5361c3734ad2a5c
Parents: d4f359a 46ea0a4
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 15:26:30 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 15:26:30 2013 -0700
----------------------------------------------------------------------
common/www/cordova.js | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
[33/50] [abbrv] git commit: moved plugins to common
Posted by pu...@apache.org.
moved plugins to common
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/765c8158
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/765c8158
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/765c8158
Branch: refs/heads/2.9.x
Commit: 765c8158b9b191803218af7aed5ceded745af731
Parents: 129c0bd
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 13:51:00 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 13:51:00 2013 -0700
----------------------------------------------------------------------
common-items/Plugins/Accelerometer.cs | 196 ++
common-items/Plugins/AudioFormatsHelper.cs | 89 +
common-items/Plugins/AudioPlayer.cs | 620 +++++++
common-items/Plugins/Battery.cs | 79 +
common-items/Plugins/Camera.cs | 490 +++++
common-items/Plugins/Capture.cs | 736 ++++++++
common-items/Plugins/Compass.cs | 362 ++++
common-items/Plugins/Contacts.cs | 664 +++++++
common-items/Plugins/DebugConsole.cs | 49 +
common-items/Plugins/Device.cs | 135 ++
common-items/Plugins/File.cs | 1676 ++++++++++++++++++
common-items/Plugins/FileTransfer.cs | 526 ++++++
common-items/Plugins/GeoLocation.cs | 34 +
common-items/Plugins/Globalization.cs | 1177 ++++++++++++
common-items/Plugins/ImageExifHelper.cs | 209 +++
common-items/Plugins/InAppBrowser.cs | 271 +++
common-items/Plugins/Media.cs | 547 ++++++
common-items/Plugins/MimeTypeMapper.cs | 101 ++
common-items/Plugins/NetworkStatus.cs | 129 ++
common-items/Plugins/Notification.cs | 361 ++++
common-items/Plugins/UI/AudioCaptureTask.cs | 107 ++
common-items/Plugins/UI/AudioRecorder.xaml | 66 +
common-items/Plugins/UI/AudioRecorder.xaml.cs | 307 ++++
common-items/Plugins/UI/ImageCapture.xaml | 26 +
common-items/Plugins/UI/ImageCapture.xaml.cs | 109 ++
common-items/Plugins/UI/NotificationBox.xaml | 62 +
common-items/Plugins/UI/NotificationBox.xaml.cs | 41 +
common-items/Plugins/UI/VideoCaptureTask.cs | 105 ++
common-items/Plugins/UI/VideoRecorder.xaml | 52 +
common-items/Plugins/UI/VideoRecorder.xaml.cs | 405 +++++
plugins/Accelerometer.cs | 196 --
plugins/AudioFormatsHelper.cs | 89 -
plugins/AudioPlayer.cs | 620 -------
plugins/Battery.cs | 79 -
plugins/Camera.cs | 490 -----
plugins/Capture.cs | 736 --------
plugins/Compass.cs | 362 ----
plugins/Contacts.cs | 664 -------
plugins/DebugConsole.cs | 49 -
plugins/Device.cs | 135 --
plugins/File.cs | 1676 ------------------
plugins/FileTransfer.cs | 526 ------
plugins/GeoLocation.cs | 34 -
plugins/Globalization.cs | 1177 ------------
plugins/ImageExifHelper.cs | 209 ---
plugins/InAppBrowser.cs | 271 ---
plugins/Media.cs | 547 ------
plugins/MimeTypeMapper.cs | 101 --
plugins/NetworkStatus.cs | 129 --
plugins/Notification.cs | 361 ----
plugins/UI/AudioCaptureTask.cs | 107 --
plugins/UI/AudioRecorder.xaml | 66 -
plugins/UI/AudioRecorder.xaml.cs | 307 ----
plugins/UI/ImageCapture.xaml | 26 -
plugins/UI/ImageCapture.xaml.cs | 109 --
plugins/UI/NotificationBox.xaml | 62 -
plugins/UI/NotificationBox.xaml.cs | 41 -
plugins/UI/VideoCaptureTask.cs | 105 --
plugins/UI/VideoRecorder.xaml | 52 -
plugins/UI/VideoRecorder.xaml.cs | 405 -----
wp8/tooling/scripts/createTemplates.js | 3 +-
61 files changed, 9732 insertions(+), 9733 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Accelerometer.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Accelerometer.cs b/common-items/Plugins/Accelerometer.cs
new file mode 100644
index 0000000..cba911c
--- /dev/null
+++ b/common-items/Plugins/Accelerometer.cs
@@ -0,0 +1,196 @@
+/*
+ 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.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading;
+using Microsoft.Devices.Sensors;
+using System.Globalization;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Captures device motion in the x, y, and z direction.
+ /// </summary>
+ public class Accelerometer : BaseCommand
+ {
+ #region AccelerometerOptions class
+ /// <summary>
+ /// Represents Accelerometer options.
+ /// </summary>
+ [DataContract]
+ public class AccelerometerOptions
+ {
+ /// <summary>
+ /// How often to retrieve the Acceleration in milliseconds
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "frequency")]
+ public int Frequency { get; set; }
+
+ /// <summary>
+ /// Watcher id
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "id")]
+ public string Id { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public AccelerometerOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ this.Frequency = 10000;
+ }
+ }
+
+ #endregion
+
+ #region Status codes and Constants
+
+ public const int Stopped = 0;
+ public const int Starting = 1;
+ public const int Running = 2;
+ public const int ErrorFailedToStart = 3;
+
+ public const double gConstant = -9.81;
+
+ #endregion
+
+ #region Static members
+
+ /// <summary>
+ /// Status of listener
+ /// </summary>
+ private static int currentStatus;
+
+ /// <summary>
+ /// Accelerometer
+ /// </summary>
+ private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
+
+ private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
+
+ #endregion
+
+ /// <summary>
+ /// Sensor listener event
+ /// </summary>
+ private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
+ {
+ this.SetStatus(Running);
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+
+ /// <summary>
+ /// Starts listening for acceleration sensor
+ /// </summary>
+ /// <returns>status of listener</returns>
+ public void start(string options)
+ {
+ if ((currentStatus == Running) || (currentStatus == Starting))
+ {
+ return;
+ }
+ try
+ {
+ lock (accelerometer)
+ {
+ accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
+ accelerometer.Start();
+ this.SetStatus(Starting);
+ }
+
+ long timeout = 2000;
+ while ((currentStatus == Starting) && (timeout > 0))
+ {
+ timeout = timeout - 100;
+ Thread.Sleep(100);
+ }
+
+ if (currentStatus != Running)
+ {
+ this.SetStatus(ErrorFailedToStart);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+ return;
+ }
+ }
+ catch (Exception)
+ {
+ this.SetStatus(ErrorFailedToStart);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+ return;
+ }
+ PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+
+ public void stop(string options)
+ {
+ if (currentStatus == Running)
+ {
+ lock (accelerometer)
+ {
+ accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
+ accelerometer.Stop();
+ this.SetStatus(Stopped);
+ }
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+
+ /// <summary>
+ /// Formats current coordinates into JSON format
+ /// </summary>
+ /// <returns>Coordinates in JSON format</returns>
+ private string GetCurrentAccelerationFormatted()
+ {
+ // convert to unix timestamp
+ // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
+ // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
+ // this resolves an issue with inconsistencies between JS dates and Native DateTime
+ string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
+ (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
+ (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
+ (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
+ return "{" + resultCoordinates + "}";
+ }
+
+ /// <summary>
+ /// Sets current status
+ /// </summary>
+ /// <param name="status">current status</param>
+ private void SetStatus(int status)
+ {
+ currentStatus = status;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/AudioFormatsHelper.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/AudioFormatsHelper.cs b/common-items/Plugins/AudioFormatsHelper.cs
new file mode 100644
index 0000000..dca7ee6
--- /dev/null
+++ b/common-items/Plugins/AudioFormatsHelper.cs
@@ -0,0 +1,89 @@
+/*
+ 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.
+
+ */
+
+using System;
+using System.IO;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides extra functionality to support different audio formats.
+ /// </summary>
+ public static class AudioFormatsHelper
+ {
+ #region Wav
+ /// <summary>
+ /// Adds wav file format header to the stream
+ /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ /// </summary>
+ /// <param name="stream">The stream</param>
+ /// <param name="sampleRate">Sample Rate</param>
+ public static void InitializeWavStream(this Stream stream, int sampleRate)
+ {
+ #region args checking
+
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream can't be null or empty");
+ }
+
+ #endregion
+
+ int numBits = 16;
+ int numBytes = numBits / 8;
+
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
+ stream.Write(BitConverter.GetBytes(0), 0, 4);
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
+ stream.Write(BitConverter.GetBytes(16), 0, 4);
+ stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+ stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+ stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
+ stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
+ stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
+ stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
+ stream.Write(BitConverter.GetBytes(0), 0, 4);
+ }
+
+ /// <summary>
+ /// Updates wav file format header
+ /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ /// </summary>
+ /// <param name="stream">Wav stream</param>
+ public static void UpdateWavStream(this Stream stream)
+ {
+ #region args checking
+
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream can't be null or empty");
+ }
+
+ #endregion
+
+ var position = stream.Position;
+
+ stream.Seek(4, SeekOrigin.Begin);
+ stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
+ stream.Seek(40, SeekOrigin.Begin);
+ stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
+ stream.Seek(position, SeekOrigin.Begin);
+ }
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/AudioPlayer.cs b/common-items/Plugins/AudioPlayer.cs
new file mode 100644
index 0000000..a83be5b
--- /dev/null
+++ b/common-items/Plugins/AudioPlayer.cs
@@ -0,0 +1,620 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Threading;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Media;
+using Microsoft.Phone.Controls;
+using System.Diagnostics;
+using System.Windows.Resources;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Implements audio record and play back functionality.
+ /// </summary>
+ internal class AudioPlayer : IDisposable
+ {
+ #region Constants
+
+ // AudioPlayer states
+ private const int PlayerState_None = 0;
+ private const int PlayerState_Starting = 1;
+ private const int PlayerState_Running = 2;
+ private const int PlayerState_Paused = 3;
+ private const int PlayerState_Stopped = 4;
+
+ // AudioPlayer messages
+ private const int MediaState = 1;
+ private const int MediaDuration = 2;
+ private const int MediaPosition = 3;
+ private const int MediaError = 9;
+
+ // AudioPlayer errors
+ private const int MediaErrorPlayModeSet = 1;
+ private const int MediaErrorAlreadyRecording = 2;
+ private const int MediaErrorStartingRecording = 3;
+ private const int MediaErrorRecordModeSet = 4;
+ private const int MediaErrorStartingPlayback = 5;
+ private const int MediaErrorResumeState = 6;
+ private const int MediaErrorPauseState = 7;
+ private const int MediaErrorStopState = 8;
+
+ //TODO: get rid of this callback, it should be universal
+ //private const string CallbackFunction = "CordovaMediaonStatus";
+
+ #endregion
+
+ /// <summary>
+ /// The AudioHandler object
+ /// </summary>
+ private Media handler;
+
+ /// <summary>
+ /// Temporary buffer to store audio chunk
+ /// </summary>
+ private byte[] buffer;
+
+ /// <summary>
+ /// Xna game loop dispatcher
+ /// </summary>
+ DispatcherTimer dtXna;
+
+ /// <summary>
+ /// Output buffer
+ /// </summary>
+ private MemoryStream memoryStream;
+
+ /// <summary>
+ /// The id of this player (used to identify Media object in JavaScript)
+ /// </summary>
+ private String id;
+
+ /// <summary>
+ /// State of recording or playback
+ /// </summary>
+ private int state = PlayerState_None;
+
+ /// <summary>
+ /// File name to play or record to
+ /// </summary>
+ private String audioFile = null;
+
+ /// <summary>
+ /// Duration of audio
+ /// </summary>
+ private double duration = -1;
+
+ /// <summary>
+ /// Audio player object
+ /// </summary>
+ private MediaElement player = null;
+
+ /// <summary>
+ /// Audio source
+ /// </summary>
+ private Microphone recorder;
+
+ /// <summary>
+ /// Internal flag specified that we should only open audio w/o playing it
+ /// </summary>
+ private bool prepareOnly = false;
+
+ /// <summary>
+ /// Creates AudioPlayer instance
+ /// </summary>
+ /// <param name="handler">Media object</param>
+ /// <param name="id">player id</param>
+ public AudioPlayer(Media handler, String id)
+ {
+ this.handler = handler;
+ this.id = id;
+ }
+
+ /// <summary>
+ /// Destroys player and stop audio playing or recording
+ /// </summary>
+ public void Dispose()
+ {
+ if (this.player != null)
+ {
+ this.stopPlaying();
+ this.player = null;
+ }
+ if (this.recorder != null)
+ {
+ this.stopRecording();
+ this.recorder = null;
+ }
+
+ this.FinalizeXnaGameLoop();
+ }
+
+ private void InvokeCallback(int message, string value, bool removeHandler)
+ {
+ string args = string.Format("('{0}',{1},{2});", this.id, message, value);
+ string callback = @"(function(id,msg,value){
+ try {
+ if (msg == Media.MEDIA_ERROR) {
+ value = {'code':value};
+ }
+ Media.onStatus(id,msg,value);
+ }
+ catch(e) {
+ console.log('Error calling Media.onStatus :: ' + e);
+ }
+ })" + args;
+ this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
+ }
+
+ private void InvokeCallback(int message, int value, bool removeHandler)
+ {
+ InvokeCallback(message, value.ToString(), removeHandler);
+ }
+
+ private void InvokeCallback(int message, double value, bool removeHandler)
+ {
+ InvokeCallback(message, value.ToString(), removeHandler);
+ }
+
+ /// <summary>
+ /// Starts recording, data is stored in memory
+ /// </summary>
+ /// <param name="filePath"></param>
+ public void startRecording(string filePath)
+ {
+ if (this.player != null)
+ {
+ InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
+ }
+ else if (this.recorder == null)
+ {
+ try
+ {
+ this.audioFile = filePath;
+ this.InitializeXnaGameLoop();
+ this.recorder = Microphone.Default;
+ this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
+ this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
+ this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
+ this.memoryStream = new MemoryStream();
+ this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
+ this.recorder.Start();
+ FrameworkDispatcher.Update();
+ this.SetState(PlayerState_Running);
+ }
+ catch (Exception)
+ {
+ InvokeCallback(MediaError, MediaErrorStartingRecording, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
+ }
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
+ }
+ }
+
+ /// <summary>
+ /// Stops recording
+ /// </summary>
+ public void stopRecording()
+ {
+ if (this.recorder != null)
+ {
+ if (this.state == PlayerState_Running)
+ {
+ try
+ {
+ this.recorder.Stop();
+ this.recorder.BufferReady -= recorderBufferReady;
+ this.recorder = null;
+ SaveAudioClipToLocalStorage();
+ this.FinalizeXnaGameLoop();
+ this.SetState(PlayerState_Stopped);
+ }
+ catch (Exception)
+ {
+ //TODO
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Starts or resume playing audio file
+ /// </summary>
+ /// <param name="filePath">The name of the audio file</param>
+ /// <summary>
+ /// Starts or resume playing audio file
+ /// </summary>
+ /// <param name="filePath">The name of the audio file</param>
+ public void startPlaying(string filePath)
+ {
+ if (this.recorder != null)
+ {
+ InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
+ return;
+ }
+
+
+ if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
+ {
+ try
+ {
+ // this.player is a MediaElement, it must be added to the visual tree in order to play
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+
+ this.player = grid.FindName("playerMediaElement") as MediaElement;
+ if (this.player == null) // still null ?
+ {
+ this.player = new MediaElement();
+ this.player.Name = "playerMediaElement";
+ grid.Children.Add(this.player);
+ this.player.Visibility = Visibility.Visible;
+ }
+ if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
+ {
+ this.player.Stop(); // stop it!
+ }
+
+ this.player.Source = null; // Garbage collect it.
+ this.player.MediaOpened += MediaOpened;
+ this.player.MediaEnded += MediaEnded;
+ this.player.MediaFailed += MediaFailed;
+ }
+ }
+ }
+
+ this.audioFile = filePath;
+
+ Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
+ if (uri.IsAbsoluteUri)
+ {
+ this.player.Source = uri;
+ }
+ else
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ // try to unpack it from the dll into isolated storage
+ StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
+ if (fileResourceStreamInfo != null)
+ {
+ using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
+ {
+ byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
+
+ string[] dirParts = filePath.Split('/');
+ string dirName = "";
+ for (int n = 0; n < dirParts.Length - 1; n++)
+ {
+ dirName += dirParts[n] + "/";
+ }
+ if (!isoFile.DirectoryExists(dirName))
+ {
+ isoFile.CreateDirectory(dirName);
+ }
+
+ using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
+ {
+ using (BinaryWriter writer = new BinaryWriter(outFile))
+ {
+ writer.Write(data);
+ }
+ }
+ }
+ }
+ }
+ if (isoFile.FileExists(filePath))
+ {
+ using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
+ {
+ this.player.SetSource(stream);
+ }
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
+ return;
+ }
+ }
+ }
+ this.SetState(PlayerState_Starting);
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
+ InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
+ }
+ }
+ else
+ {
+ if (this.state != PlayerState_Running)
+ {
+ this.player.Play();
+ this.SetState(PlayerState_Running);
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorResumeState, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Callback to be invoked when the media source is ready for playback
+ /// </summary>
+ private void MediaOpened(object sender, RoutedEventArgs arg)
+ {
+ if (this.player != null)
+ {
+ this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
+ InvokeCallback(MediaDuration, this.duration, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
+ if (!this.prepareOnly)
+ {
+ this.player.Play();
+ this.SetState(PlayerState_Running);
+ }
+ this.prepareOnly = false;
+ }
+ else
+ {
+ // TODO: occasionally MediaOpened is signalled, but player is null
+ }
+ }
+
+ /// <summary>
+ /// Callback to be invoked when playback of a media source has completed
+ /// </summary>
+ private void MediaEnded(object sender, RoutedEventArgs arg)
+ {
+ this.SetState(PlayerState_Stopped);
+ }
+
+ /// <summary>
+ /// Callback to be invoked when playback of a media source has failed
+ /// </summary>
+ private void MediaFailed(object sender, RoutedEventArgs arg)
+ {
+ player.Stop();
+ InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
+ }
+
+ /// <summary>
+ /// Seek or jump to a new time in the track
+ /// </summary>
+ /// <param name="milliseconds">The new track position</param>
+ public void seekToPlaying(int milliseconds)
+ {
+ if (this.player != null)
+ {
+ TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
+ this.player.Position = tsPos;
+ InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
+ }
+ }
+
+ /// <summary>
+ /// Set the volume of the player
+ /// </summary>
+ /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
+ public void setVolume(double vol)
+ {
+ if (this.player != null)
+ {
+ this.player.Volume = vol;
+ }
+ }
+
+ /// <summary>
+ /// Pauses playing
+ /// </summary>
+ public void pausePlaying()
+ {
+ if (this.state == PlayerState_Running)
+ {
+ this.player.Pause();
+ this.SetState(PlayerState_Paused);
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorPauseState, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
+ }
+ }
+
+
+ /// <summary>
+ /// Stops playing the audio file
+ /// </summary>
+ public void stopPlaying()
+ {
+ if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
+ {
+ this.player.Stop();
+
+ this.player.Position = new TimeSpan(0L);
+ this.SetState(PlayerState_Stopped);
+ }
+ //else // Why is it an error to call stop on a stopped media?
+ //{
+ // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
+ //}
+ }
+
+ /// <summary>
+ /// Gets current position of playback
+ /// </summary>
+ /// <returns>current position</returns>
+ public double getCurrentPosition()
+ {
+ if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
+ {
+ double currentPosition = this.player.Position.TotalSeconds;
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
+ return currentPosition;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the duration of the audio file
+ /// </summary>
+ /// <param name="filePath">The name of the audio file</param>
+ /// <returns>track duration</returns>
+ public double getDuration(string filePath)
+ {
+ if (this.recorder != null)
+ {
+ return (-2);
+ }
+
+ if (this.player != null)
+ {
+ return this.duration;
+
+ }
+ else
+ {
+ this.prepareOnly = true;
+ this.startPlaying(filePath);
+ return this.duration;
+ }
+ }
+
+ /// <summary>
+ /// Sets the state and send it to JavaScript
+ /// </summary>
+ /// <param name="state">state</param>
+ private void SetState(int state)
+ {
+ if (this.state != state)
+ {
+ InvokeCallback(MediaState, state, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
+ }
+
+ this.state = state;
+ }
+
+ #region record methods
+
+ /// <summary>
+ /// Copies data from recorder to memory storages and updates recording state
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void recorderBufferReady(object sender, EventArgs e)
+ {
+ this.recorder.GetData(this.buffer);
+ this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
+ }
+
+ /// <summary>
+ /// Writes audio data from memory to isolated storage
+ /// </summary>
+ /// <returns></returns>
+ private void SaveAudioClipToLocalStorage()
+ {
+ if (this.memoryStream == null || this.memoryStream.Length <= 0)
+ {
+ return;
+ }
+
+ this.memoryStream.UpdateWavStream();
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ string directory = Path.GetDirectoryName(audioFile);
+
+ if (!isoFile.DirectoryExists(directory))
+ {
+ isoFile.CreateDirectory(directory);
+ }
+
+ this.memoryStream.Seek(0, SeekOrigin.Begin);
+
+ using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
+ {
+ this.memoryStream.CopyTo(fileStream);
+ }
+ }
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+ #region Xna loop
+ /// <summary>
+ /// Special initialization required for the microphone: XNA game loop
+ /// </summary>
+ private void InitializeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ this.dtXna = new DispatcherTimer();
+ this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
+ this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
+ this.dtXna.Start();
+ }
+ /// <summary>
+ /// Finalizes XNA game loop for microphone
+ /// </summary>
+ private void FinalizeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ if (this.dtXna != null)
+ {
+ this.dtXna.Stop();
+ this.dtXna = null;
+ }
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Battery.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Battery.cs b/common-items/Plugins/Battery.cs
new file mode 100644
index 0000000..962959e
--- /dev/null
+++ b/common-items/Plugins/Battery.cs
@@ -0,0 +1,79 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+using Microsoft.Phone.Info;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Listens for changes to the state of the battery on the device.
+ /// Currently only the "isPlugged" parameter available via native APIs.
+ /// </summary>
+ public class Battery : BaseCommand
+ {
+ private bool isPlugged = false;
+ private EventHandler powerChanged;
+
+ public Battery()
+ {
+ powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
+ isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
+ }
+
+ public void start(string options)
+ {
+ // Register power changed event handler
+ DeviceStatus.PowerSourceChanged += powerChanged;
+
+ PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+ public void stop(string options)
+ {
+ // Unregister power changed event handler
+ DeviceStatus.PowerSourceChanged -= powerChanged;
+ }
+
+ private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
+ {
+ isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+
+ private string GetCurrentBatteryStateFormatted()
+ {
+ string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
+ "null",
+ isPlugged ? "true" : "false"
+ );
+ batteryState = "{" + batteryState + "}";
+ return batteryState;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Camera.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Camera.cs b/common-items/Plugins/Camera.cs
new file mode 100644
index 0000000..5ff8045
--- /dev/null
+++ b/common-items/Plugins/Camera.cs
@@ -0,0 +1,490 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Collections.Generic;
+using Microsoft.Phone.Tasks;
+using System.Runtime.Serialization;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows.Media.Imaging;
+using Microsoft.Phone;
+using Microsoft.Xna.Framework.Media;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Camera : BaseCommand
+ {
+
+ /// <summary>
+ /// Return base64 encoded string
+ /// </summary>
+ private const int DATA_URL = 0;
+
+ /// <summary>
+ /// Return file uri
+ /// </summary>
+ private const int FILE_URI = 1;
+
+ /// <summary>
+ /// Choose image from picture library
+ /// </summary>
+ private const int PHOTOLIBRARY = 0;
+
+ /// <summary>
+ /// Take picture from camera
+ /// </summary>
+
+ private const int CAMERA = 1;
+
+ /// <summary>
+ /// Choose image from picture library
+ /// </summary>
+ private const int SAVEDPHOTOALBUM = 2;
+
+ /// <summary>
+ /// Take a picture of type JPEG
+ /// </summary>
+ private const int JPEG = 0;
+
+ /// <summary>
+ /// Take a picture of type PNG
+ /// </summary>
+ private const int PNG = 1;
+
+ /// <summary>
+ /// Folder to store captured images
+ /// </summary>
+ private const string isoFolder = "CapturedImagesCache";
+
+ /// <summary>
+ /// Represents captureImage action options.
+ /// </summary>
+ [DataContract]
+ public class CameraOptions
+ {
+ /// <summary>
+ /// Source to getPicture from.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "sourceType")]
+ public int PictureSourceType { get; set; }
+
+ /// <summary>
+ /// Format of image that returned from getPicture.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "destinationType")]
+ public int DestinationType { get; set; }
+
+ /// <summary>
+ /// Quality of saved image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "quality")]
+ public int Quality { get; set; }
+
+ /// <summary>
+ /// Controls whether or not the image is also added to the device photo album.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
+ public bool SaveToPhotoAlbum { get; set; }
+
+ /// <summary>
+ /// Ignored
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "correctOrientation")]
+ public bool CorrectOrientation { get; set; }
+
+
+
+ /// <summary>
+ /// Ignored
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "allowEdit")]
+ public bool AllowEdit { get; set; }
+
+ /// <summary>
+ /// Height in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "encodingType")]
+ public int EncodingType { get; set; }
+
+ /// <summary>
+ /// Height in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "mediaType")]
+ public int MediaType { get; set; }
+
+
+ /// <summary>
+ /// Height in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "targetHeight")]
+ public int TargetHeight { get; set; }
+
+
+ /// <summary>
+ /// Width in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "targetWidth")]
+ public int TargetWidth { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public CameraOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ PictureSourceType = CAMERA;
+ DestinationType = FILE_URI;
+ Quality = 80;
+ TargetHeight = -1;
+ TargetWidth = -1;
+ SaveToPhotoAlbum = false;
+ CorrectOrientation = true;
+ AllowEdit = false;
+ MediaType = -1;
+ EncodingType = -1;
+ }
+ }
+
+ /// <summary>
+ /// Used to open photo library
+ /// </summary>
+ PhotoChooserTask photoChooserTask;
+
+ /// <summary>
+ /// Used to open camera application
+ /// </summary>
+ CameraCaptureTask cameraTask;
+
+ /// <summary>
+ /// Camera options
+ /// </summary>
+ CameraOptions cameraOptions;
+
+ public void takePicture(string options)
+ {
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
+ // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
+ this.cameraOptions = new CameraOptions();
+ this.cameraOptions.Quality = int.Parse(args[0]);
+ this.cameraOptions.DestinationType = int.Parse(args[1]);
+ this.cameraOptions.PictureSourceType = int.Parse(args[2]);
+ this.cameraOptions.TargetWidth = int.Parse(args[3]);
+ this.cameraOptions.TargetHeight = int.Parse(args[4]);
+ this.cameraOptions.EncodingType = int.Parse(args[5]);
+ this.cameraOptions.MediaType = int.Parse(args[6]);
+ this.cameraOptions.AllowEdit = bool.Parse(args[7]);
+ this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
+ this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
+
+ //this.cameraOptions = String.IsNullOrEmpty(options) ?
+ // new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ //TODO Check if all the options are acceptable
+
+
+ if (cameraOptions.PictureSourceType == CAMERA)
+ {
+ cameraTask = new CameraCaptureTask();
+ cameraTask.Completed += onCameraTaskCompleted;
+ cameraTask.Show();
+ }
+ else
+ {
+ if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
+ {
+ photoChooserTask = new PhotoChooserTask();
+ photoChooserTask.Completed += onPickerTaskCompleted;
+ photoChooserTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
+ }
+ }
+
+ }
+
+ public void onCameraTaskCompleted(object sender, PhotoResult e)
+ {
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ string imagePathOrContent = string.Empty;
+
+ if (cameraOptions.DestinationType == FILE_URI)
+ {
+ // Save image in media library
+ if (cameraOptions.SaveToPhotoAlbum)
+ {
+ MediaLibrary library = new MediaLibrary();
+ Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
+ }
+
+ int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
+ int newAngle = 0;
+ switch (orient)
+ {
+ case ImageExifOrientation.LandscapeLeft:
+ newAngle = 90;
+ break;
+ case ImageExifOrientation.PortraitUpsideDown:
+ newAngle = 180;
+ break;
+ case ImageExifOrientation.LandscapeRight:
+ newAngle = 270;
+ break;
+ case ImageExifOrientation.Portrait:
+ default: break; // 0 default already set
+ }
+
+ Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
+
+ // we should return stream position back after saving stream to media library
+ rotImageStream.Seek(0, SeekOrigin.Begin);
+
+ WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
+
+ imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
+
+
+ }
+ else if (cameraOptions.DestinationType == DATA_URL)
+ {
+ imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
+ }
+ else
+ {
+ // TODO: shouldn't this happen before we launch the camera-picker?
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
+ return;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
+ break;
+
+ default:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
+ break;
+ }
+
+ }
+
+ public void onPickerTaskCompleted(object sender, PhotoResult e)
+ {
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ string imagePathOrContent = string.Empty;
+
+ if (cameraOptions.DestinationType == FILE_URI)
+ {
+ WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
+ imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
+ }
+ else if (cameraOptions.DestinationType == DATA_URL)
+ {
+ imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
+
+ }
+ else
+ {
+ // TODO: shouldn't this happen before we launch the camera-picker?
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
+ return;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
+ break;
+
+ default:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Returns image content in a form of base64 string
+ /// </summary>
+ /// <param name="stream">Image stream</param>
+ /// <returns>Base64 representation of the image</returns>
+ private string GetImageContent(Stream stream)
+ {
+ int streamLength = (int)stream.Length;
+ byte[] fileData = new byte[streamLength + 1];
+ stream.Read(fileData, 0, streamLength);
+
+ //use photo's actual width & height if user doesn't provide width & height
+ if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
+ {
+ stream.Close();
+ return Convert.ToBase64String(fileData);
+ }
+ else
+ {
+ // resize photo
+ byte[] resizedFile = ResizePhoto(stream, fileData);
+ stream.Close();
+ return Convert.ToBase64String(resizedFile);
+ }
+ }
+
+ /// <summary>
+ /// Resize image
+ /// </summary>
+ /// <param name="stream">Image stream</param>
+ /// <param name="fileData">File data</param>
+ /// <returns>resized image</returns>
+ private byte[] ResizePhoto(Stream stream, byte[] fileData)
+ {
+ int streamLength = (int)stream.Length;
+ int intResult = 0;
+
+ byte[] resizedFile;
+
+ stream.Read(fileData, 0, streamLength);
+
+ BitmapImage objBitmap = new BitmapImage();
+ MemoryStream objBitmapStream = new MemoryStream(fileData);
+ MemoryStream objBitmapStreamResized = new MemoryStream();
+ WriteableBitmap objWB;
+ objBitmap.SetSource(stream);
+ objWB = new WriteableBitmap(objBitmap);
+
+ // resize the photo with user defined TargetWidth & TargetHeight
+ Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
+
+ //Convert the resized stream to a byte array.
+ streamLength = (int)objBitmapStreamResized.Length;
+ resizedFile = new Byte[streamLength]; //-1
+ objBitmapStreamResized.Position = 0;
+ //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
+ intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
+
+ return resizedFile;
+ }
+
+ /// <summary>
+ /// Saves captured image in isolated storage
+ /// </summary>
+ /// <param name="imageFileName">image file name</param>
+ /// <returns>Image path</returns>
+ private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
+ {
+
+ if (image == null)
+ {
+ throw new ArgumentNullException("imageBytes");
+ }
+ try
+ {
+
+
+ var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
+
+ if (!isoFile.DirectoryExists(isoFolder))
+ {
+ isoFile.CreateDirectory(isoFolder);
+ }
+
+ string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
+
+ using (var stream = isoFile.CreateFile(filePath))
+ {
+ // resize image if Height and Width defined via options
+ if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
+ {
+ image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
+ }
+ else
+ {
+ image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
+ }
+ }
+
+ return new Uri(filePath, UriKind.Relative).ToString();
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Capture.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Capture.cs b/common-items/Plugins/Capture.cs
new file mode 100644
index 0000000..5e14a16
--- /dev/null
+++ b/common-items/Plugins/Capture.cs
@@ -0,0 +1,736 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Runtime.Serialization;
+using System.Windows.Media.Imaging;
+using Microsoft.Phone;
+using Microsoft.Phone.Tasks;
+using Microsoft.Xna.Framework.Media;
+using WPCordovaClassLib.Cordova.UI;
+using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
+using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
+using System.Windows;
+using System.Diagnostics;
+using Microsoft.Phone.Controls;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides access to the audio, image, and video capture capabilities of the device
+ /// </summary>
+ public class Capture : BaseCommand
+ {
+ #region Internal classes (options and resultant objects)
+
+ /// <summary>
+ /// Represents captureImage action options.
+ /// </summary>
+ [DataContract]
+ public class CaptureImageOptions
+ {
+ /// <summary>
+ /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "limit")]
+ public int Limit { get; set; }
+
+ public static CaptureImageOptions Default
+ {
+ get { return new CaptureImageOptions() { Limit = 1 }; }
+ }
+ }
+
+ /// <summary>
+ /// Represents captureAudio action options.
+ /// </summary>
+ [DataContract]
+ public class CaptureAudioOptions
+ {
+ /// <summary>
+ /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "limit")]
+ public int Limit { get; set; }
+
+ public static CaptureAudioOptions Default
+ {
+ get { return new CaptureAudioOptions() { Limit = 1 }; }
+ }
+ }
+
+ /// <summary>
+ /// Represents captureVideo action options.
+ /// </summary>
+ [DataContract]
+ public class CaptureVideoOptions
+ {
+ /// <summary>
+ /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "limit")]
+ public int Limit { get; set; }
+
+ public static CaptureVideoOptions Default
+ {
+ get { return new CaptureVideoOptions() { Limit = 1 }; }
+ }
+ }
+
+ /// <summary>
+ /// Represents getFormatData action options.
+ /// </summary>
+ [DataContract]
+ public class MediaFormatOptions
+ {
+ /// <summary>
+ /// File path
+ /// </summary>
+ [DataMember(IsRequired = true, Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ /// <summary>
+ /// File mime type
+ /// </summary>
+ [DataMember(Name = "type")]
+ public string Type { get; set; }
+
+ }
+
+ /// <summary>
+ /// Stores image info
+ /// </summary>
+ [DataContract]
+ public class MediaFile
+ {
+
+ [DataMember(Name = "name")]
+ public string FileName { get; set; }
+
+ [DataMember(Name = "fullPath")]
+ public string FilePath { get; set; }
+
+ [DataMember(Name = "type")]
+ public string Type { get; set; }
+
+ [DataMember(Name = "lastModifiedDate")]
+ public string LastModifiedDate { get; set; }
+
+ [DataMember(Name = "size")]
+ public long Size { get; set; }
+
+ public MediaFile(string filePath, Picture image)
+ {
+ this.FilePath = filePath;
+ this.FileName = System.IO.Path.GetFileName(this.FilePath);
+ this.Type = MimeTypeMapper.GetMimeType(FileName);
+ this.Size = image.GetImage().Length;
+
+ using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
+ }
+
+ }
+
+ public MediaFile(string filePath, Stream stream)
+ {
+ this.FilePath = filePath;
+ this.FileName = System.IO.Path.GetFileName(this.FilePath);
+ this.Type = MimeTypeMapper.GetMimeType(FileName);
+ this.Size = stream.Length;
+
+ using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Stores additional media file data
+ /// </summary>
+ [DataContract]
+ public class MediaFileData
+ {
+ [DataMember(Name = "height")]
+ public int Height { get; set; }
+
+ [DataMember(Name = "width")]
+ public int Width { get; set; }
+
+ [DataMember(Name = "bitrate")]
+ public int Bitrate { get; set; }
+
+ [DataMember(Name = "duration")]
+ public int Duration { get; set; }
+
+ [DataMember(Name = "codecs")]
+ public string Codecs { get; set; }
+
+ public MediaFileData(WriteableBitmap image)
+ {
+ this.Height = image.PixelHeight;
+ this.Width = image.PixelWidth;
+ this.Bitrate = 0;
+ this.Duration = 0;
+ this.Codecs = "";
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Folder to store captured images
+ /// </summary>
+ private string isoFolder = "CapturedImagesCache";
+
+ /// <summary>
+ /// Capture Image options
+ /// </summary>
+ protected CaptureImageOptions captureImageOptions;
+
+ /// <summary>
+ /// Capture Audio options
+ /// </summary>
+ protected CaptureAudioOptions captureAudioOptions;
+
+ /// <summary>
+ /// Capture Video options
+ /// </summary>
+ protected CaptureVideoOptions captureVideoOptions;
+
+ /// <summary>
+ /// Used to open camera application
+ /// </summary>
+ private CameraCaptureTask cameraTask;
+
+ /// <summary>
+ /// Used for audio recording
+ /// </summary>
+ private AudioCaptureTask audioCaptureTask;
+
+ /// <summary>
+ /// Used for video recording
+ /// </summary>
+ private VideoCaptureTask videoCaptureTask;
+
+ /// <summary>
+ /// Stores information about captured files
+ /// </summary>
+ List<MediaFile> files = new List<MediaFile>();
+
+ /// <summary>
+ /// Launches default camera application to capture image
+ /// </summary>
+ /// <param name="options">may contains limit or mode parameters</param>
+ public void captureImage(string options)
+ {
+ try
+ {
+ try
+ {
+
+ string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+
+ cameraTask = new CameraCaptureTask();
+ cameraTask.Completed += this.cameraTask_Completed;
+ cameraTask.Show();
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Launches our own audio recording control to capture audio
+ /// </summary>
+ /// <param name="options">may contains additional parameters</param>
+ public void captureAudio(string options)
+ {
+ try
+ {
+ try
+ {
+ string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ audioCaptureTask = new AudioCaptureTask();
+ audioCaptureTask.Completed += audioRecordingTask_Completed;
+ audioCaptureTask.Show();
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Launches our own video recording control to capture video
+ /// </summary>
+ /// <param name="options">may contains additional parameters</param>
+ public void captureVideo(string options)
+ {
+ try
+ {
+ try
+ {
+ string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ videoCaptureTask = new VideoCaptureTask();
+ videoCaptureTask.Completed += videoRecordingTask_Completed;
+ videoCaptureTask.Show();
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the format information of the media file.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getFormatData(string options)
+ {
+ try
+ {
+ MediaFormatOptions mediaFormatOptions;
+ try
+ {
+ mediaFormatOptions = new MediaFormatOptions();
+ string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaFormatOptions.FullPath = optionStrings[0];
+ mediaFormatOptions.Type = optionStrings[1];
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+
+ string mimeType = mediaFormatOptions.Type;
+
+ if (string.IsNullOrEmpty(mimeType))
+ {
+ mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
+ }
+
+ if (mimeType.Equals("image/jpeg"))
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
+
+ if (image == null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
+ return;
+ }
+
+ MediaFileData mediaData = new MediaFileData(image);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
+ });
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ }
+ }
+
+ /// <summary>
+ /// Opens specified file in media player
+ /// </summary>
+ /// <param name="options">MediaFile to play</param>
+ public void play(string options)
+ {
+ try
+ {
+ MediaFile file;
+
+ try
+ {
+ file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (file == null || String.IsNullOrEmpty(file.FilePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
+ return;
+ }
+
+ // if url starts with '/' media player throws FileNotFound exception
+ Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
+
+ MediaPlayerLauncher player = new MediaPlayerLauncher();
+ player.Media = fileUri;
+ player.Location = MediaLocationType.Data;
+ player.Show();
+
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+
+ /// <summary>
+ /// Handles result of capture to save image information
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">stores information about current captured image</param>
+ private void cameraTask_Completed(object sender, PhotoResult e)
+ {
+
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
+
+ // Save image in media library
+ MediaLibrary library = new MediaLibrary();
+ Picture image = library.SavePicture(fileName, e.ChosenPhoto);
+
+ int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
+ int newAngle = 0;
+ switch (orient)
+ {
+ case ImageExifOrientation.LandscapeLeft:
+ newAngle = 90;
+ break;
+ case ImageExifOrientation.PortraitUpsideDown:
+ newAngle = 180;
+ break;
+ case ImageExifOrientation.LandscapeRight:
+ newAngle = 270;
+ break;
+ case ImageExifOrientation.Portrait:
+ default: break; // 0 default already set
+ }
+
+ Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
+
+ // Save image in isolated storage
+
+ // we should return stream position back after saving stream to media library
+ rotImageStream.Seek(0, SeekOrigin.Begin);
+
+ byte[] imageBytes = new byte[rotImageStream.Length];
+ rotImageStream.Read(imageBytes, 0, imageBytes.Length);
+ rotImageStream.Dispose();
+ string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
+ imageBytes = null;
+ // Get image data
+ MediaFile data = new MediaFile(pathLocalStorage, image);
+
+ this.files.Add(data);
+
+ if (files.Count < this.captureImageOptions.Limit)
+ {
+ cameraTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ if (files.Count > 0)
+ {
+ // User canceled operation, but some images were made
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
+ }
+ break;
+
+ default:
+ if (files.Count > 0)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Handles result of audio recording tasks
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">stores information about current captured audio</param>
+ private void audioRecordingTask_Completed(object sender, AudioResult e)
+ {
+
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ // Get image data
+ MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
+
+ this.files.Add(data);
+
+ if (files.Count < this.captureAudioOptions.Limit)
+ {
+ audioCaptureTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ if (files.Count > 0)
+ {
+ // User canceled operation, but some audio clips were made
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
+ }
+ break;
+
+ default:
+ if (files.Count > 0)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Handles result of video recording tasks
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">stores information about current captured video</param>
+ private void videoRecordingTask_Completed(object sender, VideoResult e)
+ {
+
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ // Get image data
+ MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
+
+ this.files.Add(data);
+
+ if (files.Count < this.captureVideoOptions.Limit)
+ {
+ videoCaptureTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ if (files.Count > 0)
+ {
+ // User canceled operation, but some video clips were made
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
+ }
+ break;
+
+ default:
+ if (files.Count > 0)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Extract file from Isolated Storage as WriteableBitmap object
+ /// </summary>
+ /// <param name="filePath"></param>
+ /// <returns></returns>
+ private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
+ {
+ try
+ {
+
+ var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
+
+ using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
+ {
+ var imageSource = PictureDecoder.DecodeJpeg(imageStream);
+ return imageSource;
+ }
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+
+ /// <summary>
+ /// Saves captured image in isolated storage
+ /// </summary>
+ /// <param name="imageFileName">image file name</param>
+ /// <param name="imageFolder">folder to store images</param>
+ /// <returns>Image path</returns>
+ private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
+ {
+ if (imageBytes == null)
+ {
+ throw new ArgumentNullException("imageBytes");
+ }
+ try
+ {
+ var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
+
+ if (!isoFile.DirectoryExists(imageFolder))
+ {
+ isoFile.CreateDirectory(imageFolder);
+ }
+ string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
+
+ using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
+ {
+ stream.Write(imageBytes, 0, imageBytes.Length);
+ }
+
+ return filePath;
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+
+ }
+}
\ No newline at end of file
[41/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/www/cordova.js
----------------------------------------------------------------------
diff --git a/common-items/www/cordova.js b/common-items/www/cordova.js
deleted file mode 100644
index 0d763d9..0000000
--- a/common-items/www/cordova.js
+++ /dev/null
@@ -1,6723 +0,0 @@
-// Platform: windowsphone
-// 2.8.0rc1-0-g22bc4d8
-/*
- 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.
-*/
-;(function() {
-var CORDOVA_JS_BUILD_LABEL = '2.8.0rc1-0-g22bc4d8';
-// file: lib/scripts/require.js
-
-var require,
- define;
-
-(function () {
- var modules = {},
- // Stack of moduleIds currently being built.
- requireStack = [],
- // Map of module ID -> index into requireStack of modules currently being built.
- inProgressModules = {},
- SEPERATOR = ".";
-
-
-
- function build(module) {
- var factory = module.factory,
- localRequire = function (id) {
- var resultantId = id;
- //Its a relative path, so lop off the last portion and add the id (minus "./")
- if (id.charAt(0) === ".") {
- resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
- }
- return require(resultantId);
- };
- module.exports = {};
- delete module.factory;
- factory(localRequire, module.exports, module);
- return module.exports;
- }
-
- require = function (id) {
- if (!modules[id]) {
- throw "module " + id + " not found";
- } else if (id in inProgressModules) {
- var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
- throw "Cycle in require graph: " + cycle;
- }
- if (modules[id].factory) {
- try {
- inProgressModules[id] = requireStack.length;
- requireStack.push(id);
- return build(modules[id]);
- } finally {
- delete inProgressModules[id];
- requireStack.pop();
- }
- }
- return modules[id].exports;
- };
-
- define = function (id, factory) {
- if (modules[id]) {
- throw "module " + id + " already defined";
- }
-
- modules[id] = {
- id: id,
- factory: factory
- };
- };
-
- define.remove = function (id) {
- delete modules[id];
- };
-
- define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
- module.exports.require = require;
- module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-
-/**
- * Listen for DOMContentLoaded and notify our channel subscribers.
- */
-document.addEventListener('DOMContentLoaded', function() {
- channel.onDOMContentLoaded.fire();
-}, false);
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
- channel.onDOMContentLoaded.fire();
-}
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
- windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof documentEventHandlers[e] != 'undefined') {
- documentEventHandlers[e].subscribe(handler);
- } else {
- m_document_addEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof windowEventHandlers[e] != 'undefined') {
- windowEventHandlers[e].subscribe(handler);
- } else {
- m_window_addEventListener.call(window, evt, handler, capture);
- }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubscribing from an event that is handled by a plugin
- if (typeof documentEventHandlers[e] != "undefined") {
- documentEventHandlers[e].unsubscribe(handler);
- } else {
- m_document_removeEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubscribing from an event that is handled by a plugin
- if (typeof windowEventHandlers[e] != "undefined") {
- windowEventHandlers[e].unsubscribe(handler);
- } else {
- m_window_removeEventListener.call(window, evt, handler, capture);
- }
-};
-
-function createEvent(type, data) {
- var event = document.createEvent('Events');
- event.initEvent(type, false, false);
- if (data) {
- for (var i in data) {
- if (data.hasOwnProperty(i)) {
- event[i] = data[i];
- }
- }
- }
- return event;
-}
-
-if(typeof window.console === "undefined") {
- window.console = {
- log:function(){}
- };
-}
-
-var cordova = {
- define:define,
- require:require,
- /**
- * Methods to add/remove your own addEventListener hijacking on document + window.
- */
- addWindowEventHandler:function(event) {
- return (windowEventHandlers[event] = channel.create(event));
- },
- addStickyDocumentEventHandler:function(event) {
- return (documentEventHandlers[event] = channel.createSticky(event));
- },
- addDocumentEventHandler:function(event) {
- return (documentEventHandlers[event] = channel.create(event));
- },
- removeWindowEventHandler:function(event) {
- delete windowEventHandlers[event];
- },
- removeDocumentEventHandler:function(event) {
- delete documentEventHandlers[event];
- },
- /**
- * Retrieve original event handlers that were replaced by Cordova
- *
- * @return object
- */
- getOriginalHandlers: function() {
- return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
- 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
- },
- /**
- * Method to fire event from native code
- * bNoDetach is required for events which cause an exception which needs to be caught in native code
- */
- fireDocumentEvent: function(type, data, bNoDetach) {
- var evt = createEvent(type, data);
- if (typeof documentEventHandlers[type] != 'undefined') {
- if( bNoDetach ) {
- documentEventHandlers[type].fire(evt);
- }
- else {
- setTimeout(function() {
- // Fire deviceready on listeners that were registered before cordova.js was loaded.
- if (type == 'deviceready') {
- document.dispatchEvent(evt);
- }
- documentEventHandlers[type].fire(evt);
- }, 0);
- }
- } else {
- document.dispatchEvent(evt);
- }
- },
- fireWindowEvent: function(type, data) {
- var evt = createEvent(type,data);
- if (typeof windowEventHandlers[type] != 'undefined') {
- setTimeout(function() {
- windowEventHandlers[type].fire(evt);
- }, 0);
- } else {
- window.dispatchEvent(evt);
- }
- },
-
- /**
- * Plugin callback mechanism.
- */
- // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
- // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
- callbackId: Math.floor(Math.random() * 2000000000),
- callbacks: {},
- callbackStatus: {
- NO_RESULT: 0,
- OK: 1,
- CLASS_NOT_FOUND_EXCEPTION: 2,
- ILLEGAL_ACCESS_EXCEPTION: 3,
- INSTANTIATION_EXCEPTION: 4,
- MALFORMED_URL_EXCEPTION: 5,
- IO_EXCEPTION: 6,
- INVALID_ACTION: 7,
- JSON_EXCEPTION: 8,
- ERROR: 9
- },
-
- /**
- * Called by native code when returning successful result from an action.
- */
- callbackSuccess: function(callbackId, args) {
- try {
- cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
- } catch (e) {
- console.log("Error in error callback: " + callbackId + " = "+e);
- }
- },
-
- /**
- * Called by native code when returning error result from an action.
- */
- callbackError: function(callbackId, args) {
- // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
- // Derive success from status.
- try {
- cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
- } catch (e) {
- console.log("Error in error callback: " + callbackId + " = "+e);
- }
- },
-
- /**
- * Called by native code when returning the result from an action.
- */
- callbackFromNative: function(callbackId, success, status, args, keepCallback) {
- var callback = cordova.callbacks[callbackId];
- if (callback) {
- if (success && status == cordova.callbackStatus.OK) {
- callback.success && callback.success.apply(null, args);
- } else if (!success) {
- callback.fail && callback.fail.apply(null, args);
- }
-
- // Clear callback if not expecting any more results
- if (!keepCallback) {
- delete cordova.callbacks[callbackId];
- }
- }
- },
- addConstructor: function(func) {
- channel.onCordovaReady.subscribe(function() {
- try {
- func();
- } catch(e) {
- console.log("Failed to run constructor: " + e);
- }
- });
- }
-};
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-module.exports = cordova;
-
-});
-
-// file: lib/common/argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
- 'A': 'Array',
- 'D': 'Date',
- 'N': 'Number',
- 'S': 'String',
- 'F': 'Function',
- 'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
- return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
- if (!moduleExports.enableChecks) {
- return;
- }
- var errMsg = null;
- var typeName;
- for (var i = 0; i < spec.length; ++i) {
- var c = spec.charAt(i),
- cUpper = c.toUpperCase(),
- arg = args[i];
- // Asterix means allow anything.
- if (c == '*') {
- continue;
- }
- typeName = utils.typeName(arg);
- if ((arg === null || arg === undefined) && c == cUpper) {
- continue;
- }
- if (typeName != typeMap[cUpper]) {
- errMsg = 'Expected ' + typeMap[cUpper];
- break;
- }
- }
- if (errMsg) {
- errMsg += ', but got ' + typeName + '.';
- errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
- // Don't log when running jake test.
- if (typeof jasmine == 'undefined') {
- console.error(errMsg);
- }
- throw TypeError(errMsg);
- }
-}
-
-function getValue(value, defaultValue) {
- return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// file: lib/common/builder.js
-define("cordova/builder", function(require, exports, module) {
-
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
- for (var prop in objects) {
- if (objects.hasOwnProperty(prop)) {
- func.apply(context, [objects[prop], prop]);
- }
- }
-}
-
-function clobber(obj, key, value) {
- exports.replaceHookForTesting(obj, key);
- obj[key] = value;
- // Getters can only be overridden by getters.
- if (obj[key] !== value) {
- utils.defineGetter(obj, key, function() {
- return value;
- });
- }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
- if (message) {
- utils.defineGetter(obj, key, function() {
- console.log(message);
- delete obj[key];
- clobber(obj, key, value);
- return value;
- });
- } else {
- clobber(obj, key, value);
- }
-}
-
-function include(parent, objects, clobber, merge) {
- each(objects, function (obj, key) {
- try {
- var result = obj.path ? require(obj.path) : {};
-
- if (clobber) {
- // Clobber if it doesn't exist.
- if (typeof parent[key] === 'undefined') {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- } else if (typeof obj.path !== 'undefined') {
- // If merging, merge properties onto parent, otherwise, clobber.
- if (merge) {
- recursiveMerge(parent[key], result);
- } else {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- }
- }
- result = parent[key];
- } else {
- // Overwrite if not currently defined.
- if (typeof parent[key] == 'undefined') {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- } else {
- // Set result to what already exists, so we can build children into it if they exist.
- result = parent[key];
- }
- }
-
- if (obj.children) {
- include(result, obj.children, clobber, merge);
- }
- } catch(e) {
- utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
- }
- });
-}
-
-/**
- * Merge properties from one object onto another recursively. Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
- for (var prop in src) {
- if (src.hasOwnProperty(prop)) {
- if (target.prototype && target.prototype.constructor === target) {
- // If the target object is a constructor override off prototype.
- clobber(target.prototype, prop, src[prop]);
- } else {
- if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
- recursiveMerge(target[prop], src[prop]);
- } else {
- clobber(target, prop, src[prop]);
- }
- }
- }
- }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
- include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
- include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
- include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
- nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
- * onNativeReady* Internal event that indicates the Cordova native side is ready.
- * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
- * onCordovaInfoReady* Internal event fired when device properties are available.
- * onCordovaConnectionReady* Internal event fired when the connection property has been set.
- * onDeviceReady* User event fired to indicate that Cordova is ready
- * onResume User event fired to indicate a start/resume lifecycle event
- * onPause User event fired to indicate a pause lifecycle event
- * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
- * pause App has moved to background
- * resume App has returned to foreground
- *
- * Listeners can be registered as:
- * document.addEventListener("deviceready", myDeviceReadyListener, false);
- * document.addEventListener("resume", myResumeListener, false);
- * document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- * window.onload
- * window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type String the channel name
- */
-var Channel = function(type, sticky) {
- this.type = type;
- // Map of guid -> function.
- this.handlers = {};
- // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
- this.state = sticky ? 1 : 0;
- // Used in sticky mode to remember args passed to fire().
- this.fireArgs = null;
- // Used by onHasSubscribersChange to know if there are any listeners.
- this.numHandlers = 0;
- // Function that is called when the first listener is subscribed, or when
- // the last listener is unsubscribed.
- this.onHasSubscribersChange = null;
-},
- channel = {
- /**
- * Calls the provided function only after all of the channels specified
- * have been fired. All channels must be sticky channels.
- */
- join: function(h, c) {
- var len = c.length,
- i = len,
- f = function() {
- if (!(--i)) h();
- };
- for (var j=0; j<len; j++) {
- if (c[j].state === 0) {
- throw Error('Can only use join with sticky channels.');
- }
- c[j].subscribe(f);
- }
- if (!len) h();
- },
- create: function(type) {
- return channel[type] = new Channel(type, false);
- },
- createSticky: function(type) {
- return channel[type] = new Channel(type, true);
- },
-
- /**
- * cordova Channels that must fire before "deviceready" is fired.
- */
- deviceReadyChannelsArray: [],
- deviceReadyChannelsMap: {},
-
- /**
- * Indicate that a feature needs to be initialized before it is ready to be used.
- * This holds up Cordova's "deviceready" event until the feature has been initialized
- * and Cordova.initComplete(feature) is called.
- *
- * @param feature {String} The unique feature name
- */
- waitForInitialization: function(feature) {
- if (feature) {
- var c = channel[feature] || this.createSticky(feature);
- this.deviceReadyChannelsMap[feature] = c;
- this.deviceReadyChannelsArray.push(c);
- }
- },
-
- /**
- * Indicate that initialization code has completed and the feature is ready to be used.
- *
- * @param feature {String} The unique feature name
- */
- initializationComplete: function(feature) {
- var c = this.deviceReadyChannelsMap[feature];
- if (c) {
- c.fire();
- }
- }
- };
-
-function forceFunction(f) {
- if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
- // need a function to call
- forceFunction(f);
- if (this.state == 2) {
- f.apply(c || this, this.fireArgs);
- return;
- }
-
- var func = f,
- guid = f.observer_guid;
- if (typeof c == "object") { func = utils.close(c, f); }
-
- if (!guid) {
- // first time any channel has seen this subscriber
- guid = '' + nextGuid++;
- }
- func.observer_guid = guid;
- f.observer_guid = guid;
-
- // Don't add the same handler more than once.
- if (!this.handlers[guid]) {
- this.handlers[guid] = func;
- this.numHandlers++;
- if (this.numHandlers == 1) {
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
- // need a function to unsubscribe
- forceFunction(f);
-
- var guid = f.observer_guid,
- handler = this.handlers[guid];
- if (handler) {
- delete this.handlers[guid];
- this.numHandlers--;
- if (this.numHandlers === 0) {
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
- var fail = false,
- fireArgs = Array.prototype.slice.call(arguments);
- // Apply stickiness.
- if (this.state == 1) {
- this.state = 2;
- this.fireArgs = fireArgs;
- }
- if (this.numHandlers) {
- // Copy the values first so that it is safe to modify it from within
- // callbacks.
- var toCall = [];
- for (var item in this.handlers) {
- toCall.push(this.handlers[item]);
- }
- for (var i = 0; i < toCall.length; ++i) {
- toCall[i].apply(this, fireArgs);
- }
- if (this.state == 2 && this.numHandlers) {
- this.numHandlers = 0;
- this.handlers = {};
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that device properties are available
-channel.createSticky('onCordovaInfoReady');
-
-// Event to indicate that the connection property has been set.
-channel.createSticky('onCordovaConnectionReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onCordovaConnectionReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib/common/commandProxy.js
-define("cordova/commandProxy", function(require, exports, module) {
-
-
-// internal map of proxy function
-var CommandProxyMap = {};
-
-module.exports = {
-
- // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
- add:function(id,proxyObj) {
- console.log("adding proxy for " + id);
- CommandProxyMap[id] = proxyObj;
- return proxyObj;
- },
-
- // cordova.commandProxy.remove("Accelerometer");
- remove:function(id) {
- var proxy = CommandProxyMap[id];
- delete CommandProxyMap[id];
- CommandProxyMap[id] = null;
- return proxy;
- },
-
- get:function(service,action) {
- return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
- }
-};
-});
-
-// file: lib/windowsphone/exec.js
-define("cordova/exec", function(require, exports, module) {
-
-var cordova = require('cordova');
-
-/**
- * Execute a cordova command. It is up to the native side whether this action
- * is synchronous or asynchronous. The native side can return:
- * Synchronous: PluginResult object as a JSON string
- * Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success The success callback
- * @param {Function} fail The fail callback
- * @param {String} service The name of the service to use
- * @param {String} action Action to be run in cordova
- * @param {String[]} [args] Zero or more arguments to pass to the method
-
- */
-
-module.exports = function(success, fail, service, action, args) {
-
- var callbackId = service + cordova.callbackId++;
- if (typeof success == "function" || typeof fail == "function") {
- cordova.callbacks[callbackId] = {success:success, fail:fail};
- }
- // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
- for(var n = 0; n < args.length; n++)
- {
- if(typeof args[n] !== "string")
- {
- args[n] = JSON.stringify(args[n]);
- }
- }
- var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
- // pass it on to Notify
- try {
- if(window.external) {
- window.external.Notify(command);
- }
- else {
- console.log("window.external not available :: command=" + command);
- }
- }
- catch(e) {
- console.log("Exception calling native with command :: " + command + " :: exception=" + e);
- }
-};
-
-
-});
-
-// file: lib/common/modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
- moduleMap = define.moduleMap,
- symbolList,
- deprecationMap;
-
-exports.reset = function() {
- symbolList = [];
- deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
- if (!(moduleName in moduleMap)) {
- throw new Error('Module ' + moduleName + ' does not exist.');
- }
- 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);
-};
-
-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 symbolPath = symbolList[i + 2];
- var lastDot = symbolPath.lastIndexOf('.');
- var namespace = symbolPath.substr(0, lastDot);
- var lastName = symbolPath.substr(lastDot + 1);
-
- var module = require(moduleName);
- 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.loadMatchingModules = function(matchingRegExp) {
- for (var k in moduleMap) {
- if (matchingRegExp.exec(k)) {
- require(k);
- }
- }
-};
-
-exports.reset();
-
-
-});
-
-// file: lib/windowsphone/platform.js
-define("cordova/platform", function(require, exports, module) {
-
-var cordova = require('cordova'),
- exec = require('cordova/exec');
-
-module.exports = {
- id: "windowsphone",
- initialize:function() {
- var modulemapper = require('cordova/modulemapper');
-
- modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
-
- modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
-
- modulemapper.mapModules(window);
-
- // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
- var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
- backButtonChannel.onHasSubscribersChange = function() {
- exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
- };
- }
-};
-
-});
-
-// file: lib/common/plugin/Acceleration.js
-define("cordova/plugin/Acceleration", function(require, exports, module) {
-
-var Acceleration = function(x, y, z, timestamp) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.timestamp = timestamp || (new Date()).getTime();
-};
-
-module.exports = Acceleration;
-
-});
-
-// file: lib/common/plugin/Camera.js
-define("cordova/plugin/Camera", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- Camera = require('cordova/plugin/CameraConstants'),
- CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
-
-var cameraExport = {};
-
-// Tack on the Camera Constants to the base camera plugin.
-for (var key in Camera) {
- cameraExport[key] = Camera[key];
-}
-
-/**
- * Gets a picture from source defined by "options.sourceType", and returns the
- * image as defined by the "options.destinationType" option.
-
- * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
- *
- * @param {Function} successCallback
- * @param {Function} errorCallback
- * @param {Object} options
- */
-cameraExport.getPicture = function(successCallback, errorCallback, options) {
- argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
- options = options || {};
- var getValue = argscheck.getValue;
-
- var quality = getValue(options.quality, 50);
- var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
- var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
- var targetWidth = getValue(options.targetWidth, -1);
- var targetHeight = getValue(options.targetHeight, -1);
- var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
- var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
- var allowEdit = !!options.allowEdit;
- var correctOrientation = !!options.correctOrientation;
- var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
- var popoverOptions = getValue(options.popoverOptions, null);
- var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
-
- var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
-
- exec(successCallback, errorCallback, "Camera", "takePicture", args);
- return new CameraPopoverHandle();
-};
-
-cameraExport.cleanup = function(successCallback, errorCallback) {
- exec(successCallback, errorCallback, "Camera", "cleanup", []);
-};
-
-module.exports = cameraExport;
-
-});
-
-// file: lib/common/plugin/CameraConstants.js
-define("cordova/plugin/CameraConstants", function(require, exports, module) {
-
-module.exports = {
- DestinationType:{
- DATA_URL: 0, // Return base64 encoded string
- FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
- NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
- },
- EncodingType:{
- JPEG: 0, // Return JPEG encoded image
- PNG: 1 // Return PNG encoded image
- },
- MediaType:{
- PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
- VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
- ALLMEDIA : 2 // allow selection from all media types
- },
- PictureSourceType:{
- PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
- CAMERA : 1, // Take picture from camera
- SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
- },
- PopoverArrowDirection:{
- ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
- ARROW_DOWN : 2,
- ARROW_LEFT : 4,
- ARROW_RIGHT : 8,
- ARROW_ANY : 15
- },
- Direction:{
- BACK: 0,
- FRONT: 1
- }
-};
-
-});
-
-// file: lib/common/plugin/CameraPopoverHandle.js
-define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-/**
- * A handle to an image picker popover.
- */
-var CameraPopoverHandle = function() {
- this.setPosition = function(popoverOptions) {
- console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
- };
-};
-
-module.exports = CameraPopoverHandle;
-
-});
-
-// file: lib/common/plugin/CameraPopoverOptions.js
-define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
-
-var Camera = require('cordova/plugin/CameraConstants');
-
-/**
- * Encapsulates options for iOS Popover image picker
- */
-var CameraPopoverOptions = function(x,y,width,height,arrowDir){
- // information of rectangle that popover should be anchored to
- this.x = x || 0;
- this.y = y || 32;
- this.width = width || 320;
- this.height = height || 480;
- // The direction of the popover arrow
- this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
-};
-
-module.exports = CameraPopoverOptions;
-
-});
-
-// file: lib/common/plugin/CaptureAudioOptions.js
-define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all audio capture operation configuration options.
- */
-var CaptureAudioOptions = function(){
- // Upper limit of sound clips user can record. Value must be equal or greater than 1.
- this.limit = 1;
- // Maximum duration of a single sound clip in seconds.
- this.duration = 0;
-};
-
-module.exports = CaptureAudioOptions;
-
-});
-
-// file: lib/common/plugin/CaptureError.js
-define("cordova/plugin/CaptureError", function(require, exports, module) {
-
-/**
- * The CaptureError interface encapsulates all errors in the Capture API.
- */
-var CaptureError = function(c) {
- this.code = c || null;
-};
-
-// Camera or microphone failed to capture image or sound.
-CaptureError.CAPTURE_INTERNAL_ERR = 0;
-// Camera application or audio capture application is currently serving other capture request.
-CaptureError.CAPTURE_APPLICATION_BUSY = 1;
-// Invalid use of the API (e.g. limit parameter has value less than one).
-CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
-// User exited camera application or audio capture application before capturing anything.
-CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
-// The requested capture operation is not supported.
-CaptureError.CAPTURE_NOT_SUPPORTED = 20;
-
-module.exports = CaptureError;
-
-});
-
-// file: lib/common/plugin/CaptureImageOptions.js
-define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all image capture operation configuration options.
- */
-var CaptureImageOptions = function(){
- // Upper limit of images user can take. Value must be equal or greater than 1.
- this.limit = 1;
-};
-
-module.exports = CaptureImageOptions;
-
-});
-
-// file: lib/common/plugin/CaptureVideoOptions.js
-define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all video capture operation configuration options.
- */
-var CaptureVideoOptions = function(){
- // Upper limit of videos user can record. Value must be equal or greater than 1.
- this.limit = 1;
- // Maximum duration of a single video clip in seconds.
- this.duration = 0;
-};
-
-module.exports = CaptureVideoOptions;
-
-});
-
-// file: lib/common/plugin/CompassError.js
-define("cordova/plugin/CompassError", function(require, exports, module) {
-
-/**
- * CompassError.
- * An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var CompassError = function(err) {
- this.code = (err !== undefined ? err : null);
-};
-
-CompassError.COMPASS_INTERNAL_ERR = 0;
-CompassError.COMPASS_NOT_SUPPORTED = 20;
-
-module.exports = CompassError;
-
-});
-
-// file: lib/common/plugin/CompassHeading.js
-define("cordova/plugin/CompassHeading", function(require, exports, module) {
-
-var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
- this.magneticHeading = magneticHeading;
- this.trueHeading = trueHeading;
- this.headingAccuracy = headingAccuracy;
- this.timestamp = timestamp || new Date().getTime();
-};
-
-module.exports = CompassHeading;
-
-});
-
-// file: lib/common/plugin/ConfigurationData.js
-define("cordova/plugin/ConfigurationData", function(require, exports, module) {
-
-/**
- * Encapsulates a set of parameters that the capture device supports.
- */
-function ConfigurationData() {
- // The ASCII-encoded string in lower case representing the media type.
- this.type = null;
- // The height attribute represents height of the image or video in pixels.
- // In the case of a sound clip this attribute has value 0.
- this.height = 0;
- // The width attribute represents width of the image or video in pixels.
- // In the case of a sound clip this attribute has value 0
- this.width = 0;
-}
-
-module.exports = ConfigurationData;
-
-});
-
-// file: lib/common/plugin/Connection.js
-define("cordova/plugin/Connection", function(require, exports, module) {
-
-/**
- * Network status
- */
-module.exports = {
- UNKNOWN: "unknown",
- ETHERNET: "ethernet",
- WIFI: "wifi",
- CELL_2G: "2g",
- CELL_3G: "3g",
- CELL_4G: "4g",
- CELL:"cellular",
- NONE: "none"
-};
-
-});
-
-// file: lib/common/plugin/Contact.js
-define("cordova/plugin/Contact", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- ContactError = require('cordova/plugin/ContactError'),
- utils = require('cordova/utils');
-
-/**
-* Converts primitives into Complex Object
-* Currently only used for Date fields
-*/
-function convertIn(contact) {
- var value = contact.birthday;
- try {
- contact.birthday = new Date(parseFloat(value));
- } catch (exception){
- console.log("Cordova Contact convertIn error: exception creating date.");
- }
- return contact;
-}
-
-/**
-* Converts Complex objects into primitives
-* Only conversion at present is for Dates.
-**/
-
-function convertOut(contact) {
- var value = contact.birthday;
- if (value !== null) {
- // try to make it a Date object if it is not already
- if (!utils.isDate(value)){
- try {
- value = new Date(value);
- } catch(exception){
- value = null;
- }
- }
- if (utils.isDate(value)){
- value = value.valueOf(); // convert to milliseconds
- }
- contact.birthday = value;
- }
- return contact;
-}
-
-/**
-* Contains information about a single contact.
-* @constructor
-* @param {DOMString} id unique identifier
-* @param {DOMString} displayName
-* @param {ContactName} name
-* @param {DOMString} nickname
-* @param {Array.<ContactField>} phoneNumbers array of phone numbers
-* @param {Array.<ContactField>} emails array of email addresses
-* @param {Array.<ContactAddress>} addresses array of addresses
-* @param {Array.<ContactField>} ims instant messaging user ids
-* @param {Array.<ContactOrganization>} organizations
-* @param {DOMString} birthday contact's birthday
-* @param {DOMString} note user notes about contact
-* @param {Array.<ContactField>} photos
-* @param {Array.<ContactField>} categories
-* @param {Array.<ContactField>} urls contact's web sites
-*/
-var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
- ims, organizations, birthday, note, photos, categories, urls) {
- this.id = id || null;
- this.rawId = null;
- this.displayName = displayName || null;
- this.name = name || null; // ContactName
- this.nickname = nickname || null;
- this.phoneNumbers = phoneNumbers || null; // ContactField[]
- this.emails = emails || null; // ContactField[]
- this.addresses = addresses || null; // ContactAddress[]
- this.ims = ims || null; // ContactField[]
- this.organizations = organizations || null; // ContactOrganization[]
- this.birthday = birthday || null;
- this.note = note || null;
- this.photos = photos || null; // ContactField[]
- this.categories = categories || null; // ContactField[]
- this.urls = urls || null; // ContactField[]
-};
-
-/**
-* Removes contact from device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.remove = function(successCB, errorCB) {
- argscheck.checkArgs('FF', 'Contact.remove', arguments);
- var fail = errorCB && function(code) {
- errorCB(new ContactError(code));
- };
- if (this.id === null) {
- fail(ContactError.UNKNOWN_ERROR);
- }
- else {
- exec(successCB, fail, "Contacts", "remove", [this.id]);
- }
-};
-
-/**
-* Creates a deep copy of this Contact.
-* With the contact ID set to null.
-* @return copy of this Contact
-*/
-Contact.prototype.clone = function() {
- var clonedContact = utils.clone(this);
- clonedContact.id = null;
- clonedContact.rawId = null;
-
- function nullIds(arr) {
- if (arr) {
- for (var i = 0; i < arr.length; ++i) {
- arr[i].id = null;
- }
- }
- }
-
- // Loop through and clear out any id's in phones, emails, etc.
- nullIds(clonedContact.phoneNumbers);
- nullIds(clonedContact.emails);
- nullIds(clonedContact.addresses);
- nullIds(clonedContact.ims);
- nullIds(clonedContact.organizations);
- nullIds(clonedContact.categories);
- nullIds(clonedContact.photos);
- nullIds(clonedContact.urls);
- return clonedContact;
-};
-
-/**
-* Persists contact to device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.save = function(successCB, errorCB) {
- argscheck.checkArgs('FFO', 'Contact.save', arguments);
- var fail = errorCB && function(code) {
- errorCB(new ContactError(code));
- };
- var success = function(result) {
- if (result) {
- if (successCB) {
- var fullContact = require('cordova/plugin/contacts').create(result);
- successCB(convertIn(fullContact));
- }
- }
- else {
- // no Entry object returned
- fail(ContactError.UNKNOWN_ERROR);
- }
- };
- var dupContact = convertOut(utils.clone(this));
- exec(success, fail, "Contacts", "save", [dupContact]);
-};
-
-
-module.exports = Contact;
-
-});
-
-// file: lib/common/plugin/ContactAddress.js
-define("cordova/plugin/ContactAddress", function(require, exports, module) {
-
-/**
-* Contact address.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code
-* @param formatted // NOTE: not a W3C standard
-* @param streetAddress
-* @param locality
-* @param region
-* @param postalCode
-* @param country
-*/
-
-var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.formatted = formatted || null;
- this.streetAddress = streetAddress || null;
- this.locality = locality || null;
- this.region = region || null;
- this.postalCode = postalCode || null;
- this.country = country || null;
-};
-
-module.exports = ContactAddress;
-
-});
-
-// file: lib/common/plugin/ContactError.js
-define("cordova/plugin/ContactError", function(require, exports, module) {
-
-/**
- * ContactError.
- * An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var ContactError = function(err) {
- this.code = (typeof err != 'undefined' ? err : null);
-};
-
-/**
- * Error codes
- */
-ContactError.UNKNOWN_ERROR = 0;
-ContactError.INVALID_ARGUMENT_ERROR = 1;
-ContactError.TIMEOUT_ERROR = 2;
-ContactError.PENDING_OPERATION_ERROR = 3;
-ContactError.IO_ERROR = 4;
-ContactError.NOT_SUPPORTED_ERROR = 5;
-ContactError.PERMISSION_DENIED_ERROR = 20;
-
-module.exports = ContactError;
-
-});
-
-// file: lib/common/plugin/ContactField.js
-define("cordova/plugin/ContactField", function(require, exports, module) {
-
-/**
-* Generic contact field.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param type
-* @param value
-* @param pref
-*/
-var ContactField = function(type, value, pref) {
- this.id = null;
- this.type = (type && type.toString()) || null;
- this.value = (value && value.toString()) || null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
-};
-
-module.exports = ContactField;
-
-});
-
-// file: lib/common/plugin/ContactFindOptions.js
-define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
-
-/**
- * ContactFindOptions.
- * @constructor
- * @param filter used to match contacts against
- * @param multiple boolean used to determine if more than one contact should be returned
- */
-
-var ContactFindOptions = function(filter, multiple) {
- this.filter = filter || '';
- this.multiple = (typeof multiple != 'undefined' ? multiple : false);
-};
-
-module.exports = ContactFindOptions;
-
-});
-
-// file: lib/common/plugin/ContactName.js
-define("cordova/plugin/ContactName", function(require, exports, module) {
-
-/**
-* Contact name.
-* @constructor
-* @param formatted // NOTE: not part of W3C standard
-* @param familyName
-* @param givenName
-* @param middle
-* @param prefix
-* @param suffix
-*/
-var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
- this.formatted = formatted || null;
- this.familyName = familyName || null;
- this.givenName = givenName || null;
- this.middleName = middle || null;
- this.honorificPrefix = prefix || null;
- this.honorificSuffix = suffix || null;
-};
-
-module.exports = ContactName;
-
-});
-
-// file: lib/common/plugin/ContactOrganization.js
-define("cordova/plugin/ContactOrganization", function(require, exports, module) {
-
-/**
-* Contact organization.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param name
-* @param dept
-* @param title
-* @param startDate
-* @param endDate
-* @param location
-* @param desc
-*/
-
-var ContactOrganization = function(pref, type, name, dept, title) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.name = name || null;
- this.department = dept || null;
- this.title = title || null;
-};
-
-module.exports = ContactOrganization;
-
-});
-
-// file: lib/common/plugin/Coordinates.js
-define("cordova/plugin/Coordinates", function(require, exports, module) {
-
-/**
- * This class contains position information.
- * @param {Object} lat
- * @param {Object} lng
- * @param {Object} alt
- * @param {Object} acc
- * @param {Object} head
- * @param {Object} vel
- * @param {Object} altacc
- * @constructor
- */
-var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
- /**
- * The latitude of the position.
- */
- this.latitude = lat;
- /**
- * The longitude of the position,
- */
- this.longitude = lng;
- /**
- * The accuracy of the position.
- */
- this.accuracy = acc;
- /**
- * The altitude of the position.
- */
- this.altitude = (alt !== undefined ? alt : null);
- /**
- * The direction the device is moving at the position.
- */
- this.heading = (head !== undefined ? head : null);
- /**
- * The velocity with which the device is moving at the position.
- */
- this.speed = (vel !== undefined ? vel : null);
-
- if (this.speed === 0 || this.speed === null) {
- this.heading = NaN;
- }
-
- /**
- * The altitude accuracy of the position.
- */
- this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
-};
-
-module.exports = Coordinates;
-
-});
-
-// file: lib/common/plugin/DirectoryEntry.js
-define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileError = require('cordova/plugin/FileError'),
- DirectoryReader = require('cordova/plugin/DirectoryReader');
-
-/**
- * An interface representing a directory on the file system.
- *
- * {boolean} isFile always false (readonly)
- * {boolean} isDirectory always true (readonly)
- * {DOMString} name of the directory, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the directory (readonly)
- * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
- */
-var DirectoryEntry = function(name, fullPath) {
- DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
-};
-
-utils.extend(DirectoryEntry, Entry);
-
-/**
- * Creates a new DirectoryReader to read entries from this directory
- */
-DirectoryEntry.prototype.createReader = function() {
- return new DirectoryReader(this.fullPath);
-};
-
-/**
- * Creates or looks up a directory
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
- * @param {Flags} options to create or exclusively create the directory
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
- argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
- var win = successCallback && function(result) {
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
-};
-
-/**
- * Deletes a directory and all of it's contents
- *
- * @param {Function} successCallback is called with no parameters
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
-};
-
-/**
- * Creates or looks up a file
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
- * @param {Flags} options to create or exclusively create the file
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
- argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
- var win = successCallback && function(result) {
- var FileEntry = require('cordova/plugin/FileEntry');
- var entry = new FileEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
-};
-
-module.exports = DirectoryEntry;
-
-});
-
-// file: lib/common/plugin/DirectoryReader.js
-define("cordova/plugin/DirectoryReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError') ;
-
-/**
- * An interface that lists the files and directories in a directory.
- */
-function DirectoryReader(path) {
- this.path = path || null;
-}
-
-/**
- * Returns a list of entries from a directory.
- *
- * @param {Function} successCallback is called with a list of entries
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
- var win = typeof successCallback !== 'function' ? null : function(result) {
- var retVal = [];
- for (var i=0; i<result.length; i++) {
- var entry = null;
- if (result[i].isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result[i].isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result[i].isDirectory;
- entry.isFile = result[i].isFile;
- entry.name = result[i].name;
- entry.fullPath = result[i].fullPath;
- retVal.push(entry);
- }
- successCallback(retVal);
- };
- var fail = typeof errorCallback !== 'function' ? null : function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "readEntries", [this.path]);
-};
-
-module.exports = DirectoryReader;
-
-});
-
-// file: lib/common/plugin/Entry.js
-define("cordova/plugin/Entry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError'),
- Metadata = require('cordova/plugin/Metadata');
-
-/**
- * Represents a file or directory on the local file system.
- *
- * @param isFile
- * {boolean} true if Entry is a file (readonly)
- * @param isDirectory
- * {boolean} true if Entry is a directory (readonly)
- * @param name
- * {DOMString} name of the file or directory, excluding the path
- * leading to it (readonly)
- * @param fullPath
- * {DOMString} the absolute full path to the file or directory
- * (readonly)
- */
-function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
- this.isFile = !!isFile;
- this.isDirectory = !!isDirectory;
- this.name = name || '';
- this.fullPath = fullPath || '';
- this.filesystem = fileSystem || null;
-}
-
-/**
- * Look up the metadata of the entry.
- *
- * @param successCallback
- * {Function} is called with a Metadata object
- * @param errorCallback
- * {Function} is called with a FileError
- */
-Entry.prototype.getMetadata = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
- var success = successCallback && function(lastModified) {
- var metadata = new Metadata(lastModified);
- successCallback(metadata);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
-
- exec(success, fail, "File", "getMetadata", [this.fullPath]);
-};
-
-/**
- * Set the metadata of the entry.
- *
- * @param successCallback
- * {Function} is called with a Metadata object
- * @param errorCallback
- * {Function} is called with a FileError
- * @param metadataObject
- * {Object} keys and values to set
- */
-Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
- argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
- exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
-};
-
-/**
- * Move a file or directory to a new location.
- *
- * @param parent
- * {DirectoryEntry} the directory to which to move this entry
- * @param newName
- * {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- * {Function} called with the new DirectoryEntry object
- * @param errorCallback
- * {Function} called with a FileError
- */
-Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
- argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- // source path
- var srcPath = this.fullPath,
- // entry name
- name = newName || this.name,
- success = function(entry) {
- if (entry) {
- if (successCallback) {
- // create appropriate Entry object
- var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
- successCallback(result);
- }
- }
- else {
- // no Entry object returned
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- // copy
- exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Copy a directory to a different location.
- *
- * @param parent
- * {DirectoryEntry} the directory to which to copy the entry
- * @param newName
- * {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- * {Function} called with the new Entry object
- * @param errorCallback
- * {Function} called with a FileError
- */
-Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
- argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
-
- // source path
- var srcPath = this.fullPath,
- // entry name
- name = newName || this.name,
- // success callback
- success = function(entry) {
- if (entry) {
- if (successCallback) {
- // create appropriate Entry object
- var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
- successCallback(result);
- }
- }
- else {
- // no Entry object returned
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- // copy
- exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Return a URL that can be used to identify this entry.
- */
-Entry.prototype.toURL = function() {
- // fullPath attribute contains the full URL
- return this.fullPath;
-};
-
-/**
- * Returns a URI that can be used to identify this entry.
- *
- * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
- * @return uri
- */
-Entry.prototype.toURI = function(mimeType) {
- console.log("DEPRECATED: Update your code to use 'toURL'");
- // fullPath attribute contains the full URI
- return this.toURL();
-};
-
-/**
- * Remove a file or directory. It is an error to attempt to delete a
- * directory that is not empty. It is an error to attempt to delete a
- * root directory of a file system.
- *
- * @param successCallback {Function} called with no parameters
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.remove = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.remove', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "remove", [this.fullPath]);
-};
-
-/**
- * Look up the parent DirectoryEntry of this entry.
- *
- * @param successCallback {Function} called with the parent DirectoryEntry object
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.getParent = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.getParent', arguments);
- var win = successCallback && function(result) {
- var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getParent", [this.fullPath]);
-};
-
-module.exports = Entry;
-
-});
-
-// file: lib/common/plugin/File.js
-define("cordova/plugin/File", function(require, exports, module) {
-
-/**
- * Constructor.
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-
-var File = function(name, fullPath, type, lastModifiedDate, size){
- this.name = name || '';
- this.fullPath = fullPath || null;
- this.type = type || null;
- this.lastModifiedDate = lastModifiedDate || null;
- this.size = size || 0;
-
- // These store the absolute start and end for slicing the file.
- this.start = 0;
- this.end = this.size;
-};
-
-/**
- * Returns a "slice" of the file. Since Cordova Files don't contain the actual
- * content, this really returns a File with adjusted start and end.
- * Slices of slices are supported.
- * start {Number} The index at which to start the slice (inclusive).
- * end {Number} The index at which to end the slice (exclusive).
- */
-File.prototype.slice = function(start, end) {
- var size = this.end - this.start;
- var newStart = 0;
- var newEnd = size;
- if (arguments.length) {
- if (start < 0) {
- newStart = Math.max(size + start, 0);
- } else {
- newStart = Math.min(size, start);
- }
- }
-
- if (arguments.length >= 2) {
- if (end < 0) {
- newEnd = Math.max(size + end, 0);
- } else {
- newEnd = Math.min(end, size);
- }
- }
-
- var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
- newFile.start = this.start + newStart;
- newFile.end = this.start + newEnd;
- return newFile;
-};
-
-
-module.exports = File;
-
-});
-
-// file: lib/common/plugin/FileEntry.js
-define("cordova/plugin/FileEntry", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileWriter = require('cordova/plugin/FileWriter'),
- File = require('cordova/plugin/File'),
- FileError = require('cordova/plugin/FileError');
-
-/**
- * An interface representing a file on the file system.
- *
- * {boolean} isFile always true (readonly)
- * {boolean} isDirectory always false (readonly)
- * {DOMString} name of the file, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the file (readonly)
- * {FileSystem} filesystem on which the file resides (readonly)
- */
-var FileEntry = function(name, fullPath) {
- FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
-};
-
-utils.extend(FileEntry, Entry);
-
-/**
- * Creates a new FileWriter associated with the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new FileWriter
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
- this.file(function(filePointer) {
- var writer = new FileWriter(filePointer);
-
- if (writer.fileName === null || writer.fileName === "") {
- errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
- } else {
- successCallback && successCallback(writer);
- }
- }, errorCallback);
-};
-
-/**
- * Returns a File that represents the current state of the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new File object
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.file = function(successCallback, errorCallback) {
- var win = successCallback && function(f) {
- var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
- successCallback(file);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
-};
-
-
-module.exports = FileEntry;
-
-});
-
-// file: lib/common/plugin/FileError.js
-define("cordova/plugin/FileError", function(require, exports, module) {
-
-/**
- * FileError
- */
-function FileError(error) {
- this.code = error || null;
-}
-
-// File error codes
-// Found in DOMException
-FileError.NOT_FOUND_ERR = 1;
-FileError.SECURITY_ERR = 2;
-FileError.ABORT_ERR = 3;
-
-// Added by File API specification
-FileError.NOT_READABLE_ERR = 4;
-FileError.ENCODING_ERR = 5;
-FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
-FileError.INVALID_STATE_ERR = 7;
-FileError.SYNTAX_ERR = 8;
-FileError.INVALID_MODIFICATION_ERR = 9;
-FileError.QUOTA_EXCEEDED_ERR = 10;
-FileError.TYPE_MISMATCH_ERR = 11;
-FileError.PATH_EXISTS_ERR = 12;
-
-module.exports = FileError;
-
-});
-
-// file: lib/common/plugin/FileReader.js
-define("cordova/plugin/FileReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
- modulemapper = require('cordova/modulemapper'),
- utils = require('cordova/utils'),
- File = require('cordova/plugin/File'),
- FileError = require('cordova/plugin/FileError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent'),
- origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
-
-/**
- * This class reads the mobile device file system.
- *
- * For Android:
- * The root directory is the root of the file system.
- * To read from the SD card, the file name is "sdcard/my_file.txt"
- * @constructor
- */
-var FileReader = function() {
- this._readyState = 0;
- this._error = null;
- this._result = null;
- this._fileName = '';
- this._realReader = origFileReader ? new origFileReader() : {};
-};
-
-// States
-FileReader.EMPTY = 0;
-FileReader.LOADING = 1;
-FileReader.DONE = 2;
-
-utils.defineGetter(FileReader.prototype, 'readyState', function() {
- return this._fileName ? this._readyState : this._realReader.readyState;
-});
-
-utils.defineGetter(FileReader.prototype, 'error', function() {
- return this._fileName ? this._error: this._realReader.error;
-});
-
-utils.defineGetter(FileReader.prototype, 'result', function() {
- return this._fileName ? this._result: this._realReader.result;
-});
-
-function defineEvent(eventName) {
- utils.defineGetterSetter(FileReader.prototype, eventName, function() {
- return this._realReader[eventName] || null;
- }, function(value) {
- this._realReader[eventName] = value;
- });
-}
-defineEvent('onloadstart'); // When the read starts.
-defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
-defineEvent('onload'); // When the read has successfully completed.
-defineEvent('onerror'); // When the read has failed (see errors).
-defineEvent('onloadend'); // When the request has completed (either in success or failure).
-defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
-
-function initRead(reader, file) {
- // Already loading something
- if (reader.readyState == FileReader.LOADING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- reader._result = null;
- reader._error = null;
- reader._readyState = FileReader.LOADING;
-
- if (typeof file == 'string') {
- // Deprecated in Cordova 2.4.
- console.warn('Using a string argument with FileReader.readAs functions is deprecated.');
- reader._fileName = file;
- } else if (typeof file.fullPath == 'string') {
- reader._fileName = file.fullPath;
- } else {
- reader._fileName = '';
- return true;
- }
-
- reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
-}
-
-/**
- * Abort reading file.
- */
-FileReader.prototype.abort = function() {
- if (origFileReader && !this._fileName) {
- return this._realReader.abort();
- }
- this._result = null;
-
- if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
- return;
- }
-
- this._readyState = FileReader.DONE;
-
- // If abort callback
- if (typeof this.onabort === 'function') {
- this.onabort(new ProgressEvent('abort', {target:this}));
- }
- // If load end callback
- if (typeof this.onloadend === 'function') {
- this.onloadend(new ProgressEvent('loadend', {target:this}));
- }
-};
-
-/**
- * Read text file.
- *
- * @param file {File} File object containing file properties
- * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
- */
-FileReader.prototype.readAsText = function(file, encoding) {
- if (initRead(this, file)) {
- return this._realReader.readAsText(file, encoding);
- }
-
- // Default encoding is UTF-8
- var enc = encoding ? encoding : "UTF-8";
- var me = this;
- var execArgs = [this._fileName, enc, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // Save result
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // null result
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsText", execArgs);
-};
-
-
-/**
- * Read file and return data as a base64 encoded data url.
- * A data url is of the form:
- * data:[<mediatype>][;base64],<data>
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsDataURL = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsDataURL(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // Save result
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsDataURL", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsBinaryString = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsBinaryString(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsBinaryString", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsArrayBuffer = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsArrayBuffer(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsArrayBuffer", execArgs);
-};
-
-module.exports = FileReader;
-
-});
-
-// file: lib/common/plugin/FileSystem.js
-define("cordova/plugin/FileSystem", function(require, exports, module) {
-
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-
-/**
- * An interface representing a file system
- *
- * @constructor
- * {DOMString} name the unique name of the file system (readonly)
- * {DirectoryEntry} root directory of the file system (readonly)
- */
-var FileSystem = function(name, root) {
- this.name = name || null;
- if (root) {
- this.root = new DirectoryEntry(root.name, root.fullPath);
- }
-};
-
-module.exports = FileSystem;
-
-});
-
-// file: lib/common/plugin/FileTransfer.js
-define("cordova/plugin/FileTransfer", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- FileTransferError = require('cordova/plugin/FileTransferError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-function newProgressEvent(result) {
- var pe = new ProgressEvent();
- pe.lengthComputable = result.lengthComputable;
- pe.loaded = result.loaded;
- pe.total = result.total;
- return pe;
-}
-
-function getBasicAuthHeader(urlString) {
- var header = null;
-
- if (window.btoa) {
- // parse the url using the Location object
- var url = document.createElement('a');
- url.href = urlString;
-
- var credentials = null;
- var protocol = url.protocol + "//";
- var origin = protocol + url.host;
-
- // check whether there are the username:password credentials in the url
- if (url.href.indexOf(origin) !== 0) { // credentials found
- var atIndex = url.href.indexOf("@");
- credentials = url.href.substring(protocol.length, atIndex);
- }
-
- if (credentials) {
- var authHeader = "Authorization";
- var authHeaderValue = "Basic " + window.btoa(credentials);
-
- header = {
- name : authHeader,
- value : authHeaderValue
- };
- }
- }
-
- return header;
-}
-
-var idCounter = 0;
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {
- this._id = ++idCounter;
- this.onprogress = null; // optional callback
-};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String} Full path of the file on the device
-* @param server {String} URL of the server to receive the file
-* @param successCallback (Function} Callback to be invoked when upload has completed
-* @param errorCallback {Function} Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
- argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
- // check for options
- var fileKey = null;
- var fileName = null;
- var mimeType = null;
- var params = null;
- var chunkedMode = true;
- var headers = null;
- var httpMethod = null;
- var basicAuthHeader = getBasicAuthHeader(server);
- if (basicAuthHeader) {
- options = options || {};
- options.headers = options.headers || {};
- options.headers[basicAuthHeader.name] = basicAuthHeader.value;
- }
-
- if (options) {
- fileKey = options.fileKey;
- fileName = options.fileName;
- mimeType = options.mimeType;
- headers = options.headers;
- httpMethod = options.httpMethod || "POST";
- if (httpMethod.toUpperCase() == "PUT"){
- httpMethod = "PUT";
- } else {
- httpMethod = "POST";
- }
- if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
- chunkedMode = options.chunkedMode;
- }
- if (options.params) {
- params = options.params;
- }
- else {
- params = {};
- }
- }
-
- var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
- errorCallback(error);
- };
-
- var self = this;
- var win = function(result) {
- if (typeof result.lengthComputable != "undefined") {
- if (self.onprogress) {
- self.onprogress(newProgressEvent(result));
- }
- } else {
- successCallback && successCallback(result);
- }
- };
- exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String} URL of the server to receive the file
- * @param target {String} Full path of the file on the device
- * @param successCallback (Function} Callback to be invoked when upload has completed
- * @param errorCallback {Function} Callback to be invoked upon error
- * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
- * @param options {FileDownloadOptions} Optional parameters such as headers
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
- argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
- var self = this;
-
- var basicAuthHeader = getBasicAuthHeader(source);
- if (basicAuthHeader) {
- options = options || {};
- options.headers = options.headers || {};
- options.headers[basicAuthHeader.name] = basicAuthHeader.value;
- }
-
- var headers = null;
- if (options) {
- headers = options.headers || null;
- }
-
- var win = function(result) {
- if (typeof result.lengthComputable != "undefined") {
- if (self.onprogress) {
- return self.onprogress(newProgressEvent(result));
- }
- } else if (successCallback) {
- var entry = null;
- if (result.isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result.isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result.isDirectory;
- entry.isFile = result.isFile;
- entry.name = result.name;
- entry.fullPath = result.fullPath;
- successCallback(entry);
- }
- };
-
- var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
- errorCallback(error);
- };
-
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
-};
-
-/**
- * Aborts the ongoing file transfer on this object. The original error
- * callback for the file transfer will be called if necessary.
- */
-FileTransfer.prototype.abort = function() {
- exec(nu
<TRUNCATED>
[49/50] [abbrv] git commit: resolve merge conflict
Posted by pu...@apache.org.
resolve merge conflict
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/61570afa
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/61570afa
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/61570afa
Branch: refs/heads/2.9.x
Commit: 61570afa77815dce0ff2d223c3dd897f431a3e71
Parents: 90097ba
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jun 18 13:54:41 2013 -0400
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 16:18:14 2013 -0700
----------------------------------------------------------------------
common/www/cordova.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/61570afa/common/www/cordova.js
----------------------------------------------------------------------
diff --git a/common/www/cordova.js b/common/www/cordova.js
index 3e70492..9d8d7a6 100644
--- a/common/www/cordova.js
+++ b/common/www/cordova.js
@@ -6717,4 +6717,6 @@ window.cordova = require('cordova');
} catch(err){
finishPluginLoading();
}
-}(window));
\ No newline at end of file
+}(window));
+
+})();
[42/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/MimeTypeMapper.cs b/common-items/Plugins/MimeTypeMapper.cs
deleted file mode 100644
index a2794f5..0000000
--- a/common-items/Plugins/MimeTypeMapper.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- 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.
-*/
-
-using System.Collections.Generic;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Represents file extension to mime type mapper.
- /// </summary>
- public static class MimeTypeMapper
- {
- /// <summary>
- /// For unknown type it is recommended to use 'application/octet-stream'
- /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
- /// </summary>
- private static string DefaultMimeType = "application/octet-stream";
-
- /// <summary>
- /// Stores mime type for all necessary extension
- /// </summary>
- private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
- {
- {"avi", "video/x-msvideo"},
- {"bmp", "image/bmp"},
- {"gif", "image/gif"},
- {"html","text/html"},
- {"jpe", "image/jpeg"},
- {"jpeg", "image/jpeg"},
- {"jpg", "image/jpeg"},
- {"js","text/javascript"},
- {"mov", "video/quicktime"},
- {"mp2", "audio/mpeg"},
- {"mp3", "audio/mpeg"},
- {"mp4", "video/mp4"},
- {"mpe", "video/mpeg"},
- {"mpeg", "video/mpeg"},
- {"mpg", "video/mpeg"},
- {"mpga", "audio/mpeg"},
- {"pbm", "image/x-portable-bitmap"},
- {"pcm", "audio/x-pcm"},
- {"pct", "image/pict"},
- {"pgm", "image/x-portable-graymap"},
- {"pic", "image/pict"},
- {"pict", "image/pict"},
- {"png", "image/png"},
- {"pnm", "image/x-portable-anymap"},
- {"pnt", "image/x-macpaint"},
- {"pntg", "image/x-macpaint"},
- {"ppm", "image/x-portable-pixmap"},
- {"qt", "video/quicktime"},
- {"ra", "audio/x-pn-realaudio"},
- {"ram", "audio/x-pn-realaudio"},
- {"ras", "image/x-cmu-raster"},
- {"rgb", "image/x-rgb"},
- {"snd", "audio/basic"},
- {"txt", "text/plain"},
- {"tif", "image/tiff"},
- {"tiff", "image/tiff"},
- {"wav", "audio/x-wav"},
- {"wbmp", "image/vnd.wap.wbmp"},
-
- };
- /// <summary>
- /// Gets mime type by file extension
- /// </summary>
- /// <param name="fileName">file name to extract extension</param>
- /// <returns>mime type</returns>
- public static string GetMimeType(string fileName)
- {
- string ext = Path.GetExtension(fileName);
-
- // invalid extension
- if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
- {
- return DefaultMimeType;
- }
-
- ext = ext.Remove(0, 1);
-
- if (MIMETypesDictionary.ContainsKey(ext))
- {
- return MIMETypesDictionary[ext];
- }
-
- return DefaultMimeType;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/NetworkStatus.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/NetworkStatus.cs b/common-items/Plugins/NetworkStatus.cs
deleted file mode 100644
index 12eb061..0000000
--- a/common-items/Plugins/NetworkStatus.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Net.NetworkInformation;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
-
- public class NetworkStatus : BaseCommand
- {
- const string UNKNOWN = "unknown";
- const string ETHERNET = "ethernet";
- const string WIFI = "wifi";
- const string CELL_2G = "2g";
- const string CELL_3G = "3g";
- const string CELL_4G = "4g";
- const string NONE = "none";
- const string CELL = "cellular";
-
- private bool HasCallback = false;
-
- public NetworkStatus()
- {
- DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
- }
-
- public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
- {
- this.getConnectionInfo("");
- }
-
- public void getConnectionInfo(string empty)
- {
- HasCallback = true;
- updateConnectionType(checkConnectionType());
- }
-
- private string checkConnectionType()
- {
- if (DeviceNetworkInformation.IsNetworkAvailable)
- {
- if (DeviceNetworkInformation.IsWiFiEnabled)
- {
- return WIFI;
- }
- else
- {
- return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
- }
- }
- return NONE;
- }
-
- private string checkConnectionType(NetworkInterfaceSubType type)
- {
- switch (type)
- {
- case NetworkInterfaceSubType.Cellular_1XRTT: //cell
- case NetworkInterfaceSubType.Cellular_GPRS: //cell
- return CELL;
- case NetworkInterfaceSubType.Cellular_EDGE: //2
- return CELL_2G;
- case NetworkInterfaceSubType.Cellular_3G:
- case NetworkInterfaceSubType.Cellular_EVDO: //3
- case NetworkInterfaceSubType.Cellular_EVDV: //3
- case NetworkInterfaceSubType.Cellular_HSPA: //3
- return CELL_3G;
- case NetworkInterfaceSubType.WiFi:
- return WIFI;
- case NetworkInterfaceSubType.Unknown:
- case NetworkInterfaceSubType.Desktop_PassThru:
- default:
- return UNKNOWN;
- }
- }
-
- void ChangeDetected(object sender, NetworkNotificationEventArgs e)
- {
- switch (e.NotificationType)
- {
- case NetworkNotificationType.InterfaceConnected:
- updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
- break;
- case NetworkNotificationType.InterfaceDisconnected:
- updateConnectionType(NONE);
- break;
- default:
- break;
- }
- }
-
- private void updateConnectionType(string type)
- {
- // This should also implicitly fire offline/online events as that is handled on the JS side
- if (this.HasCallback)
- {
- PluginResult result = new PluginResult(PluginResult.Status.OK, type);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Notification.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Notification.cs b/common-items/Plugins/Notification.cs
deleted file mode 100644
index 0759c72..0000000
--- a/common-items/Plugins/Notification.cs
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Devices;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Windows.Resources;
-using Microsoft.Phone.Controls;
-using Microsoft.Xna.Framework.Audio;
-using WPCordovaClassLib.Cordova.UI;
-using System.Diagnostics;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Notification : BaseCommand
- {
- static ProgressBar progressBar = null;
- const int DEFAULT_DURATION = 5;
-
- private NotificationBox notifyBox;
-
- private PhoneApplicationPage Page
- {
- get
- {
- PhoneApplicationPage page = null;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- page = frame.Content as PhoneApplicationPage;
- }
- return page;
- }
- }
-
- // blink api - doesn't look like there is an equivalent api we can use...
-
- [DataContract]
- public class AlertOptions
- {
- [OnDeserializing]
- public void OnDeserializing(StreamingContext context)
- {
- // set defaults
- this.message = "message";
- this.title = "Alert";
- this.buttonLabel = "ok";
- }
-
- /// <summary>
- /// message to display in the alert box
- /// </summary>
- [DataMember]
- public string message;
-
- /// <summary>
- /// title displayed on the alert window
- /// </summary>
- [DataMember]
- public string title;
-
- /// <summary>
- /// text to display on the button
- /// </summary>
- [DataMember]
- public string buttonLabel;
- }
-
- public void alert(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
- Button btnOK = new Button();
- btnOK.Content = alertOpts.buttonLabel;
- btnOK.Click += new RoutedEventHandler(btnOK_Click);
- btnOK.Tag = 1;
- notifyBox.ButtonPanel.Children.Add(btnOK);
- grid.Children.Add(notifyBox);
-
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- public void confirm(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
-
- string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
-
- if (labels == null)
- {
- labels = alertOpts.buttonLabel.Split(',');
- }
-
- for (int n = 0; n < labels.Length; n++)
- {
- Button btn = new Button();
- btn.Content = labels[n];
- btn.Tag = n;
- btn.Click += new RoutedEventHandler(btnOK_Click);
- notifyBox.ButtonPanel.Children.Add(btn);
- }
-
- grid.Children.Add(notifyBox);
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
- {
- PhoneApplicationPage page = sender as PhoneApplicationPage;
- string callbackId = "";
- if (page != null && notifyBox != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifyBox);
- dynamic notifBoxData = notifyBox.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
- }
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- e.Cancel = true;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
- }
-
- void btnOK_Click(object sender, RoutedEventArgs e)
- {
- Button btn = sender as Button;
- FrameworkElement notifBoxParent = null;
- int retVal = 0;
- string callbackId = "";
- if (btn != null)
- {
- retVal = (int)btn.Tag + 1;
-
- notifBoxParent = btn.Parent as FrameworkElement;
- while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
- !(notifBoxParent is NotificationBox)) ;
- }
- if (notifBoxParent != null)
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifBoxParent);
- }
-
- dynamic notifBoxData = notifBoxParent.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
-
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- }
-
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
- }
-
-
-
- public void beep(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- int times = int.Parse(args[0]);
-
- string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
-
- StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
-
- if (sri != null)
- {
- SoundEffect effect = SoundEffect.FromStream(sri.Stream);
- SoundEffectInstance inst = effect.CreateInstance();
- ThreadPool.QueueUserWorkItem((o) =>
- {
- // cannot interact with UI !!
- do
- {
- inst.Play();
- Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
- }
- while (--times > 0);
-
- });
-
- }
-
- // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
- DispatchCommandResult();
- }
-
- // Display an indeterminate progress indicator
- public void activityStart(string unused)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- if (page != null)
- {
- var temp = page.FindName("LayoutRoot");
- Grid grid = temp as Grid;
- if (grid != null)
- {
- if (progressBar != null)
- {
- grid.Children.Remove(progressBar);
- }
- progressBar = new ProgressBar();
- progressBar.IsIndeterminate = true;
- progressBar.IsEnabled = true;
-
- grid.Children.Add(progressBar);
- }
- }
- }
- });
- }
-
-
- // Remove our indeterminate progress indicator
- public void activityStop(string unused)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (progressBar != null)
- {
- progressBar.IsEnabled = false;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(progressBar);
- }
- }
- }
- progressBar = null;
- }
- });
- }
-
- public void vibrate(string vibrateDuration)
- {
-
- int msecs = 200; // set default
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
-
- msecs = int.Parse(args[0]);
- if (msecs < 1)
- {
- msecs = 1;
- }
- }
- catch (FormatException)
- {
-
- }
-
- VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
-
- // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
- DispatchCommandResult();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/AudioCaptureTask.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/AudioCaptureTask.cs b/common-items/Plugins/UI/AudioCaptureTask.cs
deleted file mode 100644
index 3d7d60f..0000000
--- a/common-items/Plugins/UI/AudioCaptureTask.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Audio Recording application.
- /// Use this to allow users to record audio from your application.
- /// </summary>
- public class AudioCaptureTask
- {
- /// <summary>
- /// Represents recorded audio returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
- /// </summary>
- public class AudioResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the AudioResult class.
- /// </summary>
- public AudioResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the AudioResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public AudioResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded audio.
- /// </summary>
- public Stream AudioFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded audio.
- /// </summary>
- public string AudioFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is AudioRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- AudioRecorder audioRecorder = (AudioRecorder)e.Content;
-
- if (audioRecorder != null)
- {
- audioRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new AudioResult(TaskResult.Cancel));
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/AudioRecorder.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/AudioRecorder.xaml b/common-items/Plugins/UI/AudioRecorder.xaml
deleted file mode 100644
index 0fd26ab..0000000
--- a/common-items/Plugins/UI/AudioRecorder.xaml
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Portrait" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Transparent">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
- <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
- </StackPanel>
-
- <!--ContentPanel - place additional content here-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0" VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
- <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
- <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
- </Grid>
- </Grid>
-
- <!--Sample code showing usage of ApplicationBar-->
- <!--<phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
- <shell:ApplicationBar.MenuItems>
- <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
- <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
- </shell:ApplicationBar.MenuItems>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>-->
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/AudioRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/AudioRecorder.xaml.cs b/common-items/Plugins/UI/AudioRecorder.xaml.cs
deleted file mode 100644
index 01a0832..0000000
--- a/common-items/Plugins/UI/AudioRecorder.xaml.cs
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Threading;
-using WPCordovaClassLib.Cordova.Commands;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Implements Audio Recording application
- /// </summary>
- public partial class AudioRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- private const string RecordingStartCaption = "Start";
- private const string RecordingStopCaption = "Stop";
-
- private const string LocalFolderName = "AudioCache";
- private const string FileNameFormat = "Audio-{0}.wav";
-
- #endregion
-
- #region Callbacks
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone microphone;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Recording duration
- /// </summary>
- private TimeSpan duration;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private AudioResult result = new AudioResult(TaskResult.Cancel);
-
- /// <summary>
- /// Whether we are recording audio now
- /// </summary>
- private bool IsRecording
- {
- get
- {
- return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
- }
- }
-
- #endregion
-
- /// <summary>
- /// Creates new instance of the AudioRecorder class.
- /// </summary>
- public AudioRecorder()
- {
-
- this.InitializeXnaGameLoop();
-
- // microphone requires special XNA initialization to work
- InitializeComponent();
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- private void StartRecording()
- {
- this.microphone = Microphone.Default;
- this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
-
- this.btnTake.IsEnabled = false;
- this.btnStartStop.Content = RecordingStopCaption;
-
- this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
- this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
-
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.microphone.SampleRate);
-
- this.duration = new TimeSpan(0);
-
- this.microphone.Start();
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- private void StopRecording()
- {
- this.microphone.Stop();
-
- this.microphone.BufferReady -= MicrophoneBufferReady;
-
- this.microphone = null;
-
- btnStartStop.Content = RecordingStartCaption;
-
- // check there is some data
- this.btnTake.IsEnabled = true;
- }
-
- /// <summary>
- /// Handles Start/Stop events
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStartStop_Click(object sender, RoutedEventArgs e)
- {
-
- if (this.IsRecording)
- {
- this.StopRecording();
- }
- else
- {
- this.StartRecording();
- }
- }
-
- /// <summary>
- /// Handles Take button click
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnTake_Click(object sender, RoutedEventArgs e)
- {
- this.result = this.SaveAudioClipToLocalStorage();
-
- if (Completed != null)
- {
- Completed(this, result);
- }
-
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Handles page closing event, stops recording if needed and dispatches results.
- /// </summary>
- /// <param name="e"></param>
- protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
- {
- if (IsRecording)
- {
- StopRecording();
- }
-
- this.FinalizeXnaGameLoop();
-
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Copies data from microphone to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void MicrophoneBufferReady(object sender, EventArgs e)
- {
- this.microphone.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- TimeSpan bufferDuration = this.microphone.BufferDuration;
-
- this.Dispatcher.BeginInvoke(() =>
- {
- this.duration += bufferDuration;
-
- this.txtDuration.Text = "Duration: " +
- this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
- this.duration.Seconds.ToString().PadLeft(2, '0');
- });
-
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private AudioResult SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return new AudioResult(TaskResult.Cancel);
- }
-
- this.memoryStream.UpdateWavStream();
-
- // save audio data to local isolated storage
-
- string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
-
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
- {
-
- this.memoryStream.CopyTo(fileStream);
- }
-
- AudioResult result = new AudioResult(TaskResult.OK);
- result.AudioFileName = filePath;
-
- result.AudioFile = this.memoryStream;
- result.AudioFile.Seek(0, SeekOrigin.Begin);
-
- return result;
- }
-
-
-
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (dtXna != null)
- {
- dtXna.Stop();
- dtXna = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/ImageCapture.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/ImageCapture.xaml b/common-items/Plugins/UI/ImageCapture.xaml
deleted file mode 100644
index a7eee21..0000000
--- a/common-items/Plugins/UI/ImageCapture.xaml
+++ /dev/null
@@ -1,26 +0,0 @@
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Yellow">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- </Grid>
-
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/ImageCapture.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/ImageCapture.xaml.cs b/common-items/Plugins/UI/ImageCapture.xaml.cs
deleted file mode 100644
index 234b444..0000000
--- a/common-items/Plugins/UI/ImageCapture.xaml.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class ImageCapture : PhoneApplicationPage
- {
- public ImageCapture()
- {
- InitializeComponent();
- }
- }
-
- public class ImageCaptureTask
- {
- /// <summary>
- /// Represents an image returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
- /// </summary>
- //public class AudioResult : TaskEventArgs
- //{
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class.
- // /// </summary>
- // public AudioResult()
- // { }
-
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class
- // /// with the specified Microsoft.Phone.Tasks.TaskResult.
- // /// </summary>
- // /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- // public AudioResult(TaskResult taskResult)
- // : base(taskResult)
- // { }
-
- // /// <summary>
- // /// Gets the file name of the recorded audio.
- // /// </summary>
- // public Stream AudioFile { get; internal set; }
-
- // /// <summary>
- // /// Gets the stream containing the data for the recorded audio.
- // /// </summary>
- // public string AudioFileName { get; internal set; }
- //}
-
- ///// <summary>
- ///// Occurs when a audio recording task is completed.
- ///// </summary>
- //public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- ImageCapture imageCapture = e.Content as ImageCapture;
- if (imageCapture != null)
- {
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- //imageCapture.Completed += this.Completed;
- //else if (this.Completed != null)
- //{
- // this.Completed(this, new AudioResult(TaskResult.Cancel));
- //}
- }
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/NotificationBox.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/NotificationBox.xaml b/common-items/Plugins/UI/NotificationBox.xaml
deleted file mode 100644
index 1ca5d5f..0000000
--- a/common-items/Plugins/UI/NotificationBox.xaml
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
- 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.
--->
-<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
-
- <Grid x:Name="LayoutRoot"
- Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
-
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel"
- Grid.Row="0"
- Background="{StaticResource PhoneSemitransparentBrush}">
- <TextBlock x:Name="PageTitle"
- Text="Title"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle2Style}"/>
-
- <TextBlock x:Name="SubTitle"
- Text="Subtitle"
- TextWrapping="Wrap"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle3Style}"/>
-
- <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
- <StackPanel x:Name="ButtonPanel"
- Margin="10,10"
- Orientation="Horizontal"/>
- </ScrollViewer>
-
- </StackPanel>
- </Grid>
-</UserControl>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/NotificationBox.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/NotificationBox.xaml.cs b/common-items/Plugins/UI/NotificationBox.xaml.cs
deleted file mode 100644
index 50b2f2a..0000000
--- a/common-items/Plugins/UI/NotificationBox.xaml.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class NotificationBox : UserControl
- {
- public NotificationBox()
- {
- InitializeComponent();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/VideoCaptureTask.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/VideoCaptureTask.cs b/common-items/Plugins/UI/VideoCaptureTask.cs
deleted file mode 100644
index 958c05c..0000000
--- a/common-items/Plugins/UI/VideoCaptureTask.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Video Recording application.
- /// Use this to allow users to record video from your application.
- /// </summary>
- public class VideoCaptureTask
- {
- /// <summary>
- /// Represents recorded video returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
- /// </summary>
- public class VideoResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the VideoResult class.
- /// </summary>
- public VideoResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the VideoResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public VideoResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded Video.
- /// </summary>
- public Stream VideoFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded Video.
- /// </summary>
- public string VideoFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a Video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- /// <summary>
- /// Shows Video Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is VideoRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
-
- if (VideoRecorder != null)
- {
- VideoRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new VideoResult(TaskResult.Cancel));
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/VideoRecorder.xaml
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/VideoRecorder.xaml b/common-items/Plugins/UI/VideoRecorder.xaml
deleted file mode 100644
index c78fdb0..0000000
--- a/common-items/Plugins/UI/VideoRecorder.xaml
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Landscape" Orientation="LandscapeLeft"
- shell:SystemTray.IsVisible="False">
-
- <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
-
- <Rectangle
- x:Name="viewfinderRectangle"
- Width="640"
- Height="480"
- HorizontalAlignment="Left"
- Canvas.Left="80"/>
-
- </Canvas>
-
- <phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record" x:Name="btnStartRecording" Click="StartRecording_Click" />
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/UI/VideoRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/UI/VideoRecorder.xaml.cs b/common-items/Plugins/UI/VideoRecorder.xaml.cs
deleted file mode 100644
index 6ab1cc3..0000000
--- a/common-items/Plugins/UI/VideoRecorder.xaml.cs
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media;
-using System.Windows.Navigation;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class VideoRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- /// <summary>
- /// Caption for record button in ready state
- /// </summary>
- private const string RecordingStartCaption = "Record";
-
- /// <summary>
- /// Caption for record button in recording state
- /// </summary>
- private const string RecordingStopCaption = "Stop";
-
- /// <summary>
- /// Start record icon URI
- /// </summary>
- private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
-
- /// <summary>
- /// Stop record icon URI
- /// </summary>
- private const string StopIconUri = "/Images/appbar.stop.rest.png";
-
- /// <summary>
- /// Folder to save video clips
- /// </summary>
- private const string LocalFolderName = "VideoCache";
-
- /// <summary>
- /// File name format
- /// </summary>
- private const string FileNameFormat = "Video-{0}.mp4";
-
- /// <summary>
- /// Temporary file name
- /// </summary>
- private const string defaultFileName = "NewVideoFile.mp4";
-
- #endregion
-
- #region Callbacks
- /// <summary>
- /// Occurs when a video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Viewfinder for capturing video
- /// </summary>
- private VideoBrush videoRecorderBrush;
-
- /// <summary>
- /// Path to save video clip
- /// </summary>
- private string filePath;
-
- /// <summary>
- /// Source for capturing video.
- /// </summary>
- private CaptureSource captureSource;
-
- /// <summary>
- /// Video device
- /// </summary>
- private VideoCaptureDevice videoCaptureDevice;
-
- /// <summary>
- /// File sink so save recording video in Isolated Storage
- /// </summary>
- private FileSink fileSink;
-
- /// <summary>
- /// For managing button and application state
- /// </summary>
- private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
-
- /// <summary>
- /// Current video state
- /// </summary>
- private VideoState currentVideoState;
-
- /// <summary>
- /// Stream to return result
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private VideoResult result = new VideoResult(TaskResult.Cancel);
-
- #endregion
-
- /// <summary>
- /// Initializes components
- /// </summary>
- public VideoRecorder()
- {
- InitializeComponent();
-
- PhoneAppBar = (ApplicationBar)ApplicationBar;
- PhoneAppBar.IsVisible = true;
- btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
- btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
- }
-
- /// <summary>
- /// Initializes the video recorder then page is loading
- /// </summary>
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- this.InitializeVideoRecorder();
- }
-
- /// <summary>
- /// Disposes camera and media objects then leave the page
- /// </summary>
- protected override void OnNavigatedFrom(NavigationEventArgs e)
- {
- this.DisposeVideoRecorder();
-
- if (this.Completed != null)
- {
- this.Completed(this, result);
- }
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Handles TakeVideo button click
- /// </summary>
- private void TakeVideo_Click(object sender, EventArgs e)
- {
- this.result = this.SaveVideoClip();
- this.NavigateBack();
- }
-
- private void NavigateBack()
- {
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Resaves video clip from temporary directory to persistent
- /// </summary>
- private VideoResult SaveVideoClip()
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
- {
- return new VideoResult(TaskResult.Cancel);
- }
-
- string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
- string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
- isoFile.CopyFile(filePath, newPath);
- isoFile.DeleteFile(filePath);
-
- memoryStream = new MemoryStream();
- using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
- {
- fileStream.CopyTo(memoryStream);
- }
-
- VideoResult result = new VideoResult(TaskResult.OK);
- result.VideoFileName = newPath;
- result.VideoFile = this.memoryStream;
- result.VideoFile.Seek(0, SeekOrigin.Begin);
- return result;
- }
-
- }
- catch (Exception)
- {
- return new VideoResult(TaskResult.None);
- }
- }
-
- /// <summary>
- /// Updates the buttons on the UI thread based on current state.
- /// </summary>
- /// <param name="currentState">current UI state</param>
- private void UpdateUI(VideoState currentState)
- {
- Dispatcher.BeginInvoke(delegate
- {
- switch (currentState)
- {
- case VideoState.CameraNotSupported:
- btnStartRecording.IsEnabled = false;
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Initialized:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Ready:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = true;
- break;
-
- case VideoState.Recording:
- btnStartRecording.Text = RecordingStopCaption;
- btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- default:
- break;
- }
- currentVideoState = currentState;
- });
- }
-
- /// <summary>
- /// Initializes VideoRecorder
- /// </summary>
- public void InitializeVideoRecorder()
- {
- if (captureSource == null)
- {
- captureSource = new CaptureSource();
- fileSink = new FileSink();
- videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
-
- if (videoCaptureDevice != null)
- {
- videoRecorderBrush = new VideoBrush();
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Initialized);
- }
- else
- {
- this.UpdateUI(VideoState.CameraNotSupported);
- }
- }
- }
-
- /// <summary>
- /// Sets recording state: start recording
- /// </summary>
- private void StartVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = captureSource;
- filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- }
-
- fileSink.IsolatedStorageFileName = filePath;
- }
-
- if (captureSource.VideoCaptureDevice != null
- && captureSource.State == CaptureState.Stopped)
- {
- captureSource.Start();
- }
- this.UpdateUI(VideoState.Recording);
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: stop recording
- /// </summary>
- private void StopVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = null;
- fileSink.IsolatedStorageFileName = null;
- this.StartVideoPreview();
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: display the video on the viewfinder.
- /// </summary>
- private void StartVideoPreview()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
- {
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Ready);
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Starts video recording
- /// </summary>
- private void StartRecording_Click(object sender, EventArgs e)
- {
- if (currentVideoState == VideoState.Recording)
- {
- this.StopVideoRecording();
- }
- else
- {
- this.StartVideoRecording();
- }
- }
-
- /// <summary>
- /// Releases resources
- /// </summary>
- private void DisposeVideoRecorder()
- {
- if (captureSource != null)
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- }
- captureSource = null;
- videoCaptureDevice = null;
- fileSink = null;
- videoRecorderBrush = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/SplashScreenImage.jpg
----------------------------------------------------------------------
diff --git a/common-items/SplashScreenImage.jpg b/common-items/SplashScreenImage.jpg
deleted file mode 100644
index d35501d..0000000
Binary files a/common-items/SplashScreenImage.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/__PreviewImage.jpg
----------------------------------------------------------------------
diff --git a/common-items/__PreviewImage.jpg b/common-items/__PreviewImage.jpg
deleted file mode 100644
index 1d72941..0000000
Binary files a/common-items/__PreviewImage.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/__TemplateIcon.png
----------------------------------------------------------------------
diff --git a/common-items/__TemplateIcon.png b/common-items/__TemplateIcon.png
deleted file mode 100644
index 75c17c7..0000000
Binary files a/common-items/__TemplateIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/resources/notification-beep.wav
----------------------------------------------------------------------
diff --git a/common-items/resources/notification-beep.wav b/common-items/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
Binary files a/common-items/resources/notification-beep.wav and /dev/null differ
[21/50] [abbrv] moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/www/cordova.js
----------------------------------------------------------------------
diff --git a/common-items/www/cordova.js b/common-items/www/cordova.js
new file mode 100644
index 0000000..0d763d9
--- /dev/null
+++ b/common-items/www/cordova.js
@@ -0,0 +1,6723 @@
+// Platform: windowsphone
+// 2.8.0rc1-0-g22bc4d8
+/*
+ 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.
+*/
+;(function() {
+var CORDOVA_JS_BUILD_LABEL = '2.8.0rc1-0-g22bc4d8';
+// file: lib/scripts/require.js
+
+var require,
+ define;
+
+(function () {
+ var modules = {},
+ // Stack of moduleIds currently being built.
+ requireStack = [],
+ // Map of module ID -> index into requireStack of modules currently being built.
+ inProgressModules = {},
+ SEPERATOR = ".";
+
+
+
+ function build(module) {
+ var factory = module.factory,
+ localRequire = function (id) {
+ var resultantId = id;
+ //Its a relative path, so lop off the last portion and add the id (minus "./")
+ if (id.charAt(0) === ".") {
+ resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
+ }
+ return require(resultantId);
+ };
+ module.exports = {};
+ delete module.factory;
+ factory(localRequire, module.exports, module);
+ return module.exports;
+ }
+
+ require = function (id) {
+ if (!modules[id]) {
+ throw "module " + id + " not found";
+ } else if (id in inProgressModules) {
+ var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+ throw "Cycle in require graph: " + cycle;
+ }
+ if (modules[id].factory) {
+ try {
+ inProgressModules[id] = requireStack.length;
+ requireStack.push(id);
+ return build(modules[id]);
+ } finally {
+ delete inProgressModules[id];
+ requireStack.pop();
+ }
+ }
+ return modules[id].exports;
+ };
+
+ define = function (id, factory) {
+ if (modules[id]) {
+ throw "module " + id + " already defined";
+ }
+
+ modules[id] = {
+ id: id,
+ factory: factory
+ };
+ };
+
+ define.remove = function (id) {
+ delete modules[id];
+ };
+
+ define.moduleMap = modules;
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+ module.exports.require = require;
+ module.exports.define = define;
+}
+
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+
+
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+ channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+ channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+ windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ if (typeof documentEventHandlers[e] != 'undefined') {
+ documentEventHandlers[e].subscribe(handler);
+ } else {
+ m_document_addEventListener.call(document, evt, handler, capture);
+ }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ if (typeof windowEventHandlers[e] != 'undefined') {
+ windowEventHandlers[e].subscribe(handler);
+ } else {
+ m_window_addEventListener.call(window, evt, handler, capture);
+ }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ // If unsubscribing from an event that is handled by a plugin
+ if (typeof documentEventHandlers[e] != "undefined") {
+ documentEventHandlers[e].unsubscribe(handler);
+ } else {
+ m_document_removeEventListener.call(document, evt, handler, capture);
+ }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ // If unsubscribing from an event that is handled by a plugin
+ if (typeof windowEventHandlers[e] != "undefined") {
+ windowEventHandlers[e].unsubscribe(handler);
+ } else {
+ m_window_removeEventListener.call(window, evt, handler, capture);
+ }
+};
+
+function createEvent(type, data) {
+ var event = document.createEvent('Events');
+ event.initEvent(type, false, false);
+ if (data) {
+ for (var i in data) {
+ if (data.hasOwnProperty(i)) {
+ event[i] = data[i];
+ }
+ }
+ }
+ return event;
+}
+
+if(typeof window.console === "undefined") {
+ window.console = {
+ log:function(){}
+ };
+}
+
+var cordova = {
+ define:define,
+ require:require,
+ /**
+ * Methods to add/remove your own addEventListener hijacking on document + window.
+ */
+ addWindowEventHandler:function(event) {
+ return (windowEventHandlers[event] = channel.create(event));
+ },
+ addStickyDocumentEventHandler:function(event) {
+ return (documentEventHandlers[event] = channel.createSticky(event));
+ },
+ addDocumentEventHandler:function(event) {
+ return (documentEventHandlers[event] = channel.create(event));
+ },
+ removeWindowEventHandler:function(event) {
+ delete windowEventHandlers[event];
+ },
+ removeDocumentEventHandler:function(event) {
+ delete documentEventHandlers[event];
+ },
+ /**
+ * Retrieve original event handlers that were replaced by Cordova
+ *
+ * @return object
+ */
+ getOriginalHandlers: function() {
+ return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+ 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+ },
+ /**
+ * Method to fire event from native code
+ * bNoDetach is required for events which cause an exception which needs to be caught in native code
+ */
+ fireDocumentEvent: function(type, data, bNoDetach) {
+ var evt = createEvent(type, data);
+ if (typeof documentEventHandlers[type] != 'undefined') {
+ if( bNoDetach ) {
+ documentEventHandlers[type].fire(evt);
+ }
+ else {
+ setTimeout(function() {
+ // Fire deviceready on listeners that were registered before cordova.js was loaded.
+ if (type == 'deviceready') {
+ document.dispatchEvent(evt);
+ }
+ documentEventHandlers[type].fire(evt);
+ }, 0);
+ }
+ } else {
+ document.dispatchEvent(evt);
+ }
+ },
+ fireWindowEvent: function(type, data) {
+ var evt = createEvent(type,data);
+ if (typeof windowEventHandlers[type] != 'undefined') {
+ setTimeout(function() {
+ windowEventHandlers[type].fire(evt);
+ }, 0);
+ } else {
+ window.dispatchEvent(evt);
+ }
+ },
+
+ /**
+ * Plugin callback mechanism.
+ */
+ // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+ // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+ callbackId: Math.floor(Math.random() * 2000000000),
+ callbacks: {},
+ callbackStatus: {
+ NO_RESULT: 0,
+ OK: 1,
+ CLASS_NOT_FOUND_EXCEPTION: 2,
+ ILLEGAL_ACCESS_EXCEPTION: 3,
+ INSTANTIATION_EXCEPTION: 4,
+ MALFORMED_URL_EXCEPTION: 5,
+ IO_EXCEPTION: 6,
+ INVALID_ACTION: 7,
+ JSON_EXCEPTION: 8,
+ ERROR: 9
+ },
+
+ /**
+ * Called by native code when returning successful result from an action.
+ */
+ callbackSuccess: function(callbackId, args) {
+ try {
+ cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
+ } catch (e) {
+ console.log("Error in error callback: " + callbackId + " = "+e);
+ }
+ },
+
+ /**
+ * Called by native code when returning error result from an action.
+ */
+ callbackError: function(callbackId, args) {
+ // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+ // Derive success from status.
+ try {
+ cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
+ } catch (e) {
+ console.log("Error in error callback: " + callbackId + " = "+e);
+ }
+ },
+
+ /**
+ * Called by native code when returning the result from an action.
+ */
+ callbackFromNative: function(callbackId, success, status, args, keepCallback) {
+ var callback = cordova.callbacks[callbackId];
+ if (callback) {
+ if (success && status == cordova.callbackStatus.OK) {
+ callback.success && callback.success.apply(null, args);
+ } else if (!success) {
+ callback.fail && callback.fail.apply(null, args);
+ }
+
+ // Clear callback if not expecting any more results
+ if (!keepCallback) {
+ delete cordova.callbacks[callbackId];
+ }
+ }
+ },
+ addConstructor: function(func) {
+ channel.onCordovaReady.subscribe(function() {
+ try {
+ func();
+ } catch(e) {
+ console.log("Failed to run constructor: " + e);
+ }
+ });
+ }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/argscheck.js
+define("cordova/argscheck", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+ 'A': 'Array',
+ 'D': 'Date',
+ 'N': 'Number',
+ 'S': 'String',
+ 'F': 'Function',
+ 'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+ return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+ if (!moduleExports.enableChecks) {
+ return;
+ }
+ var errMsg = null;
+ var typeName;
+ for (var i = 0; i < spec.length; ++i) {
+ var c = spec.charAt(i),
+ cUpper = c.toUpperCase(),
+ arg = args[i];
+ // Asterix means allow anything.
+ if (c == '*') {
+ continue;
+ }
+ typeName = utils.typeName(arg);
+ if ((arg === null || arg === undefined) && c == cUpper) {
+ continue;
+ }
+ if (typeName != typeMap[cUpper]) {
+ errMsg = 'Expected ' + typeMap[cUpper];
+ break;
+ }
+ }
+ if (errMsg) {
+ errMsg += ', but got ' + typeName + '.';
+ errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+ // Don't log when running jake test.
+ if (typeof jasmine == 'undefined') {
+ console.error(errMsg);
+ }
+ throw TypeError(errMsg);
+ }
+}
+
+function getValue(value, defaultValue) {
+ return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+ for (var prop in objects) {
+ if (objects.hasOwnProperty(prop)) {
+ func.apply(context, [objects[prop], prop]);
+ }
+ }
+}
+
+function clobber(obj, key, value) {
+ exports.replaceHookForTesting(obj, key);
+ obj[key] = value;
+ // Getters can only be overridden by getters.
+ if (obj[key] !== value) {
+ utils.defineGetter(obj, key, function() {
+ return value;
+ });
+ }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+ if (message) {
+ utils.defineGetter(obj, key, function() {
+ console.log(message);
+ delete obj[key];
+ clobber(obj, key, value);
+ return value;
+ });
+ } else {
+ clobber(obj, key, value);
+ }
+}
+
+function include(parent, objects, clobber, merge) {
+ each(objects, function (obj, key) {
+ try {
+ var result = obj.path ? require(obj.path) : {};
+
+ if (clobber) {
+ // Clobber if it doesn't exist.
+ if (typeof parent[key] === 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else if (typeof obj.path !== 'undefined') {
+ // If merging, merge properties onto parent, otherwise, clobber.
+ if (merge) {
+ recursiveMerge(parent[key], result);
+ } else {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ }
+ }
+ result = parent[key];
+ } else {
+ // Overwrite if not currently defined.
+ if (typeof parent[key] == 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else {
+ // Set result to what already exists, so we can build children into it if they exist.
+ result = parent[key];
+ }
+ }
+
+ if (obj.children) {
+ include(result, obj.children, clobber, merge);
+ }
+ } catch(e) {
+ utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+ }
+ });
+}
+
+/**
+ * Merge properties from one object onto another recursively. Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+ for (var prop in src) {
+ if (src.hasOwnProperty(prop)) {
+ if (target.prototype && target.prototype.constructor === target) {
+ // If the target object is a constructor override off prototype.
+ clobber(target.prototype, prop, src[prop]);
+ } else {
+ if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+ recursiveMerge(target[prop], src[prop]);
+ } else {
+ clobber(target, prop, src[prop]);
+ }
+ }
+ }
+ }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+ include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+ include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+ include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+ nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady* Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady* Internal event fired when device properties are available.
+ * onCordovaConnectionReady* Internal event fired when the connection property has been set.
+ * onDeviceReady* User event fired to indicate that Cordova is ready
+ * onResume User event fired to indicate a start/resume lifecycle event
+ * onPause User event fired to indicate a pause lifecycle event
+ * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ * pause App has moved to background
+ * resume App has returned to foreground
+ *
+ * Listeners can be registered as:
+ * document.addEventListener("deviceready", myDeviceReadyListener, false);
+ * document.addEventListener("resume", myResumeListener, false);
+ * document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ * window.onload
+ * window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type String the channel name
+ */
+var Channel = function(type, sticky) {
+ this.type = type;
+ // Map of guid -> function.
+ this.handlers = {};
+ // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+ this.state = sticky ? 1 : 0;
+ // Used in sticky mode to remember args passed to fire().
+ this.fireArgs = null;
+ // Used by onHasSubscribersChange to know if there are any listeners.
+ this.numHandlers = 0;
+ // Function that is called when the first listener is subscribed, or when
+ // the last listener is unsubscribed.
+ this.onHasSubscribersChange = null;
+},
+ channel = {
+ /**
+ * Calls the provided function only after all of the channels specified
+ * have been fired. All channels must be sticky channels.
+ */
+ join: function(h, c) {
+ var len = c.length,
+ i = len,
+ f = function() {
+ if (!(--i)) h();
+ };
+ for (var j=0; j<len; j++) {
+ if (c[j].state === 0) {
+ throw Error('Can only use join with sticky channels.');
+ }
+ c[j].subscribe(f);
+ }
+ if (!len) h();
+ },
+ create: function(type) {
+ return channel[type] = new Channel(type, false);
+ },
+ createSticky: function(type) {
+ return channel[type] = new Channel(type, true);
+ },
+
+ /**
+ * cordova Channels that must fire before "deviceready" is fired.
+ */
+ deviceReadyChannelsArray: [],
+ deviceReadyChannelsMap: {},
+
+ /**
+ * Indicate that a feature needs to be initialized before it is ready to be used.
+ * This holds up Cordova's "deviceready" event until the feature has been initialized
+ * and Cordova.initComplete(feature) is called.
+ *
+ * @param feature {String} The unique feature name
+ */
+ waitForInitialization: function(feature) {
+ if (feature) {
+ var c = channel[feature] || this.createSticky(feature);
+ this.deviceReadyChannelsMap[feature] = c;
+ this.deviceReadyChannelsArray.push(c);
+ }
+ },
+
+ /**
+ * Indicate that initialization code has completed and the feature is ready to be used.
+ *
+ * @param feature {String} The unique feature name
+ */
+ initializationComplete: function(feature) {
+ var c = this.deviceReadyChannelsMap[feature];
+ if (c) {
+ c.fire();
+ }
+ }
+ };
+
+function forceFunction(f) {
+ if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+ // need a function to call
+ forceFunction(f);
+ if (this.state == 2) {
+ f.apply(c || this, this.fireArgs);
+ return;
+ }
+
+ var func = f,
+ guid = f.observer_guid;
+ if (typeof c == "object") { func = utils.close(c, f); }
+
+ if (!guid) {
+ // first time any channel has seen this subscriber
+ guid = '' + nextGuid++;
+ }
+ func.observer_guid = guid;
+ f.observer_guid = guid;
+
+ // Don't add the same handler more than once.
+ if (!this.handlers[guid]) {
+ this.handlers[guid] = func;
+ this.numHandlers++;
+ if (this.numHandlers == 1) {
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+ // need a function to unsubscribe
+ forceFunction(f);
+
+ var guid = f.observer_guid,
+ handler = this.handlers[guid];
+ if (handler) {
+ delete this.handlers[guid];
+ this.numHandlers--;
+ if (this.numHandlers === 0) {
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+ var fail = false,
+ fireArgs = Array.prototype.slice.call(arguments);
+ // Apply stickiness.
+ if (this.state == 1) {
+ this.state = 2;
+ this.fireArgs = fireArgs;
+ }
+ if (this.numHandlers) {
+ // Copy the values first so that it is safe to modify it from within
+ // callbacks.
+ var toCall = [];
+ for (var item in this.handlers) {
+ toCall.push(this.handlers[item]);
+ }
+ for (var i = 0; i < toCall.length; ++i) {
+ toCall[i].apply(this, fireArgs);
+ }
+ if (this.state == 2 && this.numHandlers) {
+ this.numHandlers = 0;
+ this.handlers = {};
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.createSticky('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.createSticky('onCordovaConnectionReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/commandProxy.js
+define("cordova/commandProxy", function(require, exports, module) {
+
+
+// internal map of proxy function
+var CommandProxyMap = {};
+
+module.exports = {
+
+ // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
+ add:function(id,proxyObj) {
+ console.log("adding proxy for " + id);
+ CommandProxyMap[id] = proxyObj;
+ return proxyObj;
+ },
+
+ // cordova.commandProxy.remove("Accelerometer");
+ remove:function(id) {
+ var proxy = CommandProxyMap[id];
+ delete CommandProxyMap[id];
+ CommandProxyMap[id] = null;
+ return proxy;
+ },
+
+ get:function(service,action) {
+ return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
+ }
+};
+});
+
+// file: lib/windowsphone/exec.js
+define("cordova/exec", function(require, exports, module) {
+
+var cordova = require('cordova');
+
+/**
+ * Execute a cordova command. It is up to the native side whether this action
+ * is synchronous or asynchronous. The native side can return:
+ * Synchronous: PluginResult object as a JSON string
+ * Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success The success callback
+ * @param {Function} fail The fail callback
+ * @param {String} service The name of the service to use
+ * @param {String} action Action to be run in cordova
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+
+ */
+
+module.exports = function(success, fail, service, action, args) {
+
+ var callbackId = service + cordova.callbackId++;
+ if (typeof success == "function" || typeof fail == "function") {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+ // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
+ for(var n = 0; n < args.length; n++)
+ {
+ if(typeof args[n] !== "string")
+ {
+ args[n] = JSON.stringify(args[n]);
+ }
+ }
+ var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
+ // pass it on to Notify
+ try {
+ if(window.external) {
+ window.external.Notify(command);
+ }
+ else {
+ console.log("window.external not available :: command=" + command);
+ }
+ }
+ catch(e) {
+ console.log("Exception calling native with command :: " + command + " :: exception=" + e);
+ }
+};
+
+
+});
+
+// file: lib/common/modulemapper.js
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+ moduleMap = define.moduleMap,
+ symbolList,
+ deprecationMap;
+
+exports.reset = function() {
+ symbolList = [];
+ deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+ if (!(moduleName in moduleMap)) {
+ throw new Error('Module ' + moduleName + ' does not exist.');
+ }
+ 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);
+};
+
+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 symbolPath = symbolList[i + 2];
+ var lastDot = symbolPath.lastIndexOf('.');
+ var namespace = symbolPath.substr(0, lastDot);
+ var lastName = symbolPath.substr(lastDot + 1);
+
+ var module = require(moduleName);
+ 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.loadMatchingModules = function(matchingRegExp) {
+ for (var k in moduleMap) {
+ if (matchingRegExp.exec(k)) {
+ require(k);
+ }
+ }
+};
+
+exports.reset();
+
+
+});
+
+// file: lib/windowsphone/platform.js
+define("cordova/platform", function(require, exports, module) {
+
+var cordova = require('cordova'),
+ exec = require('cordova/exec');
+
+module.exports = {
+ id: "windowsphone",
+ initialize:function() {
+ var modulemapper = require('cordova/modulemapper');
+
+ modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
+
+ modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
+
+ modulemapper.mapModules(window);
+
+ // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
+ var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+ backButtonChannel.onHasSubscribersChange = function() {
+ exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
+ };
+ }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+
+var Acceleration = function(x, y, z, timestamp) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ Camera = require('cordova/plugin/CameraConstants'),
+ CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+ cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+ argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
+ options = options || {};
+ var getValue = argscheck.getValue;
+
+ var quality = getValue(options.quality, 50);
+ var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
+ var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
+ var targetWidth = getValue(options.targetWidth, -1);
+ var targetHeight = getValue(options.targetHeight, -1);
+ var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
+ var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
+ var allowEdit = !!options.allowEdit;
+ var correctOrientation = !!options.correctOrientation;
+ var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
+ var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
+
+ var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
+
+ exec(successCallback, errorCallback, "Camera", "takePicture", args);
+ return new CameraPopoverHandle();
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+ exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+
+module.exports = {
+ DestinationType:{
+ DATA_URL: 0, // Return base64 encoded string
+ FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
+ NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
+ },
+ EncodingType:{
+ JPEG: 0, // Return JPEG encoded image
+ PNG: 1 // Return PNG encoded image
+ },
+ MediaType:{
+ PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+ VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
+ ALLMEDIA : 2 // allow selection from all media types
+ },
+ PictureSourceType:{
+ PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+ CAMERA : 1, // Take picture from camera
+ SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
+ },
+ PopoverArrowDirection:{
+ ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+ ARROW_DOWN : 2,
+ ARROW_LEFT : 4,
+ ARROW_RIGHT : 8,
+ ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
+ }
+};
+
+});
+
+// file: lib/common/plugin/CameraPopoverHandle.js
+define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+/**
+ * A handle to an image picker popover.
+ */
+var CameraPopoverHandle = function() {
+ this.setPosition = function(popoverOptions) {
+ console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
+ };
+};
+
+module.exports = CameraPopoverHandle;
+
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+ // information of rectangle that popover should be anchored to
+ this.x = x || 0;
+ this.y = y || 32;
+ this.width = width || 320;
+ this.height = height || 480;
+ // The direction of the popover arrow
+ this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+ // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+ this.limit = 1;
+ // Maximum duration of a single sound clip in seconds.
+ this.duration = 0;
+};
+
+module.exports = CaptureAudioOptions;
+
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+ this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+ // Upper limit of images user can take. Value must be equal or greater than 1.
+ this.limit = 1;
+};
+
+module.exports = CaptureImageOptions;
+
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+ // Upper limit of videos user can record. Value must be equal or greater than 1.
+ this.limit = 1;
+ // Maximum duration of a single video clip in seconds.
+ this.duration = 0;
+};
+
+module.exports = CaptureVideoOptions;
+
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+
+/**
+ * CompassError.
+ * An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var CompassError = function(err) {
+ this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+ this.magneticHeading = magneticHeading;
+ this.trueHeading = trueHeading;
+ this.headingAccuracy = headingAccuracy;
+ this.timestamp = timestamp || new Date().getTime();
+};
+
+module.exports = CompassHeading;
+
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+ // The ASCII-encoded string in lower case representing the media type.
+ this.type = null;
+ // The height attribute represents height of the image or video in pixels.
+ // In the case of a sound clip this attribute has value 0.
+ this.height = 0;
+ // The width attribute represents width of the image or video in pixels.
+ // In the case of a sound clip this attribute has value 0
+ this.width = 0;
+}
+
+module.exports = ConfigurationData;
+
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+
+/**
+ * Network status
+ */
+module.exports = {
+ UNKNOWN: "unknown",
+ ETHERNET: "ethernet",
+ WIFI: "wifi",
+ CELL_2G: "2g",
+ CELL_3G: "3g",
+ CELL_4G: "4g",
+ CELL:"cellular",
+ NONE: "none"
+};
+
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ ContactError = require('cordova/plugin/ContactError'),
+ utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+ var value = contact.birthday;
+ try {
+ contact.birthday = new Date(parseFloat(value));
+ } catch (exception){
+ console.log("Cordova Contact convertIn error: exception creating date.");
+ }
+ return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+ var value = contact.birthday;
+ if (value !== null) {
+ // try to make it a Date object if it is not already
+ if (!utils.isDate(value)){
+ try {
+ value = new Date(value);
+ } catch(exception){
+ value = null;
+ }
+ }
+ if (utils.isDate(value)){
+ value = value.valueOf(); // convert to milliseconds
+ }
+ contact.birthday = value;
+ }
+ return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+ ims, organizations, birthday, note, photos, categories, urls) {
+ this.id = id || null;
+ this.rawId = null;
+ this.displayName = displayName || null;
+ this.name = name || null; // ContactName
+ this.nickname = nickname || null;
+ this.phoneNumbers = phoneNumbers || null; // ContactField[]
+ this.emails = emails || null; // ContactField[]
+ this.addresses = addresses || null; // ContactAddress[]
+ this.ims = ims || null; // ContactField[]
+ this.organizations = organizations || null; // ContactOrganization[]
+ this.birthday = birthday || null;
+ this.note = note || null;
+ this.photos = photos || null; // ContactField[]
+ this.categories = categories || null; // ContactField[]
+ this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+ argscheck.checkArgs('FF', 'Contact.remove', arguments);
+ var fail = errorCB && function(code) {
+ errorCB(new ContactError(code));
+ };
+ if (this.id === null) {
+ fail(ContactError.UNKNOWN_ERROR);
+ }
+ else {
+ exec(successCB, fail, "Contacts", "remove", [this.id]);
+ }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+ var clonedContact = utils.clone(this);
+ clonedContact.id = null;
+ clonedContact.rawId = null;
+
+ function nullIds(arr) {
+ if (arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ arr[i].id = null;
+ }
+ }
+ }
+
+ // Loop through and clear out any id's in phones, emails, etc.
+ nullIds(clonedContact.phoneNumbers);
+ nullIds(clonedContact.emails);
+ nullIds(clonedContact.addresses);
+ nullIds(clonedContact.ims);
+ nullIds(clonedContact.organizations);
+ nullIds(clonedContact.categories);
+ nullIds(clonedContact.photos);
+ nullIds(clonedContact.urls);
+ return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+ argscheck.checkArgs('FFO', 'Contact.save', arguments);
+ var fail = errorCB && function(code) {
+ errorCB(new ContactError(code));
+ };
+ var success = function(result) {
+ if (result) {
+ if (successCB) {
+ var fullContact = require('cordova/plugin/contacts').create(result);
+ successCB(convertIn(fullContact));
+ }
+ }
+ else {
+ // no Entry object returned
+ fail(ContactError.UNKNOWN_ERROR);
+ }
+ };
+ var dupContact = convertOut(utils.clone(this));
+ exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+ this.id = null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+ this.type = type || null;
+ this.formatted = formatted || null;
+ this.streetAddress = streetAddress || null;
+ this.locality = locality || null;
+ this.region = region || null;
+ this.postalCode = postalCode || null;
+ this.country = country || null;
+};
+
+module.exports = ContactAddress;
+
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+
+/**
+ * ContactError.
+ * An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var ContactError = function(err) {
+ this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+ this.id = null;
+ this.type = (type && type.toString()) || null;
+ this.value = (value && value.toString()) || null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+ this.filter = filter || '';
+ this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+ this.formatted = formatted || null;
+ this.familyName = familyName || null;
+ this.givenName = givenName || null;
+ this.middleName = middle || null;
+ this.honorificPrefix = prefix || null;
+ this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+ this.id = null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+ this.type = type || null;
+ this.name = name || null;
+ this.department = dept || null;
+ this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+ /**
+ * The latitude of the position.
+ */
+ this.latitude = lat;
+ /**
+ * The longitude of the position,
+ */
+ this.longitude = lng;
+ /**
+ * The accuracy of the position.
+ */
+ this.accuracy = acc;
+ /**
+ * The altitude of the position.
+ */
+ this.altitude = (alt !== undefined ? alt : null);
+ /**
+ * The direction the device is moving at the position.
+ */
+ this.heading = (head !== undefined ? head : null);
+ /**
+ * The velocity with which the device is moving at the position.
+ */
+ this.speed = (vel !== undefined ? vel : null);
+
+ if (this.speed === 0 || this.speed === null) {
+ this.heading = NaN;
+ }
+
+ /**
+ * The altitude accuracy of the position.
+ */
+ this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ Entry = require('cordova/plugin/Entry'),
+ FileError = require('cordova/plugin/FileError'),
+ DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+ DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+ return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or exclusively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+ argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
+ var win = successCallback && function(result) {
+ var entry = new DirectoryEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or exclusively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+ argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
+ var win = successCallback && function(result) {
+ var FileEntry = require('cordova/plugin/FileEntry');
+ var entry = new FileEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+ this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+ var win = typeof successCallback !== 'function' ? null : function(result) {
+ var retVal = [];
+ for (var i=0; i<result.length; i++) {
+ var entry = null;
+ if (result[i].isDirectory) {
+ entry = new (require('cordova/plugin/DirectoryEntry'))();
+ }
+ else if (result[i].isFile) {
+ entry = new (require('cordova/plugin/FileEntry'))();
+ }
+ entry.isDirectory = result[i].isDirectory;
+ entry.isFile = result[i].isFile;
+ entry.name = result[i].name;
+ entry.fullPath = result[i].fullPath;
+ retVal.push(entry);
+ }
+ successCallback(retVal);
+ };
+ var fail = typeof errorCallback !== 'function' ? null : function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError'),
+ Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ * {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ * {boolean} true if Entry is a directory (readonly)
+ * @param name
+ * {DOMString} name of the file or directory, excluding the path
+ * leading to it (readonly)
+ * @param fullPath
+ * {DOMString} the absolute full path to the file or directory
+ * (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+ this.isFile = !!isFile;
+ this.isDirectory = !!isDirectory;
+ this.name = name || '';
+ this.fullPath = fullPath || '';
+ this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ * {Function} is called with a Metadata object
+ * @param errorCallback
+ * {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
+ var success = successCallback && function(lastModified) {
+ var metadata = new Metadata(lastModified);
+ successCallback(metadata);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+
+ exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ * {Function} is called with a Metadata object
+ * @param errorCallback
+ * {Function} is called with a FileError
+ * @param metadataObject
+ * {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+ argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
+ exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ * {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ * {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ * {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+ argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ // source path
+ var srcPath = this.fullPath,
+ // entry name
+ name = newName || this.name,
+ success = function(entry) {
+ if (entry) {
+ if (successCallback) {
+ // create appropriate Entry object
+ var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+ successCallback(result);
+ }
+ }
+ else {
+ // no Entry object returned
+ fail && fail(FileError.NOT_FOUND_ERR);
+ }
+ };
+
+ // copy
+ exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ * {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ * {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ * {Function} called with the new Entry object
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+ argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+
+ // source path
+ var srcPath = this.fullPath,
+ // entry name
+ name = newName || this.name,
+ // success callback
+ success = function(entry) {
+ if (entry) {
+ if (successCallback) {
+ // create appropriate Entry object
+ var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+ successCallback(result);
+ }
+ }
+ else {
+ // no Entry object returned
+ fail && fail(FileError.NOT_FOUND_ERR);
+ }
+ };
+
+ // copy
+ exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+ // fullPath attribute contains the full URL
+ return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+ console.log("DEPRECATED: Update your code to use 'toURL'");
+ // fullPath attribute contains the full URI
+ return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.remove', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.getParent', arguments);
+ var win = successCallback && function(result) {
+ var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+ var entry = new DirectoryEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+ this.name = name || '';
+ this.fullPath = fullPath || null;
+ this.type = type || null;
+ this.lastModifiedDate = lastModifiedDate || null;
+ this.size = size || 0;
+
+ // These store the absolute start and end for slicing the file.
+ this.start = 0;
+ this.end = this.size;
+};
+
+/**
+ * Returns a "slice" of the file. Since Cordova Files don't contain the actual
+ * content, this really returns a File with adjusted start and end.
+ * Slices of slices are supported.
+ * start {Number} The index at which to start the slice (inclusive).
+ * end {Number} The index at which to end the slice (exclusive).
+ */
+File.prototype.slice = function(start, end) {
+ var size = this.end - this.start;
+ var newStart = 0;
+ var newEnd = size;
+ if (arguments.length) {
+ if (start < 0) {
+ newStart = Math.max(size + start, 0);
+ } else {
+ newStart = Math.min(size, start);
+ }
+ }
+
+ if (arguments.length >= 2) {
+ if (end < 0) {
+ newEnd = Math.max(size + end, 0);
+ } else {
+ newEnd = Math.min(end, size);
+ }
+ }
+
+ var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
+ newFile.start = this.start + newStart;
+ newFile.end = this.start + newEnd;
+ return newFile;
+};
+
+
+module.exports = File;
+
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ Entry = require('cordova/plugin/Entry'),
+ FileWriter = require('cordova/plugin/FileWriter'),
+ File = require('cordova/plugin/File'),
+ FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+ FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+ this.file(function(filePointer) {
+ var writer = new FileWriter(filePointer);
+
+ if (writer.fileName === null || writer.fileName === "") {
+ errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+ } else {
+ successCallback && successCallback(writer);
+ }
+ }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+ var win = successCallback && function(f) {
+ var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+ successCallback(file);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+
+/**
+ * FileError
+ */
+function FileError(error) {
+ this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+ modulemapper = require('cordova/modulemapper'),
+ utils = require('cordova/utils'),
+ File = require('cordova/plugin/File'),
+ FileError = require('cordova/plugin/FileError'),
+ ProgressEvent = require('cordova/plugin/ProgressEvent'),
+ origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ * The root directory is the root of the file system.
+ * To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+ this._readyState = 0;
+ this._error = null;
+ this._result = null;
+ this._fileName = '';
+ this._realReader = origFileReader ? new origFileReader() : {};
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+utils.defineGetter(FileReader.prototype, 'readyState', function() {
+ return this._fileName ? this._readyState : this._realReader.readyState;
+});
+
+utils.defineGetter(FileReader.prototype, 'error', function() {
+ return this._fileName ? this._error: this._realReader.error;
+});
+
+utils.defineGetter(FileReader.prototype, 'result', function() {
+ return this._fileName ? this._result: this._realReader.result;
+});
+
+function defineEvent(eventName) {
+ utils.defineGetterSetter(FileReader.prototype, eventName, function() {
+ return this._realReader[eventName] || null;
+ }, function(value) {
+ this._realReader[eventName] = value;
+ });
+}
+defineEvent('onloadstart'); // When the read starts.
+defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
+defineEvent('onload'); // When the read has successfully completed.
+defineEvent('onerror'); // When the read has failed (see errors).
+defineEvent('onloadend'); // When the request has completed (either in success or failure).
+defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
+
+function initRead(reader, file) {
+ // Already loading something
+ if (reader.readyState == FileReader.LOADING) {
+ throw new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ reader._result = null;
+ reader._error = null;
+ reader._readyState = FileReader.LOADING;
+
+ if (typeof file == 'string') {
+ // Deprecated in Cordova 2.4.
+ console.warn('Using a string argument with FileReader.readAs functions is deprecated.');
+ reader._fileName = file;
+ } else if (typeof file.fullPath == 'string') {
+ reader._fileName = file.fullPath;
+ } else {
+ reader._fileName = '';
+ return true;
+ }
+
+ reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
+}
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+ if (origFileReader && !this._fileName) {
+ return this._realReader.abort();
+ }
+ this._result = null;
+
+ if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
+ return;
+ }
+
+ this._readyState = FileReader.DONE;
+
+ // If abort callback
+ if (typeof this.onabort === 'function') {
+ this.onabort(new ProgressEvent('abort', {target:this}));
+ }
+ // If load end callback
+ if (typeof this.onloadend === 'function') {
+ this.onloadend(new ProgressEvent('loadend', {target:this}));
+ }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file {File} File object containing file properties
+ * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsText(file, encoding);
+ }
+
+ // Default encoding is UTF-8
+ var enc = encoding ? encoding : "UTF-8";
+ var me = this;
+ var execArgs = [this._fileName, enc, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // Save result
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // null result
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsText", execArgs);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ * data:[<mediatype>][;base64],<data>
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsDataURL(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // Save result
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsDataURL", execArgs);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsBinaryString(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsArrayBuffer(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
+};
+
+module.exports = FileReader;
+
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+ this.name = name || null;
+ if (root) {
+ this.root = new DirectoryEntry(root.name, root.fullPath);
+ }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ FileTransferError = require('cordova/plugin/FileTransferError'),
+ ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+function newProgressEvent(result) {
+ var pe = new ProgressEvent();
+ pe.lengthComputable = result.lengthComputable;
+ pe.loaded = result.loaded;
+ pe.total = result.total;
+ return pe;
+}
+
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) !== 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
+var idCounter = 0;
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {
+ this._id = ++idCounter;
+ this.onprogress = null; // optional callback
+};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String} Full path of the file on the device
+* @param server {String} URL of the server to receive the file
+* @param successCallback (Function} Callback to be invoked when upload has completed
+* @param errorCallback {Function} Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+ argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
+ // check for options
+ var fileKey = null;
+ var fileName = null;
+ var mimeType = null;
+ var params = null;
+ var chunkedMode = true;
+ var headers = null;
+ var httpMethod = null;
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ if (options) {
+ fileKey = options.fileKey;
+ fileName = options.fileName;
+ mimeType = options.mimeType;
+ headers = options.headers;
+ httpMethod = options.httpMethod || "POST";
+ if (httpMethod.toUpperCase() == "PUT"){
+ httpMethod = "PUT";
+ } else {
+ httpMethod = "POST";
+ }
+ if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+ chunkedMode = options.chunkedMode;
+ }
+ if (options.params) {
+ params = options.params;
+ }
+ else {
+ params = {};
+ }
+ }
+
+ var fail = errorCallback && function(e) {
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
+ errorCallback(error);
+ };
+
+ var self = this;
+ var win = function(result) {
+ if (typeof result.lengthComputable != "undefined") {
+ if (self.onprogress) {
+ self.onprogress(newProgressEvent(result));
+ }
+ } else {
+ successCallback && successCallback(result);
+ }
+ };
+ exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String} URL of the server to receive the file
+ * @param target {String} Full path of the file on the device
+ * @param successCallback (Function} Callback to be invoked when upload has completed
+ * @param errorCallback {Function} Callback to be invoked upon error
+ * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ * @param options {FileDownloadOptions} Optional parameters such as headers
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
+ argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
+ var self = this;
+
+ var basicAuthHeader = getBasicAuthHeader(source);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ var headers = null;
+ if (options) {
+ headers = options.headers || null;
+ }
+
+ var win = function(result) {
+ if (typeof result.lengthComputable != "undefined") {
+ if (self.onprogress) {
+ return self.onprogress(newProgressEvent(result));
+ }
+ } else if (successCallback) {
+ var entry = null;
+ if (result.isDirectory) {
+ entry = new (require('cordova/plugin/DirectoryEntry'))();
+ }
+ else if (result.isFile) {
+ entry = new (require('cordova/plugin/FileEntry'))();
+ }
+ entry.isDirectory = result.isDirectory;
+ entry.isFile = result.isFile;
+ entry.name = result.name;
+ entry.fullPath = result.fullPath;
+ successCallback(entry);
+ }
+ };
+
+ var fail = errorCallback && function(e) {
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
+ errorCallback(error);
+ };
+
+ exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
+};
+
+/**
+ * Aborts the ongoing file transfer on this object. The original error
+ * callback for the file transfer will be called if necessary.
+ */
+FileTransfer.prototype.abort = function() {
+ exec(null,
<TRUNCATED>
[50/50] [abbrv] git commit: both modified
Posted by pu...@apache.org.
both modified
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/d1ecfbcc
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/d1ecfbcc
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/d1ecfbcc
Branch: refs/heads/2.9.x
Commit: d1ecfbcc904f99f7cab161ec9b436ea120c43160
Parents: 61570af 3503e45
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 16:57:55 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 16:57:55 2013 -0700
----------------------------------------------------------------------
----------------------------------------------------------------------
[44/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/File.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/File.cs b/common-items/Plugins/File.cs
deleted file mode 100644
index cde7a1c..0000000
--- a/common-items/Plugins/File.cs
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to isolated storage
- /// </summary>
- public class File : BaseCommand
- {
- // Error codes
- public const int NOT_FOUND_ERR = 1;
- public const int SECURITY_ERR = 2;
- public const int ABORT_ERR = 3;
- public const int NOT_READABLE_ERR = 4;
- public const int ENCODING_ERR = 5;
- public const int NO_MODIFICATION_ALLOWED_ERR = 6;
- public const int INVALID_STATE_ERR = 7;
- public const int SYNTAX_ERR = 8;
- public const int INVALID_MODIFICATION_ERR = 9;
- public const int QUOTA_EXCEEDED_ERR = 10;
- public const int TYPE_MISMATCH_ERR = 11;
- public const int PATH_EXISTS_ERR = 12;
-
- // File system options
- public const int TEMPORARY = 0;
- public const int PERSISTENT = 1;
- public const int RESOURCE = 2;
- public const int APPLICATION = 3;
-
- /// <summary>
- /// Temporary directory name
- /// </summary>
- private readonly string TMP_DIRECTORY_NAME = "tmp";
-
- /// <summary>
- /// Represents error code for callback
- /// </summary>
- [DataContract]
- public class ErrorCode
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(IsRequired = true, Name = "code")]
- public int Code { get; set; }
-
- /// <summary>
- /// Creates ErrorCode object
- /// </summary>
- public ErrorCode(int code)
- {
- this.Code = code;
- }
- }
-
- /// <summary>
- /// Represents File action options.
- /// </summary>
- [DataContract]
- public class FileOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- ///
- private string _fileName;
- [DataMember(Name = "fileName")]
- public string FilePath
- {
- get
- {
- return this._fileName;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._fileName = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Full entryPath
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// Directory name
- /// </summary>
- [DataMember(Name = "dirName")]
- public string DirectoryName { get; set; }
-
- /// <summary>
- /// Path to create file/directory
- /// </summary>
- [DataMember(Name = "path")]
- public string Path { get; set; }
-
- /// <summary>
- /// The encoding to use to encode the file's content. Default is UTF8.
- /// </summary>
- [DataMember(Name = "encoding")]
- public string Encoding { get; set; }
-
- /// <summary>
- /// Uri to get file
- /// </summary>
- ///
- private string _uri;
- [DataMember(Name = "uri")]
- public string Uri
- {
- get
- {
- return this._uri;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._uri = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Size to truncate file
- /// </summary>
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- /// <summary>
- /// Data to write in file
- /// </summary>
- [DataMember(Name = "data")]
- public string Data { get; set; }
-
- /// <summary>
- /// Position the writing starts with
- /// </summary>
- [DataMember(Name = "position")]
- public int Position { get; set; }
-
- /// <summary>
- /// Type of file system requested
- /// </summary>
- [DataMember(Name = "type")]
- public int FileSystemType { get; set; }
-
- /// <summary>
- /// New file/directory name
- /// </summary>
- [DataMember(Name = "newName")]
- public string NewName { get; set; }
-
- /// <summary>
- /// Destination directory to copy/move file/directory
- /// </summary>
- [DataMember(Name = "parent")]
- public string Parent { get; set; }
-
- /// <summary>
- /// Options for getFile/getDirectory methods
- /// </summary>
- [DataMember(Name = "options")]
- public CreatingOptions CreatingOpt { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public FileOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Encoding = "UTF-8";
- this.FilePath = "";
- this.FileSystemType = -1;
- }
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class FileMetadata
- {
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public FileMetadata(string filePath)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- else if (!isoFile.FileExists(filePath))
- {
- // attempt to get it from the resources
- if (filePath.IndexOf("www") == 0)
- {
- Uri fileUri = new Uri(filePath, UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- this.Size = streamInfo.Stream.Length;
- this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
- this.FullPath = filePath;
- }
- }
- else
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- }
- else
- {
- //TODO get file size the other way if possible
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
- {
- this.Size = stream.Length;
- }
- this.FullPath = filePath;
- this.FileName = System.IO.Path.GetFileName(filePath);
- this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- }
- this.Type = MimeTypeMapper.GetMimeType(this.FileName);
- }
- }
- }
-
- /// <summary>
- /// Represents file or directory modification metadata
- /// </summary>
- [DataContract]
- public class ModificationMetadata
- {
- /// <summary>
- /// Modification time
- /// </summary>
- [DataMember]
- public string modificationTime { get; set; }
- }
-
- /// <summary>
- /// Represents file or directory entry
- /// </summary>
- [DataContract]
- public class FileEntry
- {
-
- /// <summary>
- /// File type
- /// </summary>
- [DataMember(Name = "isFile")]
- public bool IsFile { get; set; }
-
- /// <summary>
- /// Directory type
- /// </summary>
- [DataMember(Name = "isDirectory")]
- public bool IsDirectory { get; set; }
-
- /// <summary>
- /// File/directory name
- /// </summary>
- [DataMember(Name = "name")]
- public string Name { get; set; }
-
- /// <summary>
- /// Full path to file/directory
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- public bool IsResource { get; set; }
-
- public static FileEntry GetEntry(string filePath, bool bIsRes=false)
- {
- FileEntry entry = null;
- try
- {
- entry = new FileEntry(filePath, bIsRes);
-
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
- }
- return entry;
- }
-
- /// <summary>
- /// Creates object and sets necessary properties
- /// </summary>
- /// <param name="filePath"></param>
- public FileEntry(string filePath, bool bIsRes = false)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new ArgumentException();
- }
-
- if(filePath.Contains(" "))
- {
- Debug.WriteLine("FilePath with spaces :: " + filePath);
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- IsResource = bIsRes;
- IsFile = isoFile.FileExists(filePath);
- IsDirectory = isoFile.DirectoryExists(filePath);
- if (IsFile)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else if (IsDirectory)
- {
- this.Name = this.GetDirectoryName(filePath);
- if (string.IsNullOrEmpty(Name))
- {
- this.Name = "/";
- }
- }
- else
- {
- if (IsResource)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else
- {
- throw new FileNotFoundException();
- }
- }
-
- try
- {
- this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
- }
- catch (Exception)
- {
- this.FullPath = filePath;
- }
- }
- }
-
- /// <summary>
- /// Extracts directory name from path string
- /// Path should refer to a directory, for example \foo\ or /foo.
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- private string GetDirectoryName(string path)
- {
- if (String.IsNullOrEmpty(path))
- {
- return path;
- }
-
- string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
- if (split.Length < 1)
- {
- return null;
- }
- else
- {
- return split[split.Length - 1];
- }
- }
- }
-
-
- /// <summary>
- /// Represents info about requested file system
- /// </summary>
- [DataContract]
- public class FileSystemInfo
- {
- /// <summary>
- /// file system type
- /// </summary>
- [DataMember(Name = "name", IsRequired = true)]
- public string Name { get; set; }
-
- /// <summary>
- /// Root directory entry
- /// </summary>
- [DataMember(Name = "root", EmitDefaultValue = false)]
- public FileEntry Root { get; set; }
-
- /// <summary>
- /// Creates class instance
- /// </summary>
- /// <param name="name"></param>
- /// <param name="rootEntry"> Root directory</param>
- public FileSystemInfo(string name, FileEntry rootEntry = null)
- {
- Name = name;
- Root = rootEntry;
- }
- }
-
- [DataContract]
- public class CreatingOptions
- {
- /// <summary>
- /// Create file/directory if is doesn't exist
- /// </summary>
- [DataMember(Name = "create")]
- public bool Create { get; set; }
-
- /// <summary>
- /// Generate an exception if create=true and file/directory already exists
- /// </summary>
- [DataMember(Name = "exclusive")]
- public bool Exclusive { get; set; }
-
-
- }
-
- // returns null value if it fails.
- private string[] getOptionStrings(string options)
- {
- string[] optStings = null;
- try
- {
- optStings = JSON.JsonHelper.Deserialize<string[]>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
- }
- return optStings;
- }
-
- /// <summary>
- /// Gets amount of free space available for Isolated Storage
- /// </summary>
- /// <param name="options">No options is needed for this method</param>
- public void getFreeDiskSpace(string options)
- {
- string callbackId = getOptionStrings(options)[0];
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Check if file exists
- /// </summary>
- /// <param name="options">File path</param>
- public void testFileExists(string options)
- {
- IsDirectoryOrFileExist(options, false);
- }
-
- /// <summary>
- /// Check if directory exists
- /// </summary>
- /// <param name="options">directory name</param>
- public void testDirectoryExists(string options)
- {
- IsDirectoryOrFileExist(options, true);
- }
-
- /// <summary>
- /// Check if file or directory exist
- /// </summary>
- /// <param name="options">File path/Directory name</param>
- /// <param name="isDirectory">Flag to recognize what we should check</param>
- public void IsDirectoryOrFileExist(string options, bool isDirectory)
- {
- string[] args = getOptionStrings(options);
- string callbackId = args[1];
- FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
- string filePath = args[0];
-
- if (fileOptions == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isExist;
- if (isDirectory)
- {
- isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
- }
- else
- {
- isExist = isoFile.FileExists(fileOptions.FilePath);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
- }
- }
- catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
-
- public void readAsDataURL(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- if (filePath != null)
- {
- try
- {
- string base64URL = null;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string mimeType = MimeTypeMapper.GetMimeType(filePath);
-
- using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- string base64String = GetFileContent(stream);
- base64URL = "data:" + mimeType + ";base64," + base64String;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- public void readAsArrayBuffer(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsBinaryString(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- string encStr = optStrings[1];
- int startPos = int.Parse(optStrings[2]);
- int endPos = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- string text = "";
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- readResourceAsText(options);
- return;
- }
- Encoding encoding = Encoding.GetEncoding(encStr);
-
- using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
- {
- text = reader.ReadToEnd();
- if (startPos < 0)
- {
- startPos = Math.Max(text.Length + startPos, 0);
- }
- else if (startPos > 0)
- {
- startPos = Math.Min(text.Length, startPos);
- }
-
- if (endPos > 0)
- {
- endPos = Math.Min(text.Length, endPos);
- }
- else if (endPos < 0)
- {
- endPos = Math.Max(endPos + text.Length, 0);
- }
-
-
- text = text.Substring(startPos, endPos - startPos);
-
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Reads application resource as a text
- /// </summary>
- /// <param name="options">Path to a resource</param>
- public void readResourceAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string pathToResource = optStrings[0];
- string encStr = optStrings[1];
- int start = int.Parse(optStrings[2]);
- int endMarker = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- if (pathToResource.StartsWith("/"))
- {
- pathToResource = pathToResource.Remove(0, 1);
- }
-
- var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
-
- if (resource == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string text;
- StreamReader streamReader = new StreamReader(resource.Stream);
- text = streamReader.ReadToEnd();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- public void truncate(string options)
- {
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- int size = int.Parse(optStrings[1]);
- string callbackId = optStrings[2];
-
- try
- {
- long streamLength = 0;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= size && size <= stream.Length)
- {
- stream.SetLength(size);
- }
- streamLength = stream.Length;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- //write:["filePath","data","position"],
- public void write(string options)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- string data = optStrings[1];
- int position = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- try
- {
- if (string.IsNullOrEmpty(data))
- {
- Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(filePath))
- {
- var file = isoFile.CreateFile(filePath);
- file.Close();
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= position && position <= stream.Length)
- {
- stream.SetLength(position);
- }
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- writer.Seek(0, SeekOrigin.End);
- writer.Write(data.ToCharArray());
- }
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Look up metadata about this entry.
- /// </summary>
- /// <param name="options">filePath to entry</param>
- public void getMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
- new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
- }
- else if (isoFile.DirectoryExists(filePath))
- {
- string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- }
-
-
- /// <summary>
- /// Returns a File that represents the current state of the file that this FileEntry represents.
- /// </summary>
- /// <param name="filePath">filePath to entry</param>
- /// <returns></returns>
- public void getFileMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- FileMetadata metaData = new FileMetadata(filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- /// <summary>
- /// Look up the parent DirectoryEntry containing this Entry.
- /// If this Entry is the root of IsolatedStorage, its parent is itself.
- /// </summary>
- /// <param name="options"></param>
- public void getParent(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- FileEntry entry;
-
- if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
- {
-
-
- string path = this.GetParentDirectory(filePath);
- entry = FileEntry.GetEntry(path);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
-
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- }
-
- public void remove(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (filePath == "/" || filePath == "" || filePath == @"\")
- {
- throw new Exception("Cannot delete root file system") ;
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- else
- {
- if (isoFile.DirectoryExists(filePath))
- {
- isoFile.DeleteDirectory(filePath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- return;
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void removeRecursively(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- }
- else
- {
- if (removeDirRecursively(filePath, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- }
- }
- }
-
- public void readEntries(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(filePath))
- {
- string path = File.AddSlashToDirectory(filePath);
- List<FileEntry> entries = new List<FileEntry>();
- string[] files = isoFile.GetFileNames(path + "*");
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- foreach (string file in files)
- {
- entries.Add(FileEntry.GetEntry(path + file));
- }
- foreach (string dir in dirs)
- {
- entries.Add(FileEntry.GetEntry(path + dir + "/"));
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void requestFileSystem(string options)
- {
- // TODO: try/catch
- string[] optVals = getOptionStrings(options);
- //FileOptions fileOptions = new FileOptions();
- int fileSystemType = int.Parse(optVals[0]);
- double size = double.Parse(optVals[1]);
- string callbackId = optVals[2];
-
-
- IsolatedStorageFile.GetUserStoreForApplication();
-
- if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
-
- try
- {
- if (size != 0)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- long availableSize = isoFile.AvailableFreeSpace;
- if (size > availableSize)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
- }
- }
-
- if (fileSystemType == PERSISTENT)
- {
- // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
- }
- else if (fileSystemType == TEMPORARY)
- {
- using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
- {
- isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
- }
- }
-
- string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
- }
- else if (fileSystemType == RESOURCE)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
- }
- else if (fileSystemType == APPLICATION)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- public void resolveLocalFileSystemURI(string options)
- {
-
- string[] optVals = getOptionStrings(options);
- string uri = optVals[0].Split('?')[0];
- string callbackId = optVals[1];
-
- if (uri != null)
- {
- // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
- if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
- try
- {
- // fix encoded spaces
- string path = Uri.UnescapeDataString(uri);
-
- FileEntry uriEntry = FileEntry.GetEntry(path);
- if (uriEntry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
- }
-
- public void copyTo(string options)
- {
- TransferTo(options, false);
- }
-
- public void moveTo(string options)
- {
- TransferTo(options, true);
- }
-
- public void getFile(string options)
- {
- GetFileOrDirectory(options, false);
- }
-
- public void getDirectory(string options)
- {
- GetFileOrDirectory(options, true);
- }
-
- #region internal functionality
-
- /// <summary>
- /// Retrieves the parent directory name of the specified path,
- /// </summary>
- /// <param name="path">Path</param>
- /// <returns>Parent directory name</returns>
- private string GetParentDirectory(string path)
- {
- if (String.IsNullOrEmpty(path) || path == "/")
- {
- return "/";
- }
-
- if (path.EndsWith(@"/") || path.EndsWith(@"\"))
- {
- return this.GetParentDirectory(Path.GetDirectoryName(path));
- }
-
- string result = Path.GetDirectoryName(path);
- if (result == null)
- {
- result = "/";
- }
-
- return result;
- }
-
- private bool removeDirRecursively(string fullPath,string callbackId)
- {
- try
- {
- if (fullPath == "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(fullPath))
- {
- string tempPath = File.AddSlashToDirectory(fullPath);
- string[] files = isoFile.GetFileNames(tempPath + "*");
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.DeleteFile(tempPath + file);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- if (!removeDirRecursively(tempPath + dir, callbackId))
- {
- return false;
- }
- }
- }
- isoFile.DeleteDirectory(fullPath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
- }
- return true;
- }
-
- private bool CanonicalCompare(string pathA, string pathB)
- {
- string a = pathA.Replace("//", "/");
- string b = pathB.Replace("//", "/");
-
- return a.Equals(b, StringComparison.OrdinalIgnoreCase);
- }
-
- /*
- * copyTo:["fullPath","parent", "newName"],
- * moveTo:["fullPath","parent", "newName"],
- */
- private void TransferTo(string options, bool move)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
- string fullPath = optStrings[0];
- string parent = optStrings[1];
- string newFileName = optStrings[2];
- string callbackId = optStrings[3];
-
- char[] invalids = Path.GetInvalidPathChars();
-
- if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string parentPath = File.AddSlashToDirectory(parent);
- string currentPath = fullPath;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFileExist = isoFile.FileExists(currentPath);
- bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
- bool isParentExist = isoFile.DirectoryExists(parentPath);
-
- if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string newName;
- string newPath;
- if (isFileExist)
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? Path.GetFileName(currentPath)
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- // sanity check ..
- // cannot copy file onto itself
- if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.DirectoryExists(newPath))
- {
- // there is already a folder with the same name, operation is not allowed
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.FileExists(newPath))
- { // remove destination file if exists, in other case there will be exception
- isoFile.DeleteFile(newPath);
- }
-
- if (move)
- {
- isoFile.MoveFile(currentPath, newPath);
- }
- else
- {
- isoFile.CopyFile(currentPath, newPath, true);
- }
- }
- else
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? currentPath
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- if (move)
- {
- // remove destination directory if exists, in other case there will be exception
- // target directory should be empty
- if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
- {
- isoFile.DeleteDirectory(newPath);
- }
-
- isoFile.MoveDirectory(currentPath, newPath);
- }
- else
- {
- CopyDirectory(currentPath, newPath, isoFile);
- }
- }
- FileEntry entry = FileEntry.GetEntry(newPath);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private bool HandleException(Exception ex, string cbId="")
- {
- bool handled = false;
- string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
- if (ex is SecurityException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
- handled = true;
- }
- else if (ex is FileNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- else if (ex is ArgumentException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- handled = true;
- }
- else if (ex is IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- handled = true;
- }
- else if (ex is DirectoryNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- return handled;
- }
-
- private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
- {
- string path = File.AddSlashToDirectory(sourceDir);
-
- bool bExists = isoFile.DirectoryExists(destDir);
-
- if (!bExists)
- {
- isoFile.CreateDirectory(destDir);
- }
-
- destDir = File.AddSlashToDirectory(destDir);
-
- string[] files = isoFile.GetFileNames(path + "*");
-
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.CopyFile(path + file, destDir + file,true);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- CopyDirectory(path + dir, destDir + dir, isoFile);
- }
- }
- }
-
- private void GetFileOrDirectory(string options, bool getDirectory)
- {
- FileOptions fOptions = new FileOptions();
- string[] args = getOptionStrings(options);
-
- fOptions.FullPath = args[0];
- fOptions.Path = args[1];
-
- string callbackId = args[3];
-
- try
- {
- fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- try
- {
- if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string path;
-
- if (fOptions.Path.Split(':').Length > 2)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFile = isoFile.FileExists(path);
- bool isDirectory = isoFile.DirectoryExists(path);
- bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
- bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
- if (create)
- {
- if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
- return;
- }
-
- // need to make sure the parent exists
- // it is an error to create a directory whose immediate parent does not yet exist
- // see issue: https://issues.apache.org/jira/browse/CB-339
- string[] pathParts = path.Split('/');
- string builtPath = pathParts[0];
- for (int n = 1; n < pathParts.Length - 1; n++)
- {
- builtPath += "/" + pathParts[n];
- if (!isoFile.DirectoryExists(builtPath))
- {
- Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- }
-
- if ((getDirectory) && (!isDirectory))
- {
- isoFile.CreateDirectory(path);
- }
- else
- {
- if ((!getDirectory) && (!isFile))
- {
-
- IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
- fileStream.Close();
- }
- }
- }
- else // (not create)
- {
- if ((!isFile) && (!isDirectory))
- {
- if (path.IndexOf("//www") == 0)
- {
- Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
-
- //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
- //{
- // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
-
- //}
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- return;
- }
- if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
- return;
- }
- }
- FileEntry entry = FileEntry.GetEntry(path);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private static string AddSlashToDirectory(string dirPath)
- {
- if (dirPath.EndsWith("/"))
- {
- return dirPath;
- }
- else
- {
- return dirPath + "/";
- }
- }
-
- /// <summary>
- /// Returns file content in a form of base64 string
- /// </summary>
- /// <param name="stream">File stream</param>
- /// <returns>Base64 representation of the file</returns>
- private string GetFileContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
-
- #endregion
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/FileTransfer.cs b/common-items/Plugins/FileTransfer.cs
deleted file mode 100644
index e585895..0000000
--- a/common-items/Plugins/FileTransfer.cs
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Net;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Security;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class FileTransfer : BaseCommand
- {
- public class DownloadRequestState
- {
- // This class stores the State of the request.
- public HttpWebRequest request;
- public DownloadOptions options;
-
- public DownloadRequestState()
- {
- request = null;
- options = null;
- }
- }
-
- /// <summary>
- /// Boundary symbol
- /// </summary>
- private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
-
- // Error codes
- public const int FileNotFoundError = 1;
- public const int InvalidUrlError = 2;
- public const int ConnectionError = 3;
-
- /// <summary>
- /// Options for downloading file
- /// </summary>
- [DataContract]
- public class DownloadOptions
- {
- /// <summary>
- /// File path to download to
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address to the file to download
- /// </summary>
- [DataMember(Name = "url", IsRequired = true)]
- public string Url { get; set; }
- }
-
- /// <summary>
- /// Options for uploading file
- /// </summary>
- [DataContract]
- public class UploadOptions
- {
- /// <summary>
- /// File path to upload
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address
- /// </summary>
- [DataMember(Name = "server", IsRequired = true)]
- public string Server { get; set; }
-
- /// <summary>
- /// File key
- /// </summary>
- [DataMember(Name = "fileKey")]
- public string FileKey { get; set; }
-
- /// <summary>
- /// File name on the server
- /// </summary>
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- /// <summary>
- /// File Mime type
- /// </summary>
- [DataMember(Name = "mimeType")]
- public string MimeType { get; set; }
-
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "params")]
- public string Params { get; set; }
-
- /// <summary>
- /// Flag to recognize if we should trust every host (only in debug environments)
- /// </summary>
- [DataMember(Name = "debug")]
- public bool Debug { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public UploadOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.FileKey = "file";
- this.FileName = "image.jpg";
- this.MimeType = "image/jpeg";
- }
-
- }
-
- /// <summary>
- /// Uploading response info
- /// </summary>
- [DataContract]
- public class FileUploadResult
- {
- /// <summary>
- /// Amount of sent bytes
- /// </summary>
- [DataMember(Name = "bytesSent")]
- public long BytesSent { get; set; }
-
- /// <summary>
- /// Server response code
- /// </summary>
- [DataMember(Name = "responseCode")]
- public long ResponseCode { get; set; }
-
- /// <summary>
- /// Server response
- /// </summary>
- [DataMember(Name = "response", EmitDefaultValue = false)]
- public string Response { get; set; }
-
- /// <summary>
- /// Creates FileUploadResult object with response values
- /// </summary>
- /// <param name="bytesSent">Amount of sent bytes</param>
- /// <param name="responseCode">Server response code</param>
- /// <param name="response">Server response</param>
- public FileUploadResult(long bytesSent, long responseCode, string response)
- {
- this.BytesSent = bytesSent;
- this.ResponseCode = responseCode;
- this.Response = response;
- }
- }
-
- /// <summary>
- /// Represents transfer error codes for callback
- /// </summary>
- [DataContract]
- public class FileTransferError
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = true)]
- public int Code { get; set; }
-
- /// <summary>
- /// The source URI
- /// </summary>
- [DataMember(Name = "source", IsRequired = true)]
- public string Source { get; set; }
-
- /// <summary>
- /// The target URI
- /// </summary>
- [DataMember(Name = "target", IsRequired = true)]
- public string Target { get; set; }
-
- /// <summary>
- /// The http status code response from the remote URI
- /// </summary>
- [DataMember(Name = "http_status", IsRequired = true)]
- public int HttpStatus { get; set; }
-
- /// <summary>
- /// Creates FileTransferError object
- /// </summary>
- /// <param name="errorCode">Error code</param>
- public FileTransferError(int errorCode)
- {
- this.Code = errorCode;
- this.Source = null;
- this.Target = null;
- this.HttpStatus = 0;
- }
- public FileTransferError(int errorCode, string source, string target, int status)
- {
- this.Code = errorCode;
- this.Source = source;
- this.Target = target;
- this.HttpStatus = status;
- }
- }
-
- /// <summary>
- /// Upload options
- /// </summary>
- private UploadOptions uploadOptions;
-
- /// <summary>
- /// Bytes sent
- /// </summary>
- private long bytesSent;
-
- /// <summary>
- /// sends a file to a server
- /// </summary>
- /// <param name="options">Upload options</param>
- public void upload(string options)
- {
- Debug.WriteLine("options = " + options);
- options = options.Replace("{}", "null");
-
- try
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Uri serverUri;
- try
- {
- serverUri = new Uri(uploadOptions.Server);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
- return;
- }
- HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
- webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
- webRequest.Method = "POST";
- webRequest.BeginGetRequestStream(WriteCallback, webRequest);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
-
- public void download(string options)
- {
- DownloadOptions downloadOptions = null;
- HttpWebRequest webRequest = null;
-
- try
- {
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-
- downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
- downloadOptions.Url = optionStrings[0];
- downloadOptions.FilePath = optionStrings[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
- return;
- }
-
- if (downloadOptions != null && webRequest != null)
- {
- DownloadRequestState state = new DownloadRequestState();
- state.options = downloadOptions;
- state.request = webRequest;
- webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
- }
-
-
-
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void downloadCallback(IAsyncResult asynchronousResult)
- {
- DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
- HttpWebRequest request = reqState.request;
-
- try
- {
- HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(reqState.options.FilePath))
- {
- var file = isoFile.CreateFile(reqState.options.FilePath);
- file.Close();
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
- {
- long totalBytes = response.ContentLength;
- int bytesRead = 0;
- using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
- {
-
- using (BinaryWriter writer = new BinaryWriter(fileStream))
- {
- int BUFFER_SIZE = 1024;
- byte[] buffer;
-
- while (true)
- {
- buffer = reader.ReadBytes(BUFFER_SIZE);
- // fire a progress event ?
- bytesRead += buffer.Length;
- if (buffer.Length > 0)
- {
- writer.Write(buffer);
- }
- else
- {
- writer.Close();
- reader.Close();
- fileStream.Close();
- break;
- }
- }
- }
-
- }
-
-
- }
- }
- WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
- }
- catch (IsolatedStorageException)
- {
- // Trying to write the file somewhere within the IsoStorage.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (SecurityException)
- {
- // Trying to write the file somewhere not allowed.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (WebException webex)
- {
- // TODO: probably need better work here to properly respond with all http status codes back to JS
- // Right now am jumping through hoops just to detect 404.
- if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
- {
- // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
- // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
- // FACEPALM
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- }
-
-
-
- /// <summary>
- /// Read file from Isolated Storage and sends it to server
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void WriteCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
- {
- string lineStart = "--";
- string lineEnd = Environment.NewLine;
- byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
- string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
-
- if (uploadOptions.Params != null)
- {
-
- string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
-
- foreach (string param in arrParams)
- {
- string[] split = param.Split('=');
- string key = split[0];
- string val = split[1];
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- string formItem = string.Format(formdataTemplate, key, val);
- byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
- requestStream.Write(formItemBytes, 0, formItemBytes.Length);
- }
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(uploadOptions.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
- return;
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
- {
- string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
- string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
- byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- requestStream.Write(headerBytes, 0, headerBytes.Length);
- byte[] buffer = new byte[4096];
- int bytesRead = 0;
-
- while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
- {
- requestStream.Write(buffer, 0, bytesRead);
- bytesSent += bytesRead;
- }
- }
- byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
- requestStream.Write(endRequest, 0, endRequest.Length);
- }
- }
- webRequest.BeginGetResponse(ReadCallback, webRequest);
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- });
- }
- }
-
- /// <summary>
- /// Reads response into FileUploadResult
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void ReadCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
- {
- using (Stream streamResponse = response.GetResponseStream())
- {
- using (StreamReader streamReader = new StreamReader(streamResponse))
- {
- string responseString = streamReader.ReadToEnd();
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
- });
- }
- }
- }
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
- });
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/GeoLocation.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/GeoLocation.cs b/common-items/Plugins/GeoLocation.cs
deleted file mode 100644
index c53cb29..0000000
--- a/common-items/Plugins/GeoLocation.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Device.Location;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
- /// </summary>
- public class GeoLocation
- {
- /* Unreachable code, by design -jm */
- private void triggerGeoInclusion()
- {
- new GeoCoordinateWatcher();
- }
- }
-}
[03/50] [abbrv] git commit: script cleanup
Posted by pu...@apache.org.
script cleanup
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/df40aaf2
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/df40aaf2
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/df40aaf2
Branch: refs/heads/2.9.x
Commit: df40aaf21f7ab0e62fea4f8a547522d9695e66e2
Parents: 57b876f
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 12:20:38 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 12:20:38 2013 -0700
----------------------------------------------------------------------
wp7/tooling/scripts/dist.js | 40 ++++++++++++++++++++---------------
wp7/tooling/scripts/reversion.js | 11 +---------
2 files changed, 24 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/df40aaf2/wp7/tooling/scripts/dist.js
----------------------------------------------------------------------
diff --git a/wp7/tooling/scripts/dist.js b/wp7/tooling/scripts/dist.js
index b1fd9cb..fe2407c 100644
--- a/wp7/tooling/scripts/dist.js
+++ b/wp7/tooling/scripts/dist.js
@@ -40,16 +40,20 @@ var replace = false;
//Set up directory structure of current release
//arguments passed in
-var args = WScript.Arguments,
- //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
- ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
- // tooling scripts
- SCRIPTS = '\\tooling\\scripts';
- //Get version number
- VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
+var args = WScript.Arguments;
+Log("args = " + args);
+ //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp\cordova-wp7)
+var rootPath = WScript.ScriptFullName.split('\\tooling\\', 1);
+Log("rootPath = " + rootPath);
+// tooling scripts
+var scriptPath = '\\tooling\\scripts';
+Log("scriptPath = " + scriptPath);
+//Get version number
+var VERSION=read(rootPath+'\\..\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
+Log("VERSION = " + VERSION);
//Destination to build to
-var BUILD_DESTINATION;
+var buildDestination;
//current script that is running
var current_script = "dist";
@@ -84,7 +88,7 @@ function Log(msg, error) {
// returns the contents of a file
function read(filename) {
- //Log('Reading in ' + filename);
+ Log('Reading in ' + filename);
if(fso.FileExists(filename))
{
var f=fso.OpenTextFile(filename, 1,2);
@@ -144,20 +148,20 @@ if (args.Count() > 0) {
WScript.Quit(1);
}
else if (args(0) == '-f') {
- BUILD_DESTINATION = ROOT;
+ buildDestination = rootPath;
replace = true;
}
else {
- BUILD_DESTINATION = args(0);
+ buildDestination = args(0);
}
}
else if (args.Count() == 2) {
if (args(0) == '-f') {
replace = true;
- BUILD_DESTINATION = args(1);
+ buildDestination = args(1);
} else {
- BUILD_DESTINATION = args(0);
+ buildDestination = args(0);
if (args(1) == '-f') {
replace = true;
}
@@ -183,8 +187,9 @@ else {
/** - Copy source code to new directory **/
/*************************************************/
if (!replace) {
+ Log("Step 1");
current_script = "new.js";
- exec('cscript ' + ROOT + SCRIPTS + '\\new.js ' + BUILD_DESTINATION + ' //nologo');
+ exec('cscript ' + rootPath + scriptPath + '\\new.js ' + buildDestination + ' //nologo');
space();
}
@@ -196,7 +201,8 @@ if (!replace) {
/** - Rebuild dll **/
/*************************************************/
current_script = "reversion.js";
-exec('cscript ' + BUILD_DESTINATION + SCRIPTS + '\\reversion.js ' + VERSION + ' //nologo');
+Log("Step 2");
+exec('cscript ' + buildDestination + scriptPath + '\\reversion.js ' + VERSION + ' //nologo');
space();
/*************************************************/
@@ -208,7 +214,7 @@ space();
/*************************************************/
// New Workflow may not require building the new js, it should already be in place.
current_script = "buildjs.js";
-exec('cscript ' + BUILD_DESTINATION + SCRIPTS + '\\buildjs.js //nologo');
+exec('cscript ' + buildDestination + scriptPath + '\\buildjs.js //nologo');
space();
/*************************************************/
@@ -219,6 +225,6 @@ space();
/** - inject into Visual Studio **/
/*************************************************/
current_script = "package.js";
-exec('cscript ' + BUILD_DESTINATION + SCRIPTS + '\\package.js //nologo');
+exec('cscript ' + buildDestination + scriptPath + '\\package.js //nologo');
space();
Log("Distribution Complete.");
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/df40aaf2/wp7/tooling/scripts/reversion.js
----------------------------------------------------------------------
diff --git a/wp7/tooling/scripts/reversion.js b/wp7/tooling/scripts/reversion.js
index 8bf5ed1..7754514 100644
--- a/wp7/tooling/scripts/reversion.js
+++ b/wp7/tooling/scripts/reversion.js
@@ -132,7 +132,7 @@ function updateVersionNumbers() {
WScript.StdOut.WriteLine("Updating version numbers....");
var version_regex = /(\d+)[.](\d+)[.](\d+)(rc\d)?/;
replaceInFile(BUILD_DESTINATION + '\\VERSION', version_regex, VERSION);
- // replace assembaly versions in framework
+ // replace assembly versions in framework
var framework_regex = /Description\(\"(\d+)[.](\d+)[.](\d+)(rc\d)?\"\)\]/; //Will match ("x.x.x[rcx]")]
replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Description(\"" + VERSION + "\")]");
framework_regex = /Version\(\"(\d+)[.](\d+)[.](\d+)[.](\d+)\"\)\]/g;
@@ -193,15 +193,6 @@ function cleanup()
fso.DeleteFile(BUILD_DESTINATION + '\\' + root_folder.Item(i).Name);
}
}
- // remove old cordova.js
- var example_www = shell.NameSpace(BUILD_DESTINATION + EXAMPLE_PATH + '\\www').Items();
- for(i = 0; i < example_www.Count; i++)
- {
- if(example_www.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
- {
- fso.DeleteFile(BUILD_DESTINATION + EXAMPLE_PATH + '\\www\\' + example_www.Item(i).Name);
- }
- }
var standalone_www = shell.NameSpace(BUILD_DESTINATION + STANDALONE_PATH + '\\www').Items();
for(i = 0; i < standalone_www.Count; i++)
[25/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Globalization.cs
----------------------------------------------------------------------
diff --git a/plugins/Globalization.cs b/plugins/Globalization.cs
deleted file mode 100644
index 2c2f468..0000000
--- a/plugins/Globalization.cs
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides information about system locale, culture settings, number formats, ect.
- /// </summary>
- public class Globalization : BaseCommand
- {
-
- #region Globalization errors
-
- /// <summary>
- /// Globalization error codes.
- /// </summary>
- public enum ErrorCode : int
- {
- UnknownError = 0,
- FormattingError = 1,
- ParsingError = 2,
- PatternError = 3
- }
-
- /// <summary>
- /// Represents globalization error object.
- /// </summary>
- [DataContract]
- public class GlobalizationError
- {
- #region Error messages
- /// <summary>
- /// Error messages
- /// </summary>
- public const string UnknownError = "UNKNOWN_ERROR";
- public const string FormattingError = "FORMATTIN_ERROR";
- public const string ParsingError = "PARSING_ERROR";
- public const string PatternError = "PATTERN_ERROR";
-
- #endregion
-
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = false)]
- public ErrorCode Code { get; set; }
-
- /// <summary>
- /// Error message
- /// </summary>
- [DataMember(Name = "message", IsRequired = false)]
- public string Message { get; set; }
-
- /// <summary>
- /// Default constructor
- /// </summary>
- public GlobalizationError()
- {
- this.Code = ErrorCode.UnknownError;
- this.Message = UnknownError;
- }
-
- /// <summary>
- /// Constructor setting error code
- /// </summary>
- public GlobalizationError(ErrorCode error)
- {
- this.Code = error;
-
- switch (error)
- {
- case ErrorCode.ParsingError:
- {
- this.Message = ParsingError;
- break;
- }
- case ErrorCode.FormattingError:
- {
- this.Message = FormattingError;
- break;
- }
- case ErrorCode.PatternError:
- {
- this.Message = PatternError;
- break;
- }
- default:
- {
- this.Message = UnknownError;
- break;
- }
- }
- }
- }
-
- #endregion
-
- #region Globalization options
-
- /// <summary>
- /// Represents globalization options.
- /// </summary>
- [DataContract]
- public class GlobalizationOptions
- {
- #region available option values
- /// <summary>
- /// Number pattern types.
- /// </summary>
- public const string Percent = "percent";
- public const string Currency = "currency";
- public const string Decimal = "decimal";
-
- /// <summary>
- /// Format length types
- /// </summary>
- public const string Short = "short";
- public const string Medium = "medium";
- public const string Long = "long";
- public const string Full = "full";
-
- /// <summary>
- /// Selector types
- /// </summary>
- public const string TimeSelector = "time";
- public const string DateSelector = "date";
- public const string DateAndTimeSelector = "date and time";
-
- /// <summary>
- /// Date name types
- /// </summary>
- public const string Narrow = "narrow";
- public const string Wide = "wide";
-
- /// <summary>
- /// Date name items
- /// </summary>
- public const string Months = "months";
- public const string Days = "days";
-
- #endregion
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "options", IsRequired = false)]
- public Options AdditionalOptions { get; set; }
-
- /// <summary>
- /// Date to convert
- /// </summary>
- [DataMember(Name = "date", IsRequired = false)]
- public long Date { get; set; }
-
- /// <summary>
- /// Date as stirng
- /// </summary>
- [DataMember(Name = "dateString", IsRequired = false)]
- public string DateString { get; set; }
-
- /// <summary>
- /// Currency code
- /// </summary>
- [DataMember(Name = "currencyCode", IsRequired = false)]
- public string CurrencyCode { get; set; }
-
- /// <summary>
- /// Number as string
- /// </summary>
- [DataMember(Name = "numberString", IsRequired = false)]
- public string NumberString { get; set; }
-
- /// <summary>
- /// Number to convert
- /// </summary>
- [DataMember(Name = "number", IsRequired = false)]
- public double Number { get; set; }
- }
-
- /// <summary>
- /// Represents additional options
- /// </summary>
- [DataContract]
- public class Options
- {
- /// <summary>
- /// Pattern type
- /// </summary>
- [DataMember(Name = "type", IsRequired = false)]
- public string Type { get; set; }
-
- /// <summary>
- /// Format length
- /// </summary>
- [DataMember(Name = "formatLength", IsRequired = false)]
- public string FormatLength { get; set; }
-
- /// <summary>
- /// Selector
- /// </summary>
- [DataMember(Name = "selector", IsRequired = false)]
- public string Selector { get; set; }
-
- /// <summary>
- /// Date name item
- /// </summary>
- [DataMember(Name = "item", IsRequired = false)]
- public string Item { get; set; }
- }
-
- #endregion
-
- #region returned objects
-
- #region Number pattern object
-
- /// <summary>
- /// Represents number pattern
- /// </summary>
- [DataContract]
- public class NumberPattern
- {
- /// <summary>
- /// Pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// Symbol
- /// </summary>
- [DataMember(Name = "symbol", IsRequired = false)]
- public string Symbol { get; set; }
-
- /// <summary>
- /// Fraction
- /// </summary>
- [DataMember(Name = "fraction", IsRequired = false)]
- public int Fraction { get; set; }
-
- /// <summary>
- /// Positive
- /// </summary>
- [DataMember(Name = "positive", IsRequired = false)]
- public string Positive { get; set; }
-
- /// <summary>
- /// Negative
- /// </summary>
- [DataMember(Name = "negative", IsRequired = false)]
- public string Negative { get; set; }
-
- /// <summary>
- /// Rounding
- /// </summary>
- [DataMember(Name = "rounding", IsRequired = false)]
- public int Rounding { get; set; }
-
- /// <summary>
- /// Decimal
- /// </summary>
- [DataMember(Name = "decimal", IsRequired = false)]
- public string Decimal { get; set; }
-
- /// <summary>
- /// Grouping
- /// </summary>
- [DataMember(Name = "grouping", IsRequired = false)]
- public string Grouping { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="symbol"></param>
- /// <param name="fraction"></param>
- /// <param name="positive"></param>
- /// <param name="negative"></param>
- /// <param name="rounding"></param>
- /// <param name="dec"></param>
- /// <param name="grouping"></param>
- public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
- {
- this.Pattern = pattern;
- this.Symbol = symbol;
- this.Fraction = fraction;
- this.Positive = positive;
- this.Negative = negative;
- this.Rounding = rounding;
- this.Decimal = dec;
- this.Grouping = grouping;
- }
- }
- #endregion
-
- #region Date format object
-
- /// <summary>
- /// Represents date format
- /// </summary>
- [DataContract]
- public class DateFormat
- {
- /// <summary>
- /// Year
- /// </summary>
- [DataMember(Name = "year", IsRequired = false)]
- public int Year { get; set; }
-
- /// <summary>
- /// Month
- /// </summary>
- [DataMember(Name = "month", IsRequired = false)]
- public int Month { get; set; }
-
- /// <summary>
- /// Day
- /// </summary>
- [DataMember(Name = "day", IsRequired = false)]
- public int Day { get; set; }
-
- /// <summary>
- /// Hour
- /// </summary>
- [DataMember(Name = "hour", IsRequired = false)]
- public int Hour { get; set; }
-
- /// <summary>
- /// Minute
- /// </summary>
- [DataMember(Name = "minute", IsRequired = false)]
- public int Minute { get; set; }
-
- /// <summary>
- /// Second
- /// </summary>
- [DataMember(Name = "second", IsRequired = false)]
- public int Second { get; set; }
-
- /// <summary>
- /// Millisecond
- /// </summary>
- [DataMember(Name = "millisecond", IsRequired = false)]
- public int Millisecond { get; set; }
-
- public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
- {
- this.Year = year;
- this.Month = month;
- this.Day = day;
- this.Hour = hour;
- this.Minute = minute;
- this.Millisecond = millisecond;
- }
-
- }
- #endregion
-
- #region Date pattern object
-
- /// <summary>
- /// Represents date pattern object
- /// </summary>
- [DataContract]
- public class DatePattern
- {
-
- /// <summary>
- /// Date pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// TimeZone
- /// </summary>
- [DataMember(Name = "timezone", IsRequired = false)]
- public string TimeZone { get; set; }
-
- /// <summary>
- /// UTC offset
- /// </summary>
- [DataMember(Name = "utc_offset", IsRequired = false)]
- public double UtcOffset { get; set; }
-
- /// <summary>
- /// Dst offset
- /// </summary>
- [DataMember(Name = "dst_offset", IsRequired = false)]
- public double DstOffset { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="timezone"></param>
- /// <param name="utcOffset"></param>
- /// <param name="dstOffset"></param>
- public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
- {
- this.Pattern = pattern;
- this.TimeZone = timezone;
- this.UtcOffset = utcOffset;
- this.DstOffset = dstOffset;
- }
-
- }
-
- #endregion
-
- #endregion
-
- #region Locale info
-
- /// <summary>
- /// Gets the string identifier for the client's current locale setting.
- /// </summary>
- /// <param name="options"></param>
- public void getLocaleName(string options)
- {
- try
- {
- var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the string identifier for the client's current language.
- /// </summary>
- /// <param name="options"></param>
- public void getPreferredLanguage(string options)
- {
- try
- {
- var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Date and time info
-
- /// <summary>
- /// Gets whether daylight savings time is in effect for a given date using the client's
- /// time zone and calendar.
- /// </summary>
- /// <param name="opitons">Date to daylight savings check.</param>
- public void isDayLightSavingsTime(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the first day of the week according to the client's user preferences and calendar.
- /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
- /// </summary>
- /// <param name="options"></param>
- public void getFirstDayOfWeek(string options)
- {
- try
- {
- // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
- var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Formatting
-
- /// <summary>
- /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client.
- /// </summary>
- /// <param name="options"></param>
- public void dateToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-
- string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
- break;
- }
- case 10: // short date
- {
- format = "{0:d}";
- break;
- }
- case 11: // full date
- {
- format = "{0:D}";
- break;
- }
- case 20: // short time
- {
- format = "{0:t}";
- break;
- }
- case 21: // full time
- {
- format = "{0:T}";
- break;
- }
- default: // short datetime
- {
- format = "{0:M/dd/yy H:m:s}";
- break;
- }
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
- /// </summary>
- /// <param name="options"></param>
- public void stringToDate(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.DateString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string format = "M/dd/yy H:m:s"; // short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "MMMM/dddd/yyyy HH:mm:ss tt";
- break;
- }
- case 10: // short date
- {
- format = "d";
- break;
- }
- case 11: // full date
- {
- format = "D";
- break;
- }
- case 20: // short time
- {
- format = "t";
- break;
- }
- case 21: // full time
- {
- format = "T";
- break;
- }
- default: // short datetime
- {
- format = "M/dd/yy H:m:s";
- break;
- }
- }
- }
-
- DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
- DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getDatePattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
- string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- case 10: // short date
- {
- pattern = dateFormatInfo.ShortDatePattern;
- break;
- }
- case 11: // full date
- {
- pattern = dateFormatInfo.LongDatePattern;
- break;
- }
- case 20: // short time
- {
- pattern = dateFormatInfo.ShortTimePattern;
- break;
- }
- case 21: // full time
- {
- pattern = dateFormatInfo.LongTimePattern;
- break;
- }
- default: // short datetime
- {
- // Seems like C# doesn't support short datetime pattern so we use full format
- // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- }
- }
-
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
- /// </summary>
- /// <param name="options"></param>
- public void getDateNames(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- int type = 0; //default wide
- int item = 0; //default months
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.Type != null)
- {
- string t = globalOptions.AdditionalOptions.Type;
-
- if (t.Equals(GlobalizationOptions.Narrow))
- {
- type++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Item != null)
- {
- string t = globalOptions.AdditionalOptions.Item;
-
- if (t.Equals(GlobalizationOptions.Days))
- {
- item += 10;
- }
- }
- }
-
- //determine return value
- int method = item + type;
- string[] namesArray;
- CultureInfo currentCulture = CultureInfo.CurrentCulture;
-
- if (method == 1) //months and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
- }
- else if (method == 10) //days and wide
- {
- namesArray = currentCulture.DateTimeFormat.DayNames;
- }
- else if (method == 11) //days and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
- }
- else //default: months and wide
- {
- namesArray = currentCulture.DateTimeFormat.MonthNames;
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void numberToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- string format = string.Empty;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- format = "{0:p}";
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- format = "{0:c}";
- break;
- }
-
- default:
- {
- format = "{0:f}";
- break;
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
- /// </summary>
- /// <param name="options"></param>
- public void stringToNumber(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.NumberString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string numberString = globalOptions.NumberString;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- NumberStyles numberStyle;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- numberStyle = NumberStyles.Any;
- numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- numberStyle = NumberStyles.Currency;
- break;
- }
-
- default:
- {
- numberStyle = NumberStyles.Number;
- break;
- }
- }
-
- double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getNumberPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- CultureInfo cultureInfo = CultureInfo.CurrentCulture;
- NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
- NumberPattern pattern = null;
- string symbol;
-
- // TODO find out how to get format pattern and the number of fraction digits
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- symbol = formatInfo.PercentSymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
- break;
- }
- case GlobalizationOptions.Currency:
- {
- symbol = formatInfo.CurrencySymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
- break;
- }
- default:
- {
- symbol = formatInfo.NumberDecimalSeparator;
- pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
- break;
- }
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
- /// </summary>
- /// <param name="options"></param>
- public void getCurrencyPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string currencyCode = globalOptions.CurrencyCode;
-
- // temporary not supported via lack of api required
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
- return;
-
- // TODO find the way to get currency info from currency code
- // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
- // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
- // CultureInfo cultureInfo = new CultureInfo(currencyCode);
- // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- #endregion
-
- #region private methods
-
- /// <summary>
- /// Wraps data into JSON format
- /// </summary>
- /// <param name="data">data</param>
- /// <returns>data formatted as JSON object</returns>
- private string WrapIntoJSON<T>(T data, string keyName = "value")
- {
- string param = "{0}";
- string stringifiedData = data.ToString();
-
- if (data.GetType() == typeof(string))
- {
- param = "\"" + param + "\"";
- }
-
- if (data.GetType() == typeof(bool))
- {
- stringifiedData = stringifiedData.ToLower();
- }
-
- if (data.GetType() == typeof(string[]))
- {
- stringifiedData = JSON.JsonHelper.Serialize(data);
- }
-
- var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
- formattedData = "{" + formattedData + "}";
-
- return formattedData;
- }
-
- #endregion
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/plugins/ImageExifHelper.cs b/plugins/ImageExifHelper.cs
deleted file mode 100644
index 68ddf87..0000000
--- a/plugins/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- 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.
-
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class ImageExifOrientation
- {
- public const int Portrait = 1;
- public const int PortraitUpsideDown = 3;
- public const int LandscapeLeft = 6;
- public const int LandscapeRight = 8;
- }
-
- public class ImageExifHelper
- {
-
- public static Stream RotateStream(Stream stream, int angle)
- {
- stream.Position = 0;
- if (angle % 90 != 0 || angle < 0)
- {
- throw new ArgumentException();
- }
- if (angle % 360 == 0)
- {
- return stream;
- }
-
- angle = angle % 360;
-
- BitmapImage bitmap = new BitmapImage();
- bitmap.SetSource(stream);
- WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
- WriteableBitmap wbTarget = null;
-
- int srcPixelWidth = wbSource.PixelWidth;
- int srcPixelHeight = wbSource.PixelHeight;
-
- if (angle % 180 == 0)
- {
- wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
- }
- else
- {
- wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
- }
-
- int destPixelWidth = wbTarget.PixelWidth;
- int[] srcPxls = wbSource.Pixels;
- int[] destPxls = wbTarget.Pixels;
-
- // this ugly if/else is to avoid a conditional check for every pixel
- if (angle == 90)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 180)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 270)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
-
- MemoryStream targetStream = new MemoryStream();
- wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
- return targetStream;
- }
-
- public static int getImageOrientationFromStream(Stream imgStream)
- {
-
- // 0xFFD8 : jpgHeader
- // 0xFFE1 :
- // 0x???? : length of exif data
- // 0x????, 0x???? : Chars 'E','x','i','f'
- // 0x0000 : 2 empty bytes
- // <== mark beginning of tags SIZE:ID:VALUE
- // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determins littleEndian-ness
- // 0x002A : marker value
- // 0x???? : offset to the Image File Data
-
- // XXXX possible space before actual tag data ... we skip to mark + offset
-
- // 0x???? number of exif tags present
-
- // make sure we are at the begining
- imgStream.Seek(0, SeekOrigin.Begin);
- BinaryReader reader = new BinaryReader(imgStream);
-
- byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
- byte start = reader.ReadByte(); // 0xFF
- byte index = reader.ReadByte(); // 0xE1
-
- while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
- {
- // Get the data length
- ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // skip along
- reader.ReadBytes(dLen - 2);
- start = reader.ReadByte();
- index = reader.ReadByte();
- }
-
- // It's only success if we found the 0xFFE1 marker
- if (start != 0xFF || index != 0xE1)
- {
- // throw new Exception("Could not find Exif data block");
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 byte length of EXIF data
- ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- String exif = ""; // build the string
- for (var n = 0; n < 4; n++)
- {
- exif += reader.ReadChar();
- }
- if (exif != "Exif")
- {
- // did not find exif data ...
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 empty bytes
- //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- reader.ReadBytes(2);
-
- long headerMark = reader.BaseStream.Position; // where are we now <==
-
- //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
- reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
- if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- Debug.WriteLine("Error in data != 0x002A");
- return 0;
- }
-
- // Get the offset to the IFD (image file directory)
- ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
- imgStream.Position = headerMark + imgOffset;
- ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- for (ushort x = 0; x < tagCount; x++)
- {
- // Orientation = 0x112, aka 274
- if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // don't care ..
- uint comps = reader.ReadUInt32();
- byte[] tagData = reader.ReadBytes(4);
- int orientation = (int)tagData[0];
- Debug.WriteLine("orientation = " + orientation.ToString());
- return orientation;
- // 6 means rotate clockwise 90 deg
- // 8 means rotate counter-clockwise 90 deg
- // 1 means all is good
- // 3 means flip vertical
- }
- // skip to the next item, 12 bytes each
- reader.BaseStream.Seek(10, SeekOrigin.Current);
- }
- return 0;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/InAppBrowser.cs
----------------------------------------------------------------------
diff --git a/plugins/InAppBrowser.cs b/plugins/InAppBrowser.cs
deleted file mode 100644
index 2741355..0000000
--- a/plugins/InAppBrowser.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using WPCordovaClassLib.Cordova;
-using WPCordovaClassLib.Cordova.Commands;
-using WPCordovaClassLib.Cordova.JSON;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class BrowserOptions
- {
- [DataMember]
- public string url;
-
- [DataMember]
- public bool isGeolocationEnabled;
- }
-
- public class InAppBrowser : BaseCommand
- {
-
- private static WebBrowser browser;
- private static ApplicationBarIconButton backButton;
- private static ApplicationBarIconButton fwdButton;
-
- public void open(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
- string urlLoc = args[0];
- string target = args[1];
- /*
- _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
- _blank - always open in the InAppBrowser
- _system - always open in the system web browser
- */
- switch (target)
- {
- case "_blank":
- ShowInAppBrowser(urlLoc);
- break;
- case "_self":
- ShowCordovaBrowser(urlLoc);
- break;
- case "_system":
- ShowSystemBrowser(urlLoc);
- break;
- }
-
-
- }
-
- private void ShowCordovaBrowser(string url)
- {
- Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- CordovaView cView = page.FindName("CordovaView") as CordovaView;
- if (cView != null)
- {
- WebBrowser br = cView.Browser;
- br.Navigate(loc);
- }
- }
-
- }
- });
- }
-
- private void ShowSystemBrowser(string url)
- {
- WebBrowserTask webBrowserTask = new WebBrowserTask();
- webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
- webBrowserTask.Show();
- }
-
-
- private void ShowInAppBrowser(string url)
- {
- Uri loc = new Uri(url);
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (browser != null)
- {
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- browser.Navigate(loc);
- }
- else
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- string baseImageUrl = "Images/";
-
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- browser = new WebBrowser();
- browser.IsScriptEnabled = true;
- browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-
- browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
- browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
- browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
- browser.Navigate(loc);
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- grid.Children.Add(browser);
- }
-
- ApplicationBar bar = new ApplicationBar();
- bar.BackgroundColor = Colors.Gray;
- bar.IsMenuEnabled = false;
-
- backButton = new ApplicationBarIconButton();
- backButton.Text = "Back";
-
- backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
- backButton.Click += new EventHandler(backButton_Click);
- backButton.IsEnabled = false;
- bar.Buttons.Add(backButton);
-
-
- fwdButton = new ApplicationBarIconButton();
- fwdButton.Text = "Forward";
- fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
- fwdButton.Click += new EventHandler(fwdButton_Click);
- fwdButton.IsEnabled = false;
- bar.Buttons.Add(fwdButton);
-
- ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
- closeBtn.Text = "Close";
- closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
- closeBtn.Click += new EventHandler(closeBtn_Click);
- bar.Buttons.Add(closeBtn);
-
- page.ApplicationBar = bar;
- }
-
- }
- }
- });
- }
-
- void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
-
- }
-
- void fwdButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoForward();
- //browser.InvokeScript("execScript", "history.forward();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void backButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoBack();
- //browser.InvokeScript("execScript", "history.back();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void closeBtn_Click(object sender, EventArgs e)
- {
- this.close();
- }
-
-
- public void close(string options = "")
- {
- if (browser != null)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(browser);
- }
- page.ApplicationBar = null;
- }
- }
- browser = null;
- string message = "{\"type\":\"exit\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = false;
- this.DispatchCommandResult(result);
- });
- }
- }
-
- void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (browser != null)
- {
- backButton.IsEnabled = browser.CanGoBack;
- fwdButton.IsEnabled = browser.CanGoForward;
-
- }
- string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
- {
- string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_Navigating(object sender, NavigatingEventArgs e)
- {
- string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Media.cs
----------------------------------------------------------------------
diff --git a/plugins/Media.cs b/plugins/Media.cs
deleted file mode 100644
index 5de4884..0000000
--- a/plugins/Media.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides the ability to record and play back audio files on a device.
- /// </summary>
- public class Media : BaseCommand
- {
- /// <summary>
- /// Audio player objects
- /// </summary>
- private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
- /// <summary>
- /// Represents Media action options.
- /// </summary>
- [DataContract]
- public class MediaOptions
- {
- /// <summary>
- /// Audio id
- /// </summary>
- [DataMember(Name = "id", IsRequired = true)]
- public string Id { get; set; }
-
- /// <summary>
- /// Path to audio file
- /// </summary>
- [DataMember(Name = "src")]
- public string Src { get; set; }
-
- /// <summary>
- /// New track position
- /// </summary>
- [DataMember(Name = "milliseconds")]
- public int Milliseconds { get; set; }
- }
-
- /// <summary>
- /// Releases the audio player instance to save memory.
- /// </summary>
- public void release(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- Media.players.Remove(mediaOptions.Id);
- audio.Dispose();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts recording and save the specified file
- /// </summary>
- public void startRecordingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (mediaOptions != null)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio;
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- audio = Media.players[mediaOptions.Id];
- }
-
- if (audio != null)
- {
- audio.startRecording(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
- }
-
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
-
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Stops recording and save to the file specified when recording started
- /// </summary>
- public void stopRecordingAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopRecording();
- Media.players.Remove(mediaId);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- public void setVolume(string options) // id,volume
- {
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- string id = optionsString[0];
- double volume = double.Parse(optionsString[1]);
-
- if (Media.players.ContainsKey(id))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer player = Media.players[id];
- player.setVolume(volume);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
- return;
- }
- }
-
- // Some Audio Notes:
- // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
- // While playing, a MediaElement stops all other media playback on the phone.
- // Multiple MediaElement controls are NOT supported
-
- // Called when you create a new Media('blah') object in JS.
- public void create(string options)
- {
- // Debug.WriteLine("Creating Audio :: " + options);
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
- return;
- }
-
- AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- public void startPlayingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- if (optionsString.Length > 2 && optionsString[2] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[2]);
- }
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
- audio = Media.players[mediaOptions.Id];
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- audio.startPlaying(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Seeks to a location
- /// </summary>
- public void seekToAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- if (optionsString.Length > 1 && optionsString[1] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[1]);
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- audio.seekToPlaying(mediaOptions.Milliseconds);
- }
- else
- {
- Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlayingAudio(string options)
- {
-
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.pausePlaying();
- }
- else
- {
- Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
-
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlayingAudio(String options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopPlaying();
- }
- else
- {
- Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- public void getCurrentPositionAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
- }
-
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
-
- [Obsolete("This method will be removed shortly")]
- public void getDurationAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = Media.players[mediaOptions.Id];
- }
- else
- {
- Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
- }
-}
[09/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/MimeTypeMapper.cs b/wp7/template/Plugins/MimeTypeMapper.cs
deleted file mode 100644
index a2794f5..0000000
--- a/wp7/template/Plugins/MimeTypeMapper.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- 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.
-*/
-
-using System.Collections.Generic;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Represents file extension to mime type mapper.
- /// </summary>
- public static class MimeTypeMapper
- {
- /// <summary>
- /// For unknown type it is recommended to use 'application/octet-stream'
- /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
- /// </summary>
- private static string DefaultMimeType = "application/octet-stream";
-
- /// <summary>
- /// Stores mime type for all necessary extension
- /// </summary>
- private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
- {
- {"avi", "video/x-msvideo"},
- {"bmp", "image/bmp"},
- {"gif", "image/gif"},
- {"html","text/html"},
- {"jpe", "image/jpeg"},
- {"jpeg", "image/jpeg"},
- {"jpg", "image/jpeg"},
- {"js","text/javascript"},
- {"mov", "video/quicktime"},
- {"mp2", "audio/mpeg"},
- {"mp3", "audio/mpeg"},
- {"mp4", "video/mp4"},
- {"mpe", "video/mpeg"},
- {"mpeg", "video/mpeg"},
- {"mpg", "video/mpeg"},
- {"mpga", "audio/mpeg"},
- {"pbm", "image/x-portable-bitmap"},
- {"pcm", "audio/x-pcm"},
- {"pct", "image/pict"},
- {"pgm", "image/x-portable-graymap"},
- {"pic", "image/pict"},
- {"pict", "image/pict"},
- {"png", "image/png"},
- {"pnm", "image/x-portable-anymap"},
- {"pnt", "image/x-macpaint"},
- {"pntg", "image/x-macpaint"},
- {"ppm", "image/x-portable-pixmap"},
- {"qt", "video/quicktime"},
- {"ra", "audio/x-pn-realaudio"},
- {"ram", "audio/x-pn-realaudio"},
- {"ras", "image/x-cmu-raster"},
- {"rgb", "image/x-rgb"},
- {"snd", "audio/basic"},
- {"txt", "text/plain"},
- {"tif", "image/tiff"},
- {"tiff", "image/tiff"},
- {"wav", "audio/x-wav"},
- {"wbmp", "image/vnd.wap.wbmp"},
-
- };
- /// <summary>
- /// Gets mime type by file extension
- /// </summary>
- /// <param name="fileName">file name to extract extension</param>
- /// <returns>mime type</returns>
- public static string GetMimeType(string fileName)
- {
- string ext = Path.GetExtension(fileName);
-
- // invalid extension
- if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
- {
- return DefaultMimeType;
- }
-
- ext = ext.Remove(0, 1);
-
- if (MIMETypesDictionary.ContainsKey(ext))
- {
- return MIMETypesDictionary[ext];
- }
-
- return DefaultMimeType;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/NetworkStatus.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/NetworkStatus.cs b/wp7/template/Plugins/NetworkStatus.cs
deleted file mode 100644
index 12eb061..0000000
--- a/wp7/template/Plugins/NetworkStatus.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Net.NetworkInformation;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
-
- public class NetworkStatus : BaseCommand
- {
- const string UNKNOWN = "unknown";
- const string ETHERNET = "ethernet";
- const string WIFI = "wifi";
- const string CELL_2G = "2g";
- const string CELL_3G = "3g";
- const string CELL_4G = "4g";
- const string NONE = "none";
- const string CELL = "cellular";
-
- private bool HasCallback = false;
-
- public NetworkStatus()
- {
- DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
- }
-
- public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
- {
- this.getConnectionInfo("");
- }
-
- public void getConnectionInfo(string empty)
- {
- HasCallback = true;
- updateConnectionType(checkConnectionType());
- }
-
- private string checkConnectionType()
- {
- if (DeviceNetworkInformation.IsNetworkAvailable)
- {
- if (DeviceNetworkInformation.IsWiFiEnabled)
- {
- return WIFI;
- }
- else
- {
- return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
- }
- }
- return NONE;
- }
-
- private string checkConnectionType(NetworkInterfaceSubType type)
- {
- switch (type)
- {
- case NetworkInterfaceSubType.Cellular_1XRTT: //cell
- case NetworkInterfaceSubType.Cellular_GPRS: //cell
- return CELL;
- case NetworkInterfaceSubType.Cellular_EDGE: //2
- return CELL_2G;
- case NetworkInterfaceSubType.Cellular_3G:
- case NetworkInterfaceSubType.Cellular_EVDO: //3
- case NetworkInterfaceSubType.Cellular_EVDV: //3
- case NetworkInterfaceSubType.Cellular_HSPA: //3
- return CELL_3G;
- case NetworkInterfaceSubType.WiFi:
- return WIFI;
- case NetworkInterfaceSubType.Unknown:
- case NetworkInterfaceSubType.Desktop_PassThru:
- default:
- return UNKNOWN;
- }
- }
-
- void ChangeDetected(object sender, NetworkNotificationEventArgs e)
- {
- switch (e.NotificationType)
- {
- case NetworkNotificationType.InterfaceConnected:
- updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
- break;
- case NetworkNotificationType.InterfaceDisconnected:
- updateConnectionType(NONE);
- break;
- default:
- break;
- }
- }
-
- private void updateConnectionType(string type)
- {
- // This should also implicitly fire offline/online events as that is handled on the JS side
- if (this.HasCallback)
- {
- PluginResult result = new PluginResult(PluginResult.Status.OK, type);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Notification.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Notification.cs b/wp7/template/Plugins/Notification.cs
deleted file mode 100644
index 0759c72..0000000
--- a/wp7/template/Plugins/Notification.cs
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Devices;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Windows.Resources;
-using Microsoft.Phone.Controls;
-using Microsoft.Xna.Framework.Audio;
-using WPCordovaClassLib.Cordova.UI;
-using System.Diagnostics;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Notification : BaseCommand
- {
- static ProgressBar progressBar = null;
- const int DEFAULT_DURATION = 5;
-
- private NotificationBox notifyBox;
-
- private PhoneApplicationPage Page
- {
- get
- {
- PhoneApplicationPage page = null;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- page = frame.Content as PhoneApplicationPage;
- }
- return page;
- }
- }
-
- // blink api - doesn't look like there is an equivalent api we can use...
-
- [DataContract]
- public class AlertOptions
- {
- [OnDeserializing]
- public void OnDeserializing(StreamingContext context)
- {
- // set defaults
- this.message = "message";
- this.title = "Alert";
- this.buttonLabel = "ok";
- }
-
- /// <summary>
- /// message to display in the alert box
- /// </summary>
- [DataMember]
- public string message;
-
- /// <summary>
- /// title displayed on the alert window
- /// </summary>
- [DataMember]
- public string title;
-
- /// <summary>
- /// text to display on the button
- /// </summary>
- [DataMember]
- public string buttonLabel;
- }
-
- public void alert(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
- Button btnOK = new Button();
- btnOK.Content = alertOpts.buttonLabel;
- btnOK.Click += new RoutedEventHandler(btnOK_Click);
- btnOK.Tag = 1;
- notifyBox.ButtonPanel.Children.Add(btnOK);
- grid.Children.Add(notifyBox);
-
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- public void confirm(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
-
- string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
-
- if (labels == null)
- {
- labels = alertOpts.buttonLabel.Split(',');
- }
-
- for (int n = 0; n < labels.Length; n++)
- {
- Button btn = new Button();
- btn.Content = labels[n];
- btn.Tag = n;
- btn.Click += new RoutedEventHandler(btnOK_Click);
- notifyBox.ButtonPanel.Children.Add(btn);
- }
-
- grid.Children.Add(notifyBox);
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
- {
- PhoneApplicationPage page = sender as PhoneApplicationPage;
- string callbackId = "";
- if (page != null && notifyBox != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifyBox);
- dynamic notifBoxData = notifyBox.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
- }
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- e.Cancel = true;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
- }
-
- void btnOK_Click(object sender, RoutedEventArgs e)
- {
- Button btn = sender as Button;
- FrameworkElement notifBoxParent = null;
- int retVal = 0;
- string callbackId = "";
- if (btn != null)
- {
- retVal = (int)btn.Tag + 1;
-
- notifBoxParent = btn.Parent as FrameworkElement;
- while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
- !(notifBoxParent is NotificationBox)) ;
- }
- if (notifBoxParent != null)
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifBoxParent);
- }
-
- dynamic notifBoxData = notifBoxParent.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
-
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- }
-
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
- }
-
-
-
- public void beep(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- int times = int.Parse(args[0]);
-
- string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
-
- StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
-
- if (sri != null)
- {
- SoundEffect effect = SoundEffect.FromStream(sri.Stream);
- SoundEffectInstance inst = effect.CreateInstance();
- ThreadPool.QueueUserWorkItem((o) =>
- {
- // cannot interact with UI !!
- do
- {
- inst.Play();
- Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
- }
- while (--times > 0);
-
- });
-
- }
-
- // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
- DispatchCommandResult();
- }
-
- // Display an indeterminate progress indicator
- public void activityStart(string unused)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- if (page != null)
- {
- var temp = page.FindName("LayoutRoot");
- Grid grid = temp as Grid;
- if (grid != null)
- {
- if (progressBar != null)
- {
- grid.Children.Remove(progressBar);
- }
- progressBar = new ProgressBar();
- progressBar.IsIndeterminate = true;
- progressBar.IsEnabled = true;
-
- grid.Children.Add(progressBar);
- }
- }
- }
- });
- }
-
-
- // Remove our indeterminate progress indicator
- public void activityStop(string unused)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (progressBar != null)
- {
- progressBar.IsEnabled = false;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(progressBar);
- }
- }
- }
- progressBar = null;
- }
- });
- }
-
- public void vibrate(string vibrateDuration)
- {
-
- int msecs = 200; // set default
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
-
- msecs = int.Parse(args[0]);
- if (msecs < 1)
- {
- msecs = 1;
- }
- }
- catch (FormatException)
- {
-
- }
-
- VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
-
- // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
- DispatchCommandResult();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/AudioCaptureTask.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/AudioCaptureTask.cs b/wp7/template/Plugins/UI/AudioCaptureTask.cs
deleted file mode 100644
index 3d7d60f..0000000
--- a/wp7/template/Plugins/UI/AudioCaptureTask.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Audio Recording application.
- /// Use this to allow users to record audio from your application.
- /// </summary>
- public class AudioCaptureTask
- {
- /// <summary>
- /// Represents recorded audio returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
- /// </summary>
- public class AudioResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the AudioResult class.
- /// </summary>
- public AudioResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the AudioResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public AudioResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded audio.
- /// </summary>
- public Stream AudioFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded audio.
- /// </summary>
- public string AudioFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is AudioRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- AudioRecorder audioRecorder = (AudioRecorder)e.Content;
-
- if (audioRecorder != null)
- {
- audioRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new AudioResult(TaskResult.Cancel));
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/AudioRecorder.xaml
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/AudioRecorder.xaml b/wp7/template/Plugins/UI/AudioRecorder.xaml
deleted file mode 100644
index 0fd26ab..0000000
--- a/wp7/template/Plugins/UI/AudioRecorder.xaml
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Portrait" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Transparent">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
- <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
- </StackPanel>
-
- <!--ContentPanel - place additional content here-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0" VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
- <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
- <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
- </Grid>
- </Grid>
-
- <!--Sample code showing usage of ApplicationBar-->
- <!--<phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
- <shell:ApplicationBar.MenuItems>
- <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
- <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
- </shell:ApplicationBar.MenuItems>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>-->
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/AudioRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/AudioRecorder.xaml.cs b/wp7/template/Plugins/UI/AudioRecorder.xaml.cs
deleted file mode 100644
index 01a0832..0000000
--- a/wp7/template/Plugins/UI/AudioRecorder.xaml.cs
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Threading;
-using WPCordovaClassLib.Cordova.Commands;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Implements Audio Recording application
- /// </summary>
- public partial class AudioRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- private const string RecordingStartCaption = "Start";
- private const string RecordingStopCaption = "Stop";
-
- private const string LocalFolderName = "AudioCache";
- private const string FileNameFormat = "Audio-{0}.wav";
-
- #endregion
-
- #region Callbacks
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone microphone;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Recording duration
- /// </summary>
- private TimeSpan duration;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private AudioResult result = new AudioResult(TaskResult.Cancel);
-
- /// <summary>
- /// Whether we are recording audio now
- /// </summary>
- private bool IsRecording
- {
- get
- {
- return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
- }
- }
-
- #endregion
-
- /// <summary>
- /// Creates new instance of the AudioRecorder class.
- /// </summary>
- public AudioRecorder()
- {
-
- this.InitializeXnaGameLoop();
-
- // microphone requires special XNA initialization to work
- InitializeComponent();
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- private void StartRecording()
- {
- this.microphone = Microphone.Default;
- this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
-
- this.btnTake.IsEnabled = false;
- this.btnStartStop.Content = RecordingStopCaption;
-
- this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
- this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
-
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.microphone.SampleRate);
-
- this.duration = new TimeSpan(0);
-
- this.microphone.Start();
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- private void StopRecording()
- {
- this.microphone.Stop();
-
- this.microphone.BufferReady -= MicrophoneBufferReady;
-
- this.microphone = null;
-
- btnStartStop.Content = RecordingStartCaption;
-
- // check there is some data
- this.btnTake.IsEnabled = true;
- }
-
- /// <summary>
- /// Handles Start/Stop events
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStartStop_Click(object sender, RoutedEventArgs e)
- {
-
- if (this.IsRecording)
- {
- this.StopRecording();
- }
- else
- {
- this.StartRecording();
- }
- }
-
- /// <summary>
- /// Handles Take button click
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnTake_Click(object sender, RoutedEventArgs e)
- {
- this.result = this.SaveAudioClipToLocalStorage();
-
- if (Completed != null)
- {
- Completed(this, result);
- }
-
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Handles page closing event, stops recording if needed and dispatches results.
- /// </summary>
- /// <param name="e"></param>
- protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
- {
- if (IsRecording)
- {
- StopRecording();
- }
-
- this.FinalizeXnaGameLoop();
-
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Copies data from microphone to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void MicrophoneBufferReady(object sender, EventArgs e)
- {
- this.microphone.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- TimeSpan bufferDuration = this.microphone.BufferDuration;
-
- this.Dispatcher.BeginInvoke(() =>
- {
- this.duration += bufferDuration;
-
- this.txtDuration.Text = "Duration: " +
- this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
- this.duration.Seconds.ToString().PadLeft(2, '0');
- });
-
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private AudioResult SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return new AudioResult(TaskResult.Cancel);
- }
-
- this.memoryStream.UpdateWavStream();
-
- // save audio data to local isolated storage
-
- string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
-
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
- {
-
- this.memoryStream.CopyTo(fileStream);
- }
-
- AudioResult result = new AudioResult(TaskResult.OK);
- result.AudioFileName = filePath;
-
- result.AudioFile = this.memoryStream;
- result.AudioFile.Seek(0, SeekOrigin.Begin);
-
- return result;
- }
-
-
-
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (dtXna != null)
- {
- dtXna.Stop();
- dtXna = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/ImageCapture.xaml
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/ImageCapture.xaml b/wp7/template/Plugins/UI/ImageCapture.xaml
deleted file mode 100644
index a7eee21..0000000
--- a/wp7/template/Plugins/UI/ImageCapture.xaml
+++ /dev/null
@@ -1,26 +0,0 @@
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Yellow">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- </Grid>
-
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/ImageCapture.xaml.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/ImageCapture.xaml.cs b/wp7/template/Plugins/UI/ImageCapture.xaml.cs
deleted file mode 100644
index 234b444..0000000
--- a/wp7/template/Plugins/UI/ImageCapture.xaml.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class ImageCapture : PhoneApplicationPage
- {
- public ImageCapture()
- {
- InitializeComponent();
- }
- }
-
- public class ImageCaptureTask
- {
- /// <summary>
- /// Represents an image returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
- /// </summary>
- //public class AudioResult : TaskEventArgs
- //{
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class.
- // /// </summary>
- // public AudioResult()
- // { }
-
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class
- // /// with the specified Microsoft.Phone.Tasks.TaskResult.
- // /// </summary>
- // /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- // public AudioResult(TaskResult taskResult)
- // : base(taskResult)
- // { }
-
- // /// <summary>
- // /// Gets the file name of the recorded audio.
- // /// </summary>
- // public Stream AudioFile { get; internal set; }
-
- // /// <summary>
- // /// Gets the stream containing the data for the recorded audio.
- // /// </summary>
- // public string AudioFileName { get; internal set; }
- //}
-
- ///// <summary>
- ///// Occurs when a audio recording task is completed.
- ///// </summary>
- //public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- ImageCapture imageCapture = e.Content as ImageCapture;
- if (imageCapture != null)
- {
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- //imageCapture.Completed += this.Completed;
- //else if (this.Completed != null)
- //{
- // this.Completed(this, new AudioResult(TaskResult.Cancel));
- //}
- }
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/NotificationBox.xaml
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/NotificationBox.xaml b/wp7/template/Plugins/UI/NotificationBox.xaml
deleted file mode 100644
index 1ca5d5f..0000000
--- a/wp7/template/Plugins/UI/NotificationBox.xaml
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
- 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.
--->
-<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
-
- <Grid x:Name="LayoutRoot"
- Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
-
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel"
- Grid.Row="0"
- Background="{StaticResource PhoneSemitransparentBrush}">
- <TextBlock x:Name="PageTitle"
- Text="Title"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle2Style}"/>
-
- <TextBlock x:Name="SubTitle"
- Text="Subtitle"
- TextWrapping="Wrap"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle3Style}"/>
-
- <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
- <StackPanel x:Name="ButtonPanel"
- Margin="10,10"
- Orientation="Horizontal"/>
- </ScrollViewer>
-
- </StackPanel>
- </Grid>
-</UserControl>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/NotificationBox.xaml.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/NotificationBox.xaml.cs b/wp7/template/Plugins/UI/NotificationBox.xaml.cs
deleted file mode 100644
index 50b2f2a..0000000
--- a/wp7/template/Plugins/UI/NotificationBox.xaml.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class NotificationBox : UserControl
- {
- public NotificationBox()
- {
- InitializeComponent();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/VideoCaptureTask.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/VideoCaptureTask.cs b/wp7/template/Plugins/UI/VideoCaptureTask.cs
deleted file mode 100644
index 958c05c..0000000
--- a/wp7/template/Plugins/UI/VideoCaptureTask.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Video Recording application.
- /// Use this to allow users to record video from your application.
- /// </summary>
- public class VideoCaptureTask
- {
- /// <summary>
- /// Represents recorded video returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
- /// </summary>
- public class VideoResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the VideoResult class.
- /// </summary>
- public VideoResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the VideoResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public VideoResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded Video.
- /// </summary>
- public Stream VideoFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded Video.
- /// </summary>
- public string VideoFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a Video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- /// <summary>
- /// Shows Video Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is VideoRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
-
- if (VideoRecorder != null)
- {
- VideoRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new VideoResult(TaskResult.Cancel));
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/VideoRecorder.xaml
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/VideoRecorder.xaml b/wp7/template/Plugins/UI/VideoRecorder.xaml
deleted file mode 100644
index c78fdb0..0000000
--- a/wp7/template/Plugins/UI/VideoRecorder.xaml
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Landscape" Orientation="LandscapeLeft"
- shell:SystemTray.IsVisible="False">
-
- <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
-
- <Rectangle
- x:Name="viewfinderRectangle"
- Width="640"
- Height="480"
- HorizontalAlignment="Left"
- Canvas.Left="80"/>
-
- </Canvas>
-
- <phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record" x:Name="btnStartRecording" Click="StartRecording_Click" />
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/UI/VideoRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/UI/VideoRecorder.xaml.cs b/wp7/template/Plugins/UI/VideoRecorder.xaml.cs
deleted file mode 100644
index 6ab1cc3..0000000
--- a/wp7/template/Plugins/UI/VideoRecorder.xaml.cs
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media;
-using System.Windows.Navigation;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class VideoRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- /// <summary>
- /// Caption for record button in ready state
- /// </summary>
- private const string RecordingStartCaption = "Record";
-
- /// <summary>
- /// Caption for record button in recording state
- /// </summary>
- private const string RecordingStopCaption = "Stop";
-
- /// <summary>
- /// Start record icon URI
- /// </summary>
- private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
-
- /// <summary>
- /// Stop record icon URI
- /// </summary>
- private const string StopIconUri = "/Images/appbar.stop.rest.png";
-
- /// <summary>
- /// Folder to save video clips
- /// </summary>
- private const string LocalFolderName = "VideoCache";
-
- /// <summary>
- /// File name format
- /// </summary>
- private const string FileNameFormat = "Video-{0}.mp4";
-
- /// <summary>
- /// Temporary file name
- /// </summary>
- private const string defaultFileName = "NewVideoFile.mp4";
-
- #endregion
-
- #region Callbacks
- /// <summary>
- /// Occurs when a video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Viewfinder for capturing video
- /// </summary>
- private VideoBrush videoRecorderBrush;
-
- /// <summary>
- /// Path to save video clip
- /// </summary>
- private string filePath;
-
- /// <summary>
- /// Source for capturing video.
- /// </summary>
- private CaptureSource captureSource;
-
- /// <summary>
- /// Video device
- /// </summary>
- private VideoCaptureDevice videoCaptureDevice;
-
- /// <summary>
- /// File sink so save recording video in Isolated Storage
- /// </summary>
- private FileSink fileSink;
-
- /// <summary>
- /// For managing button and application state
- /// </summary>
- private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
-
- /// <summary>
- /// Current video state
- /// </summary>
- private VideoState currentVideoState;
-
- /// <summary>
- /// Stream to return result
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private VideoResult result = new VideoResult(TaskResult.Cancel);
-
- #endregion
-
- /// <summary>
- /// Initializes components
- /// </summary>
- public VideoRecorder()
- {
- InitializeComponent();
-
- PhoneAppBar = (ApplicationBar)ApplicationBar;
- PhoneAppBar.IsVisible = true;
- btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
- btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
- }
-
- /// <summary>
- /// Initializes the video recorder then page is loading
- /// </summary>
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- this.InitializeVideoRecorder();
- }
-
- /// <summary>
- /// Disposes camera and media objects then leave the page
- /// </summary>
- protected override void OnNavigatedFrom(NavigationEventArgs e)
- {
- this.DisposeVideoRecorder();
-
- if (this.Completed != null)
- {
- this.Completed(this, result);
- }
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Handles TakeVideo button click
- /// </summary>
- private void TakeVideo_Click(object sender, EventArgs e)
- {
- this.result = this.SaveVideoClip();
- this.NavigateBack();
- }
-
- private void NavigateBack()
- {
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Resaves video clip from temporary directory to persistent
- /// </summary>
- private VideoResult SaveVideoClip()
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
- {
- return new VideoResult(TaskResult.Cancel);
- }
-
- string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
- string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
- isoFile.CopyFile(filePath, newPath);
- isoFile.DeleteFile(filePath);
-
- memoryStream = new MemoryStream();
- using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
- {
- fileStream.CopyTo(memoryStream);
- }
-
- VideoResult result = new VideoResult(TaskResult.OK);
- result.VideoFileName = newPath;
- result.VideoFile = this.memoryStream;
- result.VideoFile.Seek(0, SeekOrigin.Begin);
- return result;
- }
-
- }
- catch (Exception)
- {
- return new VideoResult(TaskResult.None);
- }
- }
-
- /// <summary>
- /// Updates the buttons on the UI thread based on current state.
- /// </summary>
- /// <param name="currentState">current UI state</param>
- private void UpdateUI(VideoState currentState)
- {
- Dispatcher.BeginInvoke(delegate
- {
- switch (currentState)
- {
- case VideoState.CameraNotSupported:
- btnStartRecording.IsEnabled = false;
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Initialized:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Ready:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = true;
- break;
-
- case VideoState.Recording:
- btnStartRecording.Text = RecordingStopCaption;
- btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- default:
- break;
- }
- currentVideoState = currentState;
- });
- }
-
- /// <summary>
- /// Initializes VideoRecorder
- /// </summary>
- public void InitializeVideoRecorder()
- {
- if (captureSource == null)
- {
- captureSource = new CaptureSource();
- fileSink = new FileSink();
- videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
-
- if (videoCaptureDevice != null)
- {
- videoRecorderBrush = new VideoBrush();
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Initialized);
- }
- else
- {
- this.UpdateUI(VideoState.CameraNotSupported);
- }
- }
- }
-
- /// <summary>
- /// Sets recording state: start recording
- /// </summary>
- private void StartVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = captureSource;
- filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- }
-
- fileSink.IsolatedStorageFileName = filePath;
- }
-
- if (captureSource.VideoCaptureDevice != null
- && captureSource.State == CaptureState.Stopped)
- {
- captureSource.Start();
- }
- this.UpdateUI(VideoState.Recording);
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: stop recording
- /// </summary>
- private void StopVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = null;
- fileSink.IsolatedStorageFileName = null;
- this.StartVideoPreview();
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: display the video on the viewfinder.
- /// </summary>
- private void StartVideoPreview()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
- {
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Ready);
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Starts video recording
- /// </summary>
- private void StartRecording_Click(object sender, EventArgs e)
- {
- if (currentVideoState == VideoState.Recording)
- {
- this.StopVideoRecording();
- }
- else
- {
- this.StartVideoRecording();
- }
- }
-
- /// <summary>
- /// Releases resources
- /// </summary>
- private void DisposeVideoRecorder()
- {
- if (captureSource != null)
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- }
- captureSource = null;
- videoCaptureDevice = null;
- fileSink = null;
- videoRecorderBrush = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Accelerometer.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Accelerometer.cs b/wp8/template/Plugins/Accelerometer.cs
deleted file mode 100644
index cba911c..0000000
--- a/wp8/template/Plugins/Accelerometer.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Captures device motion in the x, y, and z direction.
- /// </summary>
- public class Accelerometer : BaseCommand
- {
- #region AccelerometerOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class AccelerometerOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public AccelerometerOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Frequency = 10000;
- }
- }
-
- #endregion
-
- #region Status codes and Constants
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 3;
-
- public const double gConstant = -9.81;
-
- #endregion
-
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Accelerometer
- /// </summary>
- private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
-
- private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
-
- #endregion
-
- /// <summary>
- /// Sensor listener event
- /// </summary>
- private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
- {
- this.SetStatus(Running);
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- /// <summary>
- /// Starts listening for acceleration sensor
- /// </summary>
- /// <returns>status of listener</returns>
- public void start(string options)
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return;
- }
- try
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
- accelerometer.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- public void stop(string options)
- {
- if (currentStatus == Running)
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
- accelerometer.Stop();
- this.SetStatus(Stopped);
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetCurrentAccelerationFormatted()
- {
- // convert to unix timestamp
- // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
- // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
- // this resolves an issue with inconsistencies between JS dates and Native DateTime
- string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
- (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
- return "{" + resultCoordinates + "}";
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/AudioFormatsHelper.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/AudioFormatsHelper.cs b/wp8/template/Plugins/AudioFormatsHelper.cs
deleted file mode 100644
index dca7ee6..0000000
--- a/wp8/template/Plugins/AudioFormatsHelper.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- 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.
-
- */
-
-using System;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides extra functionality to support different audio formats.
- /// </summary>
- public static class AudioFormatsHelper
- {
- #region Wav
- /// <summary>
- /// Adds wav file format header to the stream
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">The stream</param>
- /// <param name="sampleRate">Sample Rate</param>
- public static void InitializeWavStream(this Stream stream, int sampleRate)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- int numBits = 16;
- int numBytes = numBits / 8;
-
- stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
- stream.Write(BitConverter.GetBytes(16), 0, 4);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
- stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
- stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
- stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- }
-
- /// <summary>
- /// Updates wav file format header
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">Wav stream</param>
- public static void UpdateWavStream(this Stream stream)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- var position = stream.Position;
-
- stream.Seek(4, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
- stream.Seek(40, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
- stream.Seek(position, SeekOrigin.Begin);
- }
-
- #endregion
- }
-}
[46/50] [abbrv] git commit: renamed common-items to just common
Posted by pu...@apache.org.
renamed common-items to just common
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/d4f359a3
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/d4f359a3
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/d4f359a3
Branch: refs/heads/2.9.x
Commit: d4f359a361eb32903d3abf532b92c32598483907
Parents: 765c815
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 14:56:31 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 14:56:31 2013 -0700
----------------------------------------------------------------------
common-items/ApplicationIcon.png | Bin 4951 -> 0 bytes
common-items/Background.png | Bin 10259 -> 0 bytes
common-items/Images/appbar.back.rest.png | Bin 375 -> 0 bytes
common-items/Images/appbar.close.rest.png | Bin 359 -> 0 bytes
.../Images/appbar.feature.video.rest.png | Bin 433 -> 0 bytes
common-items/Images/appbar.next.rest.png | Bin 388 -> 0 bytes
common-items/Images/appbar.save.rest.png | Bin 297 -> 0 bytes
common-items/Images/appbar.stop.rest.png | Bin 350 -> 0 bytes
common-items/Plugins/Accelerometer.cs | 196 -
common-items/Plugins/AudioFormatsHelper.cs | 89 -
common-items/Plugins/AudioPlayer.cs | 620 --
common-items/Plugins/Battery.cs | 79 -
common-items/Plugins/Camera.cs | 490 --
common-items/Plugins/Capture.cs | 736 --
common-items/Plugins/Compass.cs | 362 -
common-items/Plugins/Contacts.cs | 664 --
common-items/Plugins/DebugConsole.cs | 49 -
common-items/Plugins/Device.cs | 135 -
common-items/Plugins/File.cs | 1676 -----
common-items/Plugins/FileTransfer.cs | 526 --
common-items/Plugins/GeoLocation.cs | 34 -
common-items/Plugins/Globalization.cs | 1177 ---
common-items/Plugins/ImageExifHelper.cs | 209 -
common-items/Plugins/InAppBrowser.cs | 271 -
common-items/Plugins/Media.cs | 547 --
common-items/Plugins/MimeTypeMapper.cs | 101 -
common-items/Plugins/NetworkStatus.cs | 129 -
common-items/Plugins/Notification.cs | 361 -
common-items/Plugins/UI/AudioCaptureTask.cs | 107 -
common-items/Plugins/UI/AudioRecorder.xaml | 66 -
common-items/Plugins/UI/AudioRecorder.xaml.cs | 307 -
common-items/Plugins/UI/ImageCapture.xaml | 26 -
common-items/Plugins/UI/ImageCapture.xaml.cs | 109 -
common-items/Plugins/UI/NotificationBox.xaml | 62 -
common-items/Plugins/UI/NotificationBox.xaml.cs | 41 -
common-items/Plugins/UI/VideoCaptureTask.cs | 105 -
common-items/Plugins/UI/VideoRecorder.xaml | 52 -
common-items/Plugins/UI/VideoRecorder.xaml.cs | 405 --
common-items/SplashScreenImage.jpg | Bin 33248 -> 0 bytes
common-items/__PreviewImage.jpg | Bin 25875 -> 0 bytes
common-items/__TemplateIcon.png | Bin 6546 -> 0 bytes
common-items/resources/notification-beep.wav | Bin 16630 -> 0 bytes
common-items/www/cordova.js | 6723 ------------------
common-items/www/css/index.css | 115 -
common-items/www/img/logo.png | Bin 21814 -> 0 bytes
common-items/www/index.html | 42 -
common-items/www/js/index.js | 49 -
common/ApplicationIcon.png | Bin 0 -> 4951 bytes
common/Background.png | Bin 0 -> 10259 bytes
common/Images/appbar.back.rest.png | Bin 0 -> 375 bytes
common/Images/appbar.close.rest.png | Bin 0 -> 359 bytes
common/Images/appbar.feature.video.rest.png | Bin 0 -> 433 bytes
common/Images/appbar.next.rest.png | Bin 0 -> 388 bytes
common/Images/appbar.save.rest.png | Bin 0 -> 297 bytes
common/Images/appbar.stop.rest.png | Bin 0 -> 350 bytes
common/Plugins/Accelerometer.cs | 196 +
common/Plugins/AudioFormatsHelper.cs | 89 +
common/Plugins/AudioPlayer.cs | 620 ++
common/Plugins/Battery.cs | 79 +
common/Plugins/Camera.cs | 490 ++
common/Plugins/Capture.cs | 736 ++
common/Plugins/Compass.cs | 362 +
common/Plugins/Contacts.cs | 664 ++
common/Plugins/DebugConsole.cs | 49 +
common/Plugins/Device.cs | 135 +
common/Plugins/File.cs | 1676 +++++
common/Plugins/FileTransfer.cs | 526 ++
common/Plugins/GeoLocation.cs | 34 +
common/Plugins/Globalization.cs | 1177 +++
common/Plugins/ImageExifHelper.cs | 209 +
common/Plugins/InAppBrowser.cs | 271 +
common/Plugins/Media.cs | 547 ++
common/Plugins/MimeTypeMapper.cs | 101 +
common/Plugins/NetworkStatus.cs | 129 +
common/Plugins/Notification.cs | 361 +
common/Plugins/UI/AudioCaptureTask.cs | 107 +
common/Plugins/UI/AudioRecorder.xaml | 66 +
common/Plugins/UI/AudioRecorder.xaml.cs | 307 +
common/Plugins/UI/ImageCapture.xaml | 26 +
common/Plugins/UI/ImageCapture.xaml.cs | 109 +
common/Plugins/UI/NotificationBox.xaml | 62 +
common/Plugins/UI/NotificationBox.xaml.cs | 41 +
common/Plugins/UI/VideoCaptureTask.cs | 105 +
common/Plugins/UI/VideoRecorder.xaml | 52 +
common/Plugins/UI/VideoRecorder.xaml.cs | 405 ++
common/SplashScreenImage.jpg | Bin 0 -> 33248 bytes
common/__PreviewImage.jpg | Bin 0 -> 25875 bytes
common/__TemplateIcon.png | Bin 0 -> 6546 bytes
common/resources/notification-beep.wav | Bin 0 -> 16630 bytes
common/www/cordova.js | 6723 ++++++++++++++++++
common/www/css/index.css | 115 +
common/www/img/logo.png | Bin 0 -> 21814 bytes
common/www/index.html | 42 +
common/www/js/index.js | 49 +
wp7/tooling/scripts/createTemplates.js | 22 +-
wp8/tooling/scripts/createTemplates.js | 25 +-
96 files changed, 16675 insertions(+), 16692 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/ApplicationIcon.png
----------------------------------------------------------------------
diff --git a/common-items/ApplicationIcon.png b/common-items/ApplicationIcon.png
deleted file mode 100644
index 6b69046..0000000
Binary files a/common-items/ApplicationIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Background.png
----------------------------------------------------------------------
diff --git a/common-items/Background.png b/common-items/Background.png
deleted file mode 100644
index 2667df4..0000000
Binary files a/common-items/Background.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Images/appbar.back.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.back.rest.png b/common-items/Images/appbar.back.rest.png
deleted file mode 100644
index 4bc2b92..0000000
Binary files a/common-items/Images/appbar.back.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Images/appbar.close.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.close.rest.png b/common-items/Images/appbar.close.rest.png
deleted file mode 100644
index 8166a1c..0000000
Binary files a/common-items/Images/appbar.close.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Images/appbar.feature.video.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.feature.video.rest.png b/common-items/Images/appbar.feature.video.rest.png
deleted file mode 100644
index baff565..0000000
Binary files a/common-items/Images/appbar.feature.video.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Images/appbar.next.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.next.rest.png b/common-items/Images/appbar.next.rest.png
deleted file mode 100644
index ed577d7..0000000
Binary files a/common-items/Images/appbar.next.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Images/appbar.save.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.save.rest.png b/common-items/Images/appbar.save.rest.png
deleted file mode 100644
index d49940e..0000000
Binary files a/common-items/Images/appbar.save.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Images/appbar.stop.rest.png
----------------------------------------------------------------------
diff --git a/common-items/Images/appbar.stop.rest.png b/common-items/Images/appbar.stop.rest.png
deleted file mode 100644
index 4dd724f..0000000
Binary files a/common-items/Images/appbar.stop.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Accelerometer.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Accelerometer.cs b/common-items/Plugins/Accelerometer.cs
deleted file mode 100644
index cba911c..0000000
--- a/common-items/Plugins/Accelerometer.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Captures device motion in the x, y, and z direction.
- /// </summary>
- public class Accelerometer : BaseCommand
- {
- #region AccelerometerOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class AccelerometerOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public AccelerometerOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Frequency = 10000;
- }
- }
-
- #endregion
-
- #region Status codes and Constants
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 3;
-
- public const double gConstant = -9.81;
-
- #endregion
-
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Accelerometer
- /// </summary>
- private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
-
- private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
-
- #endregion
-
- /// <summary>
- /// Sensor listener event
- /// </summary>
- private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
- {
- this.SetStatus(Running);
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- /// <summary>
- /// Starts listening for acceleration sensor
- /// </summary>
- /// <returns>status of listener</returns>
- public void start(string options)
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return;
- }
- try
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
- accelerometer.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- public void stop(string options)
- {
- if (currentStatus == Running)
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
- accelerometer.Stop();
- this.SetStatus(Stopped);
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetCurrentAccelerationFormatted()
- {
- // convert to unix timestamp
- // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
- // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
- // this resolves an issue with inconsistencies between JS dates and Native DateTime
- string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
- (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
- return "{" + resultCoordinates + "}";
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/AudioFormatsHelper.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/AudioFormatsHelper.cs b/common-items/Plugins/AudioFormatsHelper.cs
deleted file mode 100644
index dca7ee6..0000000
--- a/common-items/Plugins/AudioFormatsHelper.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- 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.
-
- */
-
-using System;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides extra functionality to support different audio formats.
- /// </summary>
- public static class AudioFormatsHelper
- {
- #region Wav
- /// <summary>
- /// Adds wav file format header to the stream
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">The stream</param>
- /// <param name="sampleRate">Sample Rate</param>
- public static void InitializeWavStream(this Stream stream, int sampleRate)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- int numBits = 16;
- int numBytes = numBits / 8;
-
- stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
- stream.Write(BitConverter.GetBytes(16), 0, 4);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
- stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
- stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
- stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- }
-
- /// <summary>
- /// Updates wav file format header
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">Wav stream</param>
- public static void UpdateWavStream(this Stream stream)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- var position = stream.Position;
-
- stream.Seek(4, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
- stream.Seek(40, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
- stream.Seek(position, SeekOrigin.Begin);
- }
-
- #endregion
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/AudioPlayer.cs b/common-items/Plugins/AudioPlayer.cs
deleted file mode 100644
index a83be5b..0000000
--- a/common-items/Plugins/AudioPlayer.cs
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Implements audio record and play back functionality.
- /// </summary>
- internal class AudioPlayer : IDisposable
- {
- #region Constants
-
- // AudioPlayer states
- private const int PlayerState_None = 0;
- private const int PlayerState_Starting = 1;
- private const int PlayerState_Running = 2;
- private const int PlayerState_Paused = 3;
- private const int PlayerState_Stopped = 4;
-
- // AudioPlayer messages
- private const int MediaState = 1;
- private const int MediaDuration = 2;
- private const int MediaPosition = 3;
- private const int MediaError = 9;
-
- // AudioPlayer errors
- private const int MediaErrorPlayModeSet = 1;
- private const int MediaErrorAlreadyRecording = 2;
- private const int MediaErrorStartingRecording = 3;
- private const int MediaErrorRecordModeSet = 4;
- private const int MediaErrorStartingPlayback = 5;
- private const int MediaErrorResumeState = 6;
- private const int MediaErrorPauseState = 7;
- private const int MediaErrorStopState = 8;
-
- //TODO: get rid of this callback, it should be universal
- //private const string CallbackFunction = "CordovaMediaonStatus";
-
- #endregion
-
- /// <summary>
- /// The AudioHandler object
- /// </summary>
- private Media handler;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// The id of this player (used to identify Media object in JavaScript)
- /// </summary>
- private String id;
-
- /// <summary>
- /// State of recording or playback
- /// </summary>
- private int state = PlayerState_None;
-
- /// <summary>
- /// File name to play or record to
- /// </summary>
- private String audioFile = null;
-
- /// <summary>
- /// Duration of audio
- /// </summary>
- private double duration = -1;
-
- /// <summary>
- /// Audio player object
- /// </summary>
- private MediaElement player = null;
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone recorder;
-
- /// <summary>
- /// Internal flag specified that we should only open audio w/o playing it
- /// </summary>
- private bool prepareOnly = false;
-
- /// <summary>
- /// Creates AudioPlayer instance
- /// </summary>
- /// <param name="handler">Media object</param>
- /// <param name="id">player id</param>
- public AudioPlayer(Media handler, String id)
- {
- this.handler = handler;
- this.id = id;
- }
-
- /// <summary>
- /// Destroys player and stop audio playing or recording
- /// </summary>
- public void Dispose()
- {
- if (this.player != null)
- {
- this.stopPlaying();
- this.player = null;
- }
- if (this.recorder != null)
- {
- this.stopRecording();
- this.recorder = null;
- }
-
- this.FinalizeXnaGameLoop();
- }
-
- private void InvokeCallback(int message, string value, bool removeHandler)
- {
- string args = string.Format("('{0}',{1},{2});", this.id, message, value);
- string callback = @"(function(id,msg,value){
- try {
- if (msg == Media.MEDIA_ERROR) {
- value = {'code':value};
- }
- Media.onStatus(id,msg,value);
- }
- catch(e) {
- console.log('Error calling Media.onStatus :: ' + e);
- }
- })" + args;
- this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
- }
-
- private void InvokeCallback(int message, int value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- private void InvokeCallback(int message, double value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- /// <param name="filePath"></param>
- public void startRecording(string filePath)
- {
- if (this.player != null)
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- }
- else if (this.recorder == null)
- {
- try
- {
- this.audioFile = filePath;
- this.InitializeXnaGameLoop();
- this.recorder = Microphone.Default;
- this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
- this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
- this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
- this.recorder.Start();
- FrameworkDispatcher.Update();
- this.SetState(PlayerState_Running);
- }
- catch (Exception)
- {
- InvokeCallback(MediaError, MediaErrorStartingRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
- }
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- public void stopRecording()
- {
- if (this.recorder != null)
- {
- if (this.state == PlayerState_Running)
- {
- try
- {
- this.recorder.Stop();
- this.recorder.BufferReady -= recorderBufferReady;
- this.recorder = null;
- SaveAudioClipToLocalStorage();
- this.FinalizeXnaGameLoop();
- this.SetState(PlayerState_Stopped);
- }
- catch (Exception)
- {
- //TODO
- }
- }
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- public void startPlaying(string filePath)
- {
- if (this.recorder != null)
- {
- InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
- return;
- }
-
-
- if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
- {
- try
- {
- // this.player is a MediaElement, it must be added to the visual tree in order to play
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
-
- this.player = grid.FindName("playerMediaElement") as MediaElement;
- if (this.player == null) // still null ?
- {
- this.player = new MediaElement();
- this.player.Name = "playerMediaElement";
- grid.Children.Add(this.player);
- this.player.Visibility = Visibility.Visible;
- }
- if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
- {
- this.player.Stop(); // stop it!
- }
-
- this.player.Source = null; // Garbage collect it.
- this.player.MediaOpened += MediaOpened;
- this.player.MediaEnded += MediaEnded;
- this.player.MediaFailed += MediaFailed;
- }
- }
- }
-
- this.audioFile = filePath;
-
- Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
- if (uri.IsAbsoluteUri)
- {
- this.player.Source = uri;
- }
- else
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- // try to unpack it from the dll into isolated storage
- StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
- if (fileResourceStreamInfo != null)
- {
- using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
- {
- byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
- string[] dirParts = filePath.Split('/');
- string dirName = "";
- for (int n = 0; n < dirParts.Length - 1; n++)
- {
- dirName += dirParts[n] + "/";
- }
- if (!isoFile.DirectoryExists(dirName))
- {
- isoFile.CreateDirectory(dirName);
- }
-
- using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
- {
- using (BinaryWriter writer = new BinaryWriter(outFile))
- {
- writer.Write(data);
- }
- }
- }
- }
- }
- if (isoFile.FileExists(filePath))
- {
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
- {
- this.player.SetSource(stream);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
- return;
- }
- }
- }
- this.SetState(PlayerState_Starting);
- }
- catch (Exception e)
- {
- Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
- }
- }
- else
- {
- if (this.state != PlayerState_Running)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorResumeState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
- }
- }
- }
-
- /// <summary>
- /// Callback to be invoked when the media source is ready for playback
- /// </summary>
- private void MediaOpened(object sender, RoutedEventArgs arg)
- {
- if (this.player != null)
- {
- this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
- InvokeCallback(MediaDuration, this.duration, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
- if (!this.prepareOnly)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- this.prepareOnly = false;
- }
- else
- {
- // TODO: occasionally MediaOpened is signalled, but player is null
- }
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has completed
- /// </summary>
- private void MediaEnded(object sender, RoutedEventArgs arg)
- {
- this.SetState(PlayerState_Stopped);
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has failed
- /// </summary>
- private void MediaFailed(object sender, RoutedEventArgs arg)
- {
- player.Stop();
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
- }
-
- /// <summary>
- /// Seek or jump to a new time in the track
- /// </summary>
- /// <param name="milliseconds">The new track position</param>
- public void seekToPlaying(int milliseconds)
- {
- if (this.player != null)
- {
- TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
- this.player.Position = tsPos;
- InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
- }
- }
-
- /// <summary>
- /// Set the volume of the player
- /// </summary>
- /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
- public void setVolume(double vol)
- {
- if (this.player != null)
- {
- this.player.Volume = vol;
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlaying()
- {
- if (this.state == PlayerState_Running)
- {
- this.player.Pause();
- this.SetState(PlayerState_Paused);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPauseState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
- }
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlaying()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- this.player.Stop();
-
- this.player.Position = new TimeSpan(0L);
- this.SetState(PlayerState_Stopped);
- }
- //else // Why is it an error to call stop on a stopped media?
- //{
- // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
- //}
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- /// <returns>current position</returns>
- public double getCurrentPosition()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- double currentPosition = this.player.Position.TotalSeconds;
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
- return currentPosition;
- }
- else
- {
- return 0;
- }
- }
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <returns>track duration</returns>
- public double getDuration(string filePath)
- {
- if (this.recorder != null)
- {
- return (-2);
- }
-
- if (this.player != null)
- {
- return this.duration;
-
- }
- else
- {
- this.prepareOnly = true;
- this.startPlaying(filePath);
- return this.duration;
- }
- }
-
- /// <summary>
- /// Sets the state and send it to JavaScript
- /// </summary>
- /// <param name="state">state</param>
- private void SetState(int state)
- {
- if (this.state != state)
- {
- InvokeCallback(MediaState, state, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
- }
-
- this.state = state;
- }
-
- #region record methods
-
- /// <summary>
- /// Copies data from recorder to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void recorderBufferReady(object sender, EventArgs e)
- {
- this.recorder.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private void SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return;
- }
-
- this.memoryStream.UpdateWavStream();
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- string directory = Path.GetDirectoryName(audioFile);
-
- if (!isoFile.DirectoryExists(directory))
- {
- isoFile.CreateDirectory(directory);
- }
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
- {
- this.memoryStream.CopyTo(fileStream);
- }
- }
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- #region Xna loop
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (this.dtXna != null)
- {
- this.dtXna.Stop();
- this.dtXna = null;
- }
- }
-
- #endregion
-
- #endregion
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Battery.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Battery.cs b/common-items/Plugins/Battery.cs
deleted file mode 100644
index 962959e..0000000
--- a/common-items/Plugins/Battery.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-using Microsoft.Phone.Info;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Listens for changes to the state of the battery on the device.
- /// Currently only the "isPlugged" parameter available via native APIs.
- /// </summary>
- public class Battery : BaseCommand
- {
- private bool isPlugged = false;
- private EventHandler powerChanged;
-
- public Battery()
- {
- powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- }
-
- public void start(string options)
- {
- // Register power changed event handler
- DeviceStatus.PowerSourceChanged += powerChanged;
-
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- public void stop(string options)
- {
- // Unregister power changed event handler
- DeviceStatus.PowerSourceChanged -= powerChanged;
- }
-
- private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
- {
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- private string GetCurrentBatteryStateFormatted()
- {
- string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
- "null",
- isPlugged ? "true" : "false"
- );
- batteryState = "{" + batteryState + "}";
- return batteryState;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Camera.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Camera.cs b/common-items/Plugins/Camera.cs
deleted file mode 100644
index 5ff8045..0000000
--- a/common-items/Plugins/Camera.cs
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Collections.Generic;
-using Microsoft.Phone.Tasks;
-using System.Runtime.Serialization;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Xna.Framework.Media;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Camera : BaseCommand
- {
-
- /// <summary>
- /// Return base64 encoded string
- /// </summary>
- private const int DATA_URL = 0;
-
- /// <summary>
- /// Return file uri
- /// </summary>
- private const int FILE_URI = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int PHOTOLIBRARY = 0;
-
- /// <summary>
- /// Take picture from camera
- /// </summary>
-
- private const int CAMERA = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int SAVEDPHOTOALBUM = 2;
-
- /// <summary>
- /// Take a picture of type JPEG
- /// </summary>
- private const int JPEG = 0;
-
- /// <summary>
- /// Take a picture of type PNG
- /// </summary>
- private const int PNG = 1;
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private const string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CameraOptions
- {
- /// <summary>
- /// Source to getPicture from.
- /// </summary>
- [DataMember(IsRequired = false, Name = "sourceType")]
- public int PictureSourceType { get; set; }
-
- /// <summary>
- /// Format of image that returned from getPicture.
- /// </summary>
- [DataMember(IsRequired = false, Name = "destinationType")]
- public int DestinationType { get; set; }
-
- /// <summary>
- /// Quality of saved image
- /// </summary>
- [DataMember(IsRequired = false, Name = "quality")]
- public int Quality { get; set; }
-
- /// <summary>
- /// Controls whether or not the image is also added to the device photo album.
- /// </summary>
- [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
- public bool SaveToPhotoAlbum { get; set; }
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "correctOrientation")]
- public bool CorrectOrientation { get; set; }
-
-
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "allowEdit")]
- public bool AllowEdit { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "encodingType")]
- public int EncodingType { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "mediaType")]
- public int MediaType { get; set; }
-
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetHeight")]
- public int TargetHeight { get; set; }
-
-
- /// <summary>
- /// Width in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetWidth")]
- public int TargetWidth { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public CameraOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- PictureSourceType = CAMERA;
- DestinationType = FILE_URI;
- Quality = 80;
- TargetHeight = -1;
- TargetWidth = -1;
- SaveToPhotoAlbum = false;
- CorrectOrientation = true;
- AllowEdit = false;
- MediaType = -1;
- EncodingType = -1;
- }
- }
-
- /// <summary>
- /// Used to open photo library
- /// </summary>
- PhotoChooserTask photoChooserTask;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Camera options
- /// </summary>
- CameraOptions cameraOptions;
-
- public void takePicture(string options)
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
- // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
- this.cameraOptions = new CameraOptions();
- this.cameraOptions.Quality = int.Parse(args[0]);
- this.cameraOptions.DestinationType = int.Parse(args[1]);
- this.cameraOptions.PictureSourceType = int.Parse(args[2]);
- this.cameraOptions.TargetWidth = int.Parse(args[3]);
- this.cameraOptions.TargetHeight = int.Parse(args[4]);
- this.cameraOptions.EncodingType = int.Parse(args[5]);
- this.cameraOptions.MediaType = int.Parse(args[6]);
- this.cameraOptions.AllowEdit = bool.Parse(args[7]);
- this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
- this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
-
- //this.cameraOptions = String.IsNullOrEmpty(options) ?
- // new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- //TODO Check if all the options are acceptable
-
-
- if (cameraOptions.PictureSourceType == CAMERA)
- {
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += onCameraTaskCompleted;
- cameraTask.Show();
- }
- else
- {
- if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
- {
- photoChooserTask = new PhotoChooserTask();
- photoChooserTask.Completed += onPickerTaskCompleted;
- photoChooserTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
- }
-
- public void onCameraTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- // Save image in media library
- if (cameraOptions.SaveToPhotoAlbum)
- {
- MediaLibrary library = new MediaLibrary();
- Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
- }
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
-
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
-
-
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
-
- }
-
- public void onPickerTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
-
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
- }
-
- /// <summary>
- /// Returns image content in a form of base64 string
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <returns>Base64 representation of the image</returns>
- private string GetImageContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
-
- //use photo's actual width & height if user doesn't provide width & height
- if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
- {
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
- else
- {
- // resize photo
- byte[] resizedFile = ResizePhoto(stream, fileData);
- stream.Close();
- return Convert.ToBase64String(resizedFile);
- }
- }
-
- /// <summary>
- /// Resize image
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <param name="fileData">File data</param>
- /// <returns>resized image</returns>
- private byte[] ResizePhoto(Stream stream, byte[] fileData)
- {
- int streamLength = (int)stream.Length;
- int intResult = 0;
-
- byte[] resizedFile;
-
- stream.Read(fileData, 0, streamLength);
-
- BitmapImage objBitmap = new BitmapImage();
- MemoryStream objBitmapStream = new MemoryStream(fileData);
- MemoryStream objBitmapStreamResized = new MemoryStream();
- WriteableBitmap objWB;
- objBitmap.SetSource(stream);
- objWB = new WriteableBitmap(objBitmap);
-
- // resize the photo with user defined TargetWidth & TargetHeight
- Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
-
- //Convert the resized stream to a byte array.
- streamLength = (int)objBitmapStreamResized.Length;
- resizedFile = new Byte[streamLength]; //-1
- objBitmapStreamResized.Position = 0;
- //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
- intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
-
- return resizedFile;
- }
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
- {
-
- if (image == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
-
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(isoFolder))
- {
- isoFile.CreateDirectory(isoFolder);
- }
-
- string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
-
- using (var stream = isoFile.CreateFile(filePath))
- {
- // resize image if Height and Width defined via options
- if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
- {
- image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
- }
- else
- {
- image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
- }
- }
-
- return new Uri(filePath, UriKind.Relative).ToString();
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- }
-}
[31/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/File.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/File.cs b/common-items/Plugins/File.cs
new file mode 100644
index 0000000..cde7a1c
--- /dev/null
+++ b/common-items/Plugins/File.cs
@@ -0,0 +1,1676 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Text;
+using System.Windows;
+using System.Windows.Resources;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides access to isolated storage
+ /// </summary>
+ public class File : BaseCommand
+ {
+ // Error codes
+ public const int NOT_FOUND_ERR = 1;
+ public const int SECURITY_ERR = 2;
+ public const int ABORT_ERR = 3;
+ public const int NOT_READABLE_ERR = 4;
+ public const int ENCODING_ERR = 5;
+ public const int NO_MODIFICATION_ALLOWED_ERR = 6;
+ public const int INVALID_STATE_ERR = 7;
+ public const int SYNTAX_ERR = 8;
+ public const int INVALID_MODIFICATION_ERR = 9;
+ public const int QUOTA_EXCEEDED_ERR = 10;
+ public const int TYPE_MISMATCH_ERR = 11;
+ public const int PATH_EXISTS_ERR = 12;
+
+ // File system options
+ public const int TEMPORARY = 0;
+ public const int PERSISTENT = 1;
+ public const int RESOURCE = 2;
+ public const int APPLICATION = 3;
+
+ /// <summary>
+ /// Temporary directory name
+ /// </summary>
+ private readonly string TMP_DIRECTORY_NAME = "tmp";
+
+ /// <summary>
+ /// Represents error code for callback
+ /// </summary>
+ [DataContract]
+ public class ErrorCode
+ {
+ /// <summary>
+ /// Error code
+ /// </summary>
+ [DataMember(IsRequired = true, Name = "code")]
+ public int Code { get; set; }
+
+ /// <summary>
+ /// Creates ErrorCode object
+ /// </summary>
+ public ErrorCode(int code)
+ {
+ this.Code = code;
+ }
+ }
+
+ /// <summary>
+ /// Represents File action options.
+ /// </summary>
+ [DataContract]
+ public class FileOptions
+ {
+ /// <summary>
+ /// File path
+ /// </summary>
+ ///
+ private string _fileName;
+ [DataMember(Name = "fileName")]
+ public string FilePath
+ {
+ get
+ {
+ return this._fileName;
+ }
+
+ set
+ {
+ int index = value.IndexOfAny(new char[] { '#', '?' });
+ this._fileName = index > -1 ? value.Substring(0, index) : value;
+ }
+ }
+
+ /// <summary>
+ /// Full entryPath
+ /// </summary>
+ [DataMember(Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ /// <summary>
+ /// Directory name
+ /// </summary>
+ [DataMember(Name = "dirName")]
+ public string DirectoryName { get; set; }
+
+ /// <summary>
+ /// Path to create file/directory
+ /// </summary>
+ [DataMember(Name = "path")]
+ public string Path { get; set; }
+
+ /// <summary>
+ /// The encoding to use to encode the file's content. Default is UTF8.
+ /// </summary>
+ [DataMember(Name = "encoding")]
+ public string Encoding { get; set; }
+
+ /// <summary>
+ /// Uri to get file
+ /// </summary>
+ ///
+ private string _uri;
+ [DataMember(Name = "uri")]
+ public string Uri
+ {
+ get
+ {
+ return this._uri;
+ }
+
+ set
+ {
+ int index = value.IndexOfAny(new char[] { '#', '?' });
+ this._uri = index > -1 ? value.Substring(0, index) : value;
+ }
+ }
+
+ /// <summary>
+ /// Size to truncate file
+ /// </summary>
+ [DataMember(Name = "size")]
+ public long Size { get; set; }
+
+ /// <summary>
+ /// Data to write in file
+ /// </summary>
+ [DataMember(Name = "data")]
+ public string Data { get; set; }
+
+ /// <summary>
+ /// Position the writing starts with
+ /// </summary>
+ [DataMember(Name = "position")]
+ public int Position { get; set; }
+
+ /// <summary>
+ /// Type of file system requested
+ /// </summary>
+ [DataMember(Name = "type")]
+ public int FileSystemType { get; set; }
+
+ /// <summary>
+ /// New file/directory name
+ /// </summary>
+ [DataMember(Name = "newName")]
+ public string NewName { get; set; }
+
+ /// <summary>
+ /// Destination directory to copy/move file/directory
+ /// </summary>
+ [DataMember(Name = "parent")]
+ public string Parent { get; set; }
+
+ /// <summary>
+ /// Options for getFile/getDirectory methods
+ /// </summary>
+ [DataMember(Name = "options")]
+ public CreatingOptions CreatingOpt { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public FileOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ this.Encoding = "UTF-8";
+ this.FilePath = "";
+ this.FileSystemType = -1;
+ }
+ }
+
+ /// <summary>
+ /// Stores image info
+ /// </summary>
+ [DataContract]
+ public class FileMetadata
+ {
+ [DataMember(Name = "fileName")]
+ public string FileName { get; set; }
+
+ [DataMember(Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ [DataMember(Name = "type")]
+ public string Type { get; set; }
+
+ [DataMember(Name = "lastModifiedDate")]
+ public string LastModifiedDate { get; set; }
+
+ [DataMember(Name = "size")]
+ public long Size { get; set; }
+
+ public FileMetadata(string filePath)
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ throw new FileNotFoundException("File doesn't exist");
+ }
+ else if (!isoFile.FileExists(filePath))
+ {
+ // attempt to get it from the resources
+ if (filePath.IndexOf("www") == 0)
+ {
+ Uri fileUri = new Uri(filePath, UriKind.Relative);
+ StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
+ if (streamInfo != null)
+ {
+ this.Size = streamInfo.Stream.Length;
+ this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
+ this.FullPath = filePath;
+ }
+ }
+ else
+ {
+ throw new FileNotFoundException("File doesn't exist");
+ }
+ }
+ else
+ {
+ //TODO get file size the other way if possible
+ using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
+ {
+ this.Size = stream.Length;
+ }
+ this.FullPath = filePath;
+ this.FileName = System.IO.Path.GetFileName(filePath);
+ this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
+ }
+ this.Type = MimeTypeMapper.GetMimeType(this.FileName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents file or directory modification metadata
+ /// </summary>
+ [DataContract]
+ public class ModificationMetadata
+ {
+ /// <summary>
+ /// Modification time
+ /// </summary>
+ [DataMember]
+ public string modificationTime { get; set; }
+ }
+
+ /// <summary>
+ /// Represents file or directory entry
+ /// </summary>
+ [DataContract]
+ public class FileEntry
+ {
+
+ /// <summary>
+ /// File type
+ /// </summary>
+ [DataMember(Name = "isFile")]
+ public bool IsFile { get; set; }
+
+ /// <summary>
+ /// Directory type
+ /// </summary>
+ [DataMember(Name = "isDirectory")]
+ public bool IsDirectory { get; set; }
+
+ /// <summary>
+ /// File/directory name
+ /// </summary>
+ [DataMember(Name = "name")]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Full path to file/directory
+ /// </summary>
+ [DataMember(Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ public bool IsResource { get; set; }
+
+ public static FileEntry GetEntry(string filePath, bool bIsRes=false)
+ {
+ FileEntry entry = null;
+ try
+ {
+ entry = new FileEntry(filePath, bIsRes);
+
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
+ }
+ return entry;
+ }
+
+ /// <summary>
+ /// Creates object and sets necessary properties
+ /// </summary>
+ /// <param name="filePath"></param>
+ public FileEntry(string filePath, bool bIsRes = false)
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ throw new ArgumentException();
+ }
+
+ if(filePath.Contains(" "))
+ {
+ Debug.WriteLine("FilePath with spaces :: " + filePath);
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ IsResource = bIsRes;
+ IsFile = isoFile.FileExists(filePath);
+ IsDirectory = isoFile.DirectoryExists(filePath);
+ if (IsFile)
+ {
+ this.Name = Path.GetFileName(filePath);
+ }
+ else if (IsDirectory)
+ {
+ this.Name = this.GetDirectoryName(filePath);
+ if (string.IsNullOrEmpty(Name))
+ {
+ this.Name = "/";
+ }
+ }
+ else
+ {
+ if (IsResource)
+ {
+ this.Name = Path.GetFileName(filePath);
+ }
+ else
+ {
+ throw new FileNotFoundException();
+ }
+ }
+
+ try
+ {
+ this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
+ }
+ catch (Exception)
+ {
+ this.FullPath = filePath;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Extracts directory name from path string
+ /// Path should refer to a directory, for example \foo\ or /foo.
+ /// </summary>
+ /// <param name="path"></param>
+ /// <returns></returns>
+ private string GetDirectoryName(string path)
+ {
+ if (String.IsNullOrEmpty(path))
+ {
+ return path;
+ }
+
+ string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
+ if (split.Length < 1)
+ {
+ return null;
+ }
+ else
+ {
+ return split[split.Length - 1];
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Represents info about requested file system
+ /// </summary>
+ [DataContract]
+ public class FileSystemInfo
+ {
+ /// <summary>
+ /// file system type
+ /// </summary>
+ [DataMember(Name = "name", IsRequired = true)]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Root directory entry
+ /// </summary>
+ [DataMember(Name = "root", EmitDefaultValue = false)]
+ public FileEntry Root { get; set; }
+
+ /// <summary>
+ /// Creates class instance
+ /// </summary>
+ /// <param name="name"></param>
+ /// <param name="rootEntry"> Root directory</param>
+ public FileSystemInfo(string name, FileEntry rootEntry = null)
+ {
+ Name = name;
+ Root = rootEntry;
+ }
+ }
+
+ [DataContract]
+ public class CreatingOptions
+ {
+ /// <summary>
+ /// Create file/directory if is doesn't exist
+ /// </summary>
+ [DataMember(Name = "create")]
+ public bool Create { get; set; }
+
+ /// <summary>
+ /// Generate an exception if create=true and file/directory already exists
+ /// </summary>
+ [DataMember(Name = "exclusive")]
+ public bool Exclusive { get; set; }
+
+
+ }
+
+ // returns null value if it fails.
+ private string[] getOptionStrings(string options)
+ {
+ string[] optStings = null;
+ try
+ {
+ optStings = JSON.JsonHelper.Deserialize<string[]>(options);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
+ }
+ return optStings;
+ }
+
+ /// <summary>
+ /// Gets amount of free space available for Isolated Storage
+ /// </summary>
+ /// <param name="options">No options is needed for this method</param>
+ public void getFreeDiskSpace(string options)
+ {
+ string callbackId = getOptionStrings(options)[0];
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
+ }
+ }
+ catch (IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Check if file exists
+ /// </summary>
+ /// <param name="options">File path</param>
+ public void testFileExists(string options)
+ {
+ IsDirectoryOrFileExist(options, false);
+ }
+
+ /// <summary>
+ /// Check if directory exists
+ /// </summary>
+ /// <param name="options">directory name</param>
+ public void testDirectoryExists(string options)
+ {
+ IsDirectoryOrFileExist(options, true);
+ }
+
+ /// <summary>
+ /// Check if file or directory exist
+ /// </summary>
+ /// <param name="options">File path/Directory name</param>
+ /// <param name="isDirectory">Flag to recognize what we should check</param>
+ public void IsDirectoryOrFileExist(string options, bool isDirectory)
+ {
+ string[] args = getOptionStrings(options);
+ string callbackId = args[1];
+ FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
+ string filePath = args[0];
+
+ if (fileOptions == null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
+ }
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ bool isExist;
+ if (isDirectory)
+ {
+ isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
+ }
+ else
+ {
+ isExist = isoFile.FileExists(fileOptions.FilePath);
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
+ }
+ }
+ catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+
+ }
+
+ public void readAsDataURL(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ int startPos = int.Parse(optStrings[1]);
+ int endPos = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+
+ if (filePath != null)
+ {
+ try
+ {
+ string base64URL = null;
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+ string mimeType = MimeTypeMapper.GetMimeType(filePath);
+
+ using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
+ {
+ string base64String = GetFileContent(stream);
+ base64URL = "data:" + mimeType + ";base64," + base64String;
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+ }
+
+ public void readAsArrayBuffer(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ int startPos = int.Parse(optStrings[1]);
+ int endPos = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
+ }
+
+ public void readAsBinaryString(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ int startPos = int.Parse(optStrings[1]);
+ int endPos = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
+ }
+
+ public void readAsText(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ string encStr = optStrings[1];
+ int startPos = int.Parse(optStrings[2]);
+ int endPos = int.Parse(optStrings[3]);
+ string callbackId = optStrings[4];
+
+ try
+ {
+ string text = "";
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ readResourceAsText(options);
+ return;
+ }
+ Encoding encoding = Encoding.GetEncoding(encStr);
+
+ using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
+ {
+ text = reader.ReadToEnd();
+ if (startPos < 0)
+ {
+ startPos = Math.Max(text.Length + startPos, 0);
+ }
+ else if (startPos > 0)
+ {
+ startPos = Math.Min(text.Length, startPos);
+ }
+
+ if (endPos > 0)
+ {
+ endPos = Math.Min(text.Length, endPos);
+ }
+ else if (endPos < 0)
+ {
+ endPos = Math.Max(endPos + text.Length, 0);
+ }
+
+
+ text = text.Substring(startPos, endPos - startPos);
+
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Reads application resource as a text
+ /// </summary>
+ /// <param name="options">Path to a resource</param>
+ public void readResourceAsText(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string pathToResource = optStrings[0];
+ string encStr = optStrings[1];
+ int start = int.Parse(optStrings[2]);
+ int endMarker = int.Parse(optStrings[3]);
+ string callbackId = optStrings[4];
+
+ try
+ {
+ if (pathToResource.StartsWith("/"))
+ {
+ pathToResource = pathToResource.Remove(0, 1);
+ }
+
+ var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
+
+ if (resource == null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ string text;
+ StreamReader streamReader = new StreamReader(resource.Stream);
+ text = streamReader.ReadToEnd();
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ public void truncate(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+
+ string filePath = optStrings[0];
+ int size = int.Parse(optStrings[1]);
+ string callbackId = optStrings[2];
+
+ try
+ {
+ long streamLength = 0;
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
+ {
+ if (0 <= size && size <= stream.Length)
+ {
+ stream.SetLength(size);
+ }
+ streamLength = stream.Length;
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ //write:["filePath","data","position"],
+ public void write(string options)
+ {
+ // TODO: try/catch
+ string[] optStrings = getOptionStrings(options);
+
+ string filePath = optStrings[0];
+ string data = optStrings[1];
+ int position = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+
+ try
+ {
+ if (string.IsNullOrEmpty(data))
+ {
+ Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ // create the file if not exists
+ if (!isoFile.FileExists(filePath))
+ {
+ var file = isoFile.CreateFile(filePath);
+ file.Close();
+ }
+
+ using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
+ {
+ if (0 <= position && position <= stream.Length)
+ {
+ stream.SetLength(position);
+ }
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Seek(0, SeekOrigin.End);
+ writer.Write(data.ToCharArray());
+ }
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Look up metadata about this entry.
+ /// </summary>
+ /// <param name="options">filePath to entry</param>
+ public void getMetadata(string options)
+ {
+ string[] optStings = getOptionStrings(options);
+ string filePath = optStings[0];
+ string callbackId = optStings[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.FileExists(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
+ new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
+ }
+ else if (isoFile.DirectoryExists(filePath))
+ {
+ string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+
+ }
+ }
+ catch (IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ }
+
+
+ /// <summary>
+ /// Returns a File that represents the current state of the file that this FileEntry represents.
+ /// </summary>
+ /// <param name="filePath">filePath to entry</param>
+ /// <returns></returns>
+ public void getFileMetadata(string options)
+ {
+ string[] optStings = getOptionStrings(options);
+ string filePath = optStings[0];
+ string callbackId = optStings[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ FileMetadata metaData = new FileMetadata(filePath);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
+ }
+ catch (IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Look up the parent DirectoryEntry containing this Entry.
+ /// If this Entry is the root of IsolatedStorage, its parent is itself.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getParent(string options)
+ {
+ string[] optStings = getOptionStrings(options);
+ string filePath = optStings[0];
+ string callbackId = optStings[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ FileEntry entry;
+
+ if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
+ {
+
+
+ string path = this.GetParentDirectory(filePath);
+ entry = FileEntry.GetEntry(path);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+ }
+ }
+ }
+
+ public void remove(string options)
+ {
+ string[] args = getOptionStrings(options);
+ string filePath = args[0];
+ string callbackId = args[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ if (filePath == "/" || filePath == "" || filePath == @"\")
+ {
+ throw new Exception("Cannot delete root file system") ;
+ }
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.FileExists(filePath))
+ {
+ isoFile.DeleteFile(filePath);
+ }
+ else
+ {
+ if (isoFile.DirectoryExists(filePath))
+ {
+ isoFile.DeleteDirectory(filePath);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ return;
+ }
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ }
+ }
+ }
+ }
+
+ public void removeRecursively(string options)
+ {
+ string[] args = getOptionStrings(options);
+ string filePath = args[0];
+ string callbackId = args[1];
+
+ if (filePath != null)
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
+ }
+ else
+ {
+ if (removeDirRecursively(filePath, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
+ }
+ }
+ }
+ }
+
+ public void readEntries(string options)
+ {
+ string[] args = getOptionStrings(options);
+ string filePath = args[0];
+ string callbackId = args[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.DirectoryExists(filePath))
+ {
+ string path = File.AddSlashToDirectory(filePath);
+ List<FileEntry> entries = new List<FileEntry>();
+ string[] files = isoFile.GetFileNames(path + "*");
+ string[] dirs = isoFile.GetDirectoryNames(path + "*");
+ foreach (string file in files)
+ {
+ entries.Add(FileEntry.GetEntry(path + file));
+ }
+ foreach (string dir in dirs)
+ {
+ entries.Add(FileEntry.GetEntry(path + dir + "/"));
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ }
+ }
+ }
+ }
+
+ public void requestFileSystem(string options)
+ {
+ // TODO: try/catch
+ string[] optVals = getOptionStrings(options);
+ //FileOptions fileOptions = new FileOptions();
+ int fileSystemType = int.Parse(optVals[0]);
+ double size = double.Parse(optVals[1]);
+ string callbackId = optVals[2];
+
+
+ IsolatedStorageFile.GetUserStoreForApplication();
+
+ if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
+ return;
+ }
+
+ try
+ {
+ if (size != 0)
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ long availableSize = isoFile.AvailableFreeSpace;
+ if (size > availableSize)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
+ return;
+ }
+ }
+ }
+
+ if (fileSystemType == PERSISTENT)
+ {
+ // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
+ }
+ else if (fileSystemType == TEMPORARY)
+ {
+ using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
+ {
+ isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
+ }
+ }
+
+ string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
+ }
+ else if (fileSystemType == RESOURCE)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
+ }
+ else if (fileSystemType == APPLICATION)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+
+ public void resolveLocalFileSystemURI(string options)
+ {
+
+ string[] optVals = getOptionStrings(options);
+ string uri = optVals[0].Split('?')[0];
+ string callbackId = optVals[1];
+
+ if (uri != null)
+ {
+ // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
+ if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+ try
+ {
+ // fix encoded spaces
+ string path = Uri.UnescapeDataString(uri);
+
+ FileEntry uriEntry = FileEntry.GetEntry(path);
+ if (uriEntry != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+ }
+
+ public void copyTo(string options)
+ {
+ TransferTo(options, false);
+ }
+
+ public void moveTo(string options)
+ {
+ TransferTo(options, true);
+ }
+
+ public void getFile(string options)
+ {
+ GetFileOrDirectory(options, false);
+ }
+
+ public void getDirectory(string options)
+ {
+ GetFileOrDirectory(options, true);
+ }
+
+ #region internal functionality
+
+ /// <summary>
+ /// Retrieves the parent directory name of the specified path,
+ /// </summary>
+ /// <param name="path">Path</param>
+ /// <returns>Parent directory name</returns>
+ private string GetParentDirectory(string path)
+ {
+ if (String.IsNullOrEmpty(path) || path == "/")
+ {
+ return "/";
+ }
+
+ if (path.EndsWith(@"/") || path.EndsWith(@"\"))
+ {
+ return this.GetParentDirectory(Path.GetDirectoryName(path));
+ }
+
+ string result = Path.GetDirectoryName(path);
+ if (result == null)
+ {
+ result = "/";
+ }
+
+ return result;
+ }
+
+ private bool removeDirRecursively(string fullPath,string callbackId)
+ {
+ try
+ {
+ if (fullPath == "/")
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ return false;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.DirectoryExists(fullPath))
+ {
+ string tempPath = File.AddSlashToDirectory(fullPath);
+ string[] files = isoFile.GetFileNames(tempPath + "*");
+ if (files.Length > 0)
+ {
+ foreach (string file in files)
+ {
+ isoFile.DeleteFile(tempPath + file);
+ }
+ }
+ string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
+ if (dirs.Length > 0)
+ {
+ foreach (string dir in dirs)
+ {
+ if (!removeDirRecursively(tempPath + dir, callbackId))
+ {
+ return false;
+ }
+ }
+ }
+ isoFile.DeleteDirectory(fullPath);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private bool CanonicalCompare(string pathA, string pathB)
+ {
+ string a = pathA.Replace("//", "/");
+ string b = pathB.Replace("//", "/");
+
+ return a.Equals(b, StringComparison.OrdinalIgnoreCase);
+ }
+
+ /*
+ * copyTo:["fullPath","parent", "newName"],
+ * moveTo:["fullPath","parent", "newName"],
+ */
+ private void TransferTo(string options, bool move)
+ {
+ // TODO: try/catch
+ string[] optStrings = getOptionStrings(options);
+ string fullPath = optStrings[0];
+ string parent = optStrings[1];
+ string newFileName = optStrings[2];
+ string callbackId = optStrings[3];
+
+ char[] invalids = Path.GetInvalidPathChars();
+
+ if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+
+ try
+ {
+ if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ string parentPath = File.AddSlashToDirectory(parent);
+ string currentPath = fullPath;
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ bool isFileExist = isoFile.FileExists(currentPath);
+ bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
+ bool isParentExist = isoFile.DirectoryExists(parentPath);
+
+ if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+ string newName;
+ string newPath;
+ if (isFileExist)
+ {
+ newName = (string.IsNullOrEmpty(newFileName))
+ ? Path.GetFileName(currentPath)
+ : newFileName;
+
+ newPath = Path.Combine(parentPath, newName);
+
+ // sanity check ..
+ // cannot copy file onto itself
+ if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
+ return;
+ }
+ else if (isoFile.DirectoryExists(newPath))
+ {
+ // there is already a folder with the same name, operation is not allowed
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
+ return;
+ }
+ else if (isoFile.FileExists(newPath))
+ { // remove destination file if exists, in other case there will be exception
+ isoFile.DeleteFile(newPath);
+ }
+
+ if (move)
+ {
+ isoFile.MoveFile(currentPath, newPath);
+ }
+ else
+ {
+ isoFile.CopyFile(currentPath, newPath, true);
+ }
+ }
+ else
+ {
+ newName = (string.IsNullOrEmpty(newFileName))
+ ? currentPath
+ : newFileName;
+
+ newPath = Path.Combine(parentPath, newName);
+
+ if (move)
+ {
+ // remove destination directory if exists, in other case there will be exception
+ // target directory should be empty
+ if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
+ {
+ isoFile.DeleteDirectory(newPath);
+ }
+
+ isoFile.MoveDirectory(currentPath, newPath);
+ }
+ else
+ {
+ CopyDirectory(currentPath, newPath, isoFile);
+ }
+ }
+ FileEntry entry = FileEntry.GetEntry(newPath);
+ if (entry != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+
+ private bool HandleException(Exception ex, string cbId="")
+ {
+ bool handled = false;
+ string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
+ if (ex is SecurityException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is FileNotFoundException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is ArgumentException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is DirectoryNotFoundException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ handled = true;
+ }
+ return handled;
+ }
+
+ private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
+ {
+ string path = File.AddSlashToDirectory(sourceDir);
+
+ bool bExists = isoFile.DirectoryExists(destDir);
+
+ if (!bExists)
+ {
+ isoFile.CreateDirectory(destDir);
+ }
+
+ destDir = File.AddSlashToDirectory(destDir);
+
+ string[] files = isoFile.GetFileNames(path + "*");
+
+ if (files.Length > 0)
+ {
+ foreach (string file in files)
+ {
+ isoFile.CopyFile(path + file, destDir + file,true);
+ }
+ }
+ string[] dirs = isoFile.GetDirectoryNames(path + "*");
+ if (dirs.Length > 0)
+ {
+ foreach (string dir in dirs)
+ {
+ CopyDirectory(path + dir, destDir + dir, isoFile);
+ }
+ }
+ }
+
+ private void GetFileOrDirectory(string options, bool getDirectory)
+ {
+ FileOptions fOptions = new FileOptions();
+ string[] args = getOptionStrings(options);
+
+ fOptions.FullPath = args[0];
+ fOptions.Path = args[1];
+
+ string callbackId = args[3];
+
+ try
+ {
+ fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
+ return;
+ }
+
+ try
+ {
+ if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ string path;
+
+ if (fOptions.Path.Split(':').Length > 2)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+
+ try
+ {
+ path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ bool isFile = isoFile.FileExists(path);
+ bool isDirectory = isoFile.DirectoryExists(path);
+ bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
+ bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
+ if (create)
+ {
+ if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
+ return;
+ }
+
+ // need to make sure the parent exists
+ // it is an error to create a directory whose immediate parent does not yet exist
+ // see issue: https://issues.apache.org/jira/browse/CB-339
+ string[] pathParts = path.Split('/');
+ string builtPath = pathParts[0];
+ for (int n = 1; n < pathParts.Length - 1; n++)
+ {
+ builtPath += "/" + pathParts[n];
+ if (!isoFile.DirectoryExists(builtPath))
+ {
+ Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+ }
+
+ if ((getDirectory) && (!isDirectory))
+ {
+ isoFile.CreateDirectory(path);
+ }
+ else
+ {
+ if ((!getDirectory) && (!isFile))
+ {
+
+ IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
+ fileStream.Close();
+ }
+ }
+ }
+ else // (not create)
+ {
+ if ((!isFile) && (!isDirectory))
+ {
+ if (path.IndexOf("//www") == 0)
+ {
+ Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
+ StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
+ if (streamInfo != null)
+ {
+ FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
+
+ //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
+ //{
+ // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
+
+ //}
+
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+
+
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ return;
+ }
+ if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
+ return;
+ }
+ }
+ FileEntry entry = FileEntry.GetEntry(path);
+ if (entry != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+
+ private static string AddSlashToDirectory(string dirPath)
+ {
+ if (dirPath.EndsWith("/"))
+ {
+ return dirPath;
+ }
+ else
+ {
+ return dirPath + "/";
+ }
+ }
+
+ /// <summary>
+ /// Returns file content in a form of base64 string
+ /// </summary>
+ /// <param name="stream">File stream</param>
+ /// <returns>Base64 representation of the file</returns>
+ private string GetFileContent(Stream stream)
+ {
+ int streamLength = (int)stream.Length;
+ byte[] fileData = new byte[streamLength + 1];
+ stream.Read(fileData, 0, streamLength);
+ stream.Close();
+ return Convert.ToBase64String(fileData);
+ }
+
+ #endregion
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/FileTransfer.cs b/common-items/Plugins/FileTransfer.cs
new file mode 100644
index 0000000..e585895
--- /dev/null
+++ b/common-items/Plugins/FileTransfer.cs
@@ -0,0 +1,526 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Net;
+using System.Runtime.Serialization;
+using System.Windows;
+using System.Security;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class FileTransfer : BaseCommand
+ {
+ public class DownloadRequestState
+ {
+ // This class stores the State of the request.
+ public HttpWebRequest request;
+ public DownloadOptions options;
+
+ public DownloadRequestState()
+ {
+ request = null;
+ options = null;
+ }
+ }
+
+ /// <summary>
+ /// Boundary symbol
+ /// </summary>
+ private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
+
+ // Error codes
+ public const int FileNotFoundError = 1;
+ public const int InvalidUrlError = 2;
+ public const int ConnectionError = 3;
+
+ /// <summary>
+ /// Options for downloading file
+ /// </summary>
+ [DataContract]
+ public class DownloadOptions
+ {
+ /// <summary>
+ /// File path to download to
+ /// </summary>
+ [DataMember(Name = "filePath", IsRequired = true)]
+ public string FilePath { get; set; }
+
+ /// <summary>
+ /// Server address to the file to download
+ /// </summary>
+ [DataMember(Name = "url", IsRequired = true)]
+ public string Url { get; set; }
+ }
+
+ /// <summary>
+ /// Options for uploading file
+ /// </summary>
+ [DataContract]
+ public class UploadOptions
+ {
+ /// <summary>
+ /// File path to upload
+ /// </summary>
+ [DataMember(Name = "filePath", IsRequired = true)]
+ public string FilePath { get; set; }
+
+ /// <summary>
+ /// Server address
+ /// </summary>
+ [DataMember(Name = "server", IsRequired = true)]
+ public string Server { get; set; }
+
+ /// <summary>
+ /// File key
+ /// </summary>
+ [DataMember(Name = "fileKey")]
+ public string FileKey { get; set; }
+
+ /// <summary>
+ /// File name on the server
+ /// </summary>
+ [DataMember(Name = "fileName")]
+ public string FileName { get; set; }
+
+ /// <summary>
+ /// File Mime type
+ /// </summary>
+ [DataMember(Name = "mimeType")]
+ public string MimeType { get; set; }
+
+
+ /// <summary>
+ /// Additional options
+ /// </summary>
+ [DataMember(Name = "params")]
+ public string Params { get; set; }
+
+ /// <summary>
+ /// Flag to recognize if we should trust every host (only in debug environments)
+ /// </summary>
+ [DataMember(Name = "debug")]
+ public bool Debug { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public UploadOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ this.FileKey = "file";
+ this.FileName = "image.jpg";
+ this.MimeType = "image/jpeg";
+ }
+
+ }
+
+ /// <summary>
+ /// Uploading response info
+ /// </summary>
+ [DataContract]
+ public class FileUploadResult
+ {
+ /// <summary>
+ /// Amount of sent bytes
+ /// </summary>
+ [DataMember(Name = "bytesSent")]
+ public long BytesSent { get; set; }
+
+ /// <summary>
+ /// Server response code
+ /// </summary>
+ [DataMember(Name = "responseCode")]
+ public long ResponseCode { get; set; }
+
+ /// <summary>
+ /// Server response
+ /// </summary>
+ [DataMember(Name = "response", EmitDefaultValue = false)]
+ public string Response { get; set; }
+
+ /// <summary>
+ /// Creates FileUploadResult object with response values
+ /// </summary>
+ /// <param name="bytesSent">Amount of sent bytes</param>
+ /// <param name="responseCode">Server response code</param>
+ /// <param name="response">Server response</param>
+ public FileUploadResult(long bytesSent, long responseCode, string response)
+ {
+ this.BytesSent = bytesSent;
+ this.ResponseCode = responseCode;
+ this.Response = response;
+ }
+ }
+
+ /// <summary>
+ /// Represents transfer error codes for callback
+ /// </summary>
+ [DataContract]
+ public class FileTransferError
+ {
+ /// <summary>
+ /// Error code
+ /// </summary>
+ [DataMember(Name = "code", IsRequired = true)]
+ public int Code { get; set; }
+
+ /// <summary>
+ /// The source URI
+ /// </summary>
+ [DataMember(Name = "source", IsRequired = true)]
+ public string Source { get; set; }
+
+ /// <summary>
+ /// The target URI
+ /// </summary>
+ [DataMember(Name = "target", IsRequired = true)]
+ public string Target { get; set; }
+
+ /// <summary>
+ /// The http status code response from the remote URI
+ /// </summary>
+ [DataMember(Name = "http_status", IsRequired = true)]
+ public int HttpStatus { get; set; }
+
+ /// <summary>
+ /// Creates FileTransferError object
+ /// </summary>
+ /// <param name="errorCode">Error code</param>
+ public FileTransferError(int errorCode)
+ {
+ this.Code = errorCode;
+ this.Source = null;
+ this.Target = null;
+ this.HttpStatus = 0;
+ }
+ public FileTransferError(int errorCode, string source, string target, int status)
+ {
+ this.Code = errorCode;
+ this.Source = source;
+ this.Target = target;
+ this.HttpStatus = status;
+ }
+ }
+
+ /// <summary>
+ /// Upload options
+ /// </summary>
+ private UploadOptions uploadOptions;
+
+ /// <summary>
+ /// Bytes sent
+ /// </summary>
+ private long bytesSent;
+
+ /// <summary>
+ /// sends a file to a server
+ /// </summary>
+ /// <param name="options">Upload options</param>
+ public void upload(string options)
+ {
+ Debug.WriteLine("options = " + options);
+ options = options.Replace("{}", "null");
+
+ try
+ {
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ Uri serverUri;
+ try
+ {
+ serverUri = new Uri(uploadOptions.Server);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
+ return;
+ }
+ HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
+ webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
+ webRequest.Method = "POST";
+ webRequest.BeginGetRequestStream(WriteCallback, webRequest);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+ }
+ }
+
+ public void download(string options)
+ {
+ DownloadOptions downloadOptions = null;
+ HttpWebRequest webRequest = null;
+
+ try
+ {
+ string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+
+ downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
+ downloadOptions.Url = optionStrings[0];
+ downloadOptions.FilePath = optionStrings[1];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
+ return;
+ }
+
+ if (downloadOptions != null && webRequest != null)
+ {
+ DownloadRequestState state = new DownloadRequestState();
+ state.options = downloadOptions;
+ state.request = webRequest;
+ webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
+ }
+
+
+
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="asynchronousResult"></param>
+ private void downloadCallback(IAsyncResult asynchronousResult)
+ {
+ DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
+ HttpWebRequest request = reqState.request;
+
+ try
+ {
+ HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ // create the file if not exists
+ if (!isoFile.FileExists(reqState.options.FilePath))
+ {
+ var file = isoFile.CreateFile(reqState.options.FilePath);
+ file.Close();
+ }
+
+ using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
+ {
+ long totalBytes = response.ContentLength;
+ int bytesRead = 0;
+ using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
+ {
+
+ using (BinaryWriter writer = new BinaryWriter(fileStream))
+ {
+ int BUFFER_SIZE = 1024;
+ byte[] buffer;
+
+ while (true)
+ {
+ buffer = reader.ReadBytes(BUFFER_SIZE);
+ // fire a progress event ?
+ bytesRead += buffer.Length;
+ if (buffer.Length > 0)
+ {
+ writer.Write(buffer);
+ }
+ else
+ {
+ writer.Close();
+ reader.Close();
+ fileStream.Close();
+ break;
+ }
+ }
+ }
+
+ }
+
+
+ }
+ }
+ WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
+ }
+ catch (IsolatedStorageException)
+ {
+ // Trying to write the file somewhere within the IsoStorage.
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+ }
+ catch (SecurityException)
+ {
+ // Trying to write the file somewhere not allowed.
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+ }
+ catch (WebException webex)
+ {
+ // TODO: probably need better work here to properly respond with all http status codes back to JS
+ // Right now am jumping through hoops just to detect 404.
+ if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
+ {
+ // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
+ // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
+ // FACEPALM
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+ }
+ }
+
+
+
+ /// <summary>
+ /// Read file from Isolated Storage and sends it to server
+ /// </summary>
+ /// <param name="asynchronousResult"></param>
+ private void WriteCallback(IAsyncResult asynchronousResult)
+ {
+ try
+ {
+ HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
+ using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
+ {
+ string lineStart = "--";
+ string lineEnd = Environment.NewLine;
+ byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
+ string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
+
+ if (uploadOptions.Params != null)
+ {
+
+ string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (string param in arrParams)
+ {
+ string[] split = param.Split('=');
+ string key = split[0];
+ string val = split[1];
+ requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+ string formItem = string.Format(formdataTemplate, key, val);
+ byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
+ requestStream.Write(formItemBytes, 0, formItemBytes.Length);
+ }
+ requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+ }
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(uploadOptions.FilePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
+ return;
+ }
+
+ using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
+ {
+ string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
+ string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
+ byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
+ requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+ requestStream.Write(headerBytes, 0, headerBytes.Length);
+ byte[] buffer = new byte[4096];
+ int bytesRead = 0;
+
+ while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ requestStream.Write(buffer, 0, bytesRead);
+ bytesSent += bytesRead;
+ }
+ }
+ byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
+ requestStream.Write(endRequest, 0, endRequest.Length);
+ }
+ }
+ webRequest.BeginGetResponse(ReadCallback, webRequest);
+ }
+ catch (Exception)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+ });
+ }
+ }
+
+ /// <summary>
+ /// Reads response into FileUploadResult
+ /// </summary>
+ /// <param name="asynchronousResult"></param>
+ private void ReadCallback(IAsyncResult asynchronousResult)
+ {
+ try
+ {
+ HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
+ using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
+ {
+ using (Stream streamResponse = response.GetResponseStream())
+ {
+ using (StreamReader streamReader = new StreamReader(streamResponse))
+ {
+ string responseString = streamReader.ReadToEnd();
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
+ });
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
+ });
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/GeoLocation.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/GeoLocation.cs b/common-items/Plugins/GeoLocation.cs
new file mode 100644
index 0000000..c53cb29
--- /dev/null
+++ b/common-items/Plugins/GeoLocation.cs
@@ -0,0 +1,34 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Device.Location;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
+ /// </summary>
+ public class GeoLocation
+ {
+ /* Unreachable code, by design -jm */
+ private void triggerGeoInclusion()
+ {
+ new GeoCoordinateWatcher();
+ }
+ }
+}
[35/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/www/cordova.js
----------------------------------------------------------------------
diff --git a/common/www/cordova.js b/common/www/cordova.js
new file mode 100644
index 0000000..0d763d9
--- /dev/null
+++ b/common/www/cordova.js
@@ -0,0 +1,6723 @@
+// Platform: windowsphone
+// 2.8.0rc1-0-g22bc4d8
+/*
+ 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.
+*/
+;(function() {
+var CORDOVA_JS_BUILD_LABEL = '2.8.0rc1-0-g22bc4d8';
+// file: lib/scripts/require.js
+
+var require,
+ define;
+
+(function () {
+ var modules = {},
+ // Stack of moduleIds currently being built.
+ requireStack = [],
+ // Map of module ID -> index into requireStack of modules currently being built.
+ inProgressModules = {},
+ SEPERATOR = ".";
+
+
+
+ function build(module) {
+ var factory = module.factory,
+ localRequire = function (id) {
+ var resultantId = id;
+ //Its a relative path, so lop off the last portion and add the id (minus "./")
+ if (id.charAt(0) === ".") {
+ resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
+ }
+ return require(resultantId);
+ };
+ module.exports = {};
+ delete module.factory;
+ factory(localRequire, module.exports, module);
+ return module.exports;
+ }
+
+ require = function (id) {
+ if (!modules[id]) {
+ throw "module " + id + " not found";
+ } else if (id in inProgressModules) {
+ var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+ throw "Cycle in require graph: " + cycle;
+ }
+ if (modules[id].factory) {
+ try {
+ inProgressModules[id] = requireStack.length;
+ requireStack.push(id);
+ return build(modules[id]);
+ } finally {
+ delete inProgressModules[id];
+ requireStack.pop();
+ }
+ }
+ return modules[id].exports;
+ };
+
+ define = function (id, factory) {
+ if (modules[id]) {
+ throw "module " + id + " already defined";
+ }
+
+ modules[id] = {
+ id: id,
+ factory: factory
+ };
+ };
+
+ define.remove = function (id) {
+ delete modules[id];
+ };
+
+ define.moduleMap = modules;
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+ module.exports.require = require;
+ module.exports.define = define;
+}
+
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+
+
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+ channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+ channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+ windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ if (typeof documentEventHandlers[e] != 'undefined') {
+ documentEventHandlers[e].subscribe(handler);
+ } else {
+ m_document_addEventListener.call(document, evt, handler, capture);
+ }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ if (typeof windowEventHandlers[e] != 'undefined') {
+ windowEventHandlers[e].subscribe(handler);
+ } else {
+ m_window_addEventListener.call(window, evt, handler, capture);
+ }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ // If unsubscribing from an event that is handled by a plugin
+ if (typeof documentEventHandlers[e] != "undefined") {
+ documentEventHandlers[e].unsubscribe(handler);
+ } else {
+ m_document_removeEventListener.call(document, evt, handler, capture);
+ }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+ var e = evt.toLowerCase();
+ // If unsubscribing from an event that is handled by a plugin
+ if (typeof windowEventHandlers[e] != "undefined") {
+ windowEventHandlers[e].unsubscribe(handler);
+ } else {
+ m_window_removeEventListener.call(window, evt, handler, capture);
+ }
+};
+
+function createEvent(type, data) {
+ var event = document.createEvent('Events');
+ event.initEvent(type, false, false);
+ if (data) {
+ for (var i in data) {
+ if (data.hasOwnProperty(i)) {
+ event[i] = data[i];
+ }
+ }
+ }
+ return event;
+}
+
+if(typeof window.console === "undefined") {
+ window.console = {
+ log:function(){}
+ };
+}
+
+var cordova = {
+ define:define,
+ require:require,
+ /**
+ * Methods to add/remove your own addEventListener hijacking on document + window.
+ */
+ addWindowEventHandler:function(event) {
+ return (windowEventHandlers[event] = channel.create(event));
+ },
+ addStickyDocumentEventHandler:function(event) {
+ return (documentEventHandlers[event] = channel.createSticky(event));
+ },
+ addDocumentEventHandler:function(event) {
+ return (documentEventHandlers[event] = channel.create(event));
+ },
+ removeWindowEventHandler:function(event) {
+ delete windowEventHandlers[event];
+ },
+ removeDocumentEventHandler:function(event) {
+ delete documentEventHandlers[event];
+ },
+ /**
+ * Retrieve original event handlers that were replaced by Cordova
+ *
+ * @return object
+ */
+ getOriginalHandlers: function() {
+ return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+ 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+ },
+ /**
+ * Method to fire event from native code
+ * bNoDetach is required for events which cause an exception which needs to be caught in native code
+ */
+ fireDocumentEvent: function(type, data, bNoDetach) {
+ var evt = createEvent(type, data);
+ if (typeof documentEventHandlers[type] != 'undefined') {
+ if( bNoDetach ) {
+ documentEventHandlers[type].fire(evt);
+ }
+ else {
+ setTimeout(function() {
+ // Fire deviceready on listeners that were registered before cordova.js was loaded.
+ if (type == 'deviceready') {
+ document.dispatchEvent(evt);
+ }
+ documentEventHandlers[type].fire(evt);
+ }, 0);
+ }
+ } else {
+ document.dispatchEvent(evt);
+ }
+ },
+ fireWindowEvent: function(type, data) {
+ var evt = createEvent(type,data);
+ if (typeof windowEventHandlers[type] != 'undefined') {
+ setTimeout(function() {
+ windowEventHandlers[type].fire(evt);
+ }, 0);
+ } else {
+ window.dispatchEvent(evt);
+ }
+ },
+
+ /**
+ * Plugin callback mechanism.
+ */
+ // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+ // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+ callbackId: Math.floor(Math.random() * 2000000000),
+ callbacks: {},
+ callbackStatus: {
+ NO_RESULT: 0,
+ OK: 1,
+ CLASS_NOT_FOUND_EXCEPTION: 2,
+ ILLEGAL_ACCESS_EXCEPTION: 3,
+ INSTANTIATION_EXCEPTION: 4,
+ MALFORMED_URL_EXCEPTION: 5,
+ IO_EXCEPTION: 6,
+ INVALID_ACTION: 7,
+ JSON_EXCEPTION: 8,
+ ERROR: 9
+ },
+
+ /**
+ * Called by native code when returning successful result from an action.
+ */
+ callbackSuccess: function(callbackId, args) {
+ try {
+ cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
+ } catch (e) {
+ console.log("Error in error callback: " + callbackId + " = "+e);
+ }
+ },
+
+ /**
+ * Called by native code when returning error result from an action.
+ */
+ callbackError: function(callbackId, args) {
+ // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+ // Derive success from status.
+ try {
+ cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
+ } catch (e) {
+ console.log("Error in error callback: " + callbackId + " = "+e);
+ }
+ },
+
+ /**
+ * Called by native code when returning the result from an action.
+ */
+ callbackFromNative: function(callbackId, success, status, args, keepCallback) {
+ var callback = cordova.callbacks[callbackId];
+ if (callback) {
+ if (success && status == cordova.callbackStatus.OK) {
+ callback.success && callback.success.apply(null, args);
+ } else if (!success) {
+ callback.fail && callback.fail.apply(null, args);
+ }
+
+ // Clear callback if not expecting any more results
+ if (!keepCallback) {
+ delete cordova.callbacks[callbackId];
+ }
+ }
+ },
+ addConstructor: function(func) {
+ channel.onCordovaReady.subscribe(function() {
+ try {
+ func();
+ } catch(e) {
+ console.log("Failed to run constructor: " + e);
+ }
+ });
+ }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/argscheck.js
+define("cordova/argscheck", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+ 'A': 'Array',
+ 'D': 'Date',
+ 'N': 'Number',
+ 'S': 'String',
+ 'F': 'Function',
+ 'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+ return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+ if (!moduleExports.enableChecks) {
+ return;
+ }
+ var errMsg = null;
+ var typeName;
+ for (var i = 0; i < spec.length; ++i) {
+ var c = spec.charAt(i),
+ cUpper = c.toUpperCase(),
+ arg = args[i];
+ // Asterix means allow anything.
+ if (c == '*') {
+ continue;
+ }
+ typeName = utils.typeName(arg);
+ if ((arg === null || arg === undefined) && c == cUpper) {
+ continue;
+ }
+ if (typeName != typeMap[cUpper]) {
+ errMsg = 'Expected ' + typeMap[cUpper];
+ break;
+ }
+ }
+ if (errMsg) {
+ errMsg += ', but got ' + typeName + '.';
+ errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+ // Don't log when running jake test.
+ if (typeof jasmine == 'undefined') {
+ console.error(errMsg);
+ }
+ throw TypeError(errMsg);
+ }
+}
+
+function getValue(value, defaultValue) {
+ return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+ for (var prop in objects) {
+ if (objects.hasOwnProperty(prop)) {
+ func.apply(context, [objects[prop], prop]);
+ }
+ }
+}
+
+function clobber(obj, key, value) {
+ exports.replaceHookForTesting(obj, key);
+ obj[key] = value;
+ // Getters can only be overridden by getters.
+ if (obj[key] !== value) {
+ utils.defineGetter(obj, key, function() {
+ return value;
+ });
+ }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+ if (message) {
+ utils.defineGetter(obj, key, function() {
+ console.log(message);
+ delete obj[key];
+ clobber(obj, key, value);
+ return value;
+ });
+ } else {
+ clobber(obj, key, value);
+ }
+}
+
+function include(parent, objects, clobber, merge) {
+ each(objects, function (obj, key) {
+ try {
+ var result = obj.path ? require(obj.path) : {};
+
+ if (clobber) {
+ // Clobber if it doesn't exist.
+ if (typeof parent[key] === 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else if (typeof obj.path !== 'undefined') {
+ // If merging, merge properties onto parent, otherwise, clobber.
+ if (merge) {
+ recursiveMerge(parent[key], result);
+ } else {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ }
+ }
+ result = parent[key];
+ } else {
+ // Overwrite if not currently defined.
+ if (typeof parent[key] == 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else {
+ // Set result to what already exists, so we can build children into it if they exist.
+ result = parent[key];
+ }
+ }
+
+ if (obj.children) {
+ include(result, obj.children, clobber, merge);
+ }
+ } catch(e) {
+ utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+ }
+ });
+}
+
+/**
+ * Merge properties from one object onto another recursively. Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+ for (var prop in src) {
+ if (src.hasOwnProperty(prop)) {
+ if (target.prototype && target.prototype.constructor === target) {
+ // If the target object is a constructor override off prototype.
+ clobber(target.prototype, prop, src[prop]);
+ } else {
+ if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+ recursiveMerge(target[prop], src[prop]);
+ } else {
+ clobber(target, prop, src[prop]);
+ }
+ }
+ }
+ }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+ include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+ include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+ include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+ nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady* Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady* Internal event fired when device properties are available.
+ * onCordovaConnectionReady* Internal event fired when the connection property has been set.
+ * onDeviceReady* User event fired to indicate that Cordova is ready
+ * onResume User event fired to indicate a start/resume lifecycle event
+ * onPause User event fired to indicate a pause lifecycle event
+ * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ * pause App has moved to background
+ * resume App has returned to foreground
+ *
+ * Listeners can be registered as:
+ * document.addEventListener("deviceready", myDeviceReadyListener, false);
+ * document.addEventListener("resume", myResumeListener, false);
+ * document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ * window.onload
+ * window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type String the channel name
+ */
+var Channel = function(type, sticky) {
+ this.type = type;
+ // Map of guid -> function.
+ this.handlers = {};
+ // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+ this.state = sticky ? 1 : 0;
+ // Used in sticky mode to remember args passed to fire().
+ this.fireArgs = null;
+ // Used by onHasSubscribersChange to know if there are any listeners.
+ this.numHandlers = 0;
+ // Function that is called when the first listener is subscribed, or when
+ // the last listener is unsubscribed.
+ this.onHasSubscribersChange = null;
+},
+ channel = {
+ /**
+ * Calls the provided function only after all of the channels specified
+ * have been fired. All channels must be sticky channels.
+ */
+ join: function(h, c) {
+ var len = c.length,
+ i = len,
+ f = function() {
+ if (!(--i)) h();
+ };
+ for (var j=0; j<len; j++) {
+ if (c[j].state === 0) {
+ throw Error('Can only use join with sticky channels.');
+ }
+ c[j].subscribe(f);
+ }
+ if (!len) h();
+ },
+ create: function(type) {
+ return channel[type] = new Channel(type, false);
+ },
+ createSticky: function(type) {
+ return channel[type] = new Channel(type, true);
+ },
+
+ /**
+ * cordova Channels that must fire before "deviceready" is fired.
+ */
+ deviceReadyChannelsArray: [],
+ deviceReadyChannelsMap: {},
+
+ /**
+ * Indicate that a feature needs to be initialized before it is ready to be used.
+ * This holds up Cordova's "deviceready" event until the feature has been initialized
+ * and Cordova.initComplete(feature) is called.
+ *
+ * @param feature {String} The unique feature name
+ */
+ waitForInitialization: function(feature) {
+ if (feature) {
+ var c = channel[feature] || this.createSticky(feature);
+ this.deviceReadyChannelsMap[feature] = c;
+ this.deviceReadyChannelsArray.push(c);
+ }
+ },
+
+ /**
+ * Indicate that initialization code has completed and the feature is ready to be used.
+ *
+ * @param feature {String} The unique feature name
+ */
+ initializationComplete: function(feature) {
+ var c = this.deviceReadyChannelsMap[feature];
+ if (c) {
+ c.fire();
+ }
+ }
+ };
+
+function forceFunction(f) {
+ if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+ // need a function to call
+ forceFunction(f);
+ if (this.state == 2) {
+ f.apply(c || this, this.fireArgs);
+ return;
+ }
+
+ var func = f,
+ guid = f.observer_guid;
+ if (typeof c == "object") { func = utils.close(c, f); }
+
+ if (!guid) {
+ // first time any channel has seen this subscriber
+ guid = '' + nextGuid++;
+ }
+ func.observer_guid = guid;
+ f.observer_guid = guid;
+
+ // Don't add the same handler more than once.
+ if (!this.handlers[guid]) {
+ this.handlers[guid] = func;
+ this.numHandlers++;
+ if (this.numHandlers == 1) {
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+ // need a function to unsubscribe
+ forceFunction(f);
+
+ var guid = f.observer_guid,
+ handler = this.handlers[guid];
+ if (handler) {
+ delete this.handlers[guid];
+ this.numHandlers--;
+ if (this.numHandlers === 0) {
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+ var fail = false,
+ fireArgs = Array.prototype.slice.call(arguments);
+ // Apply stickiness.
+ if (this.state == 1) {
+ this.state = 2;
+ this.fireArgs = fireArgs;
+ }
+ if (this.numHandlers) {
+ // Copy the values first so that it is safe to modify it from within
+ // callbacks.
+ var toCall = [];
+ for (var item in this.handlers) {
+ toCall.push(this.handlers[item]);
+ }
+ for (var i = 0; i < toCall.length; ++i) {
+ toCall[i].apply(this, fireArgs);
+ }
+ if (this.state == 2 && this.numHandlers) {
+ this.numHandlers = 0;
+ this.handlers = {};
+ this.onHasSubscribersChange && this.onHasSubscribersChange();
+ }
+ }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.createSticky('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.createSticky('onCordovaConnectionReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/commandProxy.js
+define("cordova/commandProxy", function(require, exports, module) {
+
+
+// internal map of proxy function
+var CommandProxyMap = {};
+
+module.exports = {
+
+ // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
+ add:function(id,proxyObj) {
+ console.log("adding proxy for " + id);
+ CommandProxyMap[id] = proxyObj;
+ return proxyObj;
+ },
+
+ // cordova.commandProxy.remove("Accelerometer");
+ remove:function(id) {
+ var proxy = CommandProxyMap[id];
+ delete CommandProxyMap[id];
+ CommandProxyMap[id] = null;
+ return proxy;
+ },
+
+ get:function(service,action) {
+ return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
+ }
+};
+});
+
+// file: lib/windowsphone/exec.js
+define("cordova/exec", function(require, exports, module) {
+
+var cordova = require('cordova');
+
+/**
+ * Execute a cordova command. It is up to the native side whether this action
+ * is synchronous or asynchronous. The native side can return:
+ * Synchronous: PluginResult object as a JSON string
+ * Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success The success callback
+ * @param {Function} fail The fail callback
+ * @param {String} service The name of the service to use
+ * @param {String} action Action to be run in cordova
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+
+ */
+
+module.exports = function(success, fail, service, action, args) {
+
+ var callbackId = service + cordova.callbackId++;
+ if (typeof success == "function" || typeof fail == "function") {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+ // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
+ for(var n = 0; n < args.length; n++)
+ {
+ if(typeof args[n] !== "string")
+ {
+ args[n] = JSON.stringify(args[n]);
+ }
+ }
+ var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
+ // pass it on to Notify
+ try {
+ if(window.external) {
+ window.external.Notify(command);
+ }
+ else {
+ console.log("window.external not available :: command=" + command);
+ }
+ }
+ catch(e) {
+ console.log("Exception calling native with command :: " + command + " :: exception=" + e);
+ }
+};
+
+
+});
+
+// file: lib/common/modulemapper.js
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+ moduleMap = define.moduleMap,
+ symbolList,
+ deprecationMap;
+
+exports.reset = function() {
+ symbolList = [];
+ deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+ if (!(moduleName in moduleMap)) {
+ throw new Error('Module ' + moduleName + ' does not exist.');
+ }
+ 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);
+};
+
+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 symbolPath = symbolList[i + 2];
+ var lastDot = symbolPath.lastIndexOf('.');
+ var namespace = symbolPath.substr(0, lastDot);
+ var lastName = symbolPath.substr(lastDot + 1);
+
+ var module = require(moduleName);
+ 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.loadMatchingModules = function(matchingRegExp) {
+ for (var k in moduleMap) {
+ if (matchingRegExp.exec(k)) {
+ require(k);
+ }
+ }
+};
+
+exports.reset();
+
+
+});
+
+// file: lib/windowsphone/platform.js
+define("cordova/platform", function(require, exports, module) {
+
+var cordova = require('cordova'),
+ exec = require('cordova/exec');
+
+module.exports = {
+ id: "windowsphone",
+ initialize:function() {
+ var modulemapper = require('cordova/modulemapper');
+
+ modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
+
+ modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
+
+ modulemapper.mapModules(window);
+
+ // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
+ var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+ backButtonChannel.onHasSubscribersChange = function() {
+ exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
+ };
+ }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+
+var Acceleration = function(x, y, z, timestamp) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ Camera = require('cordova/plugin/CameraConstants'),
+ CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+ cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+ argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
+ options = options || {};
+ var getValue = argscheck.getValue;
+
+ var quality = getValue(options.quality, 50);
+ var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
+ var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
+ var targetWidth = getValue(options.targetWidth, -1);
+ var targetHeight = getValue(options.targetHeight, -1);
+ var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
+ var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
+ var allowEdit = !!options.allowEdit;
+ var correctOrientation = !!options.correctOrientation;
+ var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
+ var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
+
+ var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
+
+ exec(successCallback, errorCallback, "Camera", "takePicture", args);
+ return new CameraPopoverHandle();
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+ exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+
+module.exports = {
+ DestinationType:{
+ DATA_URL: 0, // Return base64 encoded string
+ FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
+ NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
+ },
+ EncodingType:{
+ JPEG: 0, // Return JPEG encoded image
+ PNG: 1 // Return PNG encoded image
+ },
+ MediaType:{
+ PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+ VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
+ ALLMEDIA : 2 // allow selection from all media types
+ },
+ PictureSourceType:{
+ PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+ CAMERA : 1, // Take picture from camera
+ SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
+ },
+ PopoverArrowDirection:{
+ ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+ ARROW_DOWN : 2,
+ ARROW_LEFT : 4,
+ ARROW_RIGHT : 8,
+ ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
+ }
+};
+
+});
+
+// file: lib/common/plugin/CameraPopoverHandle.js
+define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+/**
+ * A handle to an image picker popover.
+ */
+var CameraPopoverHandle = function() {
+ this.setPosition = function(popoverOptions) {
+ console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
+ };
+};
+
+module.exports = CameraPopoverHandle;
+
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+ // information of rectangle that popover should be anchored to
+ this.x = x || 0;
+ this.y = y || 32;
+ this.width = width || 320;
+ this.height = height || 480;
+ // The direction of the popover arrow
+ this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+ // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+ this.limit = 1;
+ // Maximum duration of a single sound clip in seconds.
+ this.duration = 0;
+};
+
+module.exports = CaptureAudioOptions;
+
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+ this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+ // Upper limit of images user can take. Value must be equal or greater than 1.
+ this.limit = 1;
+};
+
+module.exports = CaptureImageOptions;
+
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+ // Upper limit of videos user can record. Value must be equal or greater than 1.
+ this.limit = 1;
+ // Maximum duration of a single video clip in seconds.
+ this.duration = 0;
+};
+
+module.exports = CaptureVideoOptions;
+
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+
+/**
+ * CompassError.
+ * An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var CompassError = function(err) {
+ this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+ this.magneticHeading = magneticHeading;
+ this.trueHeading = trueHeading;
+ this.headingAccuracy = headingAccuracy;
+ this.timestamp = timestamp || new Date().getTime();
+};
+
+module.exports = CompassHeading;
+
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+ // The ASCII-encoded string in lower case representing the media type.
+ this.type = null;
+ // The height attribute represents height of the image or video in pixels.
+ // In the case of a sound clip this attribute has value 0.
+ this.height = 0;
+ // The width attribute represents width of the image or video in pixels.
+ // In the case of a sound clip this attribute has value 0
+ this.width = 0;
+}
+
+module.exports = ConfigurationData;
+
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+
+/**
+ * Network status
+ */
+module.exports = {
+ UNKNOWN: "unknown",
+ ETHERNET: "ethernet",
+ WIFI: "wifi",
+ CELL_2G: "2g",
+ CELL_3G: "3g",
+ CELL_4G: "4g",
+ CELL:"cellular",
+ NONE: "none"
+};
+
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ ContactError = require('cordova/plugin/ContactError'),
+ utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+ var value = contact.birthday;
+ try {
+ contact.birthday = new Date(parseFloat(value));
+ } catch (exception){
+ console.log("Cordova Contact convertIn error: exception creating date.");
+ }
+ return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+ var value = contact.birthday;
+ if (value !== null) {
+ // try to make it a Date object if it is not already
+ if (!utils.isDate(value)){
+ try {
+ value = new Date(value);
+ } catch(exception){
+ value = null;
+ }
+ }
+ if (utils.isDate(value)){
+ value = value.valueOf(); // convert to milliseconds
+ }
+ contact.birthday = value;
+ }
+ return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+ ims, organizations, birthday, note, photos, categories, urls) {
+ this.id = id || null;
+ this.rawId = null;
+ this.displayName = displayName || null;
+ this.name = name || null; // ContactName
+ this.nickname = nickname || null;
+ this.phoneNumbers = phoneNumbers || null; // ContactField[]
+ this.emails = emails || null; // ContactField[]
+ this.addresses = addresses || null; // ContactAddress[]
+ this.ims = ims || null; // ContactField[]
+ this.organizations = organizations || null; // ContactOrganization[]
+ this.birthday = birthday || null;
+ this.note = note || null;
+ this.photos = photos || null; // ContactField[]
+ this.categories = categories || null; // ContactField[]
+ this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+ argscheck.checkArgs('FF', 'Contact.remove', arguments);
+ var fail = errorCB && function(code) {
+ errorCB(new ContactError(code));
+ };
+ if (this.id === null) {
+ fail(ContactError.UNKNOWN_ERROR);
+ }
+ else {
+ exec(successCB, fail, "Contacts", "remove", [this.id]);
+ }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+ var clonedContact = utils.clone(this);
+ clonedContact.id = null;
+ clonedContact.rawId = null;
+
+ function nullIds(arr) {
+ if (arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ arr[i].id = null;
+ }
+ }
+ }
+
+ // Loop through and clear out any id's in phones, emails, etc.
+ nullIds(clonedContact.phoneNumbers);
+ nullIds(clonedContact.emails);
+ nullIds(clonedContact.addresses);
+ nullIds(clonedContact.ims);
+ nullIds(clonedContact.organizations);
+ nullIds(clonedContact.categories);
+ nullIds(clonedContact.photos);
+ nullIds(clonedContact.urls);
+ return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+ argscheck.checkArgs('FFO', 'Contact.save', arguments);
+ var fail = errorCB && function(code) {
+ errorCB(new ContactError(code));
+ };
+ var success = function(result) {
+ if (result) {
+ if (successCB) {
+ var fullContact = require('cordova/plugin/contacts').create(result);
+ successCB(convertIn(fullContact));
+ }
+ }
+ else {
+ // no Entry object returned
+ fail(ContactError.UNKNOWN_ERROR);
+ }
+ };
+ var dupContact = convertOut(utils.clone(this));
+ exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+ this.id = null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+ this.type = type || null;
+ this.formatted = formatted || null;
+ this.streetAddress = streetAddress || null;
+ this.locality = locality || null;
+ this.region = region || null;
+ this.postalCode = postalCode || null;
+ this.country = country || null;
+};
+
+module.exports = ContactAddress;
+
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+
+/**
+ * ContactError.
+ * An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var ContactError = function(err) {
+ this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+ this.id = null;
+ this.type = (type && type.toString()) || null;
+ this.value = (value && value.toString()) || null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+ this.filter = filter || '';
+ this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+ this.formatted = formatted || null;
+ this.familyName = familyName || null;
+ this.givenName = givenName || null;
+ this.middleName = middle || null;
+ this.honorificPrefix = prefix || null;
+ this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+ this.id = null;
+ this.pref = (typeof pref != 'undefined' ? pref : false);
+ this.type = type || null;
+ this.name = name || null;
+ this.department = dept || null;
+ this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+ /**
+ * The latitude of the position.
+ */
+ this.latitude = lat;
+ /**
+ * The longitude of the position,
+ */
+ this.longitude = lng;
+ /**
+ * The accuracy of the position.
+ */
+ this.accuracy = acc;
+ /**
+ * The altitude of the position.
+ */
+ this.altitude = (alt !== undefined ? alt : null);
+ /**
+ * The direction the device is moving at the position.
+ */
+ this.heading = (head !== undefined ? head : null);
+ /**
+ * The velocity with which the device is moving at the position.
+ */
+ this.speed = (vel !== undefined ? vel : null);
+
+ if (this.speed === 0 || this.speed === null) {
+ this.heading = NaN;
+ }
+
+ /**
+ * The altitude accuracy of the position.
+ */
+ this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ Entry = require('cordova/plugin/Entry'),
+ FileError = require('cordova/plugin/FileError'),
+ DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+ DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+ return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or exclusively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+ argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
+ var win = successCallback && function(result) {
+ var entry = new DirectoryEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or exclusively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+ argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
+ var win = successCallback && function(result) {
+ var FileEntry = require('cordova/plugin/FileEntry');
+ var entry = new FileEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+ this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+ var win = typeof successCallback !== 'function' ? null : function(result) {
+ var retVal = [];
+ for (var i=0; i<result.length; i++) {
+ var entry = null;
+ if (result[i].isDirectory) {
+ entry = new (require('cordova/plugin/DirectoryEntry'))();
+ }
+ else if (result[i].isFile) {
+ entry = new (require('cordova/plugin/FileEntry'))();
+ }
+ entry.isDirectory = result[i].isDirectory;
+ entry.isFile = result[i].isFile;
+ entry.name = result[i].name;
+ entry.fullPath = result[i].fullPath;
+ retVal.push(entry);
+ }
+ successCallback(retVal);
+ };
+ var fail = typeof errorCallback !== 'function' ? null : function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError'),
+ Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ * {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ * {boolean} true if Entry is a directory (readonly)
+ * @param name
+ * {DOMString} name of the file or directory, excluding the path
+ * leading to it (readonly)
+ * @param fullPath
+ * {DOMString} the absolute full path to the file or directory
+ * (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+ this.isFile = !!isFile;
+ this.isDirectory = !!isDirectory;
+ this.name = name || '';
+ this.fullPath = fullPath || '';
+ this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ * {Function} is called with a Metadata object
+ * @param errorCallback
+ * {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
+ var success = successCallback && function(lastModified) {
+ var metadata = new Metadata(lastModified);
+ successCallback(metadata);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+
+ exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ * {Function} is called with a Metadata object
+ * @param errorCallback
+ * {Function} is called with a FileError
+ * @param metadataObject
+ * {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+ argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
+ exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ * {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ * {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ * {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+ argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ // source path
+ var srcPath = this.fullPath,
+ // entry name
+ name = newName || this.name,
+ success = function(entry) {
+ if (entry) {
+ if (successCallback) {
+ // create appropriate Entry object
+ var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+ successCallback(result);
+ }
+ }
+ else {
+ // no Entry object returned
+ fail && fail(FileError.NOT_FOUND_ERR);
+ }
+ };
+
+ // copy
+ exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ * {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ * {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ * {Function} called with the new Entry object
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+ argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+
+ // source path
+ var srcPath = this.fullPath,
+ // entry name
+ name = newName || this.name,
+ // success callback
+ success = function(entry) {
+ if (entry) {
+ if (successCallback) {
+ // create appropriate Entry object
+ var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+ successCallback(result);
+ }
+ }
+ else {
+ // no Entry object returned
+ fail && fail(FileError.NOT_FOUND_ERR);
+ }
+ };
+
+ // copy
+ exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+ // fullPath attribute contains the full URL
+ return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+ console.log("DEPRECATED: Update your code to use 'toURL'");
+ // fullPath attribute contains the full URI
+ return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.remove', arguments);
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+ argscheck.checkArgs('FF', 'Entry.getParent', arguments);
+ var win = successCallback && function(result) {
+ var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+ var entry = new DirectoryEntry(result.name, result.fullPath);
+ successCallback(entry);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+ this.name = name || '';
+ this.fullPath = fullPath || null;
+ this.type = type || null;
+ this.lastModifiedDate = lastModifiedDate || null;
+ this.size = size || 0;
+
+ // These store the absolute start and end for slicing the file.
+ this.start = 0;
+ this.end = this.size;
+};
+
+/**
+ * Returns a "slice" of the file. Since Cordova Files don't contain the actual
+ * content, this really returns a File with adjusted start and end.
+ * Slices of slices are supported.
+ * start {Number} The index at which to start the slice (inclusive).
+ * end {Number} The index at which to end the slice (exclusive).
+ */
+File.prototype.slice = function(start, end) {
+ var size = this.end - this.start;
+ var newStart = 0;
+ var newEnd = size;
+ if (arguments.length) {
+ if (start < 0) {
+ newStart = Math.max(size + start, 0);
+ } else {
+ newStart = Math.min(size, start);
+ }
+ }
+
+ if (arguments.length >= 2) {
+ if (end < 0) {
+ newEnd = Math.max(size + end, 0);
+ } else {
+ newEnd = Math.min(end, size);
+ }
+ }
+
+ var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
+ newFile.start = this.start + newStart;
+ newFile.end = this.start + newEnd;
+ return newFile;
+};
+
+
+module.exports = File;
+
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ Entry = require('cordova/plugin/Entry'),
+ FileWriter = require('cordova/plugin/FileWriter'),
+ File = require('cordova/plugin/File'),
+ FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+ FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+ this.file(function(filePointer) {
+ var writer = new FileWriter(filePointer);
+
+ if (writer.fileName === null || writer.fileName === "") {
+ errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+ } else {
+ successCallback && successCallback(writer);
+ }
+ }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+ var win = successCallback && function(f) {
+ var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+ successCallback(file);
+ };
+ var fail = errorCallback && function(code) {
+ errorCallback(new FileError(code));
+ };
+ exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+
+/**
+ * FileError
+ */
+function FileError(error) {
+ this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+ modulemapper = require('cordova/modulemapper'),
+ utils = require('cordova/utils'),
+ File = require('cordova/plugin/File'),
+ FileError = require('cordova/plugin/FileError'),
+ ProgressEvent = require('cordova/plugin/ProgressEvent'),
+ origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ * The root directory is the root of the file system.
+ * To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+ this._readyState = 0;
+ this._error = null;
+ this._result = null;
+ this._fileName = '';
+ this._realReader = origFileReader ? new origFileReader() : {};
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+utils.defineGetter(FileReader.prototype, 'readyState', function() {
+ return this._fileName ? this._readyState : this._realReader.readyState;
+});
+
+utils.defineGetter(FileReader.prototype, 'error', function() {
+ return this._fileName ? this._error: this._realReader.error;
+});
+
+utils.defineGetter(FileReader.prototype, 'result', function() {
+ return this._fileName ? this._result: this._realReader.result;
+});
+
+function defineEvent(eventName) {
+ utils.defineGetterSetter(FileReader.prototype, eventName, function() {
+ return this._realReader[eventName] || null;
+ }, function(value) {
+ this._realReader[eventName] = value;
+ });
+}
+defineEvent('onloadstart'); // When the read starts.
+defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
+defineEvent('onload'); // When the read has successfully completed.
+defineEvent('onerror'); // When the read has failed (see errors).
+defineEvent('onloadend'); // When the request has completed (either in success or failure).
+defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
+
+function initRead(reader, file) {
+ // Already loading something
+ if (reader.readyState == FileReader.LOADING) {
+ throw new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ reader._result = null;
+ reader._error = null;
+ reader._readyState = FileReader.LOADING;
+
+ if (typeof file == 'string') {
+ // Deprecated in Cordova 2.4.
+ console.warn('Using a string argument with FileReader.readAs functions is deprecated.');
+ reader._fileName = file;
+ } else if (typeof file.fullPath == 'string') {
+ reader._fileName = file.fullPath;
+ } else {
+ reader._fileName = '';
+ return true;
+ }
+
+ reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
+}
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+ if (origFileReader && !this._fileName) {
+ return this._realReader.abort();
+ }
+ this._result = null;
+
+ if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
+ return;
+ }
+
+ this._readyState = FileReader.DONE;
+
+ // If abort callback
+ if (typeof this.onabort === 'function') {
+ this.onabort(new ProgressEvent('abort', {target:this}));
+ }
+ // If load end callback
+ if (typeof this.onloadend === 'function') {
+ this.onloadend(new ProgressEvent('loadend', {target:this}));
+ }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file {File} File object containing file properties
+ * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsText(file, encoding);
+ }
+
+ // Default encoding is UTF-8
+ var enc = encoding ? encoding : "UTF-8";
+ var me = this;
+ var execArgs = [this._fileName, enc, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // Save result
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // null result
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsText", execArgs);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ * data:[<mediatype>][;base64],<data>
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsDataURL(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ // Save result
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsDataURL", execArgs);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsBinaryString(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsArrayBuffer(file);
+ }
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
+};
+
+module.exports = FileReader;
+
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+ this.name = name || null;
+ if (root) {
+ this.root = new DirectoryEntry(root.name, root.fullPath);
+ }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+
+var argscheck = require('cordova/argscheck'),
+ exec = require('cordova/exec'),
+ FileTransferError = require('cordova/plugin/FileTransferError'),
+ ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+function newProgressEvent(result) {
+ var pe = new ProgressEvent();
+ pe.lengthComputable = result.lengthComputable;
+ pe.loaded = result.loaded;
+ pe.total = result.total;
+ return pe;
+}
+
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) !== 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
+var idCounter = 0;
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {
+ this._id = ++idCounter;
+ this.onprogress = null; // optional callback
+};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String} Full path of the file on the device
+* @param server {String} URL of the server to receive the file
+* @param successCallback (Function} Callback to be invoked when upload has completed
+* @param errorCallback {Function} Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+ argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
+ // check for options
+ var fileKey = null;
+ var fileName = null;
+ var mimeType = null;
+ var params = null;
+ var chunkedMode = true;
+ var headers = null;
+ var httpMethod = null;
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ if (options) {
+ fileKey = options.fileKey;
+ fileName = options.fileName;
+ mimeType = options.mimeType;
+ headers = options.headers;
+ httpMethod = options.httpMethod || "POST";
+ if (httpMethod.toUpperCase() == "PUT"){
+ httpMethod = "PUT";
+ } else {
+ httpMethod = "POST";
+ }
+ if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+ chunkedMode = options.chunkedMode;
+ }
+ if (options.params) {
+ params = options.params;
+ }
+ else {
+ params = {};
+ }
+ }
+
+ var fail = errorCallback && function(e) {
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
+ errorCallback(error);
+ };
+
+ var self = this;
+ var win = function(result) {
+ if (typeof result.lengthComputable != "undefined") {
+ if (self.onprogress) {
+ self.onprogress(newProgressEvent(result));
+ }
+ } else {
+ successCallback && successCallback(result);
+ }
+ };
+ exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String} URL of the server to receive the file
+ * @param target {String} Full path of the file on the device
+ * @param successCallback (Function} Callback to be invoked when upload has completed
+ * @param errorCallback {Function} Callback to be invoked upon error
+ * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ * @param options {FileDownloadOptions} Optional parameters such as headers
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
+ argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
+ var self = this;
+
+ var basicAuthHeader = getBasicAuthHeader(source);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ var headers = null;
+ if (options) {
+ headers = options.headers || null;
+ }
+
+ var win = function(result) {
+ if (typeof result.lengthComputable != "undefined") {
+ if (self.onprogress) {
+ return self.onprogress(newProgressEvent(result));
+ }
+ } else if (successCallback) {
+ var entry = null;
+ if (result.isDirectory) {
+ entry = new (require('cordova/plugin/DirectoryEntry'))();
+ }
+ else if (result.isFile) {
+ entry = new (require('cordova/plugin/FileEntry'))();
+ }
+ entry.isDirectory = result.isDirectory;
+ entry.isFile = result.isFile;
+ entry.name = result.name;
+ entry.fullPath = result.fullPath;
+ successCallback(entry);
+ }
+ };
+
+ var fail = errorCallback && function(e) {
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
+ errorCallback(error);
+ };
+
+ exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
+};
+
+/**
+ * Aborts the ongoing file transfer on this object. The original error
+ * callback for the file transfer will be called if necessary.
+ */
+FileTransfer.prototype.abort = function() {
+ exec(null, null, 'FileTransfer', 'a
<TRUNCATED>
[37/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Globalization.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Globalization.cs b/common/Plugins/Globalization.cs
new file mode 100644
index 0000000..2c2f468
--- /dev/null
+++ b/common/Plugins/Globalization.cs
@@ -0,0 +1,1177 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides information about system locale, culture settings, number formats, ect.
+ /// </summary>
+ public class Globalization : BaseCommand
+ {
+
+ #region Globalization errors
+
+ /// <summary>
+ /// Globalization error codes.
+ /// </summary>
+ public enum ErrorCode : int
+ {
+ UnknownError = 0,
+ FormattingError = 1,
+ ParsingError = 2,
+ PatternError = 3
+ }
+
+ /// <summary>
+ /// Represents globalization error object.
+ /// </summary>
+ [DataContract]
+ public class GlobalizationError
+ {
+ #region Error messages
+ /// <summary>
+ /// Error messages
+ /// </summary>
+ public const string UnknownError = "UNKNOWN_ERROR";
+ public const string FormattingError = "FORMATTIN_ERROR";
+ public const string ParsingError = "PARSING_ERROR";
+ public const string PatternError = "PATTERN_ERROR";
+
+ #endregion
+
+ /// <summary>
+ /// Error code
+ /// </summary>
+ [DataMember(Name = "code", IsRequired = false)]
+ public ErrorCode Code { get; set; }
+
+ /// <summary>
+ /// Error message
+ /// </summary>
+ [DataMember(Name = "message", IsRequired = false)]
+ public string Message { get; set; }
+
+ /// <summary>
+ /// Default constructor
+ /// </summary>
+ public GlobalizationError()
+ {
+ this.Code = ErrorCode.UnknownError;
+ this.Message = UnknownError;
+ }
+
+ /// <summary>
+ /// Constructor setting error code
+ /// </summary>
+ public GlobalizationError(ErrorCode error)
+ {
+ this.Code = error;
+
+ switch (error)
+ {
+ case ErrorCode.ParsingError:
+ {
+ this.Message = ParsingError;
+ break;
+ }
+ case ErrorCode.FormattingError:
+ {
+ this.Message = FormattingError;
+ break;
+ }
+ case ErrorCode.PatternError:
+ {
+ this.Message = PatternError;
+ break;
+ }
+ default:
+ {
+ this.Message = UnknownError;
+ break;
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Globalization options
+
+ /// <summary>
+ /// Represents globalization options.
+ /// </summary>
+ [DataContract]
+ public class GlobalizationOptions
+ {
+ #region available option values
+ /// <summary>
+ /// Number pattern types.
+ /// </summary>
+ public const string Percent = "percent";
+ public const string Currency = "currency";
+ public const string Decimal = "decimal";
+
+ /// <summary>
+ /// Format length types
+ /// </summary>
+ public const string Short = "short";
+ public const string Medium = "medium";
+ public const string Long = "long";
+ public const string Full = "full";
+
+ /// <summary>
+ /// Selector types
+ /// </summary>
+ public const string TimeSelector = "time";
+ public const string DateSelector = "date";
+ public const string DateAndTimeSelector = "date and time";
+
+ /// <summary>
+ /// Date name types
+ /// </summary>
+ public const string Narrow = "narrow";
+ public const string Wide = "wide";
+
+ /// <summary>
+ /// Date name items
+ /// </summary>
+ public const string Months = "months";
+ public const string Days = "days";
+
+ #endregion
+
+ /// <summary>
+ /// Additional options
+ /// </summary>
+ [DataMember(Name = "options", IsRequired = false)]
+ public Options AdditionalOptions { get; set; }
+
+ /// <summary>
+ /// Date to convert
+ /// </summary>
+ [DataMember(Name = "date", IsRequired = false)]
+ public long Date { get; set; }
+
+ /// <summary>
+ /// Date as stirng
+ /// </summary>
+ [DataMember(Name = "dateString", IsRequired = false)]
+ public string DateString { get; set; }
+
+ /// <summary>
+ /// Currency code
+ /// </summary>
+ [DataMember(Name = "currencyCode", IsRequired = false)]
+ public string CurrencyCode { get; set; }
+
+ /// <summary>
+ /// Number as string
+ /// </summary>
+ [DataMember(Name = "numberString", IsRequired = false)]
+ public string NumberString { get; set; }
+
+ /// <summary>
+ /// Number to convert
+ /// </summary>
+ [DataMember(Name = "number", IsRequired = false)]
+ public double Number { get; set; }
+ }
+
+ /// <summary>
+ /// Represents additional options
+ /// </summary>
+ [DataContract]
+ public class Options
+ {
+ /// <summary>
+ /// Pattern type
+ /// </summary>
+ [DataMember(Name = "type", IsRequired = false)]
+ public string Type { get; set; }
+
+ /// <summary>
+ /// Format length
+ /// </summary>
+ [DataMember(Name = "formatLength", IsRequired = false)]
+ public string FormatLength { get; set; }
+
+ /// <summary>
+ /// Selector
+ /// </summary>
+ [DataMember(Name = "selector", IsRequired = false)]
+ public string Selector { get; set; }
+
+ /// <summary>
+ /// Date name item
+ /// </summary>
+ [DataMember(Name = "item", IsRequired = false)]
+ public string Item { get; set; }
+ }
+
+ #endregion
+
+ #region returned objects
+
+ #region Number pattern object
+
+ /// <summary>
+ /// Represents number pattern
+ /// </summary>
+ [DataContract]
+ public class NumberPattern
+ {
+ /// <summary>
+ /// Pattern
+ /// </summary>
+ [DataMember(Name = "pattern", IsRequired = false)]
+ public string Pattern { get; set; }
+
+ /// <summary>
+ /// Symbol
+ /// </summary>
+ [DataMember(Name = "symbol", IsRequired = false)]
+ public string Symbol { get; set; }
+
+ /// <summary>
+ /// Fraction
+ /// </summary>
+ [DataMember(Name = "fraction", IsRequired = false)]
+ public int Fraction { get; set; }
+
+ /// <summary>
+ /// Positive
+ /// </summary>
+ [DataMember(Name = "positive", IsRequired = false)]
+ public string Positive { get; set; }
+
+ /// <summary>
+ /// Negative
+ /// </summary>
+ [DataMember(Name = "negative", IsRequired = false)]
+ public string Negative { get; set; }
+
+ /// <summary>
+ /// Rounding
+ /// </summary>
+ [DataMember(Name = "rounding", IsRequired = false)]
+ public int Rounding { get; set; }
+
+ /// <summary>
+ /// Decimal
+ /// </summary>
+ [DataMember(Name = "decimal", IsRequired = false)]
+ public string Decimal { get; set; }
+
+ /// <summary>
+ /// Grouping
+ /// </summary>
+ [DataMember(Name = "grouping", IsRequired = false)]
+ public string Grouping { get; set; }
+
+ /// <summary>
+ /// Constructor of the class
+ /// </summary>
+ /// <param name="pattern"></param>
+ /// <param name="symbol"></param>
+ /// <param name="fraction"></param>
+ /// <param name="positive"></param>
+ /// <param name="negative"></param>
+ /// <param name="rounding"></param>
+ /// <param name="dec"></param>
+ /// <param name="grouping"></param>
+ public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
+ {
+ this.Pattern = pattern;
+ this.Symbol = symbol;
+ this.Fraction = fraction;
+ this.Positive = positive;
+ this.Negative = negative;
+ this.Rounding = rounding;
+ this.Decimal = dec;
+ this.Grouping = grouping;
+ }
+ }
+ #endregion
+
+ #region Date format object
+
+ /// <summary>
+ /// Represents date format
+ /// </summary>
+ [DataContract]
+ public class DateFormat
+ {
+ /// <summary>
+ /// Year
+ /// </summary>
+ [DataMember(Name = "year", IsRequired = false)]
+ public int Year { get; set; }
+
+ /// <summary>
+ /// Month
+ /// </summary>
+ [DataMember(Name = "month", IsRequired = false)]
+ public int Month { get; set; }
+
+ /// <summary>
+ /// Day
+ /// </summary>
+ [DataMember(Name = "day", IsRequired = false)]
+ public int Day { get; set; }
+
+ /// <summary>
+ /// Hour
+ /// </summary>
+ [DataMember(Name = "hour", IsRequired = false)]
+ public int Hour { get; set; }
+
+ /// <summary>
+ /// Minute
+ /// </summary>
+ [DataMember(Name = "minute", IsRequired = false)]
+ public int Minute { get; set; }
+
+ /// <summary>
+ /// Second
+ /// </summary>
+ [DataMember(Name = "second", IsRequired = false)]
+ public int Second { get; set; }
+
+ /// <summary>
+ /// Millisecond
+ /// </summary>
+ [DataMember(Name = "millisecond", IsRequired = false)]
+ public int Millisecond { get; set; }
+
+ public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
+ {
+ this.Year = year;
+ this.Month = month;
+ this.Day = day;
+ this.Hour = hour;
+ this.Minute = minute;
+ this.Millisecond = millisecond;
+ }
+
+ }
+ #endregion
+
+ #region Date pattern object
+
+ /// <summary>
+ /// Represents date pattern object
+ /// </summary>
+ [DataContract]
+ public class DatePattern
+ {
+
+ /// <summary>
+ /// Date pattern
+ /// </summary>
+ [DataMember(Name = "pattern", IsRequired = false)]
+ public string Pattern { get; set; }
+
+ /// <summary>
+ /// TimeZone
+ /// </summary>
+ [DataMember(Name = "timezone", IsRequired = false)]
+ public string TimeZone { get; set; }
+
+ /// <summary>
+ /// UTC offset
+ /// </summary>
+ [DataMember(Name = "utc_offset", IsRequired = false)]
+ public double UtcOffset { get; set; }
+
+ /// <summary>
+ /// Dst offset
+ /// </summary>
+ [DataMember(Name = "dst_offset", IsRequired = false)]
+ public double DstOffset { get; set; }
+
+ /// <summary>
+ /// Constructor of the class
+ /// </summary>
+ /// <param name="pattern"></param>
+ /// <param name="timezone"></param>
+ /// <param name="utcOffset"></param>
+ /// <param name="dstOffset"></param>
+ public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
+ {
+ this.Pattern = pattern;
+ this.TimeZone = timezone;
+ this.UtcOffset = utcOffset;
+ this.DstOffset = dstOffset;
+ }
+
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Locale info
+
+ /// <summary>
+ /// Gets the string identifier for the client's current locale setting.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getLocaleName(string options)
+ {
+ try
+ {
+ var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
+ this.DispatchCommandResult(result);
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ /// <summary>
+ /// Gets the string identifier for the client's current language.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getPreferredLanguage(string options)
+ {
+ try
+ {
+ var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
+ this.DispatchCommandResult(result);
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ #endregion
+
+ #region Date and time info
+
+ /// <summary>
+ /// Gets whether daylight savings time is in effect for a given date using the client's
+ /// time zone and calendar.
+ /// </summary>
+ /// <param name="opitons">Date to daylight savings check.</param>
+ public void isDayLightSavingsTime(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
+ TimeZoneInfo localZone = TimeZoneInfo.Local;
+ bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ /// <summary>
+ /// Gets the first day of the week according to the client's user preferences and calendar.
+ /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getFirstDayOfWeek(string options)
+ {
+ try
+ {
+ // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
+ var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
+ this.DispatchCommandResult(result);
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ #endregion
+
+ #region Formatting
+
+ /// <summary>
+ /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client.
+ /// </summary>
+ /// <param name="options"></param>
+ public void dateToString(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
+
+ string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
+ int formatLength = 0; //default format
+ int selector = 0; //default selector
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.FormatLength != null)
+ {
+ string t = globalOptions.AdditionalOptions.FormatLength;
+
+ if (t.Equals(GlobalizationOptions.Full))
+ {
+ formatLength++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Selector != null)
+ {
+ string t = globalOptions.AdditionalOptions.Selector;
+
+ if (t.Equals(GlobalizationOptions.DateSelector))
+ {
+ selector += 10;
+ }
+ else if (t.Equals(GlobalizationOptions.TimeSelector))
+ {
+ selector += 20;
+ }
+ }
+
+ //determine return value
+ int method = formatLength + selector;
+
+ switch (method)
+ {
+ case 1: // full datetime
+ {
+ format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
+ break;
+ }
+ case 10: // short date
+ {
+ format = "{0:d}";
+ break;
+ }
+ case 11: // full date
+ {
+ format = "{0:D}";
+ break;
+ }
+ case 20: // short time
+ {
+ format = "{0:t}";
+ break;
+ }
+ case 21: // full time
+ {
+ format = "{0:T}";
+ break;
+ }
+ default: // short datetime
+ {
+ format = "{0:M/dd/yy H:m:s}";
+ break;
+ }
+ }
+ }
+
+ string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
+ }
+ }
+
+ /// <summary>
+ /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
+ /// </summary>
+ /// <param name="options"></param>
+ public void stringToDate(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ if (string.IsNullOrEmpty(globalOptions.DateString))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ string format = "M/dd/yy H:m:s"; // short datetime by default
+ int formatLength = 0; //default format
+ int selector = 0; //default selector
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.FormatLength != null)
+ {
+ string t = globalOptions.AdditionalOptions.FormatLength;
+
+ if (t.Equals(GlobalizationOptions.Full))
+ {
+ formatLength++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Selector != null)
+ {
+ string t = globalOptions.AdditionalOptions.Selector;
+
+ if (t.Equals(GlobalizationOptions.DateSelector))
+ {
+ selector += 10;
+ }
+ else if (t.Equals(GlobalizationOptions.TimeSelector))
+ {
+ selector += 20;
+ }
+ }
+
+ //determine return value
+ int method = formatLength + selector;
+
+ switch (method)
+ {
+ case 1: // full datetime
+ {
+ format = "MMMM/dddd/yyyy HH:mm:ss tt";
+ break;
+ }
+ case 10: // short date
+ {
+ format = "d";
+ break;
+ }
+ case 11: // full date
+ {
+ format = "D";
+ break;
+ }
+ case 20: // short time
+ {
+ format = "t";
+ break;
+ }
+ case 21: // full time
+ {
+ format = "T";
+ break;
+ }
+ default: // short datetime
+ {
+ format = "M/dd/yy H:m:s";
+ break;
+ }
+ }
+ }
+
+ DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
+ DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
+
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getDatePattern(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
+ string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
+ int formatLength = 0; //default format
+ int selector = 0; //default selector
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.FormatLength != null)
+ {
+ string t = globalOptions.AdditionalOptions.FormatLength;
+
+ if (t.Equals(GlobalizationOptions.Full))
+ {
+ formatLength++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Selector != null)
+ {
+ string t = globalOptions.AdditionalOptions.Selector;
+
+ if (t.Equals(GlobalizationOptions.DateSelector))
+ {
+ selector += 10;
+ }
+ else if (t.Equals(GlobalizationOptions.TimeSelector))
+ {
+ selector += 20;
+ }
+ }
+
+ //determine return value
+ int method = formatLength + selector;
+
+ switch (method)
+ {
+ case 1: // full datetime
+ {
+ pattern = dateFormatInfo.FullDateTimePattern;
+ break;
+ }
+ case 10: // short date
+ {
+ pattern = dateFormatInfo.ShortDatePattern;
+ break;
+ }
+ case 11: // full date
+ {
+ pattern = dateFormatInfo.LongDatePattern;
+ break;
+ }
+ case 20: // short time
+ {
+ pattern = dateFormatInfo.ShortTimePattern;
+ break;
+ }
+ case 21: // full time
+ {
+ pattern = dateFormatInfo.LongTimePattern;
+ break;
+ }
+ default: // short datetime
+ {
+ // Seems like C# doesn't support short datetime pattern so we use full format
+ // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
+ pattern = dateFormatInfo.FullDateTimePattern;
+ break;
+ }
+ }
+ }
+
+ TimeZoneInfo localZone = TimeZoneInfo.Local;
+ DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getDateNames(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ int type = 0; //default wide
+ int item = 0; //default months
+
+ if (globalOptions.AdditionalOptions != null)
+ {
+ if (globalOptions.AdditionalOptions.Type != null)
+ {
+ string t = globalOptions.AdditionalOptions.Type;
+
+ if (t.Equals(GlobalizationOptions.Narrow))
+ {
+ type++;
+ }
+ }
+
+ if (globalOptions.AdditionalOptions.Item != null)
+ {
+ string t = globalOptions.AdditionalOptions.Item;
+
+ if (t.Equals(GlobalizationOptions.Days))
+ {
+ item += 10;
+ }
+ }
+ }
+
+ //determine return value
+ int method = item + type;
+ string[] namesArray;
+ CultureInfo currentCulture = CultureInfo.CurrentCulture;
+
+ if (method == 1) //months and narrow
+ {
+ namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
+ }
+ else if (method == 10) //days and wide
+ {
+ namesArray = currentCulture.DateTimeFormat.DayNames;
+ }
+ else if (method == 11) //days and narrow
+ {
+ namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
+ }
+ else //default: months and wide
+ {
+ namesArray = currentCulture.DateTimeFormat.MonthNames;
+ }
+
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
+ }
+ }
+
+ /// <summary>
+ /// Gets a number formatted as a string according to the client's user preferences.
+ /// </summary>
+ /// <param name="options"></param>
+ public void numberToString(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ string format = string.Empty;
+ string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
+ GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
+
+ switch (numberFormatType)
+ {
+ case GlobalizationOptions.Percent:
+ {
+ format = "{0:p}";
+ break;
+ }
+
+ case GlobalizationOptions.Currency:
+ {
+ format = "{0:c}";
+ break;
+ }
+
+ default:
+ {
+ format = "{0:f}";
+ break;
+ }
+ }
+
+ string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
+
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
+ /// </summary>
+ /// <param name="options"></param>
+ public void stringToNumber(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ if (string.IsNullOrEmpty(globalOptions.NumberString))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ string numberString = globalOptions.NumberString;
+ string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
+ GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
+
+ NumberStyles numberStyle;
+
+ switch (numberFormatType)
+ {
+ case GlobalizationOptions.Percent:
+ {
+ numberStyle = NumberStyles.Any;
+ numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
+ break;
+ }
+
+ case GlobalizationOptions.Currency:
+ {
+ numberStyle = NumberStyles.Currency;
+ break;
+ }
+
+ default:
+ {
+ numberStyle = NumberStyles.Number;
+ break;
+ }
+ }
+
+ double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
+
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
+ }
+ }
+
+
+ /// <summary>
+ /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getNumberPattern(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ CultureInfo cultureInfo = CultureInfo.CurrentCulture;
+ NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
+ string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
+ GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
+ NumberPattern pattern = null;
+ string symbol;
+
+ // TODO find out how to get format pattern and the number of fraction digits
+ switch (numberFormatType)
+ {
+ case GlobalizationOptions.Percent:
+ {
+ symbol = formatInfo.PercentSymbol;
+ pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
+ break;
+ }
+ case GlobalizationOptions.Currency:
+ {
+ symbol = formatInfo.CurrencySymbol;
+ pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
+ break;
+ }
+ default:
+ {
+ symbol = formatInfo.NumberDecimalSeparator;
+ pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
+ break;
+ }
+ }
+
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
+ }
+ }
+
+ /// <summary>
+ /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getCurrencyPattern(string options)
+ {
+ GlobalizationOptions globalOptions;
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ string currencyCode = globalOptions.CurrencyCode;
+
+ // temporary not supported via lack of api required
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
+ return;
+
+ // TODO find the way to get currency info from currency code
+ // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
+ // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
+ // CultureInfo cultureInfo = new CultureInfo(currencyCode);
+ // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
+ }
+ }
+
+ #endregion
+
+ #region private methods
+
+ /// <summary>
+ /// Wraps data into JSON format
+ /// </summary>
+ /// <param name="data">data</param>
+ /// <returns>data formatted as JSON object</returns>
+ private string WrapIntoJSON<T>(T data, string keyName = "value")
+ {
+ string param = "{0}";
+ string stringifiedData = data.ToString();
+
+ if (data.GetType() == typeof(string))
+ {
+ param = "\"" + param + "\"";
+ }
+
+ if (data.GetType() == typeof(bool))
+ {
+ stringifiedData = stringifiedData.ToLower();
+ }
+
+ if (data.GetType() == typeof(string[]))
+ {
+ stringifiedData = JSON.JsonHelper.Serialize(data);
+ }
+
+ var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
+ formattedData = "{" + formattedData + "}";
+
+ return formattedData;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/ImageExifHelper.cs b/common/Plugins/ImageExifHelper.cs
new file mode 100644
index 0000000..68ddf87
--- /dev/null
+++ b/common/Plugins/ImageExifHelper.cs
@@ -0,0 +1,209 @@
+/*
+ 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.
+
+*/
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Windows.Media.Imaging;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class ImageExifOrientation
+ {
+ public const int Portrait = 1;
+ public const int PortraitUpsideDown = 3;
+ public const int LandscapeLeft = 6;
+ public const int LandscapeRight = 8;
+ }
+
+ public class ImageExifHelper
+ {
+
+ public static Stream RotateStream(Stream stream, int angle)
+ {
+ stream.Position = 0;
+ if (angle % 90 != 0 || angle < 0)
+ {
+ throw new ArgumentException();
+ }
+ if (angle % 360 == 0)
+ {
+ return stream;
+ }
+
+ angle = angle % 360;
+
+ BitmapImage bitmap = new BitmapImage();
+ bitmap.SetSource(stream);
+ WriteableBitmap wbSource = new WriteableBitmap(bitmap);
+
+ WriteableBitmap wbTarget = null;
+
+ int srcPixelWidth = wbSource.PixelWidth;
+ int srcPixelHeight = wbSource.PixelHeight;
+
+ if (angle % 180 == 0)
+ {
+ wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
+ }
+ else
+ {
+ wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
+ }
+
+ int destPixelWidth = wbTarget.PixelWidth;
+ int[] srcPxls = wbSource.Pixels;
+ int[] destPxls = wbTarget.Pixels;
+
+ // this ugly if/else is to avoid a conditional check for every pixel
+ if (angle == 90)
+ {
+ for (int x = 0; x < srcPixelWidth; x++)
+ {
+ for (int y = 0; y < srcPixelHeight; y++)
+ {
+ destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
+ }
+ }
+ }
+ else if (angle == 180)
+ {
+ for (int x = 0; x < srcPixelWidth; x++)
+ {
+ for (int y = 0; y < srcPixelHeight; y++)
+ {
+ destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
+ }
+ }
+ }
+ else if (angle == 270)
+ {
+ for (int x = 0; x < srcPixelWidth; x++)
+ {
+ for (int y = 0; y < srcPixelHeight; y++)
+ {
+ destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
+ }
+ }
+ }
+
+ MemoryStream targetStream = new MemoryStream();
+ wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
+ return targetStream;
+ }
+
+ public static int getImageOrientationFromStream(Stream imgStream)
+ {
+
+ // 0xFFD8 : jpgHeader
+ // 0xFFE1 :
+ // 0x???? : length of exif data
+ // 0x????, 0x???? : Chars 'E','x','i','f'
+ // 0x0000 : 2 empty bytes
+ // <== mark beginning of tags SIZE:ID:VALUE
+ // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determins littleEndian-ness
+ // 0x002A : marker value
+ // 0x???? : offset to the Image File Data
+
+ // XXXX possible space before actual tag data ... we skip to mark + offset
+
+ // 0x???? number of exif tags present
+
+ // make sure we are at the begining
+ imgStream.Seek(0, SeekOrigin.Begin);
+ BinaryReader reader = new BinaryReader(imgStream);
+
+ byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
+
+ byte start = reader.ReadByte(); // 0xFF
+ byte index = reader.ReadByte(); // 0xE1
+
+ while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
+ {
+ // Get the data length
+ ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ // skip along
+ reader.ReadBytes(dLen - 2);
+ start = reader.ReadByte();
+ index = reader.ReadByte();
+ }
+
+ // It's only success if we found the 0xFFE1 marker
+ if (start != 0xFF || index != 0xE1)
+ {
+ // throw new Exception("Could not find Exif data block");
+ Debug.WriteLine("Did not find EXIF data");
+ return 0;
+ }
+
+ // read 2 byte length of EXIF data
+ ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ String exif = ""; // build the string
+ for (var n = 0; n < 4; n++)
+ {
+ exif += reader.ReadChar();
+ }
+ if (exif != "Exif")
+ {
+ // did not find exif data ...
+ Debug.WriteLine("Did not find EXIF data");
+ return 0;
+ }
+
+ // read 2 empty bytes
+ //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ reader.ReadBytes(2);
+
+ long headerMark = reader.BaseStream.Position; // where are we now <==
+
+ //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
+ reader.ReadBytes(2); // 'II' or 'MM', but we don't care
+
+ if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
+ {
+ Debug.WriteLine("Error in data != 0x002A");
+ return 0;
+ }
+
+ // Get the offset to the IFD (image file directory)
+ ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+
+ imgStream.Position = headerMark + imgOffset;
+ ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ for (ushort x = 0; x < tagCount; x++)
+ {
+ // Orientation = 0x112, aka 274
+ if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
+ {
+ ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ // don't care ..
+ uint comps = reader.ReadUInt32();
+ byte[] tagData = reader.ReadBytes(4);
+ int orientation = (int)tagData[0];
+ Debug.WriteLine("orientation = " + orientation.ToString());
+ return orientation;
+ // 6 means rotate clockwise 90 deg
+ // 8 means rotate counter-clockwise 90 deg
+ // 1 means all is good
+ // 3 means flip vertical
+ }
+ // skip to the next item, 12 bytes each
+ reader.BaseStream.Seek(10, SeekOrigin.Current);
+ }
+ return 0;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/InAppBrowser.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/InAppBrowser.cs b/common/Plugins/InAppBrowser.cs
new file mode 100644
index 0000000..2741355
--- /dev/null
+++ b/common/Plugins/InAppBrowser.cs
@@ -0,0 +1,271 @@
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Controls;
+using System.Diagnostics;
+using System.Runtime.Serialization;
+using WPCordovaClassLib.Cordova;
+using WPCordovaClassLib.Cordova.Commands;
+using WPCordovaClassLib.Cordova.JSON;
+using Microsoft.Phone.Shell;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ [DataContract]
+ public class BrowserOptions
+ {
+ [DataMember]
+ public string url;
+
+ [DataMember]
+ public bool isGeolocationEnabled;
+ }
+
+ public class InAppBrowser : BaseCommand
+ {
+
+ private static WebBrowser browser;
+ private static ApplicationBarIconButton backButton;
+ private static ApplicationBarIconButton fwdButton;
+
+ public void open(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
+ string urlLoc = args[0];
+ string target = args[1];
+ /*
+ _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
+ _blank - always open in the InAppBrowser
+ _system - always open in the system web browser
+ */
+ switch (target)
+ {
+ case "_blank":
+ ShowInAppBrowser(urlLoc);
+ break;
+ case "_self":
+ ShowCordovaBrowser(urlLoc);
+ break;
+ case "_system":
+ ShowSystemBrowser(urlLoc);
+ break;
+ }
+
+
+ }
+
+ private void ShowCordovaBrowser(string url)
+ {
+ Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ CordovaView cView = page.FindName("CordovaView") as CordovaView;
+ if (cView != null)
+ {
+ WebBrowser br = cView.Browser;
+ br.Navigate(loc);
+ }
+ }
+
+ }
+ });
+ }
+
+ private void ShowSystemBrowser(string url)
+ {
+ WebBrowserTask webBrowserTask = new WebBrowserTask();
+ webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
+ webBrowserTask.Show();
+ }
+
+
+ private void ShowInAppBrowser(string url)
+ {
+ Uri loc = new Uri(url);
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ if (browser != null)
+ {
+ //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
+ browser.Navigate(loc);
+ }
+ else
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+
+ string baseImageUrl = "Images/";
+
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ browser = new WebBrowser();
+ browser.IsScriptEnabled = true;
+ browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
+
+ browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
+ browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
+ browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
+ browser.Navigate(loc);
+ //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
+ grid.Children.Add(browser);
+ }
+
+ ApplicationBar bar = new ApplicationBar();
+ bar.BackgroundColor = Colors.Gray;
+ bar.IsMenuEnabled = false;
+
+ backButton = new ApplicationBarIconButton();
+ backButton.Text = "Back";
+
+ backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
+ backButton.Click += new EventHandler(backButton_Click);
+ backButton.IsEnabled = false;
+ bar.Buttons.Add(backButton);
+
+
+ fwdButton = new ApplicationBarIconButton();
+ fwdButton.Text = "Forward";
+ fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
+ fwdButton.Click += new EventHandler(fwdButton_Click);
+ fwdButton.IsEnabled = false;
+ bar.Buttons.Add(fwdButton);
+
+ ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
+ closeBtn.Text = "Close";
+ closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
+ closeBtn.Click += new EventHandler(closeBtn_Click);
+ bar.Buttons.Add(closeBtn);
+
+ page.ApplicationBar = bar;
+ }
+
+ }
+ }
+ });
+ }
+
+ void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+
+ }
+
+ void fwdButton_Click(object sender, EventArgs e)
+ {
+ if (browser != null)
+ {
+ try
+ {
+ browser.GoForward();
+ //browser.InvokeScript("execScript", "history.forward();");
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ void backButton_Click(object sender, EventArgs e)
+ {
+ if (browser != null)
+ {
+ try
+ {
+ browser.GoBack();
+ //browser.InvokeScript("execScript", "history.back();");
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ void closeBtn_Click(object sender, EventArgs e)
+ {
+ this.close();
+ }
+
+
+ public void close(string options = "")
+ {
+ if (browser != null)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(browser);
+ }
+ page.ApplicationBar = null;
+ }
+ }
+ browser = null;
+ string message = "{\"type\":\"exit\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.OK, message);
+ result.KeepCallback = false;
+ this.DispatchCommandResult(result);
+ });
+ }
+ }
+
+ void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (browser != null)
+ {
+ backButton.IsEnabled = browser.CanGoBack;
+ fwdButton.IsEnabled = browser.CanGoForward;
+
+ }
+ string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.OK, message);
+ result.KeepCallback = true;
+ this.DispatchCommandResult(result);
+ }
+
+ void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
+ {
+ string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
+ result.KeepCallback = true;
+ this.DispatchCommandResult(result);
+ }
+
+ void browser_Navigating(object sender, NavigatingEventArgs e)
+ {
+ string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
+ PluginResult result = new PluginResult(PluginResult.Status.OK, message);
+ result.KeepCallback = true;
+ this.DispatchCommandResult(result);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Media.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Media.cs b/common/Plugins/Media.cs
new file mode 100644
index 0000000..5de4884
--- /dev/null
+++ b/common/Plugins/Media.cs
@@ -0,0 +1,547 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Windows;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides the ability to record and play back audio files on a device.
+ /// </summary>
+ public class Media : BaseCommand
+ {
+ /// <summary>
+ /// Audio player objects
+ /// </summary>
+ private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
+
+ /// <summary>
+ /// Represents Media action options.
+ /// </summary>
+ [DataContract]
+ public class MediaOptions
+ {
+ /// <summary>
+ /// Audio id
+ /// </summary>
+ [DataMember(Name = "id", IsRequired = true)]
+ public string Id { get; set; }
+
+ /// <summary>
+ /// Path to audio file
+ /// </summary>
+ [DataMember(Name = "src")]
+ public string Src { get; set; }
+
+ /// <summary>
+ /// New track position
+ /// </summary>
+ [DataMember(Name = "milliseconds")]
+ public int Milliseconds { get; set; }
+ }
+
+ /// <summary>
+ /// Releases the audio player instance to save memory.
+ /// </summary>
+ public void release(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ if (!Media.players.ContainsKey(mediaOptions.Id))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
+ return;
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ AudioPlayer audio = Media.players[mediaOptions.Id];
+ Media.players.Remove(mediaOptions.Id);
+ audio.Dispose();
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Starts recording and save the specified file
+ /// </summary>
+ public void startRecordingAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ mediaOptions.Src = optionsString[1];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ if (mediaOptions != null)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ AudioPlayer audio;
+ if (!Media.players.ContainsKey(mediaOptions.Id))
+ {
+ audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ }
+ else
+ {
+ audio = Media.players[mediaOptions.Id];
+ }
+
+ if (audio != null)
+ {
+ audio.startRecording(mediaOptions.Src);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+
+ });
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Stops recording and save to the file specified when recording started
+ /// </summary>
+ public void stopRecordingAudio(string options)
+ {
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ audio.stopRecording();
+ Media.players.Remove(mediaId);
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+ }
+
+ public void setVolume(string options) // id,volume
+ {
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ string id = optionsString[0];
+ double volume = double.Parse(optionsString[1]);
+
+ if (Media.players.ContainsKey(id))
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ AudioPlayer player = Media.players[id];
+ player.setVolume(volume);
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
+ return;
+ }
+ }
+
+ // Some Audio Notes:
+ // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
+ // While playing, a MediaElement stops all other media playback on the phone.
+ // Multiple MediaElement controls are NOT supported
+
+ // Called when you create a new Media('blah') object in JS.
+ public void create(string options)
+ {
+ // Debug.WriteLine("Creating Audio :: " + options);
+ try
+ {
+ MediaOptions mediaOptions;
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ mediaOptions.Src = optionsString[1];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
+ return;
+ }
+
+ AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Starts or resume playing audio file
+ /// </summary>
+ public void startPlayingAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ mediaOptions.Src = optionsString[1];
+ if (optionsString.Length > 2 && optionsString[2] != null)
+ {
+ mediaOptions.Milliseconds = int.Parse(optionsString[2]);
+ }
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ AudioPlayer audio;
+
+ if (!Media.players.ContainsKey(mediaOptions.Id))
+ {
+ audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ }
+ else
+ {
+ //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
+ audio = Media.players[mediaOptions.Id];
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ audio.startPlaying(mediaOptions.Src);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+
+ /// <summary>
+ /// Seeks to a location
+ /// </summary>
+ public void seekToAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaOptions = new MediaOptions();
+ mediaOptions.Id = optionsString[0];
+ if (optionsString.Length > 1 && optionsString[1] != null)
+ {
+ mediaOptions.Milliseconds = int.Parse(optionsString[1]);
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaOptions.Id))
+ {
+ AudioPlayer audio = Media.players[mediaOptions.Id];
+ audio.seekToPlaying(mediaOptions.Milliseconds);
+ }
+ else
+ {
+ Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Pauses playing
+ /// </summary>
+ public void pausePlayingAudio(string options)
+ {
+
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ audio.pausePlaying();
+ }
+ else
+ {
+ Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+
+
+ }
+
+
+ /// <summary>
+ /// Stops playing the audio file
+ /// </summary>
+ public void stopPlayingAudio(String options)
+ {
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ audio.stopPlaying();
+ }
+ else
+ {
+ Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+ }
+
+ /// <summary>
+ /// Gets current position of playback
+ /// </summary>
+ public void getCurrentPositionAudio(string options)
+ {
+ try
+ {
+ string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ try
+ {
+ if (Media.players.ContainsKey(mediaId))
+ {
+ AudioPlayer audio = Media.players[mediaId];
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
+ }
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ });
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+ }
+
+
+ /// <summary>
+ /// Gets the duration of the audio file
+ /// </summary>
+
+ [Obsolete("This method will be removed shortly")]
+ public void getDurationAudio(string options)
+ {
+ try
+ {
+ MediaOptions mediaOptions;
+
+ try
+ {
+ mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ AudioPlayer audio;
+ if (Media.players.ContainsKey(mediaOptions.Id))
+ {
+ audio = Media.players[mediaOptions.Id];
+ }
+ else
+ {
+ Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
+ audio = new AudioPlayer(this, mediaOptions.Id);
+ Media.players.Add(mediaOptions.Id, audio);
+ }
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
+ });
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+ }
+}
[17/50] [abbrv] moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/www/cordova.js
----------------------------------------------------------------------
diff --git a/wp8/template/www/cordova.js b/wp8/template/www/cordova.js
deleted file mode 100644
index 0d763d9..0000000
--- a/wp8/template/www/cordova.js
+++ /dev/null
@@ -1,6723 +0,0 @@
-// Platform: windowsphone
-// 2.8.0rc1-0-g22bc4d8
-/*
- 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.
-*/
-;(function() {
-var CORDOVA_JS_BUILD_LABEL = '2.8.0rc1-0-g22bc4d8';
-// file: lib/scripts/require.js
-
-var require,
- define;
-
-(function () {
- var modules = {},
- // Stack of moduleIds currently being built.
- requireStack = [],
- // Map of module ID -> index into requireStack of modules currently being built.
- inProgressModules = {},
- SEPERATOR = ".";
-
-
-
- function build(module) {
- var factory = module.factory,
- localRequire = function (id) {
- var resultantId = id;
- //Its a relative path, so lop off the last portion and add the id (minus "./")
- if (id.charAt(0) === ".") {
- resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
- }
- return require(resultantId);
- };
- module.exports = {};
- delete module.factory;
- factory(localRequire, module.exports, module);
- return module.exports;
- }
-
- require = function (id) {
- if (!modules[id]) {
- throw "module " + id + " not found";
- } else if (id in inProgressModules) {
- var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
- throw "Cycle in require graph: " + cycle;
- }
- if (modules[id].factory) {
- try {
- inProgressModules[id] = requireStack.length;
- requireStack.push(id);
- return build(modules[id]);
- } finally {
- delete inProgressModules[id];
- requireStack.pop();
- }
- }
- return modules[id].exports;
- };
-
- define = function (id, factory) {
- if (modules[id]) {
- throw "module " + id + " already defined";
- }
-
- modules[id] = {
- id: id,
- factory: factory
- };
- };
-
- define.remove = function (id) {
- delete modules[id];
- };
-
- define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
- module.exports.require = require;
- module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-
-/**
- * Listen for DOMContentLoaded and notify our channel subscribers.
- */
-document.addEventListener('DOMContentLoaded', function() {
- channel.onDOMContentLoaded.fire();
-}, false);
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
- channel.onDOMContentLoaded.fire();
-}
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
- windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof documentEventHandlers[e] != 'undefined') {
- documentEventHandlers[e].subscribe(handler);
- } else {
- m_document_addEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof windowEventHandlers[e] != 'undefined') {
- windowEventHandlers[e].subscribe(handler);
- } else {
- m_window_addEventListener.call(window, evt, handler, capture);
- }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubscribing from an event that is handled by a plugin
- if (typeof documentEventHandlers[e] != "undefined") {
- documentEventHandlers[e].unsubscribe(handler);
- } else {
- m_document_removeEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubscribing from an event that is handled by a plugin
- if (typeof windowEventHandlers[e] != "undefined") {
- windowEventHandlers[e].unsubscribe(handler);
- } else {
- m_window_removeEventListener.call(window, evt, handler, capture);
- }
-};
-
-function createEvent(type, data) {
- var event = document.createEvent('Events');
- event.initEvent(type, false, false);
- if (data) {
- for (var i in data) {
- if (data.hasOwnProperty(i)) {
- event[i] = data[i];
- }
- }
- }
- return event;
-}
-
-if(typeof window.console === "undefined") {
- window.console = {
- log:function(){}
- };
-}
-
-var cordova = {
- define:define,
- require:require,
- /**
- * Methods to add/remove your own addEventListener hijacking on document + window.
- */
- addWindowEventHandler:function(event) {
- return (windowEventHandlers[event] = channel.create(event));
- },
- addStickyDocumentEventHandler:function(event) {
- return (documentEventHandlers[event] = channel.createSticky(event));
- },
- addDocumentEventHandler:function(event) {
- return (documentEventHandlers[event] = channel.create(event));
- },
- removeWindowEventHandler:function(event) {
- delete windowEventHandlers[event];
- },
- removeDocumentEventHandler:function(event) {
- delete documentEventHandlers[event];
- },
- /**
- * Retrieve original event handlers that were replaced by Cordova
- *
- * @return object
- */
- getOriginalHandlers: function() {
- return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
- 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
- },
- /**
- * Method to fire event from native code
- * bNoDetach is required for events which cause an exception which needs to be caught in native code
- */
- fireDocumentEvent: function(type, data, bNoDetach) {
- var evt = createEvent(type, data);
- if (typeof documentEventHandlers[type] != 'undefined') {
- if( bNoDetach ) {
- documentEventHandlers[type].fire(evt);
- }
- else {
- setTimeout(function() {
- // Fire deviceready on listeners that were registered before cordova.js was loaded.
- if (type == 'deviceready') {
- document.dispatchEvent(evt);
- }
- documentEventHandlers[type].fire(evt);
- }, 0);
- }
- } else {
- document.dispatchEvent(evt);
- }
- },
- fireWindowEvent: function(type, data) {
- var evt = createEvent(type,data);
- if (typeof windowEventHandlers[type] != 'undefined') {
- setTimeout(function() {
- windowEventHandlers[type].fire(evt);
- }, 0);
- } else {
- window.dispatchEvent(evt);
- }
- },
-
- /**
- * Plugin callback mechanism.
- */
- // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
- // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
- callbackId: Math.floor(Math.random() * 2000000000),
- callbacks: {},
- callbackStatus: {
- NO_RESULT: 0,
- OK: 1,
- CLASS_NOT_FOUND_EXCEPTION: 2,
- ILLEGAL_ACCESS_EXCEPTION: 3,
- INSTANTIATION_EXCEPTION: 4,
- MALFORMED_URL_EXCEPTION: 5,
- IO_EXCEPTION: 6,
- INVALID_ACTION: 7,
- JSON_EXCEPTION: 8,
- ERROR: 9
- },
-
- /**
- * Called by native code when returning successful result from an action.
- */
- callbackSuccess: function(callbackId, args) {
- try {
- cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
- } catch (e) {
- console.log("Error in error callback: " + callbackId + " = "+e);
- }
- },
-
- /**
- * Called by native code when returning error result from an action.
- */
- callbackError: function(callbackId, args) {
- // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
- // Derive success from status.
- try {
- cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
- } catch (e) {
- console.log("Error in error callback: " + callbackId + " = "+e);
- }
- },
-
- /**
- * Called by native code when returning the result from an action.
- */
- callbackFromNative: function(callbackId, success, status, args, keepCallback) {
- var callback = cordova.callbacks[callbackId];
- if (callback) {
- if (success && status == cordova.callbackStatus.OK) {
- callback.success && callback.success.apply(null, args);
- } else if (!success) {
- callback.fail && callback.fail.apply(null, args);
- }
-
- // Clear callback if not expecting any more results
- if (!keepCallback) {
- delete cordova.callbacks[callbackId];
- }
- }
- },
- addConstructor: function(func) {
- channel.onCordovaReady.subscribe(function() {
- try {
- func();
- } catch(e) {
- console.log("Failed to run constructor: " + e);
- }
- });
- }
-};
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-module.exports = cordova;
-
-});
-
-// file: lib/common/argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
- 'A': 'Array',
- 'D': 'Date',
- 'N': 'Number',
- 'S': 'String',
- 'F': 'Function',
- 'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
- return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
- if (!moduleExports.enableChecks) {
- return;
- }
- var errMsg = null;
- var typeName;
- for (var i = 0; i < spec.length; ++i) {
- var c = spec.charAt(i),
- cUpper = c.toUpperCase(),
- arg = args[i];
- // Asterix means allow anything.
- if (c == '*') {
- continue;
- }
- typeName = utils.typeName(arg);
- if ((arg === null || arg === undefined) && c == cUpper) {
- continue;
- }
- if (typeName != typeMap[cUpper]) {
- errMsg = 'Expected ' + typeMap[cUpper];
- break;
- }
- }
- if (errMsg) {
- errMsg += ', but got ' + typeName + '.';
- errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
- // Don't log when running jake test.
- if (typeof jasmine == 'undefined') {
- console.error(errMsg);
- }
- throw TypeError(errMsg);
- }
-}
-
-function getValue(value, defaultValue) {
- return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// file: lib/common/builder.js
-define("cordova/builder", function(require, exports, module) {
-
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
- for (var prop in objects) {
- if (objects.hasOwnProperty(prop)) {
- func.apply(context, [objects[prop], prop]);
- }
- }
-}
-
-function clobber(obj, key, value) {
- exports.replaceHookForTesting(obj, key);
- obj[key] = value;
- // Getters can only be overridden by getters.
- if (obj[key] !== value) {
- utils.defineGetter(obj, key, function() {
- return value;
- });
- }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
- if (message) {
- utils.defineGetter(obj, key, function() {
- console.log(message);
- delete obj[key];
- clobber(obj, key, value);
- return value;
- });
- } else {
- clobber(obj, key, value);
- }
-}
-
-function include(parent, objects, clobber, merge) {
- each(objects, function (obj, key) {
- try {
- var result = obj.path ? require(obj.path) : {};
-
- if (clobber) {
- // Clobber if it doesn't exist.
- if (typeof parent[key] === 'undefined') {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- } else if (typeof obj.path !== 'undefined') {
- // If merging, merge properties onto parent, otherwise, clobber.
- if (merge) {
- recursiveMerge(parent[key], result);
- } else {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- }
- }
- result = parent[key];
- } else {
- // Overwrite if not currently defined.
- if (typeof parent[key] == 'undefined') {
- assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
- } else {
- // Set result to what already exists, so we can build children into it if they exist.
- result = parent[key];
- }
- }
-
- if (obj.children) {
- include(result, obj.children, clobber, merge);
- }
- } catch(e) {
- utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
- }
- });
-}
-
-/**
- * Merge properties from one object onto another recursively. Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
- for (var prop in src) {
- if (src.hasOwnProperty(prop)) {
- if (target.prototype && target.prototype.constructor === target) {
- // If the target object is a constructor override off prototype.
- clobber(target.prototype, prop, src[prop]);
- } else {
- if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
- recursiveMerge(target[prop], src[prop]);
- } else {
- clobber(target, prop, src[prop]);
- }
- }
- }
- }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
- include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
- include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
- include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
- nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
- * onNativeReady* Internal event that indicates the Cordova native side is ready.
- * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
- * onCordovaInfoReady* Internal event fired when device properties are available.
- * onCordovaConnectionReady* Internal event fired when the connection property has been set.
- * onDeviceReady* User event fired to indicate that Cordova is ready
- * onResume User event fired to indicate a start/resume lifecycle event
- * onPause User event fired to indicate a pause lifecycle event
- * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
- * pause App has moved to background
- * resume App has returned to foreground
- *
- * Listeners can be registered as:
- * document.addEventListener("deviceready", myDeviceReadyListener, false);
- * document.addEventListener("resume", myResumeListener, false);
- * document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- * window.onload
- * window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type String the channel name
- */
-var Channel = function(type, sticky) {
- this.type = type;
- // Map of guid -> function.
- this.handlers = {};
- // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
- this.state = sticky ? 1 : 0;
- // Used in sticky mode to remember args passed to fire().
- this.fireArgs = null;
- // Used by onHasSubscribersChange to know if there are any listeners.
- this.numHandlers = 0;
- // Function that is called when the first listener is subscribed, or when
- // the last listener is unsubscribed.
- this.onHasSubscribersChange = null;
-},
- channel = {
- /**
- * Calls the provided function only after all of the channels specified
- * have been fired. All channels must be sticky channels.
- */
- join: function(h, c) {
- var len = c.length,
- i = len,
- f = function() {
- if (!(--i)) h();
- };
- for (var j=0; j<len; j++) {
- if (c[j].state === 0) {
- throw Error('Can only use join with sticky channels.');
- }
- c[j].subscribe(f);
- }
- if (!len) h();
- },
- create: function(type) {
- return channel[type] = new Channel(type, false);
- },
- createSticky: function(type) {
- return channel[type] = new Channel(type, true);
- },
-
- /**
- * cordova Channels that must fire before "deviceready" is fired.
- */
- deviceReadyChannelsArray: [],
- deviceReadyChannelsMap: {},
-
- /**
- * Indicate that a feature needs to be initialized before it is ready to be used.
- * This holds up Cordova's "deviceready" event until the feature has been initialized
- * and Cordova.initComplete(feature) is called.
- *
- * @param feature {String} The unique feature name
- */
- waitForInitialization: function(feature) {
- if (feature) {
- var c = channel[feature] || this.createSticky(feature);
- this.deviceReadyChannelsMap[feature] = c;
- this.deviceReadyChannelsArray.push(c);
- }
- },
-
- /**
- * Indicate that initialization code has completed and the feature is ready to be used.
- *
- * @param feature {String} The unique feature name
- */
- initializationComplete: function(feature) {
- var c = this.deviceReadyChannelsMap[feature];
- if (c) {
- c.fire();
- }
- }
- };
-
-function forceFunction(f) {
- if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
- // need a function to call
- forceFunction(f);
- if (this.state == 2) {
- f.apply(c || this, this.fireArgs);
- return;
- }
-
- var func = f,
- guid = f.observer_guid;
- if (typeof c == "object") { func = utils.close(c, f); }
-
- if (!guid) {
- // first time any channel has seen this subscriber
- guid = '' + nextGuid++;
- }
- func.observer_guid = guid;
- f.observer_guid = guid;
-
- // Don't add the same handler more than once.
- if (!this.handlers[guid]) {
- this.handlers[guid] = func;
- this.numHandlers++;
- if (this.numHandlers == 1) {
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
- // need a function to unsubscribe
- forceFunction(f);
-
- var guid = f.observer_guid,
- handler = this.handlers[guid];
- if (handler) {
- delete this.handlers[guid];
- this.numHandlers--;
- if (this.numHandlers === 0) {
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
- var fail = false,
- fireArgs = Array.prototype.slice.call(arguments);
- // Apply stickiness.
- if (this.state == 1) {
- this.state = 2;
- this.fireArgs = fireArgs;
- }
- if (this.numHandlers) {
- // Copy the values first so that it is safe to modify it from within
- // callbacks.
- var toCall = [];
- for (var item in this.handlers) {
- toCall.push(this.handlers[item]);
- }
- for (var i = 0; i < toCall.length; ++i) {
- toCall[i].apply(this, fireArgs);
- }
- if (this.state == 2 && this.numHandlers) {
- this.numHandlers = 0;
- this.handlers = {};
- this.onHasSubscribersChange && this.onHasSubscribersChange();
- }
- }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that device properties are available
-channel.createSticky('onCordovaInfoReady');
-
-// Event to indicate that the connection property has been set.
-channel.createSticky('onCordovaConnectionReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onCordovaConnectionReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib/common/commandProxy.js
-define("cordova/commandProxy", function(require, exports, module) {
-
-
-// internal map of proxy function
-var CommandProxyMap = {};
-
-module.exports = {
-
- // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
- add:function(id,proxyObj) {
- console.log("adding proxy for " + id);
- CommandProxyMap[id] = proxyObj;
- return proxyObj;
- },
-
- // cordova.commandProxy.remove("Accelerometer");
- remove:function(id) {
- var proxy = CommandProxyMap[id];
- delete CommandProxyMap[id];
- CommandProxyMap[id] = null;
- return proxy;
- },
-
- get:function(service,action) {
- return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
- }
-};
-});
-
-// file: lib/windowsphone/exec.js
-define("cordova/exec", function(require, exports, module) {
-
-var cordova = require('cordova');
-
-/**
- * Execute a cordova command. It is up to the native side whether this action
- * is synchronous or asynchronous. The native side can return:
- * Synchronous: PluginResult object as a JSON string
- * Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success The success callback
- * @param {Function} fail The fail callback
- * @param {String} service The name of the service to use
- * @param {String} action Action to be run in cordova
- * @param {String[]} [args] Zero or more arguments to pass to the method
-
- */
-
-module.exports = function(success, fail, service, action, args) {
-
- var callbackId = service + cordova.callbackId++;
- if (typeof success == "function" || typeof fail == "function") {
- cordova.callbacks[callbackId] = {success:success, fail:fail};
- }
- // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
- for(var n = 0; n < args.length; n++)
- {
- if(typeof args[n] !== "string")
- {
- args[n] = JSON.stringify(args[n]);
- }
- }
- var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
- // pass it on to Notify
- try {
- if(window.external) {
- window.external.Notify(command);
- }
- else {
- console.log("window.external not available :: command=" + command);
- }
- }
- catch(e) {
- console.log("Exception calling native with command :: " + command + " :: exception=" + e);
- }
-};
-
-
-});
-
-// file: lib/common/modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
- moduleMap = define.moduleMap,
- symbolList,
- deprecationMap;
-
-exports.reset = function() {
- symbolList = [];
- deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
- if (!(moduleName in moduleMap)) {
- throw new Error('Module ' + moduleName + ' does not exist.');
- }
- 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);
-};
-
-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 symbolPath = symbolList[i + 2];
- var lastDot = symbolPath.lastIndexOf('.');
- var namespace = symbolPath.substr(0, lastDot);
- var lastName = symbolPath.substr(lastDot + 1);
-
- var module = require(moduleName);
- 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.loadMatchingModules = function(matchingRegExp) {
- for (var k in moduleMap) {
- if (matchingRegExp.exec(k)) {
- require(k);
- }
- }
-};
-
-exports.reset();
-
-
-});
-
-// file: lib/windowsphone/platform.js
-define("cordova/platform", function(require, exports, module) {
-
-var cordova = require('cordova'),
- exec = require('cordova/exec');
-
-module.exports = {
- id: "windowsphone",
- initialize:function() {
- var modulemapper = require('cordova/modulemapper');
-
- modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
-
- modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
-
- modulemapper.mapModules(window);
-
- // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
- var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
- backButtonChannel.onHasSubscribersChange = function() {
- exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
- };
- }
-};
-
-});
-
-// file: lib/common/plugin/Acceleration.js
-define("cordova/plugin/Acceleration", function(require, exports, module) {
-
-var Acceleration = function(x, y, z, timestamp) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.timestamp = timestamp || (new Date()).getTime();
-};
-
-module.exports = Acceleration;
-
-});
-
-// file: lib/common/plugin/Camera.js
-define("cordova/plugin/Camera", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- Camera = require('cordova/plugin/CameraConstants'),
- CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
-
-var cameraExport = {};
-
-// Tack on the Camera Constants to the base camera plugin.
-for (var key in Camera) {
- cameraExport[key] = Camera[key];
-}
-
-/**
- * Gets a picture from source defined by "options.sourceType", and returns the
- * image as defined by the "options.destinationType" option.
-
- * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
- *
- * @param {Function} successCallback
- * @param {Function} errorCallback
- * @param {Object} options
- */
-cameraExport.getPicture = function(successCallback, errorCallback, options) {
- argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
- options = options || {};
- var getValue = argscheck.getValue;
-
- var quality = getValue(options.quality, 50);
- var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
- var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
- var targetWidth = getValue(options.targetWidth, -1);
- var targetHeight = getValue(options.targetHeight, -1);
- var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
- var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
- var allowEdit = !!options.allowEdit;
- var correctOrientation = !!options.correctOrientation;
- var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
- var popoverOptions = getValue(options.popoverOptions, null);
- var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
-
- var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
-
- exec(successCallback, errorCallback, "Camera", "takePicture", args);
- return new CameraPopoverHandle();
-};
-
-cameraExport.cleanup = function(successCallback, errorCallback) {
- exec(successCallback, errorCallback, "Camera", "cleanup", []);
-};
-
-module.exports = cameraExport;
-
-});
-
-// file: lib/common/plugin/CameraConstants.js
-define("cordova/plugin/CameraConstants", function(require, exports, module) {
-
-module.exports = {
- DestinationType:{
- DATA_URL: 0, // Return base64 encoded string
- FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
- NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
- },
- EncodingType:{
- JPEG: 0, // Return JPEG encoded image
- PNG: 1 // Return PNG encoded image
- },
- MediaType:{
- PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
- VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
- ALLMEDIA : 2 // allow selection from all media types
- },
- PictureSourceType:{
- PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
- CAMERA : 1, // Take picture from camera
- SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
- },
- PopoverArrowDirection:{
- ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
- ARROW_DOWN : 2,
- ARROW_LEFT : 4,
- ARROW_RIGHT : 8,
- ARROW_ANY : 15
- },
- Direction:{
- BACK: 0,
- FRONT: 1
- }
-};
-
-});
-
-// file: lib/common/plugin/CameraPopoverHandle.js
-define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-/**
- * A handle to an image picker popover.
- */
-var CameraPopoverHandle = function() {
- this.setPosition = function(popoverOptions) {
- console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
- };
-};
-
-module.exports = CameraPopoverHandle;
-
-});
-
-// file: lib/common/plugin/CameraPopoverOptions.js
-define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
-
-var Camera = require('cordova/plugin/CameraConstants');
-
-/**
- * Encapsulates options for iOS Popover image picker
- */
-var CameraPopoverOptions = function(x,y,width,height,arrowDir){
- // information of rectangle that popover should be anchored to
- this.x = x || 0;
- this.y = y || 32;
- this.width = width || 320;
- this.height = height || 480;
- // The direction of the popover arrow
- this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
-};
-
-module.exports = CameraPopoverOptions;
-
-});
-
-// file: lib/common/plugin/CaptureAudioOptions.js
-define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all audio capture operation configuration options.
- */
-var CaptureAudioOptions = function(){
- // Upper limit of sound clips user can record. Value must be equal or greater than 1.
- this.limit = 1;
- // Maximum duration of a single sound clip in seconds.
- this.duration = 0;
-};
-
-module.exports = CaptureAudioOptions;
-
-});
-
-// file: lib/common/plugin/CaptureError.js
-define("cordova/plugin/CaptureError", function(require, exports, module) {
-
-/**
- * The CaptureError interface encapsulates all errors in the Capture API.
- */
-var CaptureError = function(c) {
- this.code = c || null;
-};
-
-// Camera or microphone failed to capture image or sound.
-CaptureError.CAPTURE_INTERNAL_ERR = 0;
-// Camera application or audio capture application is currently serving other capture request.
-CaptureError.CAPTURE_APPLICATION_BUSY = 1;
-// Invalid use of the API (e.g. limit parameter has value less than one).
-CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
-// User exited camera application or audio capture application before capturing anything.
-CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
-// The requested capture operation is not supported.
-CaptureError.CAPTURE_NOT_SUPPORTED = 20;
-
-module.exports = CaptureError;
-
-});
-
-// file: lib/common/plugin/CaptureImageOptions.js
-define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all image capture operation configuration options.
- */
-var CaptureImageOptions = function(){
- // Upper limit of images user can take. Value must be equal or greater than 1.
- this.limit = 1;
-};
-
-module.exports = CaptureImageOptions;
-
-});
-
-// file: lib/common/plugin/CaptureVideoOptions.js
-define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all video capture operation configuration options.
- */
-var CaptureVideoOptions = function(){
- // Upper limit of videos user can record. Value must be equal or greater than 1.
- this.limit = 1;
- // Maximum duration of a single video clip in seconds.
- this.duration = 0;
-};
-
-module.exports = CaptureVideoOptions;
-
-});
-
-// file: lib/common/plugin/CompassError.js
-define("cordova/plugin/CompassError", function(require, exports, module) {
-
-/**
- * CompassError.
- * An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var CompassError = function(err) {
- this.code = (err !== undefined ? err : null);
-};
-
-CompassError.COMPASS_INTERNAL_ERR = 0;
-CompassError.COMPASS_NOT_SUPPORTED = 20;
-
-module.exports = CompassError;
-
-});
-
-// file: lib/common/plugin/CompassHeading.js
-define("cordova/plugin/CompassHeading", function(require, exports, module) {
-
-var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
- this.magneticHeading = magneticHeading;
- this.trueHeading = trueHeading;
- this.headingAccuracy = headingAccuracy;
- this.timestamp = timestamp || new Date().getTime();
-};
-
-module.exports = CompassHeading;
-
-});
-
-// file: lib/common/plugin/ConfigurationData.js
-define("cordova/plugin/ConfigurationData", function(require, exports, module) {
-
-/**
- * Encapsulates a set of parameters that the capture device supports.
- */
-function ConfigurationData() {
- // The ASCII-encoded string in lower case representing the media type.
- this.type = null;
- // The height attribute represents height of the image or video in pixels.
- // In the case of a sound clip this attribute has value 0.
- this.height = 0;
- // The width attribute represents width of the image or video in pixels.
- // In the case of a sound clip this attribute has value 0
- this.width = 0;
-}
-
-module.exports = ConfigurationData;
-
-});
-
-// file: lib/common/plugin/Connection.js
-define("cordova/plugin/Connection", function(require, exports, module) {
-
-/**
- * Network status
- */
-module.exports = {
- UNKNOWN: "unknown",
- ETHERNET: "ethernet",
- WIFI: "wifi",
- CELL_2G: "2g",
- CELL_3G: "3g",
- CELL_4G: "4g",
- CELL:"cellular",
- NONE: "none"
-};
-
-});
-
-// file: lib/common/plugin/Contact.js
-define("cordova/plugin/Contact", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- ContactError = require('cordova/plugin/ContactError'),
- utils = require('cordova/utils');
-
-/**
-* Converts primitives into Complex Object
-* Currently only used for Date fields
-*/
-function convertIn(contact) {
- var value = contact.birthday;
- try {
- contact.birthday = new Date(parseFloat(value));
- } catch (exception){
- console.log("Cordova Contact convertIn error: exception creating date.");
- }
- return contact;
-}
-
-/**
-* Converts Complex objects into primitives
-* Only conversion at present is for Dates.
-**/
-
-function convertOut(contact) {
- var value = contact.birthday;
- if (value !== null) {
- // try to make it a Date object if it is not already
- if (!utils.isDate(value)){
- try {
- value = new Date(value);
- } catch(exception){
- value = null;
- }
- }
- if (utils.isDate(value)){
- value = value.valueOf(); // convert to milliseconds
- }
- contact.birthday = value;
- }
- return contact;
-}
-
-/**
-* Contains information about a single contact.
-* @constructor
-* @param {DOMString} id unique identifier
-* @param {DOMString} displayName
-* @param {ContactName} name
-* @param {DOMString} nickname
-* @param {Array.<ContactField>} phoneNumbers array of phone numbers
-* @param {Array.<ContactField>} emails array of email addresses
-* @param {Array.<ContactAddress>} addresses array of addresses
-* @param {Array.<ContactField>} ims instant messaging user ids
-* @param {Array.<ContactOrganization>} organizations
-* @param {DOMString} birthday contact's birthday
-* @param {DOMString} note user notes about contact
-* @param {Array.<ContactField>} photos
-* @param {Array.<ContactField>} categories
-* @param {Array.<ContactField>} urls contact's web sites
-*/
-var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
- ims, organizations, birthday, note, photos, categories, urls) {
- this.id = id || null;
- this.rawId = null;
- this.displayName = displayName || null;
- this.name = name || null; // ContactName
- this.nickname = nickname || null;
- this.phoneNumbers = phoneNumbers || null; // ContactField[]
- this.emails = emails || null; // ContactField[]
- this.addresses = addresses || null; // ContactAddress[]
- this.ims = ims || null; // ContactField[]
- this.organizations = organizations || null; // ContactOrganization[]
- this.birthday = birthday || null;
- this.note = note || null;
- this.photos = photos || null; // ContactField[]
- this.categories = categories || null; // ContactField[]
- this.urls = urls || null; // ContactField[]
-};
-
-/**
-* Removes contact from device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.remove = function(successCB, errorCB) {
- argscheck.checkArgs('FF', 'Contact.remove', arguments);
- var fail = errorCB && function(code) {
- errorCB(new ContactError(code));
- };
- if (this.id === null) {
- fail(ContactError.UNKNOWN_ERROR);
- }
- else {
- exec(successCB, fail, "Contacts", "remove", [this.id]);
- }
-};
-
-/**
-* Creates a deep copy of this Contact.
-* With the contact ID set to null.
-* @return copy of this Contact
-*/
-Contact.prototype.clone = function() {
- var clonedContact = utils.clone(this);
- clonedContact.id = null;
- clonedContact.rawId = null;
-
- function nullIds(arr) {
- if (arr) {
- for (var i = 0; i < arr.length; ++i) {
- arr[i].id = null;
- }
- }
- }
-
- // Loop through and clear out any id's in phones, emails, etc.
- nullIds(clonedContact.phoneNumbers);
- nullIds(clonedContact.emails);
- nullIds(clonedContact.addresses);
- nullIds(clonedContact.ims);
- nullIds(clonedContact.organizations);
- nullIds(clonedContact.categories);
- nullIds(clonedContact.photos);
- nullIds(clonedContact.urls);
- return clonedContact;
-};
-
-/**
-* Persists contact to device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.save = function(successCB, errorCB) {
- argscheck.checkArgs('FFO', 'Contact.save', arguments);
- var fail = errorCB && function(code) {
- errorCB(new ContactError(code));
- };
- var success = function(result) {
- if (result) {
- if (successCB) {
- var fullContact = require('cordova/plugin/contacts').create(result);
- successCB(convertIn(fullContact));
- }
- }
- else {
- // no Entry object returned
- fail(ContactError.UNKNOWN_ERROR);
- }
- };
- var dupContact = convertOut(utils.clone(this));
- exec(success, fail, "Contacts", "save", [dupContact]);
-};
-
-
-module.exports = Contact;
-
-});
-
-// file: lib/common/plugin/ContactAddress.js
-define("cordova/plugin/ContactAddress", function(require, exports, module) {
-
-/**
-* Contact address.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code
-* @param formatted // NOTE: not a W3C standard
-* @param streetAddress
-* @param locality
-* @param region
-* @param postalCode
-* @param country
-*/
-
-var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.formatted = formatted || null;
- this.streetAddress = streetAddress || null;
- this.locality = locality || null;
- this.region = region || null;
- this.postalCode = postalCode || null;
- this.country = country || null;
-};
-
-module.exports = ContactAddress;
-
-});
-
-// file: lib/common/plugin/ContactError.js
-define("cordova/plugin/ContactError", function(require, exports, module) {
-
-/**
- * ContactError.
- * An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var ContactError = function(err) {
- this.code = (typeof err != 'undefined' ? err : null);
-};
-
-/**
- * Error codes
- */
-ContactError.UNKNOWN_ERROR = 0;
-ContactError.INVALID_ARGUMENT_ERROR = 1;
-ContactError.TIMEOUT_ERROR = 2;
-ContactError.PENDING_OPERATION_ERROR = 3;
-ContactError.IO_ERROR = 4;
-ContactError.NOT_SUPPORTED_ERROR = 5;
-ContactError.PERMISSION_DENIED_ERROR = 20;
-
-module.exports = ContactError;
-
-});
-
-// file: lib/common/plugin/ContactField.js
-define("cordova/plugin/ContactField", function(require, exports, module) {
-
-/**
-* Generic contact field.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param type
-* @param value
-* @param pref
-*/
-var ContactField = function(type, value, pref) {
- this.id = null;
- this.type = (type && type.toString()) || null;
- this.value = (value && value.toString()) || null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
-};
-
-module.exports = ContactField;
-
-});
-
-// file: lib/common/plugin/ContactFindOptions.js
-define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
-
-/**
- * ContactFindOptions.
- * @constructor
- * @param filter used to match contacts against
- * @param multiple boolean used to determine if more than one contact should be returned
- */
-
-var ContactFindOptions = function(filter, multiple) {
- this.filter = filter || '';
- this.multiple = (typeof multiple != 'undefined' ? multiple : false);
-};
-
-module.exports = ContactFindOptions;
-
-});
-
-// file: lib/common/plugin/ContactName.js
-define("cordova/plugin/ContactName", function(require, exports, module) {
-
-/**
-* Contact name.
-* @constructor
-* @param formatted // NOTE: not part of W3C standard
-* @param familyName
-* @param givenName
-* @param middle
-* @param prefix
-* @param suffix
-*/
-var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
- this.formatted = formatted || null;
- this.familyName = familyName || null;
- this.givenName = givenName || null;
- this.middleName = middle || null;
- this.honorificPrefix = prefix || null;
- this.honorificSuffix = suffix || null;
-};
-
-module.exports = ContactName;
-
-});
-
-// file: lib/common/plugin/ContactOrganization.js
-define("cordova/plugin/ContactOrganization", function(require, exports, module) {
-
-/**
-* Contact organization.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param name
-* @param dept
-* @param title
-* @param startDate
-* @param endDate
-* @param location
-* @param desc
-*/
-
-var ContactOrganization = function(pref, type, name, dept, title) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.name = name || null;
- this.department = dept || null;
- this.title = title || null;
-};
-
-module.exports = ContactOrganization;
-
-});
-
-// file: lib/common/plugin/Coordinates.js
-define("cordova/plugin/Coordinates", function(require, exports, module) {
-
-/**
- * This class contains position information.
- * @param {Object} lat
- * @param {Object} lng
- * @param {Object} alt
- * @param {Object} acc
- * @param {Object} head
- * @param {Object} vel
- * @param {Object} altacc
- * @constructor
- */
-var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
- /**
- * The latitude of the position.
- */
- this.latitude = lat;
- /**
- * The longitude of the position,
- */
- this.longitude = lng;
- /**
- * The accuracy of the position.
- */
- this.accuracy = acc;
- /**
- * The altitude of the position.
- */
- this.altitude = (alt !== undefined ? alt : null);
- /**
- * The direction the device is moving at the position.
- */
- this.heading = (head !== undefined ? head : null);
- /**
- * The velocity with which the device is moving at the position.
- */
- this.speed = (vel !== undefined ? vel : null);
-
- if (this.speed === 0 || this.speed === null) {
- this.heading = NaN;
- }
-
- /**
- * The altitude accuracy of the position.
- */
- this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
-};
-
-module.exports = Coordinates;
-
-});
-
-// file: lib/common/plugin/DirectoryEntry.js
-define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileError = require('cordova/plugin/FileError'),
- DirectoryReader = require('cordova/plugin/DirectoryReader');
-
-/**
- * An interface representing a directory on the file system.
- *
- * {boolean} isFile always false (readonly)
- * {boolean} isDirectory always true (readonly)
- * {DOMString} name of the directory, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the directory (readonly)
- * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
- */
-var DirectoryEntry = function(name, fullPath) {
- DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
-};
-
-utils.extend(DirectoryEntry, Entry);
-
-/**
- * Creates a new DirectoryReader to read entries from this directory
- */
-DirectoryEntry.prototype.createReader = function() {
- return new DirectoryReader(this.fullPath);
-};
-
-/**
- * Creates or looks up a directory
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
- * @param {Flags} options to create or exclusively create the directory
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
- argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
- var win = successCallback && function(result) {
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
-};
-
-/**
- * Deletes a directory and all of it's contents
- *
- * @param {Function} successCallback is called with no parameters
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
-};
-
-/**
- * Creates or looks up a file
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
- * @param {Flags} options to create or exclusively create the file
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
- argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
- var win = successCallback && function(result) {
- var FileEntry = require('cordova/plugin/FileEntry');
- var entry = new FileEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
-};
-
-module.exports = DirectoryEntry;
-
-});
-
-// file: lib/common/plugin/DirectoryReader.js
-define("cordova/plugin/DirectoryReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError') ;
-
-/**
- * An interface that lists the files and directories in a directory.
- */
-function DirectoryReader(path) {
- this.path = path || null;
-}
-
-/**
- * Returns a list of entries from a directory.
- *
- * @param {Function} successCallback is called with a list of entries
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
- var win = typeof successCallback !== 'function' ? null : function(result) {
- var retVal = [];
- for (var i=0; i<result.length; i++) {
- var entry = null;
- if (result[i].isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result[i].isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result[i].isDirectory;
- entry.isFile = result[i].isFile;
- entry.name = result[i].name;
- entry.fullPath = result[i].fullPath;
- retVal.push(entry);
- }
- successCallback(retVal);
- };
- var fail = typeof errorCallback !== 'function' ? null : function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "readEntries", [this.path]);
-};
-
-module.exports = DirectoryReader;
-
-});
-
-// file: lib/common/plugin/Entry.js
-define("cordova/plugin/Entry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError'),
- Metadata = require('cordova/plugin/Metadata');
-
-/**
- * Represents a file or directory on the local file system.
- *
- * @param isFile
- * {boolean} true if Entry is a file (readonly)
- * @param isDirectory
- * {boolean} true if Entry is a directory (readonly)
- * @param name
- * {DOMString} name of the file or directory, excluding the path
- * leading to it (readonly)
- * @param fullPath
- * {DOMString} the absolute full path to the file or directory
- * (readonly)
- */
-function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
- this.isFile = !!isFile;
- this.isDirectory = !!isDirectory;
- this.name = name || '';
- this.fullPath = fullPath || '';
- this.filesystem = fileSystem || null;
-}
-
-/**
- * Look up the metadata of the entry.
- *
- * @param successCallback
- * {Function} is called with a Metadata object
- * @param errorCallback
- * {Function} is called with a FileError
- */
-Entry.prototype.getMetadata = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
- var success = successCallback && function(lastModified) {
- var metadata = new Metadata(lastModified);
- successCallback(metadata);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
-
- exec(success, fail, "File", "getMetadata", [this.fullPath]);
-};
-
-/**
- * Set the metadata of the entry.
- *
- * @param successCallback
- * {Function} is called with a Metadata object
- * @param errorCallback
- * {Function} is called with a FileError
- * @param metadataObject
- * {Object} keys and values to set
- */
-Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
- argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
- exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
-};
-
-/**
- * Move a file or directory to a new location.
- *
- * @param parent
- * {DirectoryEntry} the directory to which to move this entry
- * @param newName
- * {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- * {Function} called with the new DirectoryEntry object
- * @param errorCallback
- * {Function} called with a FileError
- */
-Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
- argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- // source path
- var srcPath = this.fullPath,
- // entry name
- name = newName || this.name,
- success = function(entry) {
- if (entry) {
- if (successCallback) {
- // create appropriate Entry object
- var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
- successCallback(result);
- }
- }
- else {
- // no Entry object returned
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- // copy
- exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Copy a directory to a different location.
- *
- * @param parent
- * {DirectoryEntry} the directory to which to copy the entry
- * @param newName
- * {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- * {Function} called with the new Entry object
- * @param errorCallback
- * {Function} called with a FileError
- */
-Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
- argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
-
- // source path
- var srcPath = this.fullPath,
- // entry name
- name = newName || this.name,
- // success callback
- success = function(entry) {
- if (entry) {
- if (successCallback) {
- // create appropriate Entry object
- var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
- successCallback(result);
- }
- }
- else {
- // no Entry object returned
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- // copy
- exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Return a URL that can be used to identify this entry.
- */
-Entry.prototype.toURL = function() {
- // fullPath attribute contains the full URL
- return this.fullPath;
-};
-
-/**
- * Returns a URI that can be used to identify this entry.
- *
- * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
- * @return uri
- */
-Entry.prototype.toURI = function(mimeType) {
- console.log("DEPRECATED: Update your code to use 'toURL'");
- // fullPath attribute contains the full URI
- return this.toURL();
-};
-
-/**
- * Remove a file or directory. It is an error to attempt to delete a
- * directory that is not empty. It is an error to attempt to delete a
- * root directory of a file system.
- *
- * @param successCallback {Function} called with no parameters
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.remove = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.remove', arguments);
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "remove", [this.fullPath]);
-};
-
-/**
- * Look up the parent DirectoryEntry of this entry.
- *
- * @param successCallback {Function} called with the parent DirectoryEntry object
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.getParent = function(successCallback, errorCallback) {
- argscheck.checkArgs('FF', 'Entry.getParent', arguments);
- var win = successCallback && function(result) {
- var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getParent", [this.fullPath]);
-};
-
-module.exports = Entry;
-
-});
-
-// file: lib/common/plugin/File.js
-define("cordova/plugin/File", function(require, exports, module) {
-
-/**
- * Constructor.
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-
-var File = function(name, fullPath, type, lastModifiedDate, size){
- this.name = name || '';
- this.fullPath = fullPath || null;
- this.type = type || null;
- this.lastModifiedDate = lastModifiedDate || null;
- this.size = size || 0;
-
- // These store the absolute start and end for slicing the file.
- this.start = 0;
- this.end = this.size;
-};
-
-/**
- * Returns a "slice" of the file. Since Cordova Files don't contain the actual
- * content, this really returns a File with adjusted start and end.
- * Slices of slices are supported.
- * start {Number} The index at which to start the slice (inclusive).
- * end {Number} The index at which to end the slice (exclusive).
- */
-File.prototype.slice = function(start, end) {
- var size = this.end - this.start;
- var newStart = 0;
- var newEnd = size;
- if (arguments.length) {
- if (start < 0) {
- newStart = Math.max(size + start, 0);
- } else {
- newStart = Math.min(size, start);
- }
- }
-
- if (arguments.length >= 2) {
- if (end < 0) {
- newEnd = Math.max(size + end, 0);
- } else {
- newEnd = Math.min(end, size);
- }
- }
-
- var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
- newFile.start = this.start + newStart;
- newFile.end = this.start + newEnd;
- return newFile;
-};
-
-
-module.exports = File;
-
-});
-
-// file: lib/common/plugin/FileEntry.js
-define("cordova/plugin/FileEntry", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileWriter = require('cordova/plugin/FileWriter'),
- File = require('cordova/plugin/File'),
- FileError = require('cordova/plugin/FileError');
-
-/**
- * An interface representing a file on the file system.
- *
- * {boolean} isFile always true (readonly)
- * {boolean} isDirectory always false (readonly)
- * {DOMString} name of the file, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the file (readonly)
- * {FileSystem} filesystem on which the file resides (readonly)
- */
-var FileEntry = function(name, fullPath) {
- FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
-};
-
-utils.extend(FileEntry, Entry);
-
-/**
- * Creates a new FileWriter associated with the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new FileWriter
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
- this.file(function(filePointer) {
- var writer = new FileWriter(filePointer);
-
- if (writer.fileName === null || writer.fileName === "") {
- errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
- } else {
- successCallback && successCallback(writer);
- }
- }, errorCallback);
-};
-
-/**
- * Returns a File that represents the current state of the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new File object
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.file = function(successCallback, errorCallback) {
- var win = successCallback && function(f) {
- var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
- successCallback(file);
- };
- var fail = errorCallback && function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
-};
-
-
-module.exports = FileEntry;
-
-});
-
-// file: lib/common/plugin/FileError.js
-define("cordova/plugin/FileError", function(require, exports, module) {
-
-/**
- * FileError
- */
-function FileError(error) {
- this.code = error || null;
-}
-
-// File error codes
-// Found in DOMException
-FileError.NOT_FOUND_ERR = 1;
-FileError.SECURITY_ERR = 2;
-FileError.ABORT_ERR = 3;
-
-// Added by File API specification
-FileError.NOT_READABLE_ERR = 4;
-FileError.ENCODING_ERR = 5;
-FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
-FileError.INVALID_STATE_ERR = 7;
-FileError.SYNTAX_ERR = 8;
-FileError.INVALID_MODIFICATION_ERR = 9;
-FileError.QUOTA_EXCEEDED_ERR = 10;
-FileError.TYPE_MISMATCH_ERR = 11;
-FileError.PATH_EXISTS_ERR = 12;
-
-module.exports = FileError;
-
-});
-
-// file: lib/common/plugin/FileReader.js
-define("cordova/plugin/FileReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
- modulemapper = require('cordova/modulemapper'),
- utils = require('cordova/utils'),
- File = require('cordova/plugin/File'),
- FileError = require('cordova/plugin/FileError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent'),
- origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
-
-/**
- * This class reads the mobile device file system.
- *
- * For Android:
- * The root directory is the root of the file system.
- * To read from the SD card, the file name is "sdcard/my_file.txt"
- * @constructor
- */
-var FileReader = function() {
- this._readyState = 0;
- this._error = null;
- this._result = null;
- this._fileName = '';
- this._realReader = origFileReader ? new origFileReader() : {};
-};
-
-// States
-FileReader.EMPTY = 0;
-FileReader.LOADING = 1;
-FileReader.DONE = 2;
-
-utils.defineGetter(FileReader.prototype, 'readyState', function() {
- return this._fileName ? this._readyState : this._realReader.readyState;
-});
-
-utils.defineGetter(FileReader.prototype, 'error', function() {
- return this._fileName ? this._error: this._realReader.error;
-});
-
-utils.defineGetter(FileReader.prototype, 'result', function() {
- return this._fileName ? this._result: this._realReader.result;
-});
-
-function defineEvent(eventName) {
- utils.defineGetterSetter(FileReader.prototype, eventName, function() {
- return this._realReader[eventName] || null;
- }, function(value) {
- this._realReader[eventName] = value;
- });
-}
-defineEvent('onloadstart'); // When the read starts.
-defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
-defineEvent('onload'); // When the read has successfully completed.
-defineEvent('onerror'); // When the read has failed (see errors).
-defineEvent('onloadend'); // When the request has completed (either in success or failure).
-defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
-
-function initRead(reader, file) {
- // Already loading something
- if (reader.readyState == FileReader.LOADING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- reader._result = null;
- reader._error = null;
- reader._readyState = FileReader.LOADING;
-
- if (typeof file == 'string') {
- // Deprecated in Cordova 2.4.
- console.warn('Using a string argument with FileReader.readAs functions is deprecated.');
- reader._fileName = file;
- } else if (typeof file.fullPath == 'string') {
- reader._fileName = file.fullPath;
- } else {
- reader._fileName = '';
- return true;
- }
-
- reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
-}
-
-/**
- * Abort reading file.
- */
-FileReader.prototype.abort = function() {
- if (origFileReader && !this._fileName) {
- return this._realReader.abort();
- }
- this._result = null;
-
- if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
- return;
- }
-
- this._readyState = FileReader.DONE;
-
- // If abort callback
- if (typeof this.onabort === 'function') {
- this.onabort(new ProgressEvent('abort', {target:this}));
- }
- // If load end callback
- if (typeof this.onloadend === 'function') {
- this.onloadend(new ProgressEvent('loadend', {target:this}));
- }
-};
-
-/**
- * Read text file.
- *
- * @param file {File} File object containing file properties
- * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
- */
-FileReader.prototype.readAsText = function(file, encoding) {
- if (initRead(this, file)) {
- return this._realReader.readAsText(file, encoding);
- }
-
- // Default encoding is UTF-8
- var enc = encoding ? encoding : "UTF-8";
- var me = this;
- var execArgs = [this._fileName, enc, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // Save result
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // null result
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsText", execArgs);
-};
-
-
-/**
- * Read file and return data as a base64 encoded data url.
- * A data url is of the form:
- * data:[<mediatype>][;base64],<data>
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsDataURL = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsDataURL(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- // Save result
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsDataURL", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsBinaryString = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsBinaryString(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsBinaryString", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsArrayBuffer = function(file) {
- if (initRead(this, file)) {
- return this._realReader.readAsArrayBuffer(file);
- }
-
- var me = this;
- var execArgs = [this._fileName, file.start, file.end];
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me._readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me._readyState = FileReader.DONE;
-
- me._result = null;
-
- // Save error
- me._error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsArrayBuffer", execArgs);
-};
-
-module.exports = FileReader;
-
-});
-
-// file: lib/common/plugin/FileSystem.js
-define("cordova/plugin/FileSystem", function(require, exports, module) {
-
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-
-/**
- * An interface representing a file system
- *
- * @constructor
- * {DOMString} name the unique name of the file system (readonly)
- * {DirectoryEntry} root directory of the file system (readonly)
- */
-var FileSystem = function(name, root) {
- this.name = name || null;
- if (root) {
- this.root = new DirectoryEntry(root.name, root.fullPath);
- }
-};
-
-module.exports = FileSystem;
-
-});
-
-// file: lib/common/plugin/FileTransfer.js
-define("cordova/plugin/FileTransfer", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
- exec = require('cordova/exec'),
- FileTransferError = require('cordova/plugin/FileTransferError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-function newProgressEvent(result) {
- var pe = new ProgressEvent();
- pe.lengthComputable = result.lengthComputable;
- pe.loaded = result.loaded;
- pe.total = result.total;
- return pe;
-}
-
-function getBasicAuthHeader(urlString) {
- var header = null;
-
- if (window.btoa) {
- // parse the url using the Location object
- var url = document.createElement('a');
- url.href = urlString;
-
- var credentials = null;
- var protocol = url.protocol + "//";
- var origin = protocol + url.host;
-
- // check whether there are the username:password credentials in the url
- if (url.href.indexOf(origin) !== 0) { // credentials found
- var atIndex = url.href.indexOf("@");
- credentials = url.href.substring(protocol.length, atIndex);
- }
-
- if (credentials) {
- var authHeader = "Authorization";
- var authHeaderValue = "Basic " + window.btoa(credentials);
-
- header = {
- name : authHeader,
- value : authHeaderValue
- };
- }
- }
-
- return header;
-}
-
-var idCounter = 0;
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {
- this._id = ++idCounter;
- this.onprogress = null; // optional callback
-};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String} Full path of the file on the device
-* @param server {String} URL of the server to receive the file
-* @param successCallback (Function} Callback to be invoked when upload has completed
-* @param errorCallback {Function} Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
- argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
- // check for options
- var fileKey = null;
- var fileName = null;
- var mimeType = null;
- var params = null;
- var chunkedMode = true;
- var headers = null;
- var httpMethod = null;
- var basicAuthHeader = getBasicAuthHeader(server);
- if (basicAuthHeader) {
- options = options || {};
- options.headers = options.headers || {};
- options.headers[basicAuthHeader.name] = basicAuthHeader.value;
- }
-
- if (options) {
- fileKey = options.fileKey;
- fileName = options.fileName;
- mimeType = options.mimeType;
- headers = options.headers;
- httpMethod = options.httpMethod || "POST";
- if (httpMethod.toUpperCase() == "PUT"){
- httpMethod = "PUT";
- } else {
- httpMethod = "POST";
- }
- if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
- chunkedMode = options.chunkedMode;
- }
- if (options.params) {
- params = options.params;
- }
- else {
- params = {};
- }
- }
-
- var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
- errorCallback(error);
- };
-
- var self = this;
- var win = function(result) {
- if (typeof result.lengthComputable != "undefined") {
- if (self.onprogress) {
- self.onprogress(newProgressEvent(result));
- }
- } else {
- successCallback && successCallback(result);
- }
- };
- exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String} URL of the server to receive the file
- * @param target {String} Full path of the file on the device
- * @param successCallback (Function} Callback to be invoked when upload has completed
- * @param errorCallback {Function} Callback to be invoked upon error
- * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
- * @param options {FileDownloadOptions} Optional parameters such as headers
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
- argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
- var self = this;
-
- var basicAuthHeader = getBasicAuthHeader(source);
- if (basicAuthHeader) {
- options = options || {};
- options.headers = options.headers || {};
- options.headers[basicAuthHeader.name] = basicAuthHeader.value;
- }
-
- var headers = null;
- if (options) {
- headers = options.headers || null;
- }
-
- var win = function(result) {
- if (typeof result.lengthComputable != "undefined") {
- if (self.onprogress) {
- return self.onprogress(newProgressEvent(result));
- }
- } else if (successCallback) {
- var entry = null;
- if (result.isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result.isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result.isDirectory;
- entry.isFile = result.isFile;
- entry.name = result.name;
- entry.fullPath = result.fullPath;
- successCallback(entry);
- }
- };
-
- var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
- errorCallback(error);
- };
-
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
-};
-
-/**
- * Aborts the ongoing file transfer on this object. The original error
- * callback for the file transfer will be called if necessary.
- */
-FileTransfer.prototype.abort = function() {
- exec(nu
<TRUNCATED>
[28/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/plugins/AudioPlayer.cs b/plugins/AudioPlayer.cs
deleted file mode 100644
index a83be5b..0000000
--- a/plugins/AudioPlayer.cs
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Implements audio record and play back functionality.
- /// </summary>
- internal class AudioPlayer : IDisposable
- {
- #region Constants
-
- // AudioPlayer states
- private const int PlayerState_None = 0;
- private const int PlayerState_Starting = 1;
- private const int PlayerState_Running = 2;
- private const int PlayerState_Paused = 3;
- private const int PlayerState_Stopped = 4;
-
- // AudioPlayer messages
- private const int MediaState = 1;
- private const int MediaDuration = 2;
- private const int MediaPosition = 3;
- private const int MediaError = 9;
-
- // AudioPlayer errors
- private const int MediaErrorPlayModeSet = 1;
- private const int MediaErrorAlreadyRecording = 2;
- private const int MediaErrorStartingRecording = 3;
- private const int MediaErrorRecordModeSet = 4;
- private const int MediaErrorStartingPlayback = 5;
- private const int MediaErrorResumeState = 6;
- private const int MediaErrorPauseState = 7;
- private const int MediaErrorStopState = 8;
-
- //TODO: get rid of this callback, it should be universal
- //private const string CallbackFunction = "CordovaMediaonStatus";
-
- #endregion
-
- /// <summary>
- /// The AudioHandler object
- /// </summary>
- private Media handler;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// The id of this player (used to identify Media object in JavaScript)
- /// </summary>
- private String id;
-
- /// <summary>
- /// State of recording or playback
- /// </summary>
- private int state = PlayerState_None;
-
- /// <summary>
- /// File name to play or record to
- /// </summary>
- private String audioFile = null;
-
- /// <summary>
- /// Duration of audio
- /// </summary>
- private double duration = -1;
-
- /// <summary>
- /// Audio player object
- /// </summary>
- private MediaElement player = null;
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone recorder;
-
- /// <summary>
- /// Internal flag specified that we should only open audio w/o playing it
- /// </summary>
- private bool prepareOnly = false;
-
- /// <summary>
- /// Creates AudioPlayer instance
- /// </summary>
- /// <param name="handler">Media object</param>
- /// <param name="id">player id</param>
- public AudioPlayer(Media handler, String id)
- {
- this.handler = handler;
- this.id = id;
- }
-
- /// <summary>
- /// Destroys player and stop audio playing or recording
- /// </summary>
- public void Dispose()
- {
- if (this.player != null)
- {
- this.stopPlaying();
- this.player = null;
- }
- if (this.recorder != null)
- {
- this.stopRecording();
- this.recorder = null;
- }
-
- this.FinalizeXnaGameLoop();
- }
-
- private void InvokeCallback(int message, string value, bool removeHandler)
- {
- string args = string.Format("('{0}',{1},{2});", this.id, message, value);
- string callback = @"(function(id,msg,value){
- try {
- if (msg == Media.MEDIA_ERROR) {
- value = {'code':value};
- }
- Media.onStatus(id,msg,value);
- }
- catch(e) {
- console.log('Error calling Media.onStatus :: ' + e);
- }
- })" + args;
- this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
- }
-
- private void InvokeCallback(int message, int value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- private void InvokeCallback(int message, double value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- /// <param name="filePath"></param>
- public void startRecording(string filePath)
- {
- if (this.player != null)
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- }
- else if (this.recorder == null)
- {
- try
- {
- this.audioFile = filePath;
- this.InitializeXnaGameLoop();
- this.recorder = Microphone.Default;
- this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
- this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
- this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
- this.recorder.Start();
- FrameworkDispatcher.Update();
- this.SetState(PlayerState_Running);
- }
- catch (Exception)
- {
- InvokeCallback(MediaError, MediaErrorStartingRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
- }
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- public void stopRecording()
- {
- if (this.recorder != null)
- {
- if (this.state == PlayerState_Running)
- {
- try
- {
- this.recorder.Stop();
- this.recorder.BufferReady -= recorderBufferReady;
- this.recorder = null;
- SaveAudioClipToLocalStorage();
- this.FinalizeXnaGameLoop();
- this.SetState(PlayerState_Stopped);
- }
- catch (Exception)
- {
- //TODO
- }
- }
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- public void startPlaying(string filePath)
- {
- if (this.recorder != null)
- {
- InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
- return;
- }
-
-
- if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
- {
- try
- {
- // this.player is a MediaElement, it must be added to the visual tree in order to play
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
-
- this.player = grid.FindName("playerMediaElement") as MediaElement;
- if (this.player == null) // still null ?
- {
- this.player = new MediaElement();
- this.player.Name = "playerMediaElement";
- grid.Children.Add(this.player);
- this.player.Visibility = Visibility.Visible;
- }
- if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
- {
- this.player.Stop(); // stop it!
- }
-
- this.player.Source = null; // Garbage collect it.
- this.player.MediaOpened += MediaOpened;
- this.player.MediaEnded += MediaEnded;
- this.player.MediaFailed += MediaFailed;
- }
- }
- }
-
- this.audioFile = filePath;
-
- Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
- if (uri.IsAbsoluteUri)
- {
- this.player.Source = uri;
- }
- else
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- // try to unpack it from the dll into isolated storage
- StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
- if (fileResourceStreamInfo != null)
- {
- using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
- {
- byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
- string[] dirParts = filePath.Split('/');
- string dirName = "";
- for (int n = 0; n < dirParts.Length - 1; n++)
- {
- dirName += dirParts[n] + "/";
- }
- if (!isoFile.DirectoryExists(dirName))
- {
- isoFile.CreateDirectory(dirName);
- }
-
- using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
- {
- using (BinaryWriter writer = new BinaryWriter(outFile))
- {
- writer.Write(data);
- }
- }
- }
- }
- }
- if (isoFile.FileExists(filePath))
- {
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
- {
- this.player.SetSource(stream);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
- return;
- }
- }
- }
- this.SetState(PlayerState_Starting);
- }
- catch (Exception e)
- {
- Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
- }
- }
- else
- {
- if (this.state != PlayerState_Running)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorResumeState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
- }
- }
- }
-
- /// <summary>
- /// Callback to be invoked when the media source is ready for playback
- /// </summary>
- private void MediaOpened(object sender, RoutedEventArgs arg)
- {
- if (this.player != null)
- {
- this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
- InvokeCallback(MediaDuration, this.duration, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
- if (!this.prepareOnly)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- this.prepareOnly = false;
- }
- else
- {
- // TODO: occasionally MediaOpened is signalled, but player is null
- }
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has completed
- /// </summary>
- private void MediaEnded(object sender, RoutedEventArgs arg)
- {
- this.SetState(PlayerState_Stopped);
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has failed
- /// </summary>
- private void MediaFailed(object sender, RoutedEventArgs arg)
- {
- player.Stop();
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
- }
-
- /// <summary>
- /// Seek or jump to a new time in the track
- /// </summary>
- /// <param name="milliseconds">The new track position</param>
- public void seekToPlaying(int milliseconds)
- {
- if (this.player != null)
- {
- TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
- this.player.Position = tsPos;
- InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
- }
- }
-
- /// <summary>
- /// Set the volume of the player
- /// </summary>
- /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
- public void setVolume(double vol)
- {
- if (this.player != null)
- {
- this.player.Volume = vol;
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlaying()
- {
- if (this.state == PlayerState_Running)
- {
- this.player.Pause();
- this.SetState(PlayerState_Paused);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPauseState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
- }
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlaying()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- this.player.Stop();
-
- this.player.Position = new TimeSpan(0L);
- this.SetState(PlayerState_Stopped);
- }
- //else // Why is it an error to call stop on a stopped media?
- //{
- // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
- //}
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- /// <returns>current position</returns>
- public double getCurrentPosition()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- double currentPosition = this.player.Position.TotalSeconds;
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
- return currentPosition;
- }
- else
- {
- return 0;
- }
- }
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <returns>track duration</returns>
- public double getDuration(string filePath)
- {
- if (this.recorder != null)
- {
- return (-2);
- }
-
- if (this.player != null)
- {
- return this.duration;
-
- }
- else
- {
- this.prepareOnly = true;
- this.startPlaying(filePath);
- return this.duration;
- }
- }
-
- /// <summary>
- /// Sets the state and send it to JavaScript
- /// </summary>
- /// <param name="state">state</param>
- private void SetState(int state)
- {
- if (this.state != state)
- {
- InvokeCallback(MediaState, state, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
- }
-
- this.state = state;
- }
-
- #region record methods
-
- /// <summary>
- /// Copies data from recorder to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void recorderBufferReady(object sender, EventArgs e)
- {
- this.recorder.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private void SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return;
- }
-
- this.memoryStream.UpdateWavStream();
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- string directory = Path.GetDirectoryName(audioFile);
-
- if (!isoFile.DirectoryExists(directory))
- {
- isoFile.CreateDirectory(directory);
- }
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
- {
- this.memoryStream.CopyTo(fileStream);
- }
- }
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- #region Xna loop
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (this.dtXna != null)
- {
- this.dtXna.Stop();
- this.dtXna = null;
- }
- }
-
- #endregion
-
- #endregion
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Battery.cs
----------------------------------------------------------------------
diff --git a/plugins/Battery.cs b/plugins/Battery.cs
deleted file mode 100644
index 962959e..0000000
--- a/plugins/Battery.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-using Microsoft.Phone.Info;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Listens for changes to the state of the battery on the device.
- /// Currently only the "isPlugged" parameter available via native APIs.
- /// </summary>
- public class Battery : BaseCommand
- {
- private bool isPlugged = false;
- private EventHandler powerChanged;
-
- public Battery()
- {
- powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- }
-
- public void start(string options)
- {
- // Register power changed event handler
- DeviceStatus.PowerSourceChanged += powerChanged;
-
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- public void stop(string options)
- {
- // Unregister power changed event handler
- DeviceStatus.PowerSourceChanged -= powerChanged;
- }
-
- private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
- {
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- private string GetCurrentBatteryStateFormatted()
- {
- string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
- "null",
- isPlugged ? "true" : "false"
- );
- batteryState = "{" + batteryState + "}";
- return batteryState;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Camera.cs
----------------------------------------------------------------------
diff --git a/plugins/Camera.cs b/plugins/Camera.cs
deleted file mode 100644
index 5ff8045..0000000
--- a/plugins/Camera.cs
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Collections.Generic;
-using Microsoft.Phone.Tasks;
-using System.Runtime.Serialization;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Xna.Framework.Media;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Camera : BaseCommand
- {
-
- /// <summary>
- /// Return base64 encoded string
- /// </summary>
- private const int DATA_URL = 0;
-
- /// <summary>
- /// Return file uri
- /// </summary>
- private const int FILE_URI = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int PHOTOLIBRARY = 0;
-
- /// <summary>
- /// Take picture from camera
- /// </summary>
-
- private const int CAMERA = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int SAVEDPHOTOALBUM = 2;
-
- /// <summary>
- /// Take a picture of type JPEG
- /// </summary>
- private const int JPEG = 0;
-
- /// <summary>
- /// Take a picture of type PNG
- /// </summary>
- private const int PNG = 1;
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private const string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CameraOptions
- {
- /// <summary>
- /// Source to getPicture from.
- /// </summary>
- [DataMember(IsRequired = false, Name = "sourceType")]
- public int PictureSourceType { get; set; }
-
- /// <summary>
- /// Format of image that returned from getPicture.
- /// </summary>
- [DataMember(IsRequired = false, Name = "destinationType")]
- public int DestinationType { get; set; }
-
- /// <summary>
- /// Quality of saved image
- /// </summary>
- [DataMember(IsRequired = false, Name = "quality")]
- public int Quality { get; set; }
-
- /// <summary>
- /// Controls whether or not the image is also added to the device photo album.
- /// </summary>
- [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
- public bool SaveToPhotoAlbum { get; set; }
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "correctOrientation")]
- public bool CorrectOrientation { get; set; }
-
-
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "allowEdit")]
- public bool AllowEdit { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "encodingType")]
- public int EncodingType { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "mediaType")]
- public int MediaType { get; set; }
-
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetHeight")]
- public int TargetHeight { get; set; }
-
-
- /// <summary>
- /// Width in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetWidth")]
- public int TargetWidth { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public CameraOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- PictureSourceType = CAMERA;
- DestinationType = FILE_URI;
- Quality = 80;
- TargetHeight = -1;
- TargetWidth = -1;
- SaveToPhotoAlbum = false;
- CorrectOrientation = true;
- AllowEdit = false;
- MediaType = -1;
- EncodingType = -1;
- }
- }
-
- /// <summary>
- /// Used to open photo library
- /// </summary>
- PhotoChooserTask photoChooserTask;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Camera options
- /// </summary>
- CameraOptions cameraOptions;
-
- public void takePicture(string options)
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
- // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
- this.cameraOptions = new CameraOptions();
- this.cameraOptions.Quality = int.Parse(args[0]);
- this.cameraOptions.DestinationType = int.Parse(args[1]);
- this.cameraOptions.PictureSourceType = int.Parse(args[2]);
- this.cameraOptions.TargetWidth = int.Parse(args[3]);
- this.cameraOptions.TargetHeight = int.Parse(args[4]);
- this.cameraOptions.EncodingType = int.Parse(args[5]);
- this.cameraOptions.MediaType = int.Parse(args[6]);
- this.cameraOptions.AllowEdit = bool.Parse(args[7]);
- this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
- this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
-
- //this.cameraOptions = String.IsNullOrEmpty(options) ?
- // new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- //TODO Check if all the options are acceptable
-
-
- if (cameraOptions.PictureSourceType == CAMERA)
- {
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += onCameraTaskCompleted;
- cameraTask.Show();
- }
- else
- {
- if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
- {
- photoChooserTask = new PhotoChooserTask();
- photoChooserTask.Completed += onPickerTaskCompleted;
- photoChooserTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
- }
-
- public void onCameraTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- // Save image in media library
- if (cameraOptions.SaveToPhotoAlbum)
- {
- MediaLibrary library = new MediaLibrary();
- Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
- }
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
-
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
-
-
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
-
- }
-
- public void onPickerTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
-
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
- }
-
- /// <summary>
- /// Returns image content in a form of base64 string
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <returns>Base64 representation of the image</returns>
- private string GetImageContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
-
- //use photo's actual width & height if user doesn't provide width & height
- if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
- {
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
- else
- {
- // resize photo
- byte[] resizedFile = ResizePhoto(stream, fileData);
- stream.Close();
- return Convert.ToBase64String(resizedFile);
- }
- }
-
- /// <summary>
- /// Resize image
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <param name="fileData">File data</param>
- /// <returns>resized image</returns>
- private byte[] ResizePhoto(Stream stream, byte[] fileData)
- {
- int streamLength = (int)stream.Length;
- int intResult = 0;
-
- byte[] resizedFile;
-
- stream.Read(fileData, 0, streamLength);
-
- BitmapImage objBitmap = new BitmapImage();
- MemoryStream objBitmapStream = new MemoryStream(fileData);
- MemoryStream objBitmapStreamResized = new MemoryStream();
- WriteableBitmap objWB;
- objBitmap.SetSource(stream);
- objWB = new WriteableBitmap(objBitmap);
-
- // resize the photo with user defined TargetWidth & TargetHeight
- Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
-
- //Convert the resized stream to a byte array.
- streamLength = (int)objBitmapStreamResized.Length;
- resizedFile = new Byte[streamLength]; //-1
- objBitmapStreamResized.Position = 0;
- //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
- intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
-
- return resizedFile;
- }
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
- {
-
- if (image == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
-
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(isoFolder))
- {
- isoFile.CreateDirectory(isoFolder);
- }
-
- string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
-
- using (var stream = isoFile.CreateFile(filePath))
- {
- // resize image if Height and Width defined via options
- if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
- {
- image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
- }
- else
- {
- image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
- }
- }
-
- return new Uri(filePath, UriKind.Relative).ToString();
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Capture.cs
----------------------------------------------------------------------
diff --git a/plugins/Capture.cs b/plugins/Capture.cs
deleted file mode 100644
index 5e14a16..0000000
--- a/plugins/Capture.cs
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework.Media;
-using WPCordovaClassLib.Cordova.UI;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-using System.Windows;
-using System.Diagnostics;
-using Microsoft.Phone.Controls;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to the audio, image, and video capture capabilities of the device
- /// </summary>
- public class Capture : BaseCommand
- {
- #region Internal classes (options and resultant objects)
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CaptureImageOptions
- {
- /// <summary>
- /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureImageOptions Default
- {
- get { return new CaptureImageOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureAudio action options.
- /// </summary>
- [DataContract]
- public class CaptureAudioOptions
- {
- /// <summary>
- /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureAudioOptions Default
- {
- get { return new CaptureAudioOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureVideo action options.
- /// </summary>
- [DataContract]
- public class CaptureVideoOptions
- {
- /// <summary>
- /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureVideoOptions Default
- {
- get { return new CaptureVideoOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents getFormatData action options.
- /// </summary>
- [DataContract]
- public class MediaFormatOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- [DataMember(IsRequired = true, Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// File mime type
- /// </summary>
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class MediaFile
- {
-
- [DataMember(Name = "name")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FilePath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public MediaFile(string filePath, Picture image)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = image.GetImage().Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
-
- }
-
- public MediaFile(string filePath, Stream stream)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = stream.Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
- }
- }
-
- /// <summary>
- /// Stores additional media file data
- /// </summary>
- [DataContract]
- public class MediaFileData
- {
- [DataMember(Name = "height")]
- public int Height { get; set; }
-
- [DataMember(Name = "width")]
- public int Width { get; set; }
-
- [DataMember(Name = "bitrate")]
- public int Bitrate { get; set; }
-
- [DataMember(Name = "duration")]
- public int Duration { get; set; }
-
- [DataMember(Name = "codecs")]
- public string Codecs { get; set; }
-
- public MediaFileData(WriteableBitmap image)
- {
- this.Height = image.PixelHeight;
- this.Width = image.PixelWidth;
- this.Bitrate = 0;
- this.Duration = 0;
- this.Codecs = "";
- }
- }
-
- #endregion
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Capture Image options
- /// </summary>
- protected CaptureImageOptions captureImageOptions;
-
- /// <summary>
- /// Capture Audio options
- /// </summary>
- protected CaptureAudioOptions captureAudioOptions;
-
- /// <summary>
- /// Capture Video options
- /// </summary>
- protected CaptureVideoOptions captureVideoOptions;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- private CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Used for audio recording
- /// </summary>
- private AudioCaptureTask audioCaptureTask;
-
- /// <summary>
- /// Used for video recording
- /// </summary>
- private VideoCaptureTask videoCaptureTask;
-
- /// <summary>
- /// Stores information about captured files
- /// </summary>
- List<MediaFile> files = new List<MediaFile>();
-
- /// <summary>
- /// Launches default camera application to capture image
- /// </summary>
- /// <param name="options">may contains limit or mode parameters</param>
- public void captureImage(string options)
- {
- try
- {
- try
- {
-
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
-
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += this.cameraTask_Completed;
- cameraTask.Show();
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own audio recording control to capture audio
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureAudio(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- audioCaptureTask = new AudioCaptureTask();
- audioCaptureTask.Completed += audioRecordingTask_Completed;
- audioCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own video recording control to capture video
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureVideo(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- videoCaptureTask = new VideoCaptureTask();
- videoCaptureTask.Completed += videoRecordingTask_Completed;
- videoCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Retrieves the format information of the media file.
- /// </summary>
- /// <param name="options"></param>
- public void getFormatData(string options)
- {
- try
- {
- MediaFormatOptions mediaFormatOptions;
- try
- {
- mediaFormatOptions = new MediaFormatOptions();
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaFormatOptions.FullPath = optionStrings[0];
- mediaFormatOptions.Type = optionStrings[1];
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
- string mimeType = mediaFormatOptions.Type;
-
- if (string.IsNullOrEmpty(mimeType))
- {
- mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
- }
-
- if (mimeType.Equals("image/jpeg"))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
-
- if (image == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
- return;
- }
-
- MediaFileData mediaData = new MediaFileData(image);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
-
- /// <summary>
- /// Opens specified file in media player
- /// </summary>
- /// <param name="options">MediaFile to play</param>
- public void play(string options)
- {
- try
- {
- MediaFile file;
-
- try
- {
- file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (file == null || String.IsNullOrEmpty(file.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
- return;
- }
-
- // if url starts with '/' media player throws FileNotFound exception
- Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
-
- MediaPlayerLauncher player = new MediaPlayerLauncher();
- player.Media = fileUri;
- player.Location = MediaLocationType.Data;
- player.Show();
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Handles result of capture to save image information
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured image</param>
- private void cameraTask_Completed(object sender, PhotoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
-
- // Save image in media library
- MediaLibrary library = new MediaLibrary();
- Picture image = library.SavePicture(fileName, e.ChosenPhoto);
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // Save image in isolated storage
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- byte[] imageBytes = new byte[rotImageStream.Length];
- rotImageStream.Read(imageBytes, 0, imageBytes.Length);
- rotImageStream.Dispose();
- string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
- imageBytes = null;
- // Get image data
- MediaFile data = new MediaFile(pathLocalStorage, image);
-
- this.files.Add(data);
-
- if (files.Count < this.captureImageOptions.Limit)
- {
- cameraTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some images were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of audio recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured audio</param>
- private void audioRecordingTask_Completed(object sender, AudioResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureAudioOptions.Limit)
- {
- audioCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some audio clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of video recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured video</param>
- private void videoRecordingTask_Completed(object sender, VideoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureVideoOptions.Limit)
- {
- videoCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some video clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Extract file from Isolated Storage as WriteableBitmap object
- /// </summary>
- /// <param name="filePath"></param>
- /// <returns></returns>
- private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
- {
- try
- {
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- var imageSource = PictureDecoder.DecodeJpeg(imageStream);
- return imageSource;
- }
- }
- catch (Exception)
- {
- return null;
- }
- }
-
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <param name="imageFolder">folder to store images</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
- {
- if (imageBytes == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(imageFolder))
- {
- isoFile.CreateDirectory(imageFolder);
- }
- string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
-
- using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
- {
- stream.Write(imageBytes, 0, imageBytes.Length);
- }
-
- return filePath;
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Compass.cs
----------------------------------------------------------------------
diff --git a/plugins/Compass.cs b/plugins/Compass.cs
deleted file mode 100644
index c9e1c4d..0000000
--- a/plugins/Compass.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using DeviceCompass = Microsoft.Devices.Sensors.Compass;
-using System.Windows.Threading;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class Compass : BaseCommand
- {
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Id for get getCompass method
- /// </summary>
- private static string getCompassId = "getCompassId";
-
- /// <summary>
- /// Compass
- /// </summary>
- private static DeviceCompass compass = new DeviceCompass();
-
- /// <summary>
- /// Listeners for callbacks
- /// </summary>
- private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
-
- #endregion
-
- #region Status codes
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 4;
- public const int Not_Supported = 20;
-
- /*
- * // Capture error codes
- CompassError.COMPASS_INTERNAL_ERR = 0;
- CompassError.COMPASS_NOT_SUPPORTED = 20;
- * */
-
- #endregion
-
- #region CompassOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class CompassOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// The change in degrees required to initiate a watchHeadingFilter success callback.
- /// </summary>
- [DataMember(IsRequired = false, Name = "filter")]
- public int Filter { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- }
- #endregion
-
-
- /// <summary>
- /// Time the value was last changed
- /// </summary>
- //private DateTime lastValueChangedTime;
-
- /// <summary>
- /// Accelerometer options
- /// </summary>
- private CompassOptions compassOptions;
-
- //bool isDataValid;
-
- //bool calibrating = false;
-
- public Compass()
- {
-
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetHeadingFormatted(CompassReading reading)
- {
- // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
- string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
- reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
- reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
- reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
- return "{" + result + "}";
- }
-
- public void getHeading(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
- }
- else
- {
- //if (compass == null)
- //{
- // // Instantiate the compass.
- // compass = new DeviceCompass();
- // compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
- // compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
- // compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
- //}
-
-
- //compass.Start();
-
- }
-
- try
- {
- if (currentStatus != Running)
- {
- lock (compass)
- {
- compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- lock (compass)
- {
- compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
- if (watchers.Count < 1)
- {
- compass.Stop();
- this.SetStatus(Stopped);
- }
- }
- }
- catch (UnauthorizedAccessException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- }
- }
-
- void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Starts listening for compass sensor
- /// </summary>
- /// <returns>status of listener</returns>
- private int start()
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return currentStatus;
- }
- try
- {
- lock (compass)
- {
- watchers.Add(getCompassId, this);
- compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- }
- return currentStatus;
- }
-
- public void startWatch(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
- }
-
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- lock (compass)
- {
- watchers.Add(compassOptions.Id, this);
- compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- return;
- }
- }
-
- public void stopWatch(string options)
- {
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (currentStatus != Stopped)
- {
- lock (compass)
- {
- Compass watcher = watchers[compassOptions.Id];
- compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
- watchers.Remove(compassOptions.Id);
- watcher.Dispose();
- }
- }
- this.SetStatus(Stopped);
-
- this.DispatchCommandResult();
- }
-
- void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
- {
- //throw new NotImplementedException();
- // TODO: pass calibration error to JS
- }
-
- void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
- result.KeepCallback = true;
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
-
- }
-}
[13/50] [abbrv] git commit: plugin code becomes common code
Posted by pu...@apache.org.
plugin code becomes common code
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/dec32ea1
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/dec32ea1
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/dec32ea1
Branch: refs/heads/2.9.x
Commit: dec32ea1dacf831b74704ddd8dccf173e08d69b8
Parents: df40aaf
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 12:21:21 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 12:21:21 2013 -0700
----------------------------------------------------------------------
wp7/template/Plugins/Accelerometer.cs | 196 --
wp7/template/Plugins/AudioFormatsHelper.cs | 89 -
wp7/template/Plugins/AudioPlayer.cs | 620 -------
wp7/template/Plugins/Battery.cs | 79 -
wp7/template/Plugins/Camera.cs | 490 -----
wp7/template/Plugins/Capture.cs | 736 --------
wp7/template/Plugins/Compass.cs | 362 ----
wp7/template/Plugins/Contacts.cs | 664 -------
wp7/template/Plugins/DebugConsole.cs | 49 -
wp7/template/Plugins/Device.cs | 135 --
wp7/template/Plugins/File.cs | 1676 ------------------
wp7/template/Plugins/FileTransfer.cs | 526 ------
wp7/template/Plugins/GeoLocation.cs | 34 -
wp7/template/Plugins/Globalization.cs | 1177 ------------
wp7/template/Plugins/ImageExifHelper.cs | 209 ---
wp7/template/Plugins/InAppBrowser.cs | 271 ---
wp7/template/Plugins/Media.cs | 547 ------
wp7/template/Plugins/MimeTypeMapper.cs | 101 --
wp7/template/Plugins/NetworkStatus.cs | 129 --
wp7/template/Plugins/Notification.cs | 361 ----
wp7/template/Plugins/UI/AudioCaptureTask.cs | 107 --
wp7/template/Plugins/UI/AudioRecorder.xaml | 66 -
wp7/template/Plugins/UI/AudioRecorder.xaml.cs | 307 ----
wp7/template/Plugins/UI/ImageCapture.xaml | 26 -
wp7/template/Plugins/UI/ImageCapture.xaml.cs | 109 --
wp7/template/Plugins/UI/NotificationBox.xaml | 62 -
wp7/template/Plugins/UI/NotificationBox.xaml.cs | 41 -
wp7/template/Plugins/UI/VideoCaptureTask.cs | 105 --
wp7/template/Plugins/UI/VideoRecorder.xaml | 52 -
wp7/template/Plugins/UI/VideoRecorder.xaml.cs | 405 -----
wp8/template/Plugins/Accelerometer.cs | 196 --
wp8/template/Plugins/AudioFormatsHelper.cs | 89 -
wp8/template/Plugins/AudioPlayer.cs | 620 -------
wp8/template/Plugins/Battery.cs | 79 -
wp8/template/Plugins/Camera.cs | 490 -----
wp8/template/Plugins/Capture.cs | 736 --------
wp8/template/Plugins/Compass.cs | 362 ----
wp8/template/Plugins/Contacts.cs | 664 -------
wp8/template/Plugins/DebugConsole.cs | 49 -
wp8/template/Plugins/Device.cs | 135 --
wp8/template/Plugins/File.cs | 1676 ------------------
wp8/template/Plugins/FileTransfer.cs | 526 ------
wp8/template/Plugins/GeoLocation.cs | 34 -
wp8/template/Plugins/Globalization.cs | 1177 ------------
wp8/template/Plugins/ImageExifHelper.cs | 209 ---
wp8/template/Plugins/InAppBrowser.cs | 271 ---
wp8/template/Plugins/Media.cs | 547 ------
wp8/template/Plugins/MimeTypeMapper.cs | 101 --
wp8/template/Plugins/NetworkStatus.cs | 129 --
wp8/template/Plugins/Notification.cs | 361 ----
wp8/template/Plugins/UI/AudioCaptureTask.cs | 107 --
wp8/template/Plugins/UI/AudioRecorder.xaml | 66 -
wp8/template/Plugins/UI/AudioRecorder.xaml.cs | 307 ----
wp8/template/Plugins/UI/ImageCapture.xaml | 26 -
wp8/template/Plugins/UI/ImageCapture.xaml.cs | 109 --
wp8/template/Plugins/UI/NotificationBox.xaml | 62 -
wp8/template/Plugins/UI/NotificationBox.xaml.cs | 41 -
wp8/template/Plugins/UI/VideoCaptureTask.cs | 105 --
wp8/template/Plugins/UI/VideoRecorder.xaml | 52 -
wp8/template/Plugins/UI/VideoRecorder.xaml.cs | 405 -----
wp8/template/VERSION | 1 -
wp8/template/www/index.html | 2 +-
wp8/tooling/scripts/createTemplates.js | 1 -
63 files changed, 1 insertion(+), 19465 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Accelerometer.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Accelerometer.cs b/wp7/template/Plugins/Accelerometer.cs
deleted file mode 100644
index cba911c..0000000
--- a/wp7/template/Plugins/Accelerometer.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Captures device motion in the x, y, and z direction.
- /// </summary>
- public class Accelerometer : BaseCommand
- {
- #region AccelerometerOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class AccelerometerOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public AccelerometerOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Frequency = 10000;
- }
- }
-
- #endregion
-
- #region Status codes and Constants
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 3;
-
- public const double gConstant = -9.81;
-
- #endregion
-
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Accelerometer
- /// </summary>
- private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
-
- private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
-
- #endregion
-
- /// <summary>
- /// Sensor listener event
- /// </summary>
- private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
- {
- this.SetStatus(Running);
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- /// <summary>
- /// Starts listening for acceleration sensor
- /// </summary>
- /// <returns>status of listener</returns>
- public void start(string options)
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return;
- }
- try
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
- accelerometer.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- public void stop(string options)
- {
- if (currentStatus == Running)
- {
- lock (accelerometer)
- {
- accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
- accelerometer.Stop();
- this.SetStatus(Stopped);
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetCurrentAccelerationFormatted()
- {
- // convert to unix timestamp
- // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
- // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
- // this resolves an issue with inconsistencies between JS dates and Native DateTime
- string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
- (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
- (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
- return "{" + resultCoordinates + "}";
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/AudioFormatsHelper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/AudioFormatsHelper.cs b/wp7/template/Plugins/AudioFormatsHelper.cs
deleted file mode 100644
index dca7ee6..0000000
--- a/wp7/template/Plugins/AudioFormatsHelper.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- 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.
-
- */
-
-using System;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides extra functionality to support different audio formats.
- /// </summary>
- public static class AudioFormatsHelper
- {
- #region Wav
- /// <summary>
- /// Adds wav file format header to the stream
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">The stream</param>
- /// <param name="sampleRate">Sample Rate</param>
- public static void InitializeWavStream(this Stream stream, int sampleRate)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- int numBits = 16;
- int numBytes = numBits / 8;
-
- stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
- stream.Write(BitConverter.GetBytes(16), 0, 4);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
- stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
- stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
- stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- }
-
- /// <summary>
- /// Updates wav file format header
- /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
- /// </summary>
- /// <param name="stream">Wav stream</param>
- public static void UpdateWavStream(this Stream stream)
- {
- #region args checking
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream can't be null or empty");
- }
-
- #endregion
-
- var position = stream.Position;
-
- stream.Seek(4, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
- stream.Seek(40, SeekOrigin.Begin);
- stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
- stream.Seek(position, SeekOrigin.Begin);
- }
-
- #endregion
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/AudioPlayer.cs b/wp7/template/Plugins/AudioPlayer.cs
deleted file mode 100644
index a83be5b..0000000
--- a/wp7/template/Plugins/AudioPlayer.cs
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Implements audio record and play back functionality.
- /// </summary>
- internal class AudioPlayer : IDisposable
- {
- #region Constants
-
- // AudioPlayer states
- private const int PlayerState_None = 0;
- private const int PlayerState_Starting = 1;
- private const int PlayerState_Running = 2;
- private const int PlayerState_Paused = 3;
- private const int PlayerState_Stopped = 4;
-
- // AudioPlayer messages
- private const int MediaState = 1;
- private const int MediaDuration = 2;
- private const int MediaPosition = 3;
- private const int MediaError = 9;
-
- // AudioPlayer errors
- private const int MediaErrorPlayModeSet = 1;
- private const int MediaErrorAlreadyRecording = 2;
- private const int MediaErrorStartingRecording = 3;
- private const int MediaErrorRecordModeSet = 4;
- private const int MediaErrorStartingPlayback = 5;
- private const int MediaErrorResumeState = 6;
- private const int MediaErrorPauseState = 7;
- private const int MediaErrorStopState = 8;
-
- //TODO: get rid of this callback, it should be universal
- //private const string CallbackFunction = "CordovaMediaonStatus";
-
- #endregion
-
- /// <summary>
- /// The AudioHandler object
- /// </summary>
- private Media handler;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// The id of this player (used to identify Media object in JavaScript)
- /// </summary>
- private String id;
-
- /// <summary>
- /// State of recording or playback
- /// </summary>
- private int state = PlayerState_None;
-
- /// <summary>
- /// File name to play or record to
- /// </summary>
- private String audioFile = null;
-
- /// <summary>
- /// Duration of audio
- /// </summary>
- private double duration = -1;
-
- /// <summary>
- /// Audio player object
- /// </summary>
- private MediaElement player = null;
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone recorder;
-
- /// <summary>
- /// Internal flag specified that we should only open audio w/o playing it
- /// </summary>
- private bool prepareOnly = false;
-
- /// <summary>
- /// Creates AudioPlayer instance
- /// </summary>
- /// <param name="handler">Media object</param>
- /// <param name="id">player id</param>
- public AudioPlayer(Media handler, String id)
- {
- this.handler = handler;
- this.id = id;
- }
-
- /// <summary>
- /// Destroys player and stop audio playing or recording
- /// </summary>
- public void Dispose()
- {
- if (this.player != null)
- {
- this.stopPlaying();
- this.player = null;
- }
- if (this.recorder != null)
- {
- this.stopRecording();
- this.recorder = null;
- }
-
- this.FinalizeXnaGameLoop();
- }
-
- private void InvokeCallback(int message, string value, bool removeHandler)
- {
- string args = string.Format("('{0}',{1},{2});", this.id, message, value);
- string callback = @"(function(id,msg,value){
- try {
- if (msg == Media.MEDIA_ERROR) {
- value = {'code':value};
- }
- Media.onStatus(id,msg,value);
- }
- catch(e) {
- console.log('Error calling Media.onStatus :: ' + e);
- }
- })" + args;
- this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
- }
-
- private void InvokeCallback(int message, int value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- private void InvokeCallback(int message, double value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- /// <param name="filePath"></param>
- public void startRecording(string filePath)
- {
- if (this.player != null)
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- }
- else if (this.recorder == null)
- {
- try
- {
- this.audioFile = filePath;
- this.InitializeXnaGameLoop();
- this.recorder = Microphone.Default;
- this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
- this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
- this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
- this.recorder.Start();
- FrameworkDispatcher.Update();
- this.SetState(PlayerState_Running);
- }
- catch (Exception)
- {
- InvokeCallback(MediaError, MediaErrorStartingRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
- }
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- public void stopRecording()
- {
- if (this.recorder != null)
- {
- if (this.state == PlayerState_Running)
- {
- try
- {
- this.recorder.Stop();
- this.recorder.BufferReady -= recorderBufferReady;
- this.recorder = null;
- SaveAudioClipToLocalStorage();
- this.FinalizeXnaGameLoop();
- this.SetState(PlayerState_Stopped);
- }
- catch (Exception)
- {
- //TODO
- }
- }
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- public void startPlaying(string filePath)
- {
- if (this.recorder != null)
- {
- InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
- return;
- }
-
-
- if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
- {
- try
- {
- // this.player is a MediaElement, it must be added to the visual tree in order to play
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
-
- this.player = grid.FindName("playerMediaElement") as MediaElement;
- if (this.player == null) // still null ?
- {
- this.player = new MediaElement();
- this.player.Name = "playerMediaElement";
- grid.Children.Add(this.player);
- this.player.Visibility = Visibility.Visible;
- }
- if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
- {
- this.player.Stop(); // stop it!
- }
-
- this.player.Source = null; // Garbage collect it.
- this.player.MediaOpened += MediaOpened;
- this.player.MediaEnded += MediaEnded;
- this.player.MediaFailed += MediaFailed;
- }
- }
- }
-
- this.audioFile = filePath;
-
- Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
- if (uri.IsAbsoluteUri)
- {
- this.player.Source = uri;
- }
- else
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- // try to unpack it from the dll into isolated storage
- StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
- if (fileResourceStreamInfo != null)
- {
- using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
- {
- byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
- string[] dirParts = filePath.Split('/');
- string dirName = "";
- for (int n = 0; n < dirParts.Length - 1; n++)
- {
- dirName += dirParts[n] + "/";
- }
- if (!isoFile.DirectoryExists(dirName))
- {
- isoFile.CreateDirectory(dirName);
- }
-
- using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
- {
- using (BinaryWriter writer = new BinaryWriter(outFile))
- {
- writer.Write(data);
- }
- }
- }
- }
- }
- if (isoFile.FileExists(filePath))
- {
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
- {
- this.player.SetSource(stream);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
- return;
- }
- }
- }
- this.SetState(PlayerState_Starting);
- }
- catch (Exception e)
- {
- Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
- }
- }
- else
- {
- if (this.state != PlayerState_Running)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorResumeState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
- }
- }
- }
-
- /// <summary>
- /// Callback to be invoked when the media source is ready for playback
- /// </summary>
- private void MediaOpened(object sender, RoutedEventArgs arg)
- {
- if (this.player != null)
- {
- this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
- InvokeCallback(MediaDuration, this.duration, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
- if (!this.prepareOnly)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- this.prepareOnly = false;
- }
- else
- {
- // TODO: occasionally MediaOpened is signalled, but player is null
- }
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has completed
- /// </summary>
- private void MediaEnded(object sender, RoutedEventArgs arg)
- {
- this.SetState(PlayerState_Stopped);
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has failed
- /// </summary>
- private void MediaFailed(object sender, RoutedEventArgs arg)
- {
- player.Stop();
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
- }
-
- /// <summary>
- /// Seek or jump to a new time in the track
- /// </summary>
- /// <param name="milliseconds">The new track position</param>
- public void seekToPlaying(int milliseconds)
- {
- if (this.player != null)
- {
- TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
- this.player.Position = tsPos;
- InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
- }
- }
-
- /// <summary>
- /// Set the volume of the player
- /// </summary>
- /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
- public void setVolume(double vol)
- {
- if (this.player != null)
- {
- this.player.Volume = vol;
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlaying()
- {
- if (this.state == PlayerState_Running)
- {
- this.player.Pause();
- this.SetState(PlayerState_Paused);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPauseState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
- }
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlaying()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- this.player.Stop();
-
- this.player.Position = new TimeSpan(0L);
- this.SetState(PlayerState_Stopped);
- }
- //else // Why is it an error to call stop on a stopped media?
- //{
- // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
- //}
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- /// <returns>current position</returns>
- public double getCurrentPosition()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- double currentPosition = this.player.Position.TotalSeconds;
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
- return currentPosition;
- }
- else
- {
- return 0;
- }
- }
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <returns>track duration</returns>
- public double getDuration(string filePath)
- {
- if (this.recorder != null)
- {
- return (-2);
- }
-
- if (this.player != null)
- {
- return this.duration;
-
- }
- else
- {
- this.prepareOnly = true;
- this.startPlaying(filePath);
- return this.duration;
- }
- }
-
- /// <summary>
- /// Sets the state and send it to JavaScript
- /// </summary>
- /// <param name="state">state</param>
- private void SetState(int state)
- {
- if (this.state != state)
- {
- InvokeCallback(MediaState, state, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
- }
-
- this.state = state;
- }
-
- #region record methods
-
- /// <summary>
- /// Copies data from recorder to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void recorderBufferReady(object sender, EventArgs e)
- {
- this.recorder.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private void SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return;
- }
-
- this.memoryStream.UpdateWavStream();
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- string directory = Path.GetDirectoryName(audioFile);
-
- if (!isoFile.DirectoryExists(directory))
- {
- isoFile.CreateDirectory(directory);
- }
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
- {
- this.memoryStream.CopyTo(fileStream);
- }
- }
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- #region Xna loop
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (this.dtXna != null)
- {
- this.dtXna.Stop();
- this.dtXna = null;
- }
- }
-
- #endregion
-
- #endregion
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Battery.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Battery.cs b/wp7/template/Plugins/Battery.cs
deleted file mode 100644
index 962959e..0000000
--- a/wp7/template/Plugins/Battery.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-using Microsoft.Phone.Info;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Listens for changes to the state of the battery on the device.
- /// Currently only the "isPlugged" parameter available via native APIs.
- /// </summary>
- public class Battery : BaseCommand
- {
- private bool isPlugged = false;
- private EventHandler powerChanged;
-
- public Battery()
- {
- powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- }
-
- public void start(string options)
- {
- // Register power changed event handler
- DeviceStatus.PowerSourceChanged += powerChanged;
-
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- public void stop(string options)
- {
- // Unregister power changed event handler
- DeviceStatus.PowerSourceChanged -= powerChanged;
- }
-
- private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
- {
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- private string GetCurrentBatteryStateFormatted()
- {
- string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
- "null",
- isPlugged ? "true" : "false"
- );
- batteryState = "{" + batteryState + "}";
- return batteryState;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Camera.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Camera.cs b/wp7/template/Plugins/Camera.cs
deleted file mode 100644
index 5ff8045..0000000
--- a/wp7/template/Plugins/Camera.cs
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Collections.Generic;
-using Microsoft.Phone.Tasks;
-using System.Runtime.Serialization;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Xna.Framework.Media;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Camera : BaseCommand
- {
-
- /// <summary>
- /// Return base64 encoded string
- /// </summary>
- private const int DATA_URL = 0;
-
- /// <summary>
- /// Return file uri
- /// </summary>
- private const int FILE_URI = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int PHOTOLIBRARY = 0;
-
- /// <summary>
- /// Take picture from camera
- /// </summary>
-
- private const int CAMERA = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int SAVEDPHOTOALBUM = 2;
-
- /// <summary>
- /// Take a picture of type JPEG
- /// </summary>
- private const int JPEG = 0;
-
- /// <summary>
- /// Take a picture of type PNG
- /// </summary>
- private const int PNG = 1;
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private const string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CameraOptions
- {
- /// <summary>
- /// Source to getPicture from.
- /// </summary>
- [DataMember(IsRequired = false, Name = "sourceType")]
- public int PictureSourceType { get; set; }
-
- /// <summary>
- /// Format of image that returned from getPicture.
- /// </summary>
- [DataMember(IsRequired = false, Name = "destinationType")]
- public int DestinationType { get; set; }
-
- /// <summary>
- /// Quality of saved image
- /// </summary>
- [DataMember(IsRequired = false, Name = "quality")]
- public int Quality { get; set; }
-
- /// <summary>
- /// Controls whether or not the image is also added to the device photo album.
- /// </summary>
- [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
- public bool SaveToPhotoAlbum { get; set; }
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "correctOrientation")]
- public bool CorrectOrientation { get; set; }
-
-
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "allowEdit")]
- public bool AllowEdit { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "encodingType")]
- public int EncodingType { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "mediaType")]
- public int MediaType { get; set; }
-
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetHeight")]
- public int TargetHeight { get; set; }
-
-
- /// <summary>
- /// Width in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetWidth")]
- public int TargetWidth { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public CameraOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- PictureSourceType = CAMERA;
- DestinationType = FILE_URI;
- Quality = 80;
- TargetHeight = -1;
- TargetWidth = -1;
- SaveToPhotoAlbum = false;
- CorrectOrientation = true;
- AllowEdit = false;
- MediaType = -1;
- EncodingType = -1;
- }
- }
-
- /// <summary>
- /// Used to open photo library
- /// </summary>
- PhotoChooserTask photoChooserTask;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Camera options
- /// </summary>
- CameraOptions cameraOptions;
-
- public void takePicture(string options)
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
- // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
- this.cameraOptions = new CameraOptions();
- this.cameraOptions.Quality = int.Parse(args[0]);
- this.cameraOptions.DestinationType = int.Parse(args[1]);
- this.cameraOptions.PictureSourceType = int.Parse(args[2]);
- this.cameraOptions.TargetWidth = int.Parse(args[3]);
- this.cameraOptions.TargetHeight = int.Parse(args[4]);
- this.cameraOptions.EncodingType = int.Parse(args[5]);
- this.cameraOptions.MediaType = int.Parse(args[6]);
- this.cameraOptions.AllowEdit = bool.Parse(args[7]);
- this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
- this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
-
- //this.cameraOptions = String.IsNullOrEmpty(options) ?
- // new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- //TODO Check if all the options are acceptable
-
-
- if (cameraOptions.PictureSourceType == CAMERA)
- {
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += onCameraTaskCompleted;
- cameraTask.Show();
- }
- else
- {
- if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
- {
- photoChooserTask = new PhotoChooserTask();
- photoChooserTask.Completed += onPickerTaskCompleted;
- photoChooserTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
- }
-
- public void onCameraTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- // Save image in media library
- if (cameraOptions.SaveToPhotoAlbum)
- {
- MediaLibrary library = new MediaLibrary();
- Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
- }
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
-
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
-
-
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
-
- }
-
- public void onPickerTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
-
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
- }
-
- /// <summary>
- /// Returns image content in a form of base64 string
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <returns>Base64 representation of the image</returns>
- private string GetImageContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
-
- //use photo's actual width & height if user doesn't provide width & height
- if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
- {
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
- else
- {
- // resize photo
- byte[] resizedFile = ResizePhoto(stream, fileData);
- stream.Close();
- return Convert.ToBase64String(resizedFile);
- }
- }
-
- /// <summary>
- /// Resize image
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <param name="fileData">File data</param>
- /// <returns>resized image</returns>
- private byte[] ResizePhoto(Stream stream, byte[] fileData)
- {
- int streamLength = (int)stream.Length;
- int intResult = 0;
-
- byte[] resizedFile;
-
- stream.Read(fileData, 0, streamLength);
-
- BitmapImage objBitmap = new BitmapImage();
- MemoryStream objBitmapStream = new MemoryStream(fileData);
- MemoryStream objBitmapStreamResized = new MemoryStream();
- WriteableBitmap objWB;
- objBitmap.SetSource(stream);
- objWB = new WriteableBitmap(objBitmap);
-
- // resize the photo with user defined TargetWidth & TargetHeight
- Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
-
- //Convert the resized stream to a byte array.
- streamLength = (int)objBitmapStreamResized.Length;
- resizedFile = new Byte[streamLength]; //-1
- objBitmapStreamResized.Position = 0;
- //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
- intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
-
- return resizedFile;
- }
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
- {
-
- if (image == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
-
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(isoFolder))
- {
- isoFile.CreateDirectory(isoFolder);
- }
-
- string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
-
- using (var stream = isoFile.CreateFile(filePath))
- {
- // resize image if Height and Width defined via options
- if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
- {
- image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
- }
- else
- {
- image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
- }
- }
-
- return new Uri(filePath, UriKind.Relative).ToString();
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Capture.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Capture.cs b/wp7/template/Plugins/Capture.cs
deleted file mode 100644
index 5e14a16..0000000
--- a/wp7/template/Plugins/Capture.cs
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework.Media;
-using WPCordovaClassLib.Cordova.UI;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-using System.Windows;
-using System.Diagnostics;
-using Microsoft.Phone.Controls;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to the audio, image, and video capture capabilities of the device
- /// </summary>
- public class Capture : BaseCommand
- {
- #region Internal classes (options and resultant objects)
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CaptureImageOptions
- {
- /// <summary>
- /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureImageOptions Default
- {
- get { return new CaptureImageOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureAudio action options.
- /// </summary>
- [DataContract]
- public class CaptureAudioOptions
- {
- /// <summary>
- /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureAudioOptions Default
- {
- get { return new CaptureAudioOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureVideo action options.
- /// </summary>
- [DataContract]
- public class CaptureVideoOptions
- {
- /// <summary>
- /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureVideoOptions Default
- {
- get { return new CaptureVideoOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents getFormatData action options.
- /// </summary>
- [DataContract]
- public class MediaFormatOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- [DataMember(IsRequired = true, Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// File mime type
- /// </summary>
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class MediaFile
- {
-
- [DataMember(Name = "name")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FilePath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public MediaFile(string filePath, Picture image)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = image.GetImage().Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
-
- }
-
- public MediaFile(string filePath, Stream stream)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = stream.Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
- }
- }
-
- /// <summary>
- /// Stores additional media file data
- /// </summary>
- [DataContract]
- public class MediaFileData
- {
- [DataMember(Name = "height")]
- public int Height { get; set; }
-
- [DataMember(Name = "width")]
- public int Width { get; set; }
-
- [DataMember(Name = "bitrate")]
- public int Bitrate { get; set; }
-
- [DataMember(Name = "duration")]
- public int Duration { get; set; }
-
- [DataMember(Name = "codecs")]
- public string Codecs { get; set; }
-
- public MediaFileData(WriteableBitmap image)
- {
- this.Height = image.PixelHeight;
- this.Width = image.PixelWidth;
- this.Bitrate = 0;
- this.Duration = 0;
- this.Codecs = "";
- }
- }
-
- #endregion
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Capture Image options
- /// </summary>
- protected CaptureImageOptions captureImageOptions;
-
- /// <summary>
- /// Capture Audio options
- /// </summary>
- protected CaptureAudioOptions captureAudioOptions;
-
- /// <summary>
- /// Capture Video options
- /// </summary>
- protected CaptureVideoOptions captureVideoOptions;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- private CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Used for audio recording
- /// </summary>
- private AudioCaptureTask audioCaptureTask;
-
- /// <summary>
- /// Used for video recording
- /// </summary>
- private VideoCaptureTask videoCaptureTask;
-
- /// <summary>
- /// Stores information about captured files
- /// </summary>
- List<MediaFile> files = new List<MediaFile>();
-
- /// <summary>
- /// Launches default camera application to capture image
- /// </summary>
- /// <param name="options">may contains limit or mode parameters</param>
- public void captureImage(string options)
- {
- try
- {
- try
- {
-
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
-
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += this.cameraTask_Completed;
- cameraTask.Show();
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own audio recording control to capture audio
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureAudio(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- audioCaptureTask = new AudioCaptureTask();
- audioCaptureTask.Completed += audioRecordingTask_Completed;
- audioCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own video recording control to capture video
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureVideo(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- videoCaptureTask = new VideoCaptureTask();
- videoCaptureTask.Completed += videoRecordingTask_Completed;
- videoCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Retrieves the format information of the media file.
- /// </summary>
- /// <param name="options"></param>
- public void getFormatData(string options)
- {
- try
- {
- MediaFormatOptions mediaFormatOptions;
- try
- {
- mediaFormatOptions = new MediaFormatOptions();
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaFormatOptions.FullPath = optionStrings[0];
- mediaFormatOptions.Type = optionStrings[1];
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
- string mimeType = mediaFormatOptions.Type;
-
- if (string.IsNullOrEmpty(mimeType))
- {
- mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
- }
-
- if (mimeType.Equals("image/jpeg"))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
-
- if (image == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
- return;
- }
-
- MediaFileData mediaData = new MediaFileData(image);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
-
- /// <summary>
- /// Opens specified file in media player
- /// </summary>
- /// <param name="options">MediaFile to play</param>
- public void play(string options)
- {
- try
- {
- MediaFile file;
-
- try
- {
- file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (file == null || String.IsNullOrEmpty(file.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
- return;
- }
-
- // if url starts with '/' media player throws FileNotFound exception
- Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
-
- MediaPlayerLauncher player = new MediaPlayerLauncher();
- player.Media = fileUri;
- player.Location = MediaLocationType.Data;
- player.Show();
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Handles result of capture to save image information
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured image</param>
- private void cameraTask_Completed(object sender, PhotoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
-
- // Save image in media library
- MediaLibrary library = new MediaLibrary();
- Picture image = library.SavePicture(fileName, e.ChosenPhoto);
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // Save image in isolated storage
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- byte[] imageBytes = new byte[rotImageStream.Length];
- rotImageStream.Read(imageBytes, 0, imageBytes.Length);
- rotImageStream.Dispose();
- string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
- imageBytes = null;
- // Get image data
- MediaFile data = new MediaFile(pathLocalStorage, image);
-
- this.files.Add(data);
-
- if (files.Count < this.captureImageOptions.Limit)
- {
- cameraTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some images were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of audio recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured audio</param>
- private void audioRecordingTask_Completed(object sender, AudioResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureAudioOptions.Limit)
- {
- audioCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some audio clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of video recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured video</param>
- private void videoRecordingTask_Completed(object sender, VideoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureVideoOptions.Limit)
- {
- videoCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some video clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Extract file from Isolated Storage as WriteableBitmap object
- /// </summary>
- /// <param name="filePath"></param>
- /// <returns></returns>
- private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
- {
- try
- {
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- var imageSource = PictureDecoder.DecodeJpeg(imageStream);
- return imageSource;
- }
- }
- catch (Exception)
- {
- return null;
- }
- }
-
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <param name="imageFolder">folder to store images</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
- {
- if (imageBytes == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(imageFolder))
- {
- isoFile.CreateDirectory(imageFolder);
- }
- string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
-
- using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
- {
- stream.Write(imageBytes, 0, imageBytes.Length);
- }
-
- return filePath;
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
-
- }
-}
\ No newline at end of file
[02/50] [abbrv] git commit: update build scripts for WP8
Posted by pu...@apache.org.
update build scripts for WP8
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/57b876f3
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/57b876f3
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/57b876f3
Branch: refs/heads/2.9.x
Commit: 57b876f3d4b935c1c5c01a8227422721e1142bbf
Parents: 6c3badc
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 12:17:42 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 12:17:42 2013 -0700
----------------------------------------------------------------------
wp8/template/MyTemplate.vstemplate | 133 ++++++++++
wp8/template/__PreviewImage.jpg | Bin 0 -> 25875 bytes
wp8/template/__TemplateIcon.png | Bin 0 -> 6546 bytes
wp8/template/vs/MyTemplateStandAlone.vstemplate | 144 ----------
wp8/template/vs/description.txt | 8 -
wp8/template/vs/pg_templateIcon.png | Bin 6546 -> 0 bytes
wp8/template/vs/pg_templatePreview.jpg | Bin 25875 -> 0 bytes
wp8/tooling/scripts/createTemplates.bat | 2 +
wp8/tooling/scripts/createTemplates.js | 261 +++++++++++++++++++
9 files changed, 396 insertions(+), 152 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/MyTemplate.vstemplate
----------------------------------------------------------------------
diff --git a/wp8/template/MyTemplate.vstemplate b/wp8/template/MyTemplate.vstemplate
new file mode 100644
index 0000000..6eebeef
--- /dev/null
+++ b/wp8/template/MyTemplate.vstemplate
@@ -0,0 +1,133 @@
+<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
+ <TemplateData>
+ <Name>CordovaWP8_2_9_0rc1</Name>
+ <Description>Starter project for building a Cordova app for Windows Phone 8 version: 0.0.0</Description>
+ <ProjectType>CSharp</ProjectType>
+ <ProjectSubType>
+ </ProjectSubType>
+ <SortOrder>1000</SortOrder>
+ <CreateNewFolder>true</CreateNewFolder>
+ <DefaultName>CordovaWP8_2_9_0rc1</DefaultName>
+ <ProvideDefaultName>true</ProvideDefaultName>
+ <LocationField>Enabled</LocationField>
+ <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+ <Icon>__TemplateIcon.png</Icon>
+ <PreviewImage>__PreviewImage.jpg</PreviewImage>
+ </TemplateData>
+ <TemplateContent>
+ <Project TargetFileName="CordovaWP8AppProj.csproj" File="CordovaWP8AppProj.csproj" ReplaceParameters="true">
+ <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
+ <Folder Name="cordova" TargetFolderName="cordova">
+ <ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
+ <Folder Name="lib" TargetFolderName="lib">
+ <ProjectItem ReplaceParameters="true" TargetFileName="build.js">build.js</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="clean.js">clean.js</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="deploy.js">deploy.js</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="log.js">log.js</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="target-list.js">target-list.js</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
+ </Folder>
+ <Folder Name="cordovalib" TargetFolderName="cordovalib">
+ <ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
+ <Folder Name="Commands" TargetFolderName="Commands">
+ <ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="DOMStorageHelper.cs">DOMStorageHelper.cs</ProjectItem>
+ <Folder Name="JSON" TargetFolderName="JSON">
+ <ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
+ </Folder>
+ <Folder Name="Images" TargetFolderName="Images">
+ <ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
+ <Folder Name="Plugins" TargetFolderName="Plugins">
+ <ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="DebugConsole.cs">DebugConsole.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
+ <Folder Name="UI" TargetFolderName="UI">
+ <ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
+ </Folder>
+ </Folder>
+ <Folder Name="Properties" TargetFolderName="Properties">
+ <ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
+ </Folder>
+ <Folder Name="resources" TargetFolderName="resources">
+ <ProjectItem ReplaceParameters="false" TargetFileName="notification-beep.wav">notification-beep.wav</ProjectItem>
+ </Folder>
+ <Folder Name="Service References" TargetFolderName="Service References" />
+ <ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
+ <Folder Name="www" TargetFolderName="www">
+ <ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
+ <Folder Name="css" TargetFolderName="css">
+ <ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
+ </Folder>
+ <Folder Name="img" TargetFolderName="img">
+ <ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
+ <Folder Name="js" TargetFolderName="js">
+ <ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
+ </Folder>
+ </Folder>
+ </Project>
+ </TemplateContent>
+</VSTemplate>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/__PreviewImage.jpg
----------------------------------------------------------------------
diff --git a/wp8/template/__PreviewImage.jpg b/wp8/template/__PreviewImage.jpg
new file mode 100644
index 0000000..1d72941
Binary files /dev/null and b/wp8/template/__PreviewImage.jpg differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/__TemplateIcon.png
----------------------------------------------------------------------
diff --git a/wp8/template/__TemplateIcon.png b/wp8/template/__TemplateIcon.png
new file mode 100644
index 0000000..75c17c7
Binary files /dev/null and b/wp8/template/__TemplateIcon.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/vs/MyTemplateStandAlone.vstemplate
----------------------------------------------------------------------
diff --git a/wp8/template/vs/MyTemplateStandAlone.vstemplate b/wp8/template/vs/MyTemplateStandAlone.vstemplate
deleted file mode 100644
index 6ecd8db..0000000
--- a/wp8/template/vs/MyTemplateStandAlone.vstemplate
+++ /dev/null
@@ -1,144 +0,0 @@
-<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
- <TemplateData>
- <Name>CordovaWP8_0_0_0</Name>
- <Description>Cordova 0.0.0 for Windows Phone 8 using the Cordova source code directly.</Description>
- <ProjectType>CSharp</ProjectType>
- <ProjectSubType>
- </ProjectSubType>
- <SortOrder>1000</SortOrder>
- <CreateNewFolder>true</CreateNewFolder>
- <DefaultName>CordovaWP8_0_0_0</DefaultName>
- <ProvideDefaultName>true</ProvideDefaultName>
- <LocationField>Enabled</LocationField>
- <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
- <Icon>__TemplateIcon.png</Icon>
- <PreviewImage>__PreviewImage.jpg</PreviewImage>
- </TemplateData>
- <TemplateContent>
- <Project TargetFileName="CordovaAppProj.csproj" File="CordovaAppProj.csproj" ReplaceParameters="true">
- <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
- <Folder Name="cordovalib" TargetFolderName="cordovalib">
- <ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
- <Folder Name="Commands" TargetFolderName="Commands">
- <ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
- </Folder>
- <ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="DOMStorageHelper.cs">DOMStorageHelper.cs</ProjectItem>
- <Folder Name="JSON" TargetFolderName="JSON">
- <ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
- </Folder>
- <ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
- </Folder>
- <Folder Name="Images" TargetFolderName="Images">
- <ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
- </Folder>
- <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
- <Folder Name="Plugins" TargetFolderName="Plugins">
- <ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="DebugConsole.cs">DebugConsole.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
- <Folder Name="UI" TargetFolderName="UI">
- <ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
- </Folder>
- </Folder>
- <Folder Name="Properties" TargetFolderName="Properties">
- <ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
- <ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
- </Folder>
- <Folder Name="resources" TargetFolderName="resources">
- <ProjectItem ReplaceParameters="false" TargetFileName="notification-beep.wav">notification-beep.wav</ProjectItem>
- </Folder>
- <Folder Name="Service References" TargetFolderName="Service References" />
- <ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
- <Folder Name="www" TargetFolderName="www">
- <ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
- <Folder Name="css" TargetFolderName="css">
- <ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
- </Folder>
- <Folder Name="img" TargetFolderName="img">
- <ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
- </Folder>
- <ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
- <Folder Name="js" TargetFolderName="js">
- <ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
- </Folder>
- </Folder>
- <Folder Name="cordova" TargetFolderName="cordova">
- <ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
- <Folder Name="lib" TargetFolderName="lib">
- <ProjectItem ReplaceParameters="false" TargetFileName="build.js">build.js</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="clean.js">clean.js</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="deploy.js">deploy.js</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="log.js">log.js</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="target-list.js">target-list.js</ProjectItem>
- <Folder Name="CordovaDeploy" TargetFolderName="CordovaDeploy">
- <ProjectItem ReplaceParameters="false" TargetFileName="CordovaDeploy.sln">CordovaDeploy.sln</ProjectItem>
- <Folder Name="CordovaDeploy" TargetFolderName="CordovaDeploy">
- <ProjectItem ReplaceParameters="false" TargetFileName="app.config">app.config</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="CordovaDeploy.csproj">CordovaDeploy.csproj</ProjectItem>
- <ProjectItem ReplaceParameters="false" TargetFileName="Program.cs">Program.cs</ProjectItem>
- <Folder Name="Properties" TargetFolderName="Properties">
- <ProjectItem ReplaceParameters="false" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
- </Folder>
- </Folder>
- </Folder>
- </Folder>
- </Folder>
- </Project>
- </TemplateContent>
-</VSTemplate>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/vs/description.txt
----------------------------------------------------------------------
diff --git a/wp8/template/vs/description.txt b/wp8/template/vs/description.txt
deleted file mode 100644
index 99306fa..0000000
--- a/wp8/template/vs/description.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CordovaWP8_2_6_0_Full
-Apache Cordova 0.0.0 Windows Phone 8 App using a pre-built dll.
-
-CordovaWP8_2_6_0_StandAlone
-Apache Cordova 0.0.0 Windows Phone 8 App including all framework source code.
-
-
-
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/vs/pg_templateIcon.png
----------------------------------------------------------------------
diff --git a/wp8/template/vs/pg_templateIcon.png b/wp8/template/vs/pg_templateIcon.png
deleted file mode 100644
index 75c17c7..0000000
Binary files a/wp8/template/vs/pg_templateIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/template/vs/pg_templatePreview.jpg
----------------------------------------------------------------------
diff --git a/wp8/template/vs/pg_templatePreview.jpg b/wp8/template/vs/pg_templatePreview.jpg
deleted file mode 100644
index 1d72941..0000000
Binary files a/wp8/template/vs/pg_templatePreview.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/tooling/scripts/createTemplates.bat
----------------------------------------------------------------------
diff --git a/wp8/tooling/scripts/createTemplates.bat b/wp8/tooling/scripts/createTemplates.bat
new file mode 100644
index 0000000..cf85190
--- /dev/null
+++ b/wp8/tooling/scripts/createTemplates.bat
@@ -0,0 +1,2 @@
+@echo off
+cscript "%~dp0\createTemplates.js" %* //nologo
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/57b876f3/wp8/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp8/tooling/scripts/createTemplates.js b/wp8/tooling/scripts/createTemplates.js
new file mode 100644
index 0000000..573c176
--- /dev/null
+++ b/wp8/tooling/scripts/createTemplates.js
@@ -0,0 +1,261 @@
+/*
+ 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 fso = WScript.CreateObject('Scripting.FileSystemObject'),
+ shell = WScript.CreateObject("shell.application"),
+ wscript_shell = WScript.CreateObject("WScript.Shell");
+
+//Set up directory structure of current release
+//arguments passed in
+var args = WScript.Arguments;
+
+//Root folder of cordova-windowsphone (i.e C:\Cordova\cordova-windowsphone)
+var repoRoot = WScript.ScriptFullName.split('\\wp8\\tooling\\', 1);
+
+//Sub folder containing templates
+var templatePath = '\\template';
+
+//Get version number
+var versionNum ='0.0.0';
+
+var platformRoot = WScript.ScriptFullName.split('\\tooling\\', 1);
+
+// set with the -install switch, default false
+var addToVS = false;
+
+// help function
+function Usage() {
+ Log("\nUsage: createTemplates [-install]");
+ Log("Build/zips up templates from the local repo")
+ Log(" -install : also installs templates to user directory on success\n");
+}
+
+// logs messaged to stdout and stderr
+function Log(msg, error) {
+ if (error) {
+ WScript.StdErr.WriteLine(msg);
+ }
+ else {
+ WScript.StdOut.WriteLine(msg);
+ }
+}
+
+// deletes file if it exists
+function deleteFileIfExists(path) {
+ if(fso.FileExists(path)) {
+ fso.DeleteFile(path);
+ }
+}
+
+function deleteFolderIfExists(path) {
+ if(fso.FolderExists(path)) {
+ fso.DeleteFolder(path);
+ }
+}
+
+var ForReading = 1, ForWriting = 2, ForAppending = 8;
+var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
+
+// returns the contents of a file
+function read(filename) {
+ WScript.Echo('Reading in ' + filename);
+ if(fso.FileExists(filename))
+ {
+ var f=fso.OpenTextFile(filename, 1,2);
+ var s=f.ReadAll();
+ f.Close();
+ return s;
+ }
+ else
+ {
+ WScript.StdErr.WriteLine('Cannot read non-existant file : ' + filename);
+ WScript.Quit(1);
+ }
+ return null;
+}
+
+// writes the contents to the specified file
+function write(filename, contents) {
+ var f=fso.OpenTextFile(filename, ForWriting, TristateTrue);
+ f.Write(contents);
+ f.Close();
+}
+
+// replaces the matches of regexp with replacement
+function replaceInFile(filename, regexp, replacement) {
+ //WScript.Echo("Replaceing with "+replacement+ " in:");
+ var text = read(filename).replace(regexp,replacement);
+ //WScript.Echo(text);
+ write(filename,text);
+}
+
+// executes a commmand in the shell
+function exec(command) {
+ Log("exec:" + command);
+ var oShell=wscript_shell.Exec(command);
+ var maxTime = 5000;
+ while (oShell.Status === 0) {
+ if(maxTime > 0) {
+ maxTime -= 100;
+ WScript.sleep(100);
+ }
+ else {
+ Log("Exec timed out with command :: " + command);
+ }
+ }
+}
+
+// executes a commmand in the shell
+function exec_verbose(command) {
+ //Log("Command: " + command);
+ var oShell=wscript_shell.Exec(command);
+ while (oShell.Status === 0) {
+ //Wait a little bit so we're not super looping
+ WScript.sleep(100);
+ //Print any stdout output from the script
+ if(!oShell.StdOut.AtEndOfStream) {
+ var line = oShell.StdOut.ReadLine();
+ Log(line);
+ }
+ }
+ //Check to make sure our scripts did not encounter an error
+ if(!oShell.StdErr.AtEndOfStream)
+ {
+ var err_line = oShell.StdErr.ReadAll();
+ WScript.StdErr.WriteLine(err_line);
+ WScript.Quit(1);
+ }
+}
+
+function copyFile(src,dest) {
+ exec('%comspec% /c copy /Y ' + src + ' ' + dest);
+}
+
+
+// packages templates into .zip
+function package_templates()
+{
+ Log("Creating template .zip files ...");
+ var templateOutFilename = repoRoot + '\\CordovaWP8_' + versionNum.replace(/\./g, '_') + '.zip';
+
+ // clear the destination
+ deleteFileIfExists(templateOutFilename);
+
+ // clean the template folder, if the project was opened in VS, it creates some useless cruft.
+ deleteFolderIfExists(platformRoot + templatePath + '\\Bin');
+ deleteFolderIfExists(platformRoot + templatePath + '\\obj');
+ deleteFolderIfExists(platformRoot + templatePath + '\\Service\ References');
+
+ deleteFileIfExists(platformRoot + templatePath + "\\CordovaWP8Solution.v11.suo");
+
+ exec('%comspec% /c xcopy /Y /E /I ' + repoRoot + '\\Plugins ' + platformRoot + templatePath + '\\Plugins');
+ copyFile(repoRoot + '\\VERSION',platformRoot + templatePath);
+
+ // update .vstemplate files for the template zips.
+ var name_regex = /CordovaWP8[_](\d+)[_](\d+)[_](\d+)(rc\d)?/g;
+ var discript_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
+
+ replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', name_regex, 'CordovaWP8_' + versionNum.replace(/\./g, '_'));
+ replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', discript_regex, "Cordova " + versionNum);
+
+
+ zip_project(templateOutFilename, platformRoot + templatePath);
+
+ if(addToVS)
+ {
+ var template_dir = wscript_shell.ExpandEnvironmentStrings("%USERPROFILE%") + '\\Documents\\Visual Studio 2012\\Templates\\ProjectTemplates\\Testing';
+ if(fso.FolderExists(template_dir ))
+ {
+ Log("template_dir = " + template_dir);
+ dest = shell.NameSpace(template_dir);
+ dest.CopyHere(templateOutFilename, 4|20);
+ }
+ else
+ {
+ Log("WARNING: Could not find template directory in Visual Studio,\n you can manually copy over the template .zip files.");
+ }
+ }
+}
+
+function zip_project(zip_path, project_path) {
+ // create empty ZIP file and open for adding
+ var file = fso.CreateTextFile(zip_path, true);
+
+ // create twenty-two byte "fingerprint" for .zip
+ file.write("PK");
+ file.write(String.fromCharCode(5));
+ file.write(String.fromCharCode(6));
+ file.write('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0');
+ file.Close();
+
+ // open .zip folder and copy contents of project_path to zip_path
+ var zipFolder = shell.NameSpace(zip_path);
+ Log("zip_path = " + zip_path);
+ Log("zipFolder = " + zipFolder);
+ Log("project_path = " + project_path);
+
+ var sourceItems = shell.NameSpace(project_path).items();
+ if (zipFolder !== null) {
+ zipFolder.CopyHere(sourceItems, 4|16|512|1024);
+ var maxTime = 5000;
+ Log("sourceItems.Count = " + sourceItems.Count);
+ while(zipFolder.items().Count < sourceItems.Count)
+ {
+ maxTime -= 100;
+ if(maxTime > 0 ) {
+ WScript.Sleep(100);
+ }
+ else {
+ Log('Timeout. Failed to create .zip file.', true);
+ break;
+ }
+ }
+ Log("zipFolder.items().Count = " + zipFolder.items().Count);
+ }
+ else {
+ Log('Failed to create .zip file.', true);
+ }
+}
+
+// delete any unneeded files when finished
+function cleanUp() {
+
+}
+
+function parseArgs() {
+ if(args.Count() > 0) {
+
+ //Support help flags -help, --help, /?
+ if(args(0).indexOf("-help") > -1 ||
+ args(0).indexOf("/?") > -1 ) {
+ Usage();
+ WScript.Quit(1);
+ }
+ else if(args(0).indexOf("-install") > -1) {
+ addToVS = true;
+ }
+ }
+}
+
+// MAIN
+parseArgs();
+// build/package the templates
+versionNum = read(repoRoot + "\\VERSION");
+package_templates(repoRoot);
+cleanUp();
\ No newline at end of file
[12/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Compass.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Compass.cs b/wp7/template/Plugins/Compass.cs
deleted file mode 100644
index c9e1c4d..0000000
--- a/wp7/template/Plugins/Compass.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using DeviceCompass = Microsoft.Devices.Sensors.Compass;
-using System.Windows.Threading;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class Compass : BaseCommand
- {
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Id for get getCompass method
- /// </summary>
- private static string getCompassId = "getCompassId";
-
- /// <summary>
- /// Compass
- /// </summary>
- private static DeviceCompass compass = new DeviceCompass();
-
- /// <summary>
- /// Listeners for callbacks
- /// </summary>
- private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
-
- #endregion
-
- #region Status codes
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 4;
- public const int Not_Supported = 20;
-
- /*
- * // Capture error codes
- CompassError.COMPASS_INTERNAL_ERR = 0;
- CompassError.COMPASS_NOT_SUPPORTED = 20;
- * */
-
- #endregion
-
- #region CompassOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class CompassOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// The change in degrees required to initiate a watchHeadingFilter success callback.
- /// </summary>
- [DataMember(IsRequired = false, Name = "filter")]
- public int Filter { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- }
- #endregion
-
-
- /// <summary>
- /// Time the value was last changed
- /// </summary>
- //private DateTime lastValueChangedTime;
-
- /// <summary>
- /// Accelerometer options
- /// </summary>
- private CompassOptions compassOptions;
-
- //bool isDataValid;
-
- //bool calibrating = false;
-
- public Compass()
- {
-
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetHeadingFormatted(CompassReading reading)
- {
- // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
- string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
- reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
- reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
- reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
- return "{" + result + "}";
- }
-
- public void getHeading(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
- }
- else
- {
- //if (compass == null)
- //{
- // // Instantiate the compass.
- // compass = new DeviceCompass();
- // compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
- // compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
- // compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
- //}
-
-
- //compass.Start();
-
- }
-
- try
- {
- if (currentStatus != Running)
- {
- lock (compass)
- {
- compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- lock (compass)
- {
- compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
- if (watchers.Count < 1)
- {
- compass.Stop();
- this.SetStatus(Stopped);
- }
- }
- }
- catch (UnauthorizedAccessException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- }
- }
-
- void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Starts listening for compass sensor
- /// </summary>
- /// <returns>status of listener</returns>
- private int start()
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return currentStatus;
- }
- try
- {
- lock (compass)
- {
- watchers.Add(getCompassId, this);
- compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- }
- return currentStatus;
- }
-
- public void startWatch(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
- }
-
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- lock (compass)
- {
- watchers.Add(compassOptions.Id, this);
- compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- return;
- }
- }
-
- public void stopWatch(string options)
- {
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (currentStatus != Stopped)
- {
- lock (compass)
- {
- Compass watcher = watchers[compassOptions.Id];
- compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
- watchers.Remove(compassOptions.Id);
- watcher.Dispose();
- }
- }
- this.SetStatus(Stopped);
-
- this.DispatchCommandResult();
- }
-
- void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
- {
- //throw new NotImplementedException();
- // TODO: pass calibration error to JS
- }
-
- void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
- result.KeepCallback = true;
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Contacts.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Contacts.cs b/wp7/template/Plugins/Contacts.cs
deleted file mode 100644
index af78942..0000000
--- a/wp7/template/Plugins/Contacts.cs
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Tasks;
-using Microsoft.Phone.UserData;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Windows;
-using DeviceContacts = Microsoft.Phone.UserData.Contacts;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class SearchOptions
- {
- [DataMember]
- public string filter { get; set; }
- [DataMember]
- public bool multiple { get; set; }
- }
-
- [DataContract]
- public class ContactSearchParams
- {
- [DataMember]
- public string[] fields { get; set; }
- [DataMember]
- public SearchOptions options { get; set; }
- }
-
- [DataContract]
- public class JSONContactAddress
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string streetAddress { get; set; }
- [DataMember]
- public string locality { get; set; }
- [DataMember]
- public string region { get; set; }
- [DataMember]
- public string postalCode { get; set; }
- [DataMember]
- public string country { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactName
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string familyName { get; set; }
- [DataMember]
- public string givenName { get; set; }
- [DataMember]
- public string middleName { get; set; }
- [DataMember]
- public string honorificPrefix { get; set; }
- [DataMember]
- public string honorificSuffix { get; set; }
- }
-
- [DataContract]
- public class JSONContactField
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string value { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactOrganization
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string name { get; set; }
- [DataMember]
- public bool pref { get; set; }
- [DataMember]
- public string department { get; set; }
- [DataMember]
- public string title { get; set; }
- }
-
- [DataContract]
- public class JSONContact
- {
- [DataMember]
- public string id { get; set; }
- [DataMember]
- public string rawId { get; set; }
- [DataMember]
- public string displayName { get; set; }
- [DataMember]
- public string nickname { get; set; }
- [DataMember]
- public string note { get; set; }
-
- [DataMember]
- public JSONContactName name { get; set; }
-
- [DataMember]
- public JSONContactField[] emails { get; set; }
-
- [DataMember]
- public JSONContactField[] phoneNumbers { get; set; }
-
- [DataMember]
- public JSONContactField[] ims { get; set; }
-
- [DataMember]
- public JSONContactField[] photos { get; set; }
-
- [DataMember]
- public JSONContactField[] categories { get; set; }
-
- [DataMember]
- public JSONContactField[] urls { get; set; }
-
- [DataMember]
- public JSONContactOrganization[] organizations { get; set; }
-
- [DataMember]
- public JSONContactAddress[] addresses { get; set; }
- }
-
-
- public class Contacts : BaseCommand
- {
-
- public const int UNKNOWN_ERROR = 0;
- public const int INVALID_ARGUMENT_ERROR = 1;
- public const int TIMEOUT_ERROR = 2;
- public const int PENDING_OPERATION_ERROR = 3;
- public const int IO_ERROR = 4;
- public const int NOT_SUPPORTED_ERROR = 5;
- public const int PERMISSION_DENIED_ERROR = 20;
- public const int SYNTAX_ERR = 8;
-
- public Contacts()
- {
-
- }
-
- // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
- public void save(string jsonContact)
- {
-
- // jsonContact is actually an array of 1 {contact}
- string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
-
-
- JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
-
- SaveContactTask contactTask = new SaveContactTask();
-
- if (contact.nickname != null)
- {
- contactTask.Nickname = contact.nickname;
- }
- if (contact.urls != null && contact.urls.Length > 0)
- {
- contactTask.Website = contact.urls[0].value;
- }
- if (contact.note != null)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.name
- if (contact.name != null)
- {
- if (contact.name.givenName != null)
- contactTask.FirstName = contact.name.givenName;
- if (contact.name.familyName != null)
- contactTask.LastName = contact.name.familyName;
- if (contact.name.middleName != null)
- contactTask.MiddleName = contact.name.middleName;
- if (contact.name.honorificSuffix != null)
- contactTask.Suffix = contact.name.honorificSuffix;
- if (contact.name.honorificPrefix != null)
- contactTask.Title = contact.name.honorificPrefix;
- }
- #endregion
-
- #region contact.org
- if (contact.organizations != null && contact.organizations.Count() > 0)
- {
- contactTask.Company = contact.organizations[0].name;
- contactTask.JobTitle = contact.organizations[0].title;
- }
- #endregion
-
- #region contact.phoneNumbers
- if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
- {
- foreach (JSONContactField field in contact.phoneNumbers)
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkPhone = field.value;
- }
- else if (fieldType == "home")
- {
- contactTask.HomePhone = field.value;
- }
- else if (fieldType == "mobile")
- {
- contactTask.MobilePhone = field.value;
- }
- }
- }
- #endregion
-
- #region contact.emails
-
- if (contact.emails != null && contact.emails.Length > 0)
- {
-
- // set up different email types if they are not explicitly defined
- foreach (string type in new string[] { "personal", "work", "other" })
- {
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null && String.IsNullOrEmpty(field.type))
- {
- field.type = type;
- break;
- }
- }
- }
-
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null)
- {
- if (field.type != null && field.type != "other")
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkEmail = field.value;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.PersonalEmail = field.value;
- }
- }
- else
- {
- contactTask.OtherEmail = field.value;
- }
- }
-
- }
- }
- #endregion
-
- if (contact.note != null && contact.note.Length > 0)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.addresses
- if (contact.addresses != null && contact.addresses.Length > 0)
- {
- foreach (JSONContactAddress address in contact.addresses)
- {
- if (address.type == null)
- {
- address.type = "home"; // set a default
- }
- string fieldType = address.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkAddressCity = address.locality;
- contactTask.WorkAddressCountry = address.country;
- contactTask.WorkAddressState = address.region;
- contactTask.WorkAddressStreet = address.streetAddress;
- contactTask.WorkAddressZipCode = address.postalCode;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.HomeAddressCity = address.locality;
- contactTask.HomeAddressCountry = address.country;
- contactTask.HomeAddressState = address.region;
- contactTask.HomeAddressStreet = address.streetAddress;
- contactTask.HomeAddressZipCode = address.postalCode;
- }
- else
- {
- // no other address fields available ...
- Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
- }
- }
- }
- #endregion
-
-
- contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
- contactTask.Show();
- }
-
- void ContactSaveTaskCompleted(object sender, SaveContactResult e)
- {
- SaveContactTask task = sender as SaveContactTask;
-
- if (e.TaskResult == TaskResult.OK)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
-
- string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
-
- deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
- });
-
-
- }
- else if (e.TaskResult == TaskResult.Cancel)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
- }
- }
-
- void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- if (e.Results.Count() > 0)
- {
- List<Contact> foundContacts = new List<Contact>();
-
- int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
- Contact newContact = (from Contact contact in e.Results
- where contact.GetHashCode() == n
- select contact).First();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
-
-
- public void remove(string id)
- {
- // note id is wrapped in [] and always has exactly one string ...
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
- }
-
- public void search(string searchCriteria)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
-
- ContactSearchParams searchParams = new ContactSearchParams();
- try
- {
- searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
- searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
- return;
- }
-
- if (searchParams.options == null)
- {
- searchParams.options = new SearchOptions();
- searchParams.options.filter = "";
- searchParams.options.multiple = true;
- }
-
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
-
- // default is to search all fields
- FilterKind filterKind = FilterKind.None;
- // if only one field is specified, we will try the 3 available DeviceContact search filters
- if (searchParams.fields.Count() == 1)
- {
- if (searchParams.fields.Contains("name"))
- {
- filterKind = FilterKind.DisplayName;
- }
- else if (searchParams.fields.Contains("emails"))
- {
- filterKind = FilterKind.EmailAddress;
- }
- else if (searchParams.fields.Contains("phoneNumbers"))
- {
- filterKind = FilterKind.PhoneNumber;
- }
- }
-
- try
- {
-
- deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
- }
- catch (Exception ex)
- {
- Debug.WriteLine("search contacts exception :: " + ex.Message);
- }
- }
-
- private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- ContactSearchParams searchParams = (ContactSearchParams)e.State;
-
- List<Contact> foundContacts = null;
-
- // if we have multiple search fields
- if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
- {
- foundContacts = new List<Contact>();
- if (searchParams.fields.Contains("emails"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactEmailAddress a in con.EmailAddresses
- where a.EmailAddress.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("displayName"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.DisplayName.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("name"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("phoneNumbers"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactPhoneNumber a in con.PhoneNumbers
- where a.PhoneNumber.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("urls"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from string a in con.Websites
- where a.Contains(searchParams.options.filter)
- select con);
- }
- }
- else
- {
- foundContacts = new List<Contact>(e.Results);
- }
-
- //List<string> contactList = new List<string>();
-
- string strResult = "";
-
- IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
-
- foreach (Contact contact in distinctContacts)
- {
- strResult += FormatJSONContact(contact, null) + ",";
- //contactList.Add(FormatJSONContact(contact, null));
- if (!searchParams.options.multiple)
- {
- break; // just return the first item
- }
- }
- PluginResult result = new PluginResult(PluginResult.Status.OK);
- result.Message = "[" + strResult.TrimEnd(',') + "]";
- DispatchCommandResult(result);
-
- }
-
- private string FormatJSONPhoneNumbers(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactPhoneNumber number in con.PhoneNumbers)
- {
-
- string contactField = string.Format(contactFieldFormat,
- number.Kind.ToString(),
- number.PhoneNumber);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONEmails(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactEmailAddress address in con.EmailAddresses)
- {
- string contactField = string.Format(contactFieldFormat,
- address.Kind.ToString(),
- address.EmailAddress);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string getFormattedJSONAddress(ContactAddress address, bool isPrefered)
- {
-
- string addressFormatString = "\"pref\":{0}," + // bool
- "\"type\":\"{1}\"," +
- "\"formatted\":\"{2}\"," +
- "\"streetAddress\":\"{3}\"," +
- "\"locality\":\"{4}\"," +
- "\"region\":\"{5}\"," +
- "\"postalCode\":\"{6}\"," +
- "\"country\":\"{7}\"";
-
- string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
- + address.PhysicalAddress.AddressLine2 + " "
- + address.PhysicalAddress.City + " "
- + address.PhysicalAddress.StateProvince + " "
- + address.PhysicalAddress.CountryRegion + " "
- + address.PhysicalAddress.PostalCode;
-
- string jsonAddress = string.Format(addressFormatString,
- isPrefered ? "\"true\"" : "\"false\"",
- address.Kind.ToString(),
- formattedAddress,
- address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
- address.PhysicalAddress.City,
- address.PhysicalAddress.StateProvince,
- address.PhysicalAddress.PostalCode,
- address.PhysicalAddress.CountryRegion);
-
- //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
-
- return "{" + jsonAddress + "}";
- }
-
- private string FormatJSONAddresses(Contact con)
- {
- string retVal = "";
- foreach (ContactAddress address in con.Addresses)
- {
- retVal += this.getFormattedJSONAddress(address, false) + ",";
- }
-
- //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONWebsites(Contact con)
- {
- string retVal = "";
- foreach (string website in con.Websites)
- {
- retVal += "\"" + website + "\",";
- }
- return retVal.TrimEnd(',');
- }
-
- /*
- * formatted: The complete name of the contact. (DOMString)
- familyName: The contacts family name. (DOMString)
- givenName: The contacts given name. (DOMString)
- middleName: The contacts middle name. (DOMString)
- honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
- honorificSuffix: The contacts suffix (example Esq.). (DOMString)
- */
- private string FormatJSONName(Contact con)
- {
- string retVal = "";
- string formatStr = "\"formatted\":\"{0}\"," +
- "\"familyName\":\"{1}\"," +
- "\"givenName\":\"{2}\"," +
- "\"middleName\":\"{3}\"," +
- "\"honorificPrefix\":\"{4}\"," +
- "\"honorificSuffix\":\"{5}\"";
-
- if (con.CompleteName != null)
- {
- retVal = string.Format(formatStr,
- con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
- con.CompleteName.LastName,
- con.CompleteName.FirstName,
- con.CompleteName.MiddleName,
- con.CompleteName.Title,
- con.CompleteName.Suffix);
- }
- else
- {
- retVal = string.Format(formatStr,"","","","","","");
- }
-
- return "{" + retVal + "}";
- }
-
- private string FormatJSONContact(Contact con, string[] fields)
- {
-
- string contactFormatStr = "\"id\":\"{0}\"," +
- "\"displayName\":\"{1}\"," +
- "\"nickname\":\"{2}\"," +
- "\"phoneNumbers\":[{3}]," +
- "\"emails\":[{4}]," +
- "\"addresses\":[{5}]," +
- "\"urls\":[{6}]," +
- "\"name\":{7}," +
- "\"note\":\"{8}\"," +
- "\"birthday\":\"{9}\"";
-
-
- string jsonContact = String.Format(contactFormatStr,
- con.GetHashCode(),
- con.DisplayName,
- con.CompleteName != null ? con.CompleteName.Nickname : "",
- FormatJSONPhoneNumbers(con),
- FormatJSONEmails(con),
- FormatJSONAddresses(con),
- FormatJSONWebsites(con),
- FormatJSONName(con),
- con.Notes.FirstOrDefault(),
- con.Birthdays.FirstOrDefault());
-
- //Debug.WriteLine("jsonContact = " + jsonContact);
- // JSON requires new line characters be escaped
- return "{" + jsonContact.Replace("\n", "\\n") + "}";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/DebugConsole.cs b/wp7/template/Plugins/DebugConsole.cs
deleted file mode 100644
index fa9863a..0000000
--- a/wp7/template/Plugins/DebugConsole.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class DebugConsole : BaseCommand
- {
- // warn, error
- public void log(string msg)
- {
- Debug.WriteLine("Log:" + msg);
- }
-
- public void error(string msg)
- {
- Debug.WriteLine("Error:" + msg);
- }
-
- public void warn(string msg)
- {
- Debug.WriteLine("Warn:" + msg);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Device.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Device.cs b/wp7/template/Plugins/Device.cs
deleted file mode 100644
index 8abb4ff..0000000
--- a/wp7/template/Plugins/Device.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Info;
-using System.IO.IsolatedStorage;
-using System.Windows.Resources;
-using System.IO;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Device : BaseCommand
- {
- public void getDeviceInfo(string notused)
- {
-
- string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
- this.name,
- this.cordova,
- this.platform,
- this.uuid,
- this.version,
- this.model);
-
-
-
- res = "{" + res + "}";
- //Debug.WriteLine("Result::" + res);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
- }
-
- public string model
- {
- get
- {
- return DeviceStatus.DeviceName;
- //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion);
- }
- }
-
- public string name
- {
- get
- {
- return DeviceStatus.DeviceName;
-
- }
- }
-
- public string cordova
- {
- get
- {
- // TODO: should be able to dynamically read the Cordova version from somewhere...
- return "0.0.0";
- }
- }
-
- public string platform
- {
- get
- {
- return Environment.OSVersion.Platform.ToString();
- }
- }
-
- public string uuid
- {
- get
- {
- string returnVal = "";
- object id;
- UserExtendedProperties.TryGetValue("ANID", out id);
-
- if (id != null)
- {
- returnVal = id.ToString().Substring(2, 32);
- }
- else
- {
- returnVal = "???unknown???";
-
- using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- try
- {
- IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
- using (StreamReader reader = new StreamReader(fileStream))
- {
- returnVal = reader.ReadLine();
- }
- }
- catch (Exception /*ex*/)
- {
-
- }
- }
- }
-
- return returnVal;
- }
- }
-
- public string version
- {
- get
- {
- return Environment.OSVersion.Version.ToString();
- }
- }
-
- }
-}
[06/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/File.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/File.cs b/wp8/template/Plugins/File.cs
deleted file mode 100644
index cde7a1c..0000000
--- a/wp8/template/Plugins/File.cs
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to isolated storage
- /// </summary>
- public class File : BaseCommand
- {
- // Error codes
- public const int NOT_FOUND_ERR = 1;
- public const int SECURITY_ERR = 2;
- public const int ABORT_ERR = 3;
- public const int NOT_READABLE_ERR = 4;
- public const int ENCODING_ERR = 5;
- public const int NO_MODIFICATION_ALLOWED_ERR = 6;
- public const int INVALID_STATE_ERR = 7;
- public const int SYNTAX_ERR = 8;
- public const int INVALID_MODIFICATION_ERR = 9;
- public const int QUOTA_EXCEEDED_ERR = 10;
- public const int TYPE_MISMATCH_ERR = 11;
- public const int PATH_EXISTS_ERR = 12;
-
- // File system options
- public const int TEMPORARY = 0;
- public const int PERSISTENT = 1;
- public const int RESOURCE = 2;
- public const int APPLICATION = 3;
-
- /// <summary>
- /// Temporary directory name
- /// </summary>
- private readonly string TMP_DIRECTORY_NAME = "tmp";
-
- /// <summary>
- /// Represents error code for callback
- /// </summary>
- [DataContract]
- public class ErrorCode
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(IsRequired = true, Name = "code")]
- public int Code { get; set; }
-
- /// <summary>
- /// Creates ErrorCode object
- /// </summary>
- public ErrorCode(int code)
- {
- this.Code = code;
- }
- }
-
- /// <summary>
- /// Represents File action options.
- /// </summary>
- [DataContract]
- public class FileOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- ///
- private string _fileName;
- [DataMember(Name = "fileName")]
- public string FilePath
- {
- get
- {
- return this._fileName;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._fileName = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Full entryPath
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// Directory name
- /// </summary>
- [DataMember(Name = "dirName")]
- public string DirectoryName { get; set; }
-
- /// <summary>
- /// Path to create file/directory
- /// </summary>
- [DataMember(Name = "path")]
- public string Path { get; set; }
-
- /// <summary>
- /// The encoding to use to encode the file's content. Default is UTF8.
- /// </summary>
- [DataMember(Name = "encoding")]
- public string Encoding { get; set; }
-
- /// <summary>
- /// Uri to get file
- /// </summary>
- ///
- private string _uri;
- [DataMember(Name = "uri")]
- public string Uri
- {
- get
- {
- return this._uri;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._uri = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Size to truncate file
- /// </summary>
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- /// <summary>
- /// Data to write in file
- /// </summary>
- [DataMember(Name = "data")]
- public string Data { get; set; }
-
- /// <summary>
- /// Position the writing starts with
- /// </summary>
- [DataMember(Name = "position")]
- public int Position { get; set; }
-
- /// <summary>
- /// Type of file system requested
- /// </summary>
- [DataMember(Name = "type")]
- public int FileSystemType { get; set; }
-
- /// <summary>
- /// New file/directory name
- /// </summary>
- [DataMember(Name = "newName")]
- public string NewName { get; set; }
-
- /// <summary>
- /// Destination directory to copy/move file/directory
- /// </summary>
- [DataMember(Name = "parent")]
- public string Parent { get; set; }
-
- /// <summary>
- /// Options for getFile/getDirectory methods
- /// </summary>
- [DataMember(Name = "options")]
- public CreatingOptions CreatingOpt { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public FileOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Encoding = "UTF-8";
- this.FilePath = "";
- this.FileSystemType = -1;
- }
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class FileMetadata
- {
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public FileMetadata(string filePath)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- else if (!isoFile.FileExists(filePath))
- {
- // attempt to get it from the resources
- if (filePath.IndexOf("www") == 0)
- {
- Uri fileUri = new Uri(filePath, UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- this.Size = streamInfo.Stream.Length;
- this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
- this.FullPath = filePath;
- }
- }
- else
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- }
- else
- {
- //TODO get file size the other way if possible
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
- {
- this.Size = stream.Length;
- }
- this.FullPath = filePath;
- this.FileName = System.IO.Path.GetFileName(filePath);
- this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- }
- this.Type = MimeTypeMapper.GetMimeType(this.FileName);
- }
- }
- }
-
- /// <summary>
- /// Represents file or directory modification metadata
- /// </summary>
- [DataContract]
- public class ModificationMetadata
- {
- /// <summary>
- /// Modification time
- /// </summary>
- [DataMember]
- public string modificationTime { get; set; }
- }
-
- /// <summary>
- /// Represents file or directory entry
- /// </summary>
- [DataContract]
- public class FileEntry
- {
-
- /// <summary>
- /// File type
- /// </summary>
- [DataMember(Name = "isFile")]
- public bool IsFile { get; set; }
-
- /// <summary>
- /// Directory type
- /// </summary>
- [DataMember(Name = "isDirectory")]
- public bool IsDirectory { get; set; }
-
- /// <summary>
- /// File/directory name
- /// </summary>
- [DataMember(Name = "name")]
- public string Name { get; set; }
-
- /// <summary>
- /// Full path to file/directory
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- public bool IsResource { get; set; }
-
- public static FileEntry GetEntry(string filePath, bool bIsRes=false)
- {
- FileEntry entry = null;
- try
- {
- entry = new FileEntry(filePath, bIsRes);
-
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
- }
- return entry;
- }
-
- /// <summary>
- /// Creates object and sets necessary properties
- /// </summary>
- /// <param name="filePath"></param>
- public FileEntry(string filePath, bool bIsRes = false)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new ArgumentException();
- }
-
- if(filePath.Contains(" "))
- {
- Debug.WriteLine("FilePath with spaces :: " + filePath);
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- IsResource = bIsRes;
- IsFile = isoFile.FileExists(filePath);
- IsDirectory = isoFile.DirectoryExists(filePath);
- if (IsFile)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else if (IsDirectory)
- {
- this.Name = this.GetDirectoryName(filePath);
- if (string.IsNullOrEmpty(Name))
- {
- this.Name = "/";
- }
- }
- else
- {
- if (IsResource)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else
- {
- throw new FileNotFoundException();
- }
- }
-
- try
- {
- this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
- }
- catch (Exception)
- {
- this.FullPath = filePath;
- }
- }
- }
-
- /// <summary>
- /// Extracts directory name from path string
- /// Path should refer to a directory, for example \foo\ or /foo.
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- private string GetDirectoryName(string path)
- {
- if (String.IsNullOrEmpty(path))
- {
- return path;
- }
-
- string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
- if (split.Length < 1)
- {
- return null;
- }
- else
- {
- return split[split.Length - 1];
- }
- }
- }
-
-
- /// <summary>
- /// Represents info about requested file system
- /// </summary>
- [DataContract]
- public class FileSystemInfo
- {
- /// <summary>
- /// file system type
- /// </summary>
- [DataMember(Name = "name", IsRequired = true)]
- public string Name { get; set; }
-
- /// <summary>
- /// Root directory entry
- /// </summary>
- [DataMember(Name = "root", EmitDefaultValue = false)]
- public FileEntry Root { get; set; }
-
- /// <summary>
- /// Creates class instance
- /// </summary>
- /// <param name="name"></param>
- /// <param name="rootEntry"> Root directory</param>
- public FileSystemInfo(string name, FileEntry rootEntry = null)
- {
- Name = name;
- Root = rootEntry;
- }
- }
-
- [DataContract]
- public class CreatingOptions
- {
- /// <summary>
- /// Create file/directory if is doesn't exist
- /// </summary>
- [DataMember(Name = "create")]
- public bool Create { get; set; }
-
- /// <summary>
- /// Generate an exception if create=true and file/directory already exists
- /// </summary>
- [DataMember(Name = "exclusive")]
- public bool Exclusive { get; set; }
-
-
- }
-
- // returns null value if it fails.
- private string[] getOptionStrings(string options)
- {
- string[] optStings = null;
- try
- {
- optStings = JSON.JsonHelper.Deserialize<string[]>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
- }
- return optStings;
- }
-
- /// <summary>
- /// Gets amount of free space available for Isolated Storage
- /// </summary>
- /// <param name="options">No options is needed for this method</param>
- public void getFreeDiskSpace(string options)
- {
- string callbackId = getOptionStrings(options)[0];
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Check if file exists
- /// </summary>
- /// <param name="options">File path</param>
- public void testFileExists(string options)
- {
- IsDirectoryOrFileExist(options, false);
- }
-
- /// <summary>
- /// Check if directory exists
- /// </summary>
- /// <param name="options">directory name</param>
- public void testDirectoryExists(string options)
- {
- IsDirectoryOrFileExist(options, true);
- }
-
- /// <summary>
- /// Check if file or directory exist
- /// </summary>
- /// <param name="options">File path/Directory name</param>
- /// <param name="isDirectory">Flag to recognize what we should check</param>
- public void IsDirectoryOrFileExist(string options, bool isDirectory)
- {
- string[] args = getOptionStrings(options);
- string callbackId = args[1];
- FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
- string filePath = args[0];
-
- if (fileOptions == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isExist;
- if (isDirectory)
- {
- isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
- }
- else
- {
- isExist = isoFile.FileExists(fileOptions.FilePath);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
- }
- }
- catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
-
- public void readAsDataURL(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- if (filePath != null)
- {
- try
- {
- string base64URL = null;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string mimeType = MimeTypeMapper.GetMimeType(filePath);
-
- using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- string base64String = GetFileContent(stream);
- base64URL = "data:" + mimeType + ";base64," + base64String;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- public void readAsArrayBuffer(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsBinaryString(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- string encStr = optStrings[1];
- int startPos = int.Parse(optStrings[2]);
- int endPos = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- string text = "";
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- readResourceAsText(options);
- return;
- }
- Encoding encoding = Encoding.GetEncoding(encStr);
-
- using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
- {
- text = reader.ReadToEnd();
- if (startPos < 0)
- {
- startPos = Math.Max(text.Length + startPos, 0);
- }
- else if (startPos > 0)
- {
- startPos = Math.Min(text.Length, startPos);
- }
-
- if (endPos > 0)
- {
- endPos = Math.Min(text.Length, endPos);
- }
- else if (endPos < 0)
- {
- endPos = Math.Max(endPos + text.Length, 0);
- }
-
-
- text = text.Substring(startPos, endPos - startPos);
-
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Reads application resource as a text
- /// </summary>
- /// <param name="options">Path to a resource</param>
- public void readResourceAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string pathToResource = optStrings[0];
- string encStr = optStrings[1];
- int start = int.Parse(optStrings[2]);
- int endMarker = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- if (pathToResource.StartsWith("/"))
- {
- pathToResource = pathToResource.Remove(0, 1);
- }
-
- var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
-
- if (resource == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string text;
- StreamReader streamReader = new StreamReader(resource.Stream);
- text = streamReader.ReadToEnd();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- public void truncate(string options)
- {
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- int size = int.Parse(optStrings[1]);
- string callbackId = optStrings[2];
-
- try
- {
- long streamLength = 0;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= size && size <= stream.Length)
- {
- stream.SetLength(size);
- }
- streamLength = stream.Length;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- //write:["filePath","data","position"],
- public void write(string options)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- string data = optStrings[1];
- int position = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- try
- {
- if (string.IsNullOrEmpty(data))
- {
- Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(filePath))
- {
- var file = isoFile.CreateFile(filePath);
- file.Close();
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= position && position <= stream.Length)
- {
- stream.SetLength(position);
- }
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- writer.Seek(0, SeekOrigin.End);
- writer.Write(data.ToCharArray());
- }
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Look up metadata about this entry.
- /// </summary>
- /// <param name="options">filePath to entry</param>
- public void getMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
- new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
- }
- else if (isoFile.DirectoryExists(filePath))
- {
- string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- }
-
-
- /// <summary>
- /// Returns a File that represents the current state of the file that this FileEntry represents.
- /// </summary>
- /// <param name="filePath">filePath to entry</param>
- /// <returns></returns>
- public void getFileMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- FileMetadata metaData = new FileMetadata(filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- /// <summary>
- /// Look up the parent DirectoryEntry containing this Entry.
- /// If this Entry is the root of IsolatedStorage, its parent is itself.
- /// </summary>
- /// <param name="options"></param>
- public void getParent(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- FileEntry entry;
-
- if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
- {
-
-
- string path = this.GetParentDirectory(filePath);
- entry = FileEntry.GetEntry(path);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
-
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- }
-
- public void remove(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (filePath == "/" || filePath == "" || filePath == @"\")
- {
- throw new Exception("Cannot delete root file system") ;
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- else
- {
- if (isoFile.DirectoryExists(filePath))
- {
- isoFile.DeleteDirectory(filePath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- return;
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void removeRecursively(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- }
- else
- {
- if (removeDirRecursively(filePath, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- }
- }
- }
-
- public void readEntries(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(filePath))
- {
- string path = File.AddSlashToDirectory(filePath);
- List<FileEntry> entries = new List<FileEntry>();
- string[] files = isoFile.GetFileNames(path + "*");
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- foreach (string file in files)
- {
- entries.Add(FileEntry.GetEntry(path + file));
- }
- foreach (string dir in dirs)
- {
- entries.Add(FileEntry.GetEntry(path + dir + "/"));
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void requestFileSystem(string options)
- {
- // TODO: try/catch
- string[] optVals = getOptionStrings(options);
- //FileOptions fileOptions = new FileOptions();
- int fileSystemType = int.Parse(optVals[0]);
- double size = double.Parse(optVals[1]);
- string callbackId = optVals[2];
-
-
- IsolatedStorageFile.GetUserStoreForApplication();
-
- if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
-
- try
- {
- if (size != 0)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- long availableSize = isoFile.AvailableFreeSpace;
- if (size > availableSize)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
- }
- }
-
- if (fileSystemType == PERSISTENT)
- {
- // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
- }
- else if (fileSystemType == TEMPORARY)
- {
- using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
- {
- isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
- }
- }
-
- string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
- }
- else if (fileSystemType == RESOURCE)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
- }
- else if (fileSystemType == APPLICATION)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- public void resolveLocalFileSystemURI(string options)
- {
-
- string[] optVals = getOptionStrings(options);
- string uri = optVals[0].Split('?')[0];
- string callbackId = optVals[1];
-
- if (uri != null)
- {
- // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
- if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
- try
- {
- // fix encoded spaces
- string path = Uri.UnescapeDataString(uri);
-
- FileEntry uriEntry = FileEntry.GetEntry(path);
- if (uriEntry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
- }
-
- public void copyTo(string options)
- {
- TransferTo(options, false);
- }
-
- public void moveTo(string options)
- {
- TransferTo(options, true);
- }
-
- public void getFile(string options)
- {
- GetFileOrDirectory(options, false);
- }
-
- public void getDirectory(string options)
- {
- GetFileOrDirectory(options, true);
- }
-
- #region internal functionality
-
- /// <summary>
- /// Retrieves the parent directory name of the specified path,
- /// </summary>
- /// <param name="path">Path</param>
- /// <returns>Parent directory name</returns>
- private string GetParentDirectory(string path)
- {
- if (String.IsNullOrEmpty(path) || path == "/")
- {
- return "/";
- }
-
- if (path.EndsWith(@"/") || path.EndsWith(@"\"))
- {
- return this.GetParentDirectory(Path.GetDirectoryName(path));
- }
-
- string result = Path.GetDirectoryName(path);
- if (result == null)
- {
- result = "/";
- }
-
- return result;
- }
-
- private bool removeDirRecursively(string fullPath,string callbackId)
- {
- try
- {
- if (fullPath == "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(fullPath))
- {
- string tempPath = File.AddSlashToDirectory(fullPath);
- string[] files = isoFile.GetFileNames(tempPath + "*");
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.DeleteFile(tempPath + file);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- if (!removeDirRecursively(tempPath + dir, callbackId))
- {
- return false;
- }
- }
- }
- isoFile.DeleteDirectory(fullPath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
- }
- return true;
- }
-
- private bool CanonicalCompare(string pathA, string pathB)
- {
- string a = pathA.Replace("//", "/");
- string b = pathB.Replace("//", "/");
-
- return a.Equals(b, StringComparison.OrdinalIgnoreCase);
- }
-
- /*
- * copyTo:["fullPath","parent", "newName"],
- * moveTo:["fullPath","parent", "newName"],
- */
- private void TransferTo(string options, bool move)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
- string fullPath = optStrings[0];
- string parent = optStrings[1];
- string newFileName = optStrings[2];
- string callbackId = optStrings[3];
-
- char[] invalids = Path.GetInvalidPathChars();
-
- if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string parentPath = File.AddSlashToDirectory(parent);
- string currentPath = fullPath;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFileExist = isoFile.FileExists(currentPath);
- bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
- bool isParentExist = isoFile.DirectoryExists(parentPath);
-
- if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string newName;
- string newPath;
- if (isFileExist)
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? Path.GetFileName(currentPath)
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- // sanity check ..
- // cannot copy file onto itself
- if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.DirectoryExists(newPath))
- {
- // there is already a folder with the same name, operation is not allowed
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.FileExists(newPath))
- { // remove destination file if exists, in other case there will be exception
- isoFile.DeleteFile(newPath);
- }
-
- if (move)
- {
- isoFile.MoveFile(currentPath, newPath);
- }
- else
- {
- isoFile.CopyFile(currentPath, newPath, true);
- }
- }
- else
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? currentPath
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- if (move)
- {
- // remove destination directory if exists, in other case there will be exception
- // target directory should be empty
- if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
- {
- isoFile.DeleteDirectory(newPath);
- }
-
- isoFile.MoveDirectory(currentPath, newPath);
- }
- else
- {
- CopyDirectory(currentPath, newPath, isoFile);
- }
- }
- FileEntry entry = FileEntry.GetEntry(newPath);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private bool HandleException(Exception ex, string cbId="")
- {
- bool handled = false;
- string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
- if (ex is SecurityException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
- handled = true;
- }
- else if (ex is FileNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- else if (ex is ArgumentException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- handled = true;
- }
- else if (ex is IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- handled = true;
- }
- else if (ex is DirectoryNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- return handled;
- }
-
- private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
- {
- string path = File.AddSlashToDirectory(sourceDir);
-
- bool bExists = isoFile.DirectoryExists(destDir);
-
- if (!bExists)
- {
- isoFile.CreateDirectory(destDir);
- }
-
- destDir = File.AddSlashToDirectory(destDir);
-
- string[] files = isoFile.GetFileNames(path + "*");
-
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.CopyFile(path + file, destDir + file,true);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- CopyDirectory(path + dir, destDir + dir, isoFile);
- }
- }
- }
-
- private void GetFileOrDirectory(string options, bool getDirectory)
- {
- FileOptions fOptions = new FileOptions();
- string[] args = getOptionStrings(options);
-
- fOptions.FullPath = args[0];
- fOptions.Path = args[1];
-
- string callbackId = args[3];
-
- try
- {
- fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- try
- {
- if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string path;
-
- if (fOptions.Path.Split(':').Length > 2)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFile = isoFile.FileExists(path);
- bool isDirectory = isoFile.DirectoryExists(path);
- bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
- bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
- if (create)
- {
- if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
- return;
- }
-
- // need to make sure the parent exists
- // it is an error to create a directory whose immediate parent does not yet exist
- // see issue: https://issues.apache.org/jira/browse/CB-339
- string[] pathParts = path.Split('/');
- string builtPath = pathParts[0];
- for (int n = 1; n < pathParts.Length - 1; n++)
- {
- builtPath += "/" + pathParts[n];
- if (!isoFile.DirectoryExists(builtPath))
- {
- Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- }
-
- if ((getDirectory) && (!isDirectory))
- {
- isoFile.CreateDirectory(path);
- }
- else
- {
- if ((!getDirectory) && (!isFile))
- {
-
- IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
- fileStream.Close();
- }
- }
- }
- else // (not create)
- {
- if ((!isFile) && (!isDirectory))
- {
- if (path.IndexOf("//www") == 0)
- {
- Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
-
- //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
- //{
- // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
-
- //}
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- return;
- }
- if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
- return;
- }
- }
- FileEntry entry = FileEntry.GetEntry(path);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private static string AddSlashToDirectory(string dirPath)
- {
- if (dirPath.EndsWith("/"))
- {
- return dirPath;
- }
- else
- {
- return dirPath + "/";
- }
- }
-
- /// <summary>
- /// Returns file content in a form of base64 string
- /// </summary>
- /// <param name="stream">File stream</param>
- /// <returns>Base64 representation of the file</returns>
- private string GetFileContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
-
- #endregion
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/FileTransfer.cs b/wp8/template/Plugins/FileTransfer.cs
deleted file mode 100644
index e585895..0000000
--- a/wp8/template/Plugins/FileTransfer.cs
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Net;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Security;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class FileTransfer : BaseCommand
- {
- public class DownloadRequestState
- {
- // This class stores the State of the request.
- public HttpWebRequest request;
- public DownloadOptions options;
-
- public DownloadRequestState()
- {
- request = null;
- options = null;
- }
- }
-
- /// <summary>
- /// Boundary symbol
- /// </summary>
- private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
-
- // Error codes
- public const int FileNotFoundError = 1;
- public const int InvalidUrlError = 2;
- public const int ConnectionError = 3;
-
- /// <summary>
- /// Options for downloading file
- /// </summary>
- [DataContract]
- public class DownloadOptions
- {
- /// <summary>
- /// File path to download to
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address to the file to download
- /// </summary>
- [DataMember(Name = "url", IsRequired = true)]
- public string Url { get; set; }
- }
-
- /// <summary>
- /// Options for uploading file
- /// </summary>
- [DataContract]
- public class UploadOptions
- {
- /// <summary>
- /// File path to upload
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address
- /// </summary>
- [DataMember(Name = "server", IsRequired = true)]
- public string Server { get; set; }
-
- /// <summary>
- /// File key
- /// </summary>
- [DataMember(Name = "fileKey")]
- public string FileKey { get; set; }
-
- /// <summary>
- /// File name on the server
- /// </summary>
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- /// <summary>
- /// File Mime type
- /// </summary>
- [DataMember(Name = "mimeType")]
- public string MimeType { get; set; }
-
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "params")]
- public string Params { get; set; }
-
- /// <summary>
- /// Flag to recognize if we should trust every host (only in debug environments)
- /// </summary>
- [DataMember(Name = "debug")]
- public bool Debug { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public UploadOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.FileKey = "file";
- this.FileName = "image.jpg";
- this.MimeType = "image/jpeg";
- }
-
- }
-
- /// <summary>
- /// Uploading response info
- /// </summary>
- [DataContract]
- public class FileUploadResult
- {
- /// <summary>
- /// Amount of sent bytes
- /// </summary>
- [DataMember(Name = "bytesSent")]
- public long BytesSent { get; set; }
-
- /// <summary>
- /// Server response code
- /// </summary>
- [DataMember(Name = "responseCode")]
- public long ResponseCode { get; set; }
-
- /// <summary>
- /// Server response
- /// </summary>
- [DataMember(Name = "response", EmitDefaultValue = false)]
- public string Response { get; set; }
-
- /// <summary>
- /// Creates FileUploadResult object with response values
- /// </summary>
- /// <param name="bytesSent">Amount of sent bytes</param>
- /// <param name="responseCode">Server response code</param>
- /// <param name="response">Server response</param>
- public FileUploadResult(long bytesSent, long responseCode, string response)
- {
- this.BytesSent = bytesSent;
- this.ResponseCode = responseCode;
- this.Response = response;
- }
- }
-
- /// <summary>
- /// Represents transfer error codes for callback
- /// </summary>
- [DataContract]
- public class FileTransferError
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = true)]
- public int Code { get; set; }
-
- /// <summary>
- /// The source URI
- /// </summary>
- [DataMember(Name = "source", IsRequired = true)]
- public string Source { get; set; }
-
- /// <summary>
- /// The target URI
- /// </summary>
- [DataMember(Name = "target", IsRequired = true)]
- public string Target { get; set; }
-
- /// <summary>
- /// The http status code response from the remote URI
- /// </summary>
- [DataMember(Name = "http_status", IsRequired = true)]
- public int HttpStatus { get; set; }
-
- /// <summary>
- /// Creates FileTransferError object
- /// </summary>
- /// <param name="errorCode">Error code</param>
- public FileTransferError(int errorCode)
- {
- this.Code = errorCode;
- this.Source = null;
- this.Target = null;
- this.HttpStatus = 0;
- }
- public FileTransferError(int errorCode, string source, string target, int status)
- {
- this.Code = errorCode;
- this.Source = source;
- this.Target = target;
- this.HttpStatus = status;
- }
- }
-
- /// <summary>
- /// Upload options
- /// </summary>
- private UploadOptions uploadOptions;
-
- /// <summary>
- /// Bytes sent
- /// </summary>
- private long bytesSent;
-
- /// <summary>
- /// sends a file to a server
- /// </summary>
- /// <param name="options">Upload options</param>
- public void upload(string options)
- {
- Debug.WriteLine("options = " + options);
- options = options.Replace("{}", "null");
-
- try
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Uri serverUri;
- try
- {
- serverUri = new Uri(uploadOptions.Server);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
- return;
- }
- HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
- webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
- webRequest.Method = "POST";
- webRequest.BeginGetRequestStream(WriteCallback, webRequest);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
-
- public void download(string options)
- {
- DownloadOptions downloadOptions = null;
- HttpWebRequest webRequest = null;
-
- try
- {
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-
- downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
- downloadOptions.Url = optionStrings[0];
- downloadOptions.FilePath = optionStrings[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
- return;
- }
-
- if (downloadOptions != null && webRequest != null)
- {
- DownloadRequestState state = new DownloadRequestState();
- state.options = downloadOptions;
- state.request = webRequest;
- webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
- }
-
-
-
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void downloadCallback(IAsyncResult asynchronousResult)
- {
- DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
- HttpWebRequest request = reqState.request;
-
- try
- {
- HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(reqState.options.FilePath))
- {
- var file = isoFile.CreateFile(reqState.options.FilePath);
- file.Close();
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
- {
- long totalBytes = response.ContentLength;
- int bytesRead = 0;
- using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
- {
-
- using (BinaryWriter writer = new BinaryWriter(fileStream))
- {
- int BUFFER_SIZE = 1024;
- byte[] buffer;
-
- while (true)
- {
- buffer = reader.ReadBytes(BUFFER_SIZE);
- // fire a progress event ?
- bytesRead += buffer.Length;
- if (buffer.Length > 0)
- {
- writer.Write(buffer);
- }
- else
- {
- writer.Close();
- reader.Close();
- fileStream.Close();
- break;
- }
- }
- }
-
- }
-
-
- }
- }
- WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
- }
- catch (IsolatedStorageException)
- {
- // Trying to write the file somewhere within the IsoStorage.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (SecurityException)
- {
- // Trying to write the file somewhere not allowed.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (WebException webex)
- {
- // TODO: probably need better work here to properly respond with all http status codes back to JS
- // Right now am jumping through hoops just to detect 404.
- if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
- {
- // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
- // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
- // FACEPALM
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- }
-
-
-
- /// <summary>
- /// Read file from Isolated Storage and sends it to server
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void WriteCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
- {
- string lineStart = "--";
- string lineEnd = Environment.NewLine;
- byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
- string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
-
- if (uploadOptions.Params != null)
- {
-
- string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
-
- foreach (string param in arrParams)
- {
- string[] split = param.Split('=');
- string key = split[0];
- string val = split[1];
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- string formItem = string.Format(formdataTemplate, key, val);
- byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
- requestStream.Write(formItemBytes, 0, formItemBytes.Length);
- }
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(uploadOptions.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
- return;
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
- {
- string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
- string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
- byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- requestStream.Write(headerBytes, 0, headerBytes.Length);
- byte[] buffer = new byte[4096];
- int bytesRead = 0;
-
- while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
- {
- requestStream.Write(buffer, 0, bytesRead);
- bytesSent += bytesRead;
- }
- }
- byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
- requestStream.Write(endRequest, 0, endRequest.Length);
- }
- }
- webRequest.BeginGetResponse(ReadCallback, webRequest);
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- });
- }
- }
-
- /// <summary>
- /// Reads response into FileUploadResult
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void ReadCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
- {
- using (Stream streamResponse = response.GetResponseStream())
- {
- using (StreamReader streamReader = new StreamReader(streamResponse))
- {
- string responseString = streamReader.ReadToEnd();
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
- });
- }
- }
- }
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
- });
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/GeoLocation.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/GeoLocation.cs b/wp8/template/Plugins/GeoLocation.cs
deleted file mode 100644
index c53cb29..0000000
--- a/wp8/template/Plugins/GeoLocation.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Device.Location;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
- /// </summary>
- public class GeoLocation
- {
- /* Unreachable code, by design -jm */
- private void triggerGeoInclusion()
- {
- new GeoCoordinateWatcher();
- }
- }
-}
[18/50] [abbrv] moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/www/css/index.css
----------------------------------------------------------------------
diff --git a/wp7/template/www/css/index.css b/wp7/template/www/css/index.css
deleted file mode 100644
index 1d34d88..0000000
--- a/wp7/template/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-* {
- -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
- -webkit-text-size-adjust: none; /* prevent WebKit from resizing text to fit */
- -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
- -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
-}
-
-body {
- background-color:#E4E4E4;
- background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-webkit-gradient(
- linear,
- left top,
- left bottom,
- color-stop(0, #A7A7A7),
- color-stop(0.51, #E4E4E4)
- );
- background-attachment:fixed;
- font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
- font-size:12px;
- height:100%;
- margin:0px;
- padding:0px;
- text-transform:uppercase;
- width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
- background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
- position:absolute; /* position in the center of the screen */
- left:50%;
- top:50%;
- height:50px; /* text area height */
- width:225px; /* text area width */
- text-align:center;
- padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
- margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
- /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
- .app {
- background-position:left center;
- padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
- margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
- /* offset horizontal: half of image width and text area width */
- }
-}
-
-h1 {
- font-size:24px;
- font-weight:normal;
- margin:0px;
- overflow:visible;
- padding:0px;
- text-align:center;
-}
-
-.event {
- border-radius:4px;
- -webkit-border-radius:4px;
- color:#FFFFFF;
- font-size:12px;
- margin:0px 30px;
- padding:2px 0px;
-}
-
-.event.listening {
- background-color:#333333;
- display:block;
-}
-
-.event.received {
- background-color:#4B946A;
- display:none;
-}
-
-@keyframes fade {
- from { opacity: 1.0; }
- 50% { opacity: 0.4; }
- to { opacity: 1.0; }
-}
-
-@-webkit-keyframes fade {
- from { opacity: 1.0; }
- 50% { opacity: 0.4; }
- to { opacity: 1.0; }
-}
-
-.blink {
- animation:fade 3000ms infinite;
- -webkit-animation:fade 3000ms infinite;
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/www/img/logo.png
----------------------------------------------------------------------
diff --git a/wp7/template/www/img/logo.png b/wp7/template/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/wp7/template/www/img/logo.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/www/index.html
----------------------------------------------------------------------
diff --git a/wp7/template/www/index.html b/wp7/template/www/index.html
deleted file mode 100644
index 842b364..0000000
--- a/wp7/template/www/index.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<!--
- 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.
--->
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="format-detection" content="telephone=no" />
- <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
- <link rel="stylesheet" type="text/css" href="css/index.css" />
- <title>Hello World</title>
- </head>
- <body>
- <div class="app">
- <h1>Apache Cordova</h1>
- <div id="deviceready" class="blink">
- <p class="event listening">Connecting to Device</p>
- <p class="event received">Device is Ready</p>
- </div>
- </div>
- <script type="text/javascript" src="cordova.js"></script>
- <script type="text/javascript" src="js/index.js"></script>
- <script type="text/javascript">
- app.initialize();
- </script>
- </body>
-</html>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/www/js/index.js
----------------------------------------------------------------------
diff --git a/wp7/template/www/js/index.js b/wp7/template/www/js/index.js
deleted file mode 100644
index bf02e98..0000000
--- a/wp7/template/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 app = {
- // Application Constructor
- initialize: function() {
- this.bindEvents();
- },
- // Bind Event Listeners
- //
- // Bind any events that are required on startup. Common events are:
- // `load`, `deviceready`, `offline`, and `online`.
- bindEvents: function() {
- document.addEventListener('deviceready', this.onDeviceReady, false);
- },
- // deviceready Event Handler
- //
- // The scope of `this` is the event. In order to call the `receivedEvent`
- // function, we must explicitly call `app.receivedEvent(...);`
- onDeviceReady: function() {
- app.receivedEvent('deviceready');
- },
- // Update DOM on a Received Event
- receivedEvent: function(id) {
- var parentElement = document.getElementById(id);
- var listeningElement = parentElement.querySelector('.listening');
- var receivedElement = parentElement.querySelector('.received');
-
- listeningElement.setAttribute('style', 'display:none;');
- receivedElement.setAttribute('style', 'display:block;');
-
- console.log('Received Event: ' + id);
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp7/tooling/scripts/createTemplates.js b/wp7/tooling/scripts/createTemplates.js
index b8755cc..b24a94b 100644
--- a/wp7/tooling/scripts/createTemplates.js
+++ b/wp7/tooling/scripts/createTemplates.js
@@ -147,10 +147,44 @@ function copyFile(src,dest) {
exec('%comspec% /c copy /Y ' + src + ' ' + dest);
}
+function copyCommonItemsToTemplate() {
+ var srcPath = repoRoot + '\\common-items';
+ var destPath = platformRoot + templatePath;
+
+ var folder = fso.GetFolder(srcPath);
+ // iterate over the files in the folder
+ for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
+ //Log("File: " + srcPath + "\\" + files.item().name);
+ copyFile(srcPath + "\\" + files.item().name, destPath + "\\" + files.item().name);
+ }
+ // iterate over the child folders in the folder
+ for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
+ Log("Folder: " + srcPath + "\\" + subFlds.item().name);
+ exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " "
+ + destPath + "\\" + subFlds.item().name);
+ }
+}
+
+// delete desination items
+function removeCommonItems() {
+ var srcPath = repoRoot + '\\common-items';
+ var destPath = platformRoot + templatePath;
+ var folder = fso.GetFolder(srcPath);
+ // iterate over the files in the folder
+ for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
+ deleteFileIfExists(destPath + "\\" + files.item().name);
+ }
+ // iterate over the child folders in the folder
+ for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
+ deleteFolderIfExists(destPath + "\\" + subFlds.item().name);
+ }
+}
+
// packages templates into .zip
function package_templates()
{
+
Log("Creating template .zip files ...");
var templateOutFilename = repoRoot + '\\CordovaWP7_' + versionNum.replace(/\./g, '_') + '.zip';
@@ -165,6 +199,9 @@ function package_templates()
deleteFileIfExists(platformRoot + templatePath + "\\CordovaWP7Solution.v11.suo");
exec('%comspec% /c xcopy /Y /E /I ' + repoRoot + '\\Plugins ' + platformRoot + templatePath + '\\Plugins');
+
+ copyCommonItemsToTemplate();
+
copyFile(repoRoot + '\\VERSION',platformRoot + templatePath);
// update .vstemplate files for the template zips.
@@ -174,7 +211,6 @@ function package_templates()
replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', name_regex, 'CordovaWP7_' + versionNum.replace(/\./g, '_'));
replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', discript_regex, "Cordova " + versionNum);
-
zip_project(templateOutFilename, platformRoot + templatePath);
if(addToVS)
@@ -194,6 +230,7 @@ function package_templates()
}
function zip_project(zip_path, project_path) {
+
// create empty ZIP file and open for adding
var file = fso.CreateTextFile(zip_path, true);
@@ -235,10 +272,13 @@ function zip_project(zip_path, project_path) {
// delete any unneeded files when finished
function cleanUp() {
-
+ removeCommonItems();
+ deleteFileIfExists(platformRoot + templatePath + "\\VERSION");
+ deleteFolderIfExists(platformRoot + templatePath + '\\Plugins');
}
function parseArgs() {
+
if(args.Count() > 0) {
//Support help flags -help, --help, /?
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/ApplicationIcon.png
----------------------------------------------------------------------
diff --git a/wp8/template/ApplicationIcon.png b/wp8/template/ApplicationIcon.png
deleted file mode 100644
index 6b69046..0000000
Binary files a/wp8/template/ApplicationIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Background.png
----------------------------------------------------------------------
diff --git a/wp8/template/Background.png b/wp8/template/Background.png
deleted file mode 100644
index 2667df4..0000000
Binary files a/wp8/template/Background.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Images/appbar.back.rest.png
----------------------------------------------------------------------
diff --git a/wp8/template/Images/appbar.back.rest.png b/wp8/template/Images/appbar.back.rest.png
deleted file mode 100644
index 4bc2b92..0000000
Binary files a/wp8/template/Images/appbar.back.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Images/appbar.close.rest.png
----------------------------------------------------------------------
diff --git a/wp8/template/Images/appbar.close.rest.png b/wp8/template/Images/appbar.close.rest.png
deleted file mode 100644
index 8166a1c..0000000
Binary files a/wp8/template/Images/appbar.close.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Images/appbar.feature.video.rest.png
----------------------------------------------------------------------
diff --git a/wp8/template/Images/appbar.feature.video.rest.png b/wp8/template/Images/appbar.feature.video.rest.png
deleted file mode 100644
index baff565..0000000
Binary files a/wp8/template/Images/appbar.feature.video.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Images/appbar.next.rest.png
----------------------------------------------------------------------
diff --git a/wp8/template/Images/appbar.next.rest.png b/wp8/template/Images/appbar.next.rest.png
deleted file mode 100644
index ed577d7..0000000
Binary files a/wp8/template/Images/appbar.next.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Images/appbar.save.rest.png
----------------------------------------------------------------------
diff --git a/wp8/template/Images/appbar.save.rest.png b/wp8/template/Images/appbar.save.rest.png
deleted file mode 100644
index d49940e..0000000
Binary files a/wp8/template/Images/appbar.save.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/Images/appbar.stop.rest.png
----------------------------------------------------------------------
diff --git a/wp8/template/Images/appbar.stop.rest.png b/wp8/template/Images/appbar.stop.rest.png
deleted file mode 100644
index 4dd724f..0000000
Binary files a/wp8/template/Images/appbar.stop.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/SplashScreenImage.jpg
----------------------------------------------------------------------
diff --git a/wp8/template/SplashScreenImage.jpg b/wp8/template/SplashScreenImage.jpg
deleted file mode 100644
index d35501d..0000000
Binary files a/wp8/template/SplashScreenImage.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/__PreviewImage.jpg
----------------------------------------------------------------------
diff --git a/wp8/template/__PreviewImage.jpg b/wp8/template/__PreviewImage.jpg
deleted file mode 100644
index 1d72941..0000000
Binary files a/wp8/template/__PreviewImage.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/__TemplateIcon.png
----------------------------------------------------------------------
diff --git a/wp8/template/__TemplateIcon.png b/wp8/template/__TemplateIcon.png
deleted file mode 100644
index 75c17c7..0000000
Binary files a/wp8/template/__TemplateIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/resources/notification-beep.wav
----------------------------------------------------------------------
diff --git a/wp8/template/resources/notification-beep.wav b/wp8/template/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
Binary files a/wp8/template/resources/notification-beep.wav and /dev/null differ
[04/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/MimeTypeMapper.cs b/wp8/template/Plugins/MimeTypeMapper.cs
deleted file mode 100644
index a2794f5..0000000
--- a/wp8/template/Plugins/MimeTypeMapper.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- 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.
-*/
-
-using System.Collections.Generic;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Represents file extension to mime type mapper.
- /// </summary>
- public static class MimeTypeMapper
- {
- /// <summary>
- /// For unknown type it is recommended to use 'application/octet-stream'
- /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
- /// </summary>
- private static string DefaultMimeType = "application/octet-stream";
-
- /// <summary>
- /// Stores mime type for all necessary extension
- /// </summary>
- private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
- {
- {"avi", "video/x-msvideo"},
- {"bmp", "image/bmp"},
- {"gif", "image/gif"},
- {"html","text/html"},
- {"jpe", "image/jpeg"},
- {"jpeg", "image/jpeg"},
- {"jpg", "image/jpeg"},
- {"js","text/javascript"},
- {"mov", "video/quicktime"},
- {"mp2", "audio/mpeg"},
- {"mp3", "audio/mpeg"},
- {"mp4", "video/mp4"},
- {"mpe", "video/mpeg"},
- {"mpeg", "video/mpeg"},
- {"mpg", "video/mpeg"},
- {"mpga", "audio/mpeg"},
- {"pbm", "image/x-portable-bitmap"},
- {"pcm", "audio/x-pcm"},
- {"pct", "image/pict"},
- {"pgm", "image/x-portable-graymap"},
- {"pic", "image/pict"},
- {"pict", "image/pict"},
- {"png", "image/png"},
- {"pnm", "image/x-portable-anymap"},
- {"pnt", "image/x-macpaint"},
- {"pntg", "image/x-macpaint"},
- {"ppm", "image/x-portable-pixmap"},
- {"qt", "video/quicktime"},
- {"ra", "audio/x-pn-realaudio"},
- {"ram", "audio/x-pn-realaudio"},
- {"ras", "image/x-cmu-raster"},
- {"rgb", "image/x-rgb"},
- {"snd", "audio/basic"},
- {"txt", "text/plain"},
- {"tif", "image/tiff"},
- {"tiff", "image/tiff"},
- {"wav", "audio/x-wav"},
- {"wbmp", "image/vnd.wap.wbmp"},
-
- };
- /// <summary>
- /// Gets mime type by file extension
- /// </summary>
- /// <param name="fileName">file name to extract extension</param>
- /// <returns>mime type</returns>
- public static string GetMimeType(string fileName)
- {
- string ext = Path.GetExtension(fileName);
-
- // invalid extension
- if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
- {
- return DefaultMimeType;
- }
-
- ext = ext.Remove(0, 1);
-
- if (MIMETypesDictionary.ContainsKey(ext))
- {
- return MIMETypesDictionary[ext];
- }
-
- return DefaultMimeType;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/NetworkStatus.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/NetworkStatus.cs b/wp8/template/Plugins/NetworkStatus.cs
deleted file mode 100644
index 12eb061..0000000
--- a/wp8/template/Plugins/NetworkStatus.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Net.NetworkInformation;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
-
- public class NetworkStatus : BaseCommand
- {
- const string UNKNOWN = "unknown";
- const string ETHERNET = "ethernet";
- const string WIFI = "wifi";
- const string CELL_2G = "2g";
- const string CELL_3G = "3g";
- const string CELL_4G = "4g";
- const string NONE = "none";
- const string CELL = "cellular";
-
- private bool HasCallback = false;
-
- public NetworkStatus()
- {
- DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
- }
-
- public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
- {
- this.getConnectionInfo("");
- }
-
- public void getConnectionInfo(string empty)
- {
- HasCallback = true;
- updateConnectionType(checkConnectionType());
- }
-
- private string checkConnectionType()
- {
- if (DeviceNetworkInformation.IsNetworkAvailable)
- {
- if (DeviceNetworkInformation.IsWiFiEnabled)
- {
- return WIFI;
- }
- else
- {
- return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
- }
- }
- return NONE;
- }
-
- private string checkConnectionType(NetworkInterfaceSubType type)
- {
- switch (type)
- {
- case NetworkInterfaceSubType.Cellular_1XRTT: //cell
- case NetworkInterfaceSubType.Cellular_GPRS: //cell
- return CELL;
- case NetworkInterfaceSubType.Cellular_EDGE: //2
- return CELL_2G;
- case NetworkInterfaceSubType.Cellular_3G:
- case NetworkInterfaceSubType.Cellular_EVDO: //3
- case NetworkInterfaceSubType.Cellular_EVDV: //3
- case NetworkInterfaceSubType.Cellular_HSPA: //3
- return CELL_3G;
- case NetworkInterfaceSubType.WiFi:
- return WIFI;
- case NetworkInterfaceSubType.Unknown:
- case NetworkInterfaceSubType.Desktop_PassThru:
- default:
- return UNKNOWN;
- }
- }
-
- void ChangeDetected(object sender, NetworkNotificationEventArgs e)
- {
- switch (e.NotificationType)
- {
- case NetworkNotificationType.InterfaceConnected:
- updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
- break;
- case NetworkNotificationType.InterfaceDisconnected:
- updateConnectionType(NONE);
- break;
- default:
- break;
- }
- }
-
- private void updateConnectionType(string type)
- {
- // This should also implicitly fire offline/online events as that is handled on the JS side
- if (this.HasCallback)
- {
- PluginResult result = new PluginResult(PluginResult.Status.OK, type);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Notification.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Notification.cs b/wp8/template/Plugins/Notification.cs
deleted file mode 100644
index 0759c72..0000000
--- a/wp8/template/Plugins/Notification.cs
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Devices;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Windows.Resources;
-using Microsoft.Phone.Controls;
-using Microsoft.Xna.Framework.Audio;
-using WPCordovaClassLib.Cordova.UI;
-using System.Diagnostics;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Notification : BaseCommand
- {
- static ProgressBar progressBar = null;
- const int DEFAULT_DURATION = 5;
-
- private NotificationBox notifyBox;
-
- private PhoneApplicationPage Page
- {
- get
- {
- PhoneApplicationPage page = null;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- page = frame.Content as PhoneApplicationPage;
- }
- return page;
- }
- }
-
- // blink api - doesn't look like there is an equivalent api we can use...
-
- [DataContract]
- public class AlertOptions
- {
- [OnDeserializing]
- public void OnDeserializing(StreamingContext context)
- {
- // set defaults
- this.message = "message";
- this.title = "Alert";
- this.buttonLabel = "ok";
- }
-
- /// <summary>
- /// message to display in the alert box
- /// </summary>
- [DataMember]
- public string message;
-
- /// <summary>
- /// title displayed on the alert window
- /// </summary>
- [DataMember]
- public string title;
-
- /// <summary>
- /// text to display on the button
- /// </summary>
- [DataMember]
- public string buttonLabel;
- }
-
- public void alert(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
- Button btnOK = new Button();
- btnOK.Content = alertOpts.buttonLabel;
- btnOK.Click += new RoutedEventHandler(btnOK_Click);
- btnOK.Tag = 1;
- notifyBox.ButtonPanel.Children.Add(btnOK);
- grid.Children.Add(notifyBox);
-
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- public void confirm(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
-
- string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
-
- if (labels == null)
- {
- labels = alertOpts.buttonLabel.Split(',');
- }
-
- for (int n = 0; n < labels.Length; n++)
- {
- Button btn = new Button();
- btn.Content = labels[n];
- btn.Tag = n;
- btn.Click += new RoutedEventHandler(btnOK_Click);
- notifyBox.ButtonPanel.Children.Add(btn);
- }
-
- grid.Children.Add(notifyBox);
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
- {
- PhoneApplicationPage page = sender as PhoneApplicationPage;
- string callbackId = "";
- if (page != null && notifyBox != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifyBox);
- dynamic notifBoxData = notifyBox.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
- }
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- e.Cancel = true;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
- }
-
- void btnOK_Click(object sender, RoutedEventArgs e)
- {
- Button btn = sender as Button;
- FrameworkElement notifBoxParent = null;
- int retVal = 0;
- string callbackId = "";
- if (btn != null)
- {
- retVal = (int)btn.Tag + 1;
-
- notifBoxParent = btn.Parent as FrameworkElement;
- while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
- !(notifBoxParent is NotificationBox)) ;
- }
- if (notifBoxParent != null)
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifBoxParent);
- }
-
- dynamic notifBoxData = notifBoxParent.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
-
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- }
-
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
- }
-
-
-
- public void beep(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- int times = int.Parse(args[0]);
-
- string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
-
- StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
-
- if (sri != null)
- {
- SoundEffect effect = SoundEffect.FromStream(sri.Stream);
- SoundEffectInstance inst = effect.CreateInstance();
- ThreadPool.QueueUserWorkItem((o) =>
- {
- // cannot interact with UI !!
- do
- {
- inst.Play();
- Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
- }
- while (--times > 0);
-
- });
-
- }
-
- // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
- DispatchCommandResult();
- }
-
- // Display an indeterminate progress indicator
- public void activityStart(string unused)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- if (page != null)
- {
- var temp = page.FindName("LayoutRoot");
- Grid grid = temp as Grid;
- if (grid != null)
- {
- if (progressBar != null)
- {
- grid.Children.Remove(progressBar);
- }
- progressBar = new ProgressBar();
- progressBar.IsIndeterminate = true;
- progressBar.IsEnabled = true;
-
- grid.Children.Add(progressBar);
- }
- }
- }
- });
- }
-
-
- // Remove our indeterminate progress indicator
- public void activityStop(string unused)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (progressBar != null)
- {
- progressBar.IsEnabled = false;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(progressBar);
- }
- }
- }
- progressBar = null;
- }
- });
- }
-
- public void vibrate(string vibrateDuration)
- {
-
- int msecs = 200; // set default
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
-
- msecs = int.Parse(args[0]);
- if (msecs < 1)
- {
- msecs = 1;
- }
- }
- catch (FormatException)
- {
-
- }
-
- VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
-
- // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
- DispatchCommandResult();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/AudioCaptureTask.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/AudioCaptureTask.cs b/wp8/template/Plugins/UI/AudioCaptureTask.cs
deleted file mode 100644
index 3d7d60f..0000000
--- a/wp8/template/Plugins/UI/AudioCaptureTask.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Audio Recording application.
- /// Use this to allow users to record audio from your application.
- /// </summary>
- public class AudioCaptureTask
- {
- /// <summary>
- /// Represents recorded audio returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
- /// </summary>
- public class AudioResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the AudioResult class.
- /// </summary>
- public AudioResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the AudioResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public AudioResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded audio.
- /// </summary>
- public Stream AudioFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded audio.
- /// </summary>
- public string AudioFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is AudioRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- AudioRecorder audioRecorder = (AudioRecorder)e.Content;
-
- if (audioRecorder != null)
- {
- audioRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new AudioResult(TaskResult.Cancel));
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/AudioRecorder.xaml
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/AudioRecorder.xaml b/wp8/template/Plugins/UI/AudioRecorder.xaml
deleted file mode 100644
index 0fd26ab..0000000
--- a/wp8/template/Plugins/UI/AudioRecorder.xaml
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Portrait" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Transparent">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
- <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
- </StackPanel>
-
- <!--ContentPanel - place additional content here-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0" VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
- <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
- <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
- </Grid>
- </Grid>
-
- <!--Sample code showing usage of ApplicationBar-->
- <!--<phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
- <shell:ApplicationBar.MenuItems>
- <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
- <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
- </shell:ApplicationBar.MenuItems>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>-->
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/AudioRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/AudioRecorder.xaml.cs b/wp8/template/Plugins/UI/AudioRecorder.xaml.cs
deleted file mode 100644
index 01a0832..0000000
--- a/wp8/template/Plugins/UI/AudioRecorder.xaml.cs
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Threading;
-using WPCordovaClassLib.Cordova.Commands;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Implements Audio Recording application
- /// </summary>
- public partial class AudioRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- private const string RecordingStartCaption = "Start";
- private const string RecordingStopCaption = "Stop";
-
- private const string LocalFolderName = "AudioCache";
- private const string FileNameFormat = "Audio-{0}.wav";
-
- #endregion
-
- #region Callbacks
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone microphone;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Recording duration
- /// </summary>
- private TimeSpan duration;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private AudioResult result = new AudioResult(TaskResult.Cancel);
-
- /// <summary>
- /// Whether we are recording audio now
- /// </summary>
- private bool IsRecording
- {
- get
- {
- return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
- }
- }
-
- #endregion
-
- /// <summary>
- /// Creates new instance of the AudioRecorder class.
- /// </summary>
- public AudioRecorder()
- {
-
- this.InitializeXnaGameLoop();
-
- // microphone requires special XNA initialization to work
- InitializeComponent();
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- private void StartRecording()
- {
- this.microphone = Microphone.Default;
- this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
-
- this.btnTake.IsEnabled = false;
- this.btnStartStop.Content = RecordingStopCaption;
-
- this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
- this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
-
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.microphone.SampleRate);
-
- this.duration = new TimeSpan(0);
-
- this.microphone.Start();
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- private void StopRecording()
- {
- this.microphone.Stop();
-
- this.microphone.BufferReady -= MicrophoneBufferReady;
-
- this.microphone = null;
-
- btnStartStop.Content = RecordingStartCaption;
-
- // check there is some data
- this.btnTake.IsEnabled = true;
- }
-
- /// <summary>
- /// Handles Start/Stop events
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStartStop_Click(object sender, RoutedEventArgs e)
- {
-
- if (this.IsRecording)
- {
- this.StopRecording();
- }
- else
- {
- this.StartRecording();
- }
- }
-
- /// <summary>
- /// Handles Take button click
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnTake_Click(object sender, RoutedEventArgs e)
- {
- this.result = this.SaveAudioClipToLocalStorage();
-
- if (Completed != null)
- {
- Completed(this, result);
- }
-
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Handles page closing event, stops recording if needed and dispatches results.
- /// </summary>
- /// <param name="e"></param>
- protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
- {
- if (IsRecording)
- {
- StopRecording();
- }
-
- this.FinalizeXnaGameLoop();
-
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Copies data from microphone to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void MicrophoneBufferReady(object sender, EventArgs e)
- {
- this.microphone.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- TimeSpan bufferDuration = this.microphone.BufferDuration;
-
- this.Dispatcher.BeginInvoke(() =>
- {
- this.duration += bufferDuration;
-
- this.txtDuration.Text = "Duration: " +
- this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
- this.duration.Seconds.ToString().PadLeft(2, '0');
- });
-
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private AudioResult SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return new AudioResult(TaskResult.Cancel);
- }
-
- this.memoryStream.UpdateWavStream();
-
- // save audio data to local isolated storage
-
- string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
-
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
- {
-
- this.memoryStream.CopyTo(fileStream);
- }
-
- AudioResult result = new AudioResult(TaskResult.OK);
- result.AudioFileName = filePath;
-
- result.AudioFile = this.memoryStream;
- result.AudioFile.Seek(0, SeekOrigin.Begin);
-
- return result;
- }
-
-
-
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (dtXna != null)
- {
- dtXna.Stop();
- dtXna = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/ImageCapture.xaml
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/ImageCapture.xaml b/wp8/template/Plugins/UI/ImageCapture.xaml
deleted file mode 100644
index a7eee21..0000000
--- a/wp8/template/Plugins/UI/ImageCapture.xaml
+++ /dev/null
@@ -1,26 +0,0 @@
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Yellow">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- </Grid>
-
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/ImageCapture.xaml.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/ImageCapture.xaml.cs b/wp8/template/Plugins/UI/ImageCapture.xaml.cs
deleted file mode 100644
index 234b444..0000000
--- a/wp8/template/Plugins/UI/ImageCapture.xaml.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class ImageCapture : PhoneApplicationPage
- {
- public ImageCapture()
- {
- InitializeComponent();
- }
- }
-
- public class ImageCaptureTask
- {
- /// <summary>
- /// Represents an image returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
- /// </summary>
- //public class AudioResult : TaskEventArgs
- //{
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class.
- // /// </summary>
- // public AudioResult()
- // { }
-
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class
- // /// with the specified Microsoft.Phone.Tasks.TaskResult.
- // /// </summary>
- // /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- // public AudioResult(TaskResult taskResult)
- // : base(taskResult)
- // { }
-
- // /// <summary>
- // /// Gets the file name of the recorded audio.
- // /// </summary>
- // public Stream AudioFile { get; internal set; }
-
- // /// <summary>
- // /// Gets the stream containing the data for the recorded audio.
- // /// </summary>
- // public string AudioFileName { get; internal set; }
- //}
-
- ///// <summary>
- ///// Occurs when a audio recording task is completed.
- ///// </summary>
- //public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- ImageCapture imageCapture = e.Content as ImageCapture;
- if (imageCapture != null)
- {
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- //imageCapture.Completed += this.Completed;
- //else if (this.Completed != null)
- //{
- // this.Completed(this, new AudioResult(TaskResult.Cancel));
- //}
- }
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/NotificationBox.xaml
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/NotificationBox.xaml b/wp8/template/Plugins/UI/NotificationBox.xaml
deleted file mode 100644
index 1ca5d5f..0000000
--- a/wp8/template/Plugins/UI/NotificationBox.xaml
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
- 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.
--->
-<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
-
- <Grid x:Name="LayoutRoot"
- Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
-
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel"
- Grid.Row="0"
- Background="{StaticResource PhoneSemitransparentBrush}">
- <TextBlock x:Name="PageTitle"
- Text="Title"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle2Style}"/>
-
- <TextBlock x:Name="SubTitle"
- Text="Subtitle"
- TextWrapping="Wrap"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle3Style}"/>
-
- <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
- <StackPanel x:Name="ButtonPanel"
- Margin="10,10"
- Orientation="Horizontal"/>
- </ScrollViewer>
-
- </StackPanel>
- </Grid>
-</UserControl>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/NotificationBox.xaml.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/NotificationBox.xaml.cs b/wp8/template/Plugins/UI/NotificationBox.xaml.cs
deleted file mode 100644
index 50b2f2a..0000000
--- a/wp8/template/Plugins/UI/NotificationBox.xaml.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class NotificationBox : UserControl
- {
- public NotificationBox()
- {
- InitializeComponent();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/VideoCaptureTask.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/VideoCaptureTask.cs b/wp8/template/Plugins/UI/VideoCaptureTask.cs
deleted file mode 100644
index 958c05c..0000000
--- a/wp8/template/Plugins/UI/VideoCaptureTask.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Video Recording application.
- /// Use this to allow users to record video from your application.
- /// </summary>
- public class VideoCaptureTask
- {
- /// <summary>
- /// Represents recorded video returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
- /// </summary>
- public class VideoResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the VideoResult class.
- /// </summary>
- public VideoResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the VideoResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public VideoResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded Video.
- /// </summary>
- public Stream VideoFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded Video.
- /// </summary>
- public string VideoFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a Video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- /// <summary>
- /// Shows Video Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is VideoRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
-
- if (VideoRecorder != null)
- {
- VideoRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new VideoResult(TaskResult.Cancel));
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/VideoRecorder.xaml
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/VideoRecorder.xaml b/wp8/template/Plugins/UI/VideoRecorder.xaml
deleted file mode 100644
index c78fdb0..0000000
--- a/wp8/template/Plugins/UI/VideoRecorder.xaml
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Landscape" Orientation="LandscapeLeft"
- shell:SystemTray.IsVisible="False">
-
- <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
-
- <Rectangle
- x:Name="viewfinderRectangle"
- Width="640"
- Height="480"
- HorizontalAlignment="Left"
- Canvas.Left="80"/>
-
- </Canvas>
-
- <phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record" x:Name="btnStartRecording" Click="StartRecording_Click" />
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/UI/VideoRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/UI/VideoRecorder.xaml.cs b/wp8/template/Plugins/UI/VideoRecorder.xaml.cs
deleted file mode 100644
index 6ab1cc3..0000000
--- a/wp8/template/Plugins/UI/VideoRecorder.xaml.cs
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media;
-using System.Windows.Navigation;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class VideoRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- /// <summary>
- /// Caption for record button in ready state
- /// </summary>
- private const string RecordingStartCaption = "Record";
-
- /// <summary>
- /// Caption for record button in recording state
- /// </summary>
- private const string RecordingStopCaption = "Stop";
-
- /// <summary>
- /// Start record icon URI
- /// </summary>
- private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
-
- /// <summary>
- /// Stop record icon URI
- /// </summary>
- private const string StopIconUri = "/Images/appbar.stop.rest.png";
-
- /// <summary>
- /// Folder to save video clips
- /// </summary>
- private const string LocalFolderName = "VideoCache";
-
- /// <summary>
- /// File name format
- /// </summary>
- private const string FileNameFormat = "Video-{0}.mp4";
-
- /// <summary>
- /// Temporary file name
- /// </summary>
- private const string defaultFileName = "NewVideoFile.mp4";
-
- #endregion
-
- #region Callbacks
- /// <summary>
- /// Occurs when a video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Viewfinder for capturing video
- /// </summary>
- private VideoBrush videoRecorderBrush;
-
- /// <summary>
- /// Path to save video clip
- /// </summary>
- private string filePath;
-
- /// <summary>
- /// Source for capturing video.
- /// </summary>
- private CaptureSource captureSource;
-
- /// <summary>
- /// Video device
- /// </summary>
- private VideoCaptureDevice videoCaptureDevice;
-
- /// <summary>
- /// File sink so save recording video in Isolated Storage
- /// </summary>
- private FileSink fileSink;
-
- /// <summary>
- /// For managing button and application state
- /// </summary>
- private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
-
- /// <summary>
- /// Current video state
- /// </summary>
- private VideoState currentVideoState;
-
- /// <summary>
- /// Stream to return result
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private VideoResult result = new VideoResult(TaskResult.Cancel);
-
- #endregion
-
- /// <summary>
- /// Initializes components
- /// </summary>
- public VideoRecorder()
- {
- InitializeComponent();
-
- PhoneAppBar = (ApplicationBar)ApplicationBar;
- PhoneAppBar.IsVisible = true;
- btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
- btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
- }
-
- /// <summary>
- /// Initializes the video recorder then page is loading
- /// </summary>
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- this.InitializeVideoRecorder();
- }
-
- /// <summary>
- /// Disposes camera and media objects then leave the page
- /// </summary>
- protected override void OnNavigatedFrom(NavigationEventArgs e)
- {
- this.DisposeVideoRecorder();
-
- if (this.Completed != null)
- {
- this.Completed(this, result);
- }
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Handles TakeVideo button click
- /// </summary>
- private void TakeVideo_Click(object sender, EventArgs e)
- {
- this.result = this.SaveVideoClip();
- this.NavigateBack();
- }
-
- private void NavigateBack()
- {
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Resaves video clip from temporary directory to persistent
- /// </summary>
- private VideoResult SaveVideoClip()
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
- {
- return new VideoResult(TaskResult.Cancel);
- }
-
- string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
- string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
- isoFile.CopyFile(filePath, newPath);
- isoFile.DeleteFile(filePath);
-
- memoryStream = new MemoryStream();
- using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
- {
- fileStream.CopyTo(memoryStream);
- }
-
- VideoResult result = new VideoResult(TaskResult.OK);
- result.VideoFileName = newPath;
- result.VideoFile = this.memoryStream;
- result.VideoFile.Seek(0, SeekOrigin.Begin);
- return result;
- }
-
- }
- catch (Exception)
- {
- return new VideoResult(TaskResult.None);
- }
- }
-
- /// <summary>
- /// Updates the buttons on the UI thread based on current state.
- /// </summary>
- /// <param name="currentState">current UI state</param>
- private void UpdateUI(VideoState currentState)
- {
- Dispatcher.BeginInvoke(delegate
- {
- switch (currentState)
- {
- case VideoState.CameraNotSupported:
- btnStartRecording.IsEnabled = false;
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Initialized:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Ready:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = true;
- break;
-
- case VideoState.Recording:
- btnStartRecording.Text = RecordingStopCaption;
- btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- default:
- break;
- }
- currentVideoState = currentState;
- });
- }
-
- /// <summary>
- /// Initializes VideoRecorder
- /// </summary>
- public void InitializeVideoRecorder()
- {
- if (captureSource == null)
- {
- captureSource = new CaptureSource();
- fileSink = new FileSink();
- videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
-
- if (videoCaptureDevice != null)
- {
- videoRecorderBrush = new VideoBrush();
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Initialized);
- }
- else
- {
- this.UpdateUI(VideoState.CameraNotSupported);
- }
- }
- }
-
- /// <summary>
- /// Sets recording state: start recording
- /// </summary>
- private void StartVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = captureSource;
- filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- }
-
- fileSink.IsolatedStorageFileName = filePath;
- }
-
- if (captureSource.VideoCaptureDevice != null
- && captureSource.State == CaptureState.Stopped)
- {
- captureSource.Start();
- }
- this.UpdateUI(VideoState.Recording);
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: stop recording
- /// </summary>
- private void StopVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = null;
- fileSink.IsolatedStorageFileName = null;
- this.StartVideoPreview();
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: display the video on the viewfinder.
- /// </summary>
- private void StartVideoPreview()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
- {
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Ready);
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Starts video recording
- /// </summary>
- private void StartRecording_Click(object sender, EventArgs e)
- {
- if (currentVideoState == VideoState.Recording)
- {
- this.StopVideoRecording();
- }
- else
- {
- this.StartVideoRecording();
- }
- }
-
- /// <summary>
- /// Releases resources
- /// </summary>
- private void DisposeVideoRecorder()
- {
- if (captureSource != null)
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- }
- captureSource = null;
- videoCaptureDevice = null;
- fileSink = null;
- videoRecorderBrush = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/VERSION
----------------------------------------------------------------------
diff --git a/wp8/template/VERSION b/wp8/template/VERSION
deleted file mode 100644
index bd52db8..0000000
--- a/wp8/template/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.0.0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/www/index.html
----------------------------------------------------------------------
diff --git a/wp8/template/www/index.html b/wp8/template/www/index.html
index e8fb3e5..842b364 100644
--- a/wp8/template/www/index.html
+++ b/wp8/template/www/index.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp8/tooling/scripts/createTemplates.js b/wp8/tooling/scripts/createTemplates.js
index 573c176..b25a19a 100644
--- a/wp8/tooling/scripts/createTemplates.js
+++ b/wp8/tooling/scripts/createTemplates.js
@@ -174,7 +174,6 @@ function package_templates()
replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', name_regex, 'CordovaWP8_' + versionNum.replace(/\./g, '_'));
replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', discript_regex, "Cordova " + versionNum);
-
zip_project(templateOutFilename, platformRoot + templatePath);
if(addToVS)
[32/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Compass.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Compass.cs b/common-items/Plugins/Compass.cs
new file mode 100644
index 0000000..c9e1c4d
--- /dev/null
+++ b/common-items/Plugins/Compass.cs
@@ -0,0 +1,362 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using DeviceCompass = Microsoft.Devices.Sensors.Compass;
+using System.Windows.Threading;
+using System.Runtime.Serialization;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Threading;
+using Microsoft.Devices.Sensors;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+ public class Compass : BaseCommand
+ {
+ #region Static members
+
+ /// <summary>
+ /// Status of listener
+ /// </summary>
+ private static int currentStatus;
+
+ /// <summary>
+ /// Id for get getCompass method
+ /// </summary>
+ private static string getCompassId = "getCompassId";
+
+ /// <summary>
+ /// Compass
+ /// </summary>
+ private static DeviceCompass compass = new DeviceCompass();
+
+ /// <summary>
+ /// Listeners for callbacks
+ /// </summary>
+ private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
+
+ #endregion
+
+ #region Status codes
+
+ public const int Stopped = 0;
+ public const int Starting = 1;
+ public const int Running = 2;
+ public const int ErrorFailedToStart = 4;
+ public const int Not_Supported = 20;
+
+ /*
+ * // Capture error codes
+ CompassError.COMPASS_INTERNAL_ERR = 0;
+ CompassError.COMPASS_NOT_SUPPORTED = 20;
+ * */
+
+ #endregion
+
+ #region CompassOptions class
+ /// <summary>
+ /// Represents Accelerometer options.
+ /// </summary>
+ [DataContract]
+ public class CompassOptions
+ {
+ /// <summary>
+ /// How often to retrieve the Acceleration in milliseconds
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "frequency")]
+ public int Frequency { get; set; }
+
+ /// <summary>
+ /// The change in degrees required to initiate a watchHeadingFilter success callback.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "filter")]
+ public int Filter { get; set; }
+
+ /// <summary>
+ /// Watcher id
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "id")]
+ public string Id { get; set; }
+
+ }
+ #endregion
+
+
+ /// <summary>
+ /// Time the value was last changed
+ /// </summary>
+ //private DateTime lastValueChangedTime;
+
+ /// <summary>
+ /// Accelerometer options
+ /// </summary>
+ private CompassOptions compassOptions;
+
+ //bool isDataValid;
+
+ //bool calibrating = false;
+
+ public Compass()
+ {
+
+ }
+
+ /// <summary>
+ /// Formats current coordinates into JSON format
+ /// </summary>
+ /// <returns>Coordinates in JSON format</returns>
+ private string GetHeadingFormatted(CompassReading reading)
+ {
+ // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
+ string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
+ reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
+ reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
+ reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
+ return "{" + result + "}";
+ }
+
+ public void getHeading(string options)
+ {
+ if (!DeviceCompass.IsSupported)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
+ }
+ else
+ {
+ //if (compass == null)
+ //{
+ // // Instantiate the compass.
+ // compass = new DeviceCompass();
+ // compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
+ // compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
+ // compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
+ //}
+
+
+ //compass.Start();
+
+ }
+
+ try
+ {
+ if (currentStatus != Running)
+ {
+ lock (compass)
+ {
+ compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
+ compass.Start();
+ this.SetStatus(Starting);
+ }
+
+ long timeout = 2000;
+ while ((currentStatus == Starting) && (timeout > 0))
+ {
+ timeout = timeout - 100;
+ Thread.Sleep(100);
+ }
+
+ if (currentStatus != Running)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+ return;
+ }
+ }
+ lock (compass)
+ {
+ compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
+ if (watchers.Count < 1)
+ {
+ compass.Stop();
+ this.SetStatus(Stopped);
+ }
+ }
+ }
+ catch (UnauthorizedAccessException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+ }
+ }
+
+ void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
+ {
+ this.SetStatus(Running);
+ if (compass.IsDataValid)
+ {
+ // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
+ // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
+ // A negative value indicates that the true heading could not be determined.
+ // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
+ //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
+
+ //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
+
+ DispatchCommandResult(result);
+ }
+ }
+
+ /// <summary>
+ /// Starts listening for compass sensor
+ /// </summary>
+ /// <returns>status of listener</returns>
+ private int start()
+ {
+ if ((currentStatus == Running) || (currentStatus == Starting))
+ {
+ return currentStatus;
+ }
+ try
+ {
+ lock (compass)
+ {
+ watchers.Add(getCompassId, this);
+ compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
+ compass.Start();
+ this.SetStatus(Starting);
+ }
+ }
+ catch (Exception)
+ {
+ this.SetStatus(ErrorFailedToStart);
+ }
+ return currentStatus;
+ }
+
+ public void startWatch(string options)
+ {
+ if (!DeviceCompass.IsSupported)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
+ }
+
+ try
+ {
+ compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (string.IsNullOrEmpty(compassOptions.Id))
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ lock (compass)
+ {
+ watchers.Add(compassOptions.Id, this);
+ compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
+ compass.Start();
+ this.SetStatus(Starting);
+ }
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+ return;
+ }
+ }
+
+ public void stopWatch(string options)
+ {
+ try
+ {
+ compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (string.IsNullOrEmpty(compassOptions.Id))
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ if (currentStatus != Stopped)
+ {
+ lock (compass)
+ {
+ Compass watcher = watchers[compassOptions.Id];
+ compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
+ watchers.Remove(compassOptions.Id);
+ watcher.Dispose();
+ }
+ }
+ this.SetStatus(Stopped);
+
+ this.DispatchCommandResult();
+ }
+
+ void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
+ {
+ //throw new NotImplementedException();
+ // TODO: pass calibration error to JS
+ }
+
+ void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
+ {
+ this.SetStatus(Running);
+ if (compass.IsDataValid)
+ {
+ // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
+ // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
+ // A negative value indicates that the true heading could not be determined.
+ // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
+ //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
+
+ //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
+ result.KeepCallback = true;
+
+ DispatchCommandResult(result);
+ }
+ }
+
+ /// <summary>
+ /// Sets current status
+ /// </summary>
+ /// <param name="status">current status</param>
+ private void SetStatus(int status)
+ {
+ currentStatus = status;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Contacts.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Contacts.cs b/common-items/Plugins/Contacts.cs
new file mode 100644
index 0000000..af78942
--- /dev/null
+++ b/common-items/Plugins/Contacts.cs
@@ -0,0 +1,664 @@
+/*
+ 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.
+*/
+
+using Microsoft.Phone.Tasks;
+using Microsoft.Phone.UserData;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Windows;
+using DeviceContacts = Microsoft.Phone.UserData.Contacts;
+
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ [DataContract]
+ public class SearchOptions
+ {
+ [DataMember]
+ public string filter { get; set; }
+ [DataMember]
+ public bool multiple { get; set; }
+ }
+
+ [DataContract]
+ public class ContactSearchParams
+ {
+ [DataMember]
+ public string[] fields { get; set; }
+ [DataMember]
+ public SearchOptions options { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactAddress
+ {
+ [DataMember]
+ public string formatted { get; set; }
+ [DataMember]
+ public string type { get; set; }
+ [DataMember]
+ public string streetAddress { get; set; }
+ [DataMember]
+ public string locality { get; set; }
+ [DataMember]
+ public string region { get; set; }
+ [DataMember]
+ public string postalCode { get; set; }
+ [DataMember]
+ public string country { get; set; }
+ [DataMember]
+ public bool pref { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactName
+ {
+ [DataMember]
+ public string formatted { get; set; }
+ [DataMember]
+ public string familyName { get; set; }
+ [DataMember]
+ public string givenName { get; set; }
+ [DataMember]
+ public string middleName { get; set; }
+ [DataMember]
+ public string honorificPrefix { get; set; }
+ [DataMember]
+ public string honorificSuffix { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactField
+ {
+ [DataMember]
+ public string type { get; set; }
+ [DataMember]
+ public string value { get; set; }
+ [DataMember]
+ public bool pref { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactOrganization
+ {
+ [DataMember]
+ public string type { get; set; }
+ [DataMember]
+ public string name { get; set; }
+ [DataMember]
+ public bool pref { get; set; }
+ [DataMember]
+ public string department { get; set; }
+ [DataMember]
+ public string title { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContact
+ {
+ [DataMember]
+ public string id { get; set; }
+ [DataMember]
+ public string rawId { get; set; }
+ [DataMember]
+ public string displayName { get; set; }
+ [DataMember]
+ public string nickname { get; set; }
+ [DataMember]
+ public string note { get; set; }
+
+ [DataMember]
+ public JSONContactName name { get; set; }
+
+ [DataMember]
+ public JSONContactField[] emails { get; set; }
+
+ [DataMember]
+ public JSONContactField[] phoneNumbers { get; set; }
+
+ [DataMember]
+ public JSONContactField[] ims { get; set; }
+
+ [DataMember]
+ public JSONContactField[] photos { get; set; }
+
+ [DataMember]
+ public JSONContactField[] categories { get; set; }
+
+ [DataMember]
+ public JSONContactField[] urls { get; set; }
+
+ [DataMember]
+ public JSONContactOrganization[] organizations { get; set; }
+
+ [DataMember]
+ public JSONContactAddress[] addresses { get; set; }
+ }
+
+
+ public class Contacts : BaseCommand
+ {
+
+ public const int UNKNOWN_ERROR = 0;
+ public const int INVALID_ARGUMENT_ERROR = 1;
+ public const int TIMEOUT_ERROR = 2;
+ public const int PENDING_OPERATION_ERROR = 3;
+ public const int IO_ERROR = 4;
+ public const int NOT_SUPPORTED_ERROR = 5;
+ public const int PERMISSION_DENIED_ERROR = 20;
+ public const int SYNTAX_ERR = 8;
+
+ public Contacts()
+ {
+
+ }
+
+ // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
+ public void save(string jsonContact)
+ {
+
+ // jsonContact is actually an array of 1 {contact}
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
+
+
+ JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
+
+ SaveContactTask contactTask = new SaveContactTask();
+
+ if (contact.nickname != null)
+ {
+ contactTask.Nickname = contact.nickname;
+ }
+ if (contact.urls != null && contact.urls.Length > 0)
+ {
+ contactTask.Website = contact.urls[0].value;
+ }
+ if (contact.note != null)
+ {
+ contactTask.Notes = contact.note;
+ }
+
+ #region contact.name
+ if (contact.name != null)
+ {
+ if (contact.name.givenName != null)
+ contactTask.FirstName = contact.name.givenName;
+ if (contact.name.familyName != null)
+ contactTask.LastName = contact.name.familyName;
+ if (contact.name.middleName != null)
+ contactTask.MiddleName = contact.name.middleName;
+ if (contact.name.honorificSuffix != null)
+ contactTask.Suffix = contact.name.honorificSuffix;
+ if (contact.name.honorificPrefix != null)
+ contactTask.Title = contact.name.honorificPrefix;
+ }
+ #endregion
+
+ #region contact.org
+ if (contact.organizations != null && contact.organizations.Count() > 0)
+ {
+ contactTask.Company = contact.organizations[0].name;
+ contactTask.JobTitle = contact.organizations[0].title;
+ }
+ #endregion
+
+ #region contact.phoneNumbers
+ if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
+ {
+ foreach (JSONContactField field in contact.phoneNumbers)
+ {
+ string fieldType = field.type.ToLower();
+ if (fieldType == "work")
+ {
+ contactTask.WorkPhone = field.value;
+ }
+ else if (fieldType == "home")
+ {
+ contactTask.HomePhone = field.value;
+ }
+ else if (fieldType == "mobile")
+ {
+ contactTask.MobilePhone = field.value;
+ }
+ }
+ }
+ #endregion
+
+ #region contact.emails
+
+ if (contact.emails != null && contact.emails.Length > 0)
+ {
+
+ // set up different email types if they are not explicitly defined
+ foreach (string type in new string[] { "personal", "work", "other" })
+ {
+ foreach (JSONContactField field in contact.emails)
+ {
+ if (field != null && String.IsNullOrEmpty(field.type))
+ {
+ field.type = type;
+ break;
+ }
+ }
+ }
+
+ foreach (JSONContactField field in contact.emails)
+ {
+ if (field != null)
+ {
+ if (field.type != null && field.type != "other")
+ {
+ string fieldType = field.type.ToLower();
+ if (fieldType == "work")
+ {
+ contactTask.WorkEmail = field.value;
+ }
+ else if (fieldType == "home" || fieldType == "personal")
+ {
+ contactTask.PersonalEmail = field.value;
+ }
+ }
+ else
+ {
+ contactTask.OtherEmail = field.value;
+ }
+ }
+
+ }
+ }
+ #endregion
+
+ if (contact.note != null && contact.note.Length > 0)
+ {
+ contactTask.Notes = contact.note;
+ }
+
+ #region contact.addresses
+ if (contact.addresses != null && contact.addresses.Length > 0)
+ {
+ foreach (JSONContactAddress address in contact.addresses)
+ {
+ if (address.type == null)
+ {
+ address.type = "home"; // set a default
+ }
+ string fieldType = address.type.ToLower();
+ if (fieldType == "work")
+ {
+ contactTask.WorkAddressCity = address.locality;
+ contactTask.WorkAddressCountry = address.country;
+ contactTask.WorkAddressState = address.region;
+ contactTask.WorkAddressStreet = address.streetAddress;
+ contactTask.WorkAddressZipCode = address.postalCode;
+ }
+ else if (fieldType == "home" || fieldType == "personal")
+ {
+ contactTask.HomeAddressCity = address.locality;
+ contactTask.HomeAddressCountry = address.country;
+ contactTask.HomeAddressState = address.region;
+ contactTask.HomeAddressStreet = address.streetAddress;
+ contactTask.HomeAddressZipCode = address.postalCode;
+ }
+ else
+ {
+ // no other address fields available ...
+ Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
+ }
+ }
+ }
+ #endregion
+
+
+ contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
+ contactTask.Show();
+ }
+
+ void ContactSaveTaskCompleted(object sender, SaveContactResult e)
+ {
+ SaveContactTask task = sender as SaveContactTask;
+
+ if (e.TaskResult == TaskResult.OK)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DeviceContacts deviceContacts = new DeviceContacts();
+ deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
+
+ string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
+
+ deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
+ });
+
+
+ }
+ else if (e.TaskResult == TaskResult.Cancel)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
+ }
+ }
+
+ void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
+ {
+ if (e.Results.Count() > 0)
+ {
+ List<Contact> foundContacts = new List<Contact>();
+
+ int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
+ Contact newContact = (from Contact contact in e.Results
+ where contact.GetHashCode() == n
+ select contact).First();
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
+ }
+ }
+
+
+
+ public void remove(string id)
+ {
+ // note id is wrapped in [] and always has exactly one string ...
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
+ }
+
+ public void search(string searchCriteria)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
+
+ ContactSearchParams searchParams = new ContactSearchParams();
+ try
+ {
+ searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
+ searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
+ return;
+ }
+
+ if (searchParams.options == null)
+ {
+ searchParams.options = new SearchOptions();
+ searchParams.options.filter = "";
+ searchParams.options.multiple = true;
+ }
+
+ DeviceContacts deviceContacts = new DeviceContacts();
+ deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
+
+ // default is to search all fields
+ FilterKind filterKind = FilterKind.None;
+ // if only one field is specified, we will try the 3 available DeviceContact search filters
+ if (searchParams.fields.Count() == 1)
+ {
+ if (searchParams.fields.Contains("name"))
+ {
+ filterKind = FilterKind.DisplayName;
+ }
+ else if (searchParams.fields.Contains("emails"))
+ {
+ filterKind = FilterKind.EmailAddress;
+ }
+ else if (searchParams.fields.Contains("phoneNumbers"))
+ {
+ filterKind = FilterKind.PhoneNumber;
+ }
+ }
+
+ try
+ {
+
+ deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("search contacts exception :: " + ex.Message);
+ }
+ }
+
+ private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
+ {
+ ContactSearchParams searchParams = (ContactSearchParams)e.State;
+
+ List<Contact> foundContacts = null;
+
+ // if we have multiple search fields
+ if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
+ {
+ foundContacts = new List<Contact>();
+ if (searchParams.fields.Contains("emails"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ from ContactEmailAddress a in con.EmailAddresses
+ where a.EmailAddress.Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("displayName"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ where con.DisplayName.Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("name"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("phoneNumbers"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ from ContactPhoneNumber a in con.PhoneNumbers
+ where a.PhoneNumber.Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("urls"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ from string a in con.Websites
+ where a.Contains(searchParams.options.filter)
+ select con);
+ }
+ }
+ else
+ {
+ foundContacts = new List<Contact>(e.Results);
+ }
+
+ //List<string> contactList = new List<string>();
+
+ string strResult = "";
+
+ IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
+
+ foreach (Contact contact in distinctContacts)
+ {
+ strResult += FormatJSONContact(contact, null) + ",";
+ //contactList.Add(FormatJSONContact(contact, null));
+ if (!searchParams.options.multiple)
+ {
+ break; // just return the first item
+ }
+ }
+ PluginResult result = new PluginResult(PluginResult.Status.OK);
+ result.Message = "[" + strResult.TrimEnd(',') + "]";
+ DispatchCommandResult(result);
+
+ }
+
+ private string FormatJSONPhoneNumbers(Contact con)
+ {
+ string retVal = "";
+ string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
+ foreach (ContactPhoneNumber number in con.PhoneNumbers)
+ {
+
+ string contactField = string.Format(contactFieldFormat,
+ number.Kind.ToString(),
+ number.PhoneNumber);
+
+ retVal += "{" + contactField + "},";
+ }
+ return retVal.TrimEnd(',');
+ }
+
+ private string FormatJSONEmails(Contact con)
+ {
+ string retVal = "";
+ string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
+ foreach (ContactEmailAddress address in con.EmailAddresses)
+ {
+ string contactField = string.Format(contactFieldFormat,
+ address.Kind.ToString(),
+ address.EmailAddress);
+
+ retVal += "{" + contactField + "},";
+ }
+ return retVal.TrimEnd(',');
+ }
+
+ private string getFormattedJSONAddress(ContactAddress address, bool isPrefered)
+ {
+
+ string addressFormatString = "\"pref\":{0}," + // bool
+ "\"type\":\"{1}\"," +
+ "\"formatted\":\"{2}\"," +
+ "\"streetAddress\":\"{3}\"," +
+ "\"locality\":\"{4}\"," +
+ "\"region\":\"{5}\"," +
+ "\"postalCode\":\"{6}\"," +
+ "\"country\":\"{7}\"";
+
+ string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
+ + address.PhysicalAddress.AddressLine2 + " "
+ + address.PhysicalAddress.City + " "
+ + address.PhysicalAddress.StateProvince + " "
+ + address.PhysicalAddress.CountryRegion + " "
+ + address.PhysicalAddress.PostalCode;
+
+ string jsonAddress = string.Format(addressFormatString,
+ isPrefered ? "\"true\"" : "\"false\"",
+ address.Kind.ToString(),
+ formattedAddress,
+ address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
+ address.PhysicalAddress.City,
+ address.PhysicalAddress.StateProvince,
+ address.PhysicalAddress.PostalCode,
+ address.PhysicalAddress.CountryRegion);
+
+ //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
+
+ return "{" + jsonAddress + "}";
+ }
+
+ private string FormatJSONAddresses(Contact con)
+ {
+ string retVal = "";
+ foreach (ContactAddress address in con.Addresses)
+ {
+ retVal += this.getFormattedJSONAddress(address, false) + ",";
+ }
+
+ //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
+ return retVal.TrimEnd(',');
+ }
+
+ private string FormatJSONWebsites(Contact con)
+ {
+ string retVal = "";
+ foreach (string website in con.Websites)
+ {
+ retVal += "\"" + website + "\",";
+ }
+ return retVal.TrimEnd(',');
+ }
+
+ /*
+ * formatted: The complete name of the contact. (DOMString)
+ familyName: The contacts family name. (DOMString)
+ givenName: The contacts given name. (DOMString)
+ middleName: The contacts middle name. (DOMString)
+ honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
+ honorificSuffix: The contacts suffix (example Esq.). (DOMString)
+ */
+ private string FormatJSONName(Contact con)
+ {
+ string retVal = "";
+ string formatStr = "\"formatted\":\"{0}\"," +
+ "\"familyName\":\"{1}\"," +
+ "\"givenName\":\"{2}\"," +
+ "\"middleName\":\"{3}\"," +
+ "\"honorificPrefix\":\"{4}\"," +
+ "\"honorificSuffix\":\"{5}\"";
+
+ if (con.CompleteName != null)
+ {
+ retVal = string.Format(formatStr,
+ con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
+ con.CompleteName.LastName,
+ con.CompleteName.FirstName,
+ con.CompleteName.MiddleName,
+ con.CompleteName.Title,
+ con.CompleteName.Suffix);
+ }
+ else
+ {
+ retVal = string.Format(formatStr,"","","","","","");
+ }
+
+ return "{" + retVal + "}";
+ }
+
+ private string FormatJSONContact(Contact con, string[] fields)
+ {
+
+ string contactFormatStr = "\"id\":\"{0}\"," +
+ "\"displayName\":\"{1}\"," +
+ "\"nickname\":\"{2}\"," +
+ "\"phoneNumbers\":[{3}]," +
+ "\"emails\":[{4}]," +
+ "\"addresses\":[{5}]," +
+ "\"urls\":[{6}]," +
+ "\"name\":{7}," +
+ "\"note\":\"{8}\"," +
+ "\"birthday\":\"{9}\"";
+
+
+ string jsonContact = String.Format(contactFormatStr,
+ con.GetHashCode(),
+ con.DisplayName,
+ con.CompleteName != null ? con.CompleteName.Nickname : "",
+ FormatJSONPhoneNumbers(con),
+ FormatJSONEmails(con),
+ FormatJSONAddresses(con),
+ FormatJSONWebsites(con),
+ FormatJSONName(con),
+ con.Notes.FirstOrDefault(),
+ con.Birthdays.FirstOrDefault());
+
+ //Debug.WriteLine("jsonContact = " + jsonContact);
+ // JSON requires new line characters be escaped
+ return "{" + jsonContact.Replace("\n", "\\n") + "}";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/DebugConsole.cs b/common-items/Plugins/DebugConsole.cs
new file mode 100644
index 0000000..fa9863a
--- /dev/null
+++ b/common-items/Plugins/DebugConsole.cs
@@ -0,0 +1,49 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+ public class DebugConsole : BaseCommand
+ {
+ // warn, error
+ public void log(string msg)
+ {
+ Debug.WriteLine("Log:" + msg);
+ }
+
+ public void error(string msg)
+ {
+ Debug.WriteLine("Error:" + msg);
+ }
+
+ public void warn(string msg)
+ {
+ Debug.WriteLine("Warn:" + msg);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/common-items/Plugins/Device.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Device.cs b/common-items/Plugins/Device.cs
new file mode 100644
index 0000000..8abb4ff
--- /dev/null
+++ b/common-items/Plugins/Device.cs
@@ -0,0 +1,135 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Info;
+using System.IO.IsolatedStorage;
+using System.Windows.Resources;
+using System.IO;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Device : BaseCommand
+ {
+ public void getDeviceInfo(string notused)
+ {
+
+ string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
+ this.name,
+ this.cordova,
+ this.platform,
+ this.uuid,
+ this.version,
+ this.model);
+
+
+
+ res = "{" + res + "}";
+ //Debug.WriteLine("Result::" + res);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
+ }
+
+ public string model
+ {
+ get
+ {
+ return DeviceStatus.DeviceName;
+ //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion);
+ }
+ }
+
+ public string name
+ {
+ get
+ {
+ return DeviceStatus.DeviceName;
+
+ }
+ }
+
+ public string cordova
+ {
+ get
+ {
+ // TODO: should be able to dynamically read the Cordova version from somewhere...
+ return "0.0.0";
+ }
+ }
+
+ public string platform
+ {
+ get
+ {
+ return Environment.OSVersion.Platform.ToString();
+ }
+ }
+
+ public string uuid
+ {
+ get
+ {
+ string returnVal = "";
+ object id;
+ UserExtendedProperties.TryGetValue("ANID", out id);
+
+ if (id != null)
+ {
+ returnVal = id.ToString().Substring(2, 32);
+ }
+ else
+ {
+ returnVal = "???unknown???";
+
+ using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ try
+ {
+ IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
+
+ using (StreamReader reader = new StreamReader(fileStream))
+ {
+ returnVal = reader.ReadLine();
+ }
+ }
+ catch (Exception /*ex*/)
+ {
+
+ }
+ }
+ }
+
+ return returnVal;
+ }
+ }
+
+ public string version
+ {
+ get
+ {
+ return Environment.OSVersion.Version.ToString();
+ }
+ }
+
+ }
+}
[10/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Globalization.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Globalization.cs b/wp7/template/Plugins/Globalization.cs
deleted file mode 100644
index 2c2f468..0000000
--- a/wp7/template/Plugins/Globalization.cs
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides information about system locale, culture settings, number formats, ect.
- /// </summary>
- public class Globalization : BaseCommand
- {
-
- #region Globalization errors
-
- /// <summary>
- /// Globalization error codes.
- /// </summary>
- public enum ErrorCode : int
- {
- UnknownError = 0,
- FormattingError = 1,
- ParsingError = 2,
- PatternError = 3
- }
-
- /// <summary>
- /// Represents globalization error object.
- /// </summary>
- [DataContract]
- public class GlobalizationError
- {
- #region Error messages
- /// <summary>
- /// Error messages
- /// </summary>
- public const string UnknownError = "UNKNOWN_ERROR";
- public const string FormattingError = "FORMATTIN_ERROR";
- public const string ParsingError = "PARSING_ERROR";
- public const string PatternError = "PATTERN_ERROR";
-
- #endregion
-
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = false)]
- public ErrorCode Code { get; set; }
-
- /// <summary>
- /// Error message
- /// </summary>
- [DataMember(Name = "message", IsRequired = false)]
- public string Message { get; set; }
-
- /// <summary>
- /// Default constructor
- /// </summary>
- public GlobalizationError()
- {
- this.Code = ErrorCode.UnknownError;
- this.Message = UnknownError;
- }
-
- /// <summary>
- /// Constructor setting error code
- /// </summary>
- public GlobalizationError(ErrorCode error)
- {
- this.Code = error;
-
- switch (error)
- {
- case ErrorCode.ParsingError:
- {
- this.Message = ParsingError;
- break;
- }
- case ErrorCode.FormattingError:
- {
- this.Message = FormattingError;
- break;
- }
- case ErrorCode.PatternError:
- {
- this.Message = PatternError;
- break;
- }
- default:
- {
- this.Message = UnknownError;
- break;
- }
- }
- }
- }
-
- #endregion
-
- #region Globalization options
-
- /// <summary>
- /// Represents globalization options.
- /// </summary>
- [DataContract]
- public class GlobalizationOptions
- {
- #region available option values
- /// <summary>
- /// Number pattern types.
- /// </summary>
- public const string Percent = "percent";
- public const string Currency = "currency";
- public const string Decimal = "decimal";
-
- /// <summary>
- /// Format length types
- /// </summary>
- public const string Short = "short";
- public const string Medium = "medium";
- public const string Long = "long";
- public const string Full = "full";
-
- /// <summary>
- /// Selector types
- /// </summary>
- public const string TimeSelector = "time";
- public const string DateSelector = "date";
- public const string DateAndTimeSelector = "date and time";
-
- /// <summary>
- /// Date name types
- /// </summary>
- public const string Narrow = "narrow";
- public const string Wide = "wide";
-
- /// <summary>
- /// Date name items
- /// </summary>
- public const string Months = "months";
- public const string Days = "days";
-
- #endregion
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "options", IsRequired = false)]
- public Options AdditionalOptions { get; set; }
-
- /// <summary>
- /// Date to convert
- /// </summary>
- [DataMember(Name = "date", IsRequired = false)]
- public long Date { get; set; }
-
- /// <summary>
- /// Date as stirng
- /// </summary>
- [DataMember(Name = "dateString", IsRequired = false)]
- public string DateString { get; set; }
-
- /// <summary>
- /// Currency code
- /// </summary>
- [DataMember(Name = "currencyCode", IsRequired = false)]
- public string CurrencyCode { get; set; }
-
- /// <summary>
- /// Number as string
- /// </summary>
- [DataMember(Name = "numberString", IsRequired = false)]
- public string NumberString { get; set; }
-
- /// <summary>
- /// Number to convert
- /// </summary>
- [DataMember(Name = "number", IsRequired = false)]
- public double Number { get; set; }
- }
-
- /// <summary>
- /// Represents additional options
- /// </summary>
- [DataContract]
- public class Options
- {
- /// <summary>
- /// Pattern type
- /// </summary>
- [DataMember(Name = "type", IsRequired = false)]
- public string Type { get; set; }
-
- /// <summary>
- /// Format length
- /// </summary>
- [DataMember(Name = "formatLength", IsRequired = false)]
- public string FormatLength { get; set; }
-
- /// <summary>
- /// Selector
- /// </summary>
- [DataMember(Name = "selector", IsRequired = false)]
- public string Selector { get; set; }
-
- /// <summary>
- /// Date name item
- /// </summary>
- [DataMember(Name = "item", IsRequired = false)]
- public string Item { get; set; }
- }
-
- #endregion
-
- #region returned objects
-
- #region Number pattern object
-
- /// <summary>
- /// Represents number pattern
- /// </summary>
- [DataContract]
- public class NumberPattern
- {
- /// <summary>
- /// Pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// Symbol
- /// </summary>
- [DataMember(Name = "symbol", IsRequired = false)]
- public string Symbol { get; set; }
-
- /// <summary>
- /// Fraction
- /// </summary>
- [DataMember(Name = "fraction", IsRequired = false)]
- public int Fraction { get; set; }
-
- /// <summary>
- /// Positive
- /// </summary>
- [DataMember(Name = "positive", IsRequired = false)]
- public string Positive { get; set; }
-
- /// <summary>
- /// Negative
- /// </summary>
- [DataMember(Name = "negative", IsRequired = false)]
- public string Negative { get; set; }
-
- /// <summary>
- /// Rounding
- /// </summary>
- [DataMember(Name = "rounding", IsRequired = false)]
- public int Rounding { get; set; }
-
- /// <summary>
- /// Decimal
- /// </summary>
- [DataMember(Name = "decimal", IsRequired = false)]
- public string Decimal { get; set; }
-
- /// <summary>
- /// Grouping
- /// </summary>
- [DataMember(Name = "grouping", IsRequired = false)]
- public string Grouping { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="symbol"></param>
- /// <param name="fraction"></param>
- /// <param name="positive"></param>
- /// <param name="negative"></param>
- /// <param name="rounding"></param>
- /// <param name="dec"></param>
- /// <param name="grouping"></param>
- public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
- {
- this.Pattern = pattern;
- this.Symbol = symbol;
- this.Fraction = fraction;
- this.Positive = positive;
- this.Negative = negative;
- this.Rounding = rounding;
- this.Decimal = dec;
- this.Grouping = grouping;
- }
- }
- #endregion
-
- #region Date format object
-
- /// <summary>
- /// Represents date format
- /// </summary>
- [DataContract]
- public class DateFormat
- {
- /// <summary>
- /// Year
- /// </summary>
- [DataMember(Name = "year", IsRequired = false)]
- public int Year { get; set; }
-
- /// <summary>
- /// Month
- /// </summary>
- [DataMember(Name = "month", IsRequired = false)]
- public int Month { get; set; }
-
- /// <summary>
- /// Day
- /// </summary>
- [DataMember(Name = "day", IsRequired = false)]
- public int Day { get; set; }
-
- /// <summary>
- /// Hour
- /// </summary>
- [DataMember(Name = "hour", IsRequired = false)]
- public int Hour { get; set; }
-
- /// <summary>
- /// Minute
- /// </summary>
- [DataMember(Name = "minute", IsRequired = false)]
- public int Minute { get; set; }
-
- /// <summary>
- /// Second
- /// </summary>
- [DataMember(Name = "second", IsRequired = false)]
- public int Second { get; set; }
-
- /// <summary>
- /// Millisecond
- /// </summary>
- [DataMember(Name = "millisecond", IsRequired = false)]
- public int Millisecond { get; set; }
-
- public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
- {
- this.Year = year;
- this.Month = month;
- this.Day = day;
- this.Hour = hour;
- this.Minute = minute;
- this.Millisecond = millisecond;
- }
-
- }
- #endregion
-
- #region Date pattern object
-
- /// <summary>
- /// Represents date pattern object
- /// </summary>
- [DataContract]
- public class DatePattern
- {
-
- /// <summary>
- /// Date pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// TimeZone
- /// </summary>
- [DataMember(Name = "timezone", IsRequired = false)]
- public string TimeZone { get; set; }
-
- /// <summary>
- /// UTC offset
- /// </summary>
- [DataMember(Name = "utc_offset", IsRequired = false)]
- public double UtcOffset { get; set; }
-
- /// <summary>
- /// Dst offset
- /// </summary>
- [DataMember(Name = "dst_offset", IsRequired = false)]
- public double DstOffset { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="timezone"></param>
- /// <param name="utcOffset"></param>
- /// <param name="dstOffset"></param>
- public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
- {
- this.Pattern = pattern;
- this.TimeZone = timezone;
- this.UtcOffset = utcOffset;
- this.DstOffset = dstOffset;
- }
-
- }
-
- #endregion
-
- #endregion
-
- #region Locale info
-
- /// <summary>
- /// Gets the string identifier for the client's current locale setting.
- /// </summary>
- /// <param name="options"></param>
- public void getLocaleName(string options)
- {
- try
- {
- var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the string identifier for the client's current language.
- /// </summary>
- /// <param name="options"></param>
- public void getPreferredLanguage(string options)
- {
- try
- {
- var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Date and time info
-
- /// <summary>
- /// Gets whether daylight savings time is in effect for a given date using the client's
- /// time zone and calendar.
- /// </summary>
- /// <param name="opitons">Date to daylight savings check.</param>
- public void isDayLightSavingsTime(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the first day of the week according to the client's user preferences and calendar.
- /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
- /// </summary>
- /// <param name="options"></param>
- public void getFirstDayOfWeek(string options)
- {
- try
- {
- // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
- var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Formatting
-
- /// <summary>
- /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client.
- /// </summary>
- /// <param name="options"></param>
- public void dateToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-
- string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
- break;
- }
- case 10: // short date
- {
- format = "{0:d}";
- break;
- }
- case 11: // full date
- {
- format = "{0:D}";
- break;
- }
- case 20: // short time
- {
- format = "{0:t}";
- break;
- }
- case 21: // full time
- {
- format = "{0:T}";
- break;
- }
- default: // short datetime
- {
- format = "{0:M/dd/yy H:m:s}";
- break;
- }
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
- /// </summary>
- /// <param name="options"></param>
- public void stringToDate(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.DateString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string format = "M/dd/yy H:m:s"; // short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "MMMM/dddd/yyyy HH:mm:ss tt";
- break;
- }
- case 10: // short date
- {
- format = "d";
- break;
- }
- case 11: // full date
- {
- format = "D";
- break;
- }
- case 20: // short time
- {
- format = "t";
- break;
- }
- case 21: // full time
- {
- format = "T";
- break;
- }
- default: // short datetime
- {
- format = "M/dd/yy H:m:s";
- break;
- }
- }
- }
-
- DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
- DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getDatePattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
- string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- case 10: // short date
- {
- pattern = dateFormatInfo.ShortDatePattern;
- break;
- }
- case 11: // full date
- {
- pattern = dateFormatInfo.LongDatePattern;
- break;
- }
- case 20: // short time
- {
- pattern = dateFormatInfo.ShortTimePattern;
- break;
- }
- case 21: // full time
- {
- pattern = dateFormatInfo.LongTimePattern;
- break;
- }
- default: // short datetime
- {
- // Seems like C# doesn't support short datetime pattern so we use full format
- // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- }
- }
-
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
- /// </summary>
- /// <param name="options"></param>
- public void getDateNames(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- int type = 0; //default wide
- int item = 0; //default months
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.Type != null)
- {
- string t = globalOptions.AdditionalOptions.Type;
-
- if (t.Equals(GlobalizationOptions.Narrow))
- {
- type++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Item != null)
- {
- string t = globalOptions.AdditionalOptions.Item;
-
- if (t.Equals(GlobalizationOptions.Days))
- {
- item += 10;
- }
- }
- }
-
- //determine return value
- int method = item + type;
- string[] namesArray;
- CultureInfo currentCulture = CultureInfo.CurrentCulture;
-
- if (method == 1) //months and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
- }
- else if (method == 10) //days and wide
- {
- namesArray = currentCulture.DateTimeFormat.DayNames;
- }
- else if (method == 11) //days and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
- }
- else //default: months and wide
- {
- namesArray = currentCulture.DateTimeFormat.MonthNames;
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void numberToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- string format = string.Empty;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- format = "{0:p}";
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- format = "{0:c}";
- break;
- }
-
- default:
- {
- format = "{0:f}";
- break;
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
- /// </summary>
- /// <param name="options"></param>
- public void stringToNumber(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.NumberString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string numberString = globalOptions.NumberString;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- NumberStyles numberStyle;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- numberStyle = NumberStyles.Any;
- numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- numberStyle = NumberStyles.Currency;
- break;
- }
-
- default:
- {
- numberStyle = NumberStyles.Number;
- break;
- }
- }
-
- double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getNumberPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- CultureInfo cultureInfo = CultureInfo.CurrentCulture;
- NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
- NumberPattern pattern = null;
- string symbol;
-
- // TODO find out how to get format pattern and the number of fraction digits
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- symbol = formatInfo.PercentSymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
- break;
- }
- case GlobalizationOptions.Currency:
- {
- symbol = formatInfo.CurrencySymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
- break;
- }
- default:
- {
- symbol = formatInfo.NumberDecimalSeparator;
- pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
- break;
- }
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
- /// </summary>
- /// <param name="options"></param>
- public void getCurrencyPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string currencyCode = globalOptions.CurrencyCode;
-
- // temporary not supported via lack of api required
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
- return;
-
- // TODO find the way to get currency info from currency code
- // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
- // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
- // CultureInfo cultureInfo = new CultureInfo(currencyCode);
- // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- #endregion
-
- #region private methods
-
- /// <summary>
- /// Wraps data into JSON format
- /// </summary>
- /// <param name="data">data</param>
- /// <returns>data formatted as JSON object</returns>
- private string WrapIntoJSON<T>(T data, string keyName = "value")
- {
- string param = "{0}";
- string stringifiedData = data.ToString();
-
- if (data.GetType() == typeof(string))
- {
- param = "\"" + param + "\"";
- }
-
- if (data.GetType() == typeof(bool))
- {
- stringifiedData = stringifiedData.ToLower();
- }
-
- if (data.GetType() == typeof(string[]))
- {
- stringifiedData = JSON.JsonHelper.Serialize(data);
- }
-
- var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
- formattedData = "{" + formattedData + "}";
-
- return formattedData;
- }
-
- #endregion
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/ImageExifHelper.cs b/wp7/template/Plugins/ImageExifHelper.cs
deleted file mode 100644
index 68ddf87..0000000
--- a/wp7/template/Plugins/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- 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.
-
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class ImageExifOrientation
- {
- public const int Portrait = 1;
- public const int PortraitUpsideDown = 3;
- public const int LandscapeLeft = 6;
- public const int LandscapeRight = 8;
- }
-
- public class ImageExifHelper
- {
-
- public static Stream RotateStream(Stream stream, int angle)
- {
- stream.Position = 0;
- if (angle % 90 != 0 || angle < 0)
- {
- throw new ArgumentException();
- }
- if (angle % 360 == 0)
- {
- return stream;
- }
-
- angle = angle % 360;
-
- BitmapImage bitmap = new BitmapImage();
- bitmap.SetSource(stream);
- WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
- WriteableBitmap wbTarget = null;
-
- int srcPixelWidth = wbSource.PixelWidth;
- int srcPixelHeight = wbSource.PixelHeight;
-
- if (angle % 180 == 0)
- {
- wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
- }
- else
- {
- wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
- }
-
- int destPixelWidth = wbTarget.PixelWidth;
- int[] srcPxls = wbSource.Pixels;
- int[] destPxls = wbTarget.Pixels;
-
- // this ugly if/else is to avoid a conditional check for every pixel
- if (angle == 90)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 180)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 270)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
-
- MemoryStream targetStream = new MemoryStream();
- wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
- return targetStream;
- }
-
- public static int getImageOrientationFromStream(Stream imgStream)
- {
-
- // 0xFFD8 : jpgHeader
- // 0xFFE1 :
- // 0x???? : length of exif data
- // 0x????, 0x???? : Chars 'E','x','i','f'
- // 0x0000 : 2 empty bytes
- // <== mark beginning of tags SIZE:ID:VALUE
- // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determins littleEndian-ness
- // 0x002A : marker value
- // 0x???? : offset to the Image File Data
-
- // XXXX possible space before actual tag data ... we skip to mark + offset
-
- // 0x???? number of exif tags present
-
- // make sure we are at the begining
- imgStream.Seek(0, SeekOrigin.Begin);
- BinaryReader reader = new BinaryReader(imgStream);
-
- byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
- byte start = reader.ReadByte(); // 0xFF
- byte index = reader.ReadByte(); // 0xE1
-
- while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
- {
- // Get the data length
- ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // skip along
- reader.ReadBytes(dLen - 2);
- start = reader.ReadByte();
- index = reader.ReadByte();
- }
-
- // It's only success if we found the 0xFFE1 marker
- if (start != 0xFF || index != 0xE1)
- {
- // throw new Exception("Could not find Exif data block");
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 byte length of EXIF data
- ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- String exif = ""; // build the string
- for (var n = 0; n < 4; n++)
- {
- exif += reader.ReadChar();
- }
- if (exif != "Exif")
- {
- // did not find exif data ...
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 empty bytes
- //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- reader.ReadBytes(2);
-
- long headerMark = reader.BaseStream.Position; // where are we now <==
-
- //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
- reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
- if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- Debug.WriteLine("Error in data != 0x002A");
- return 0;
- }
-
- // Get the offset to the IFD (image file directory)
- ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
- imgStream.Position = headerMark + imgOffset;
- ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- for (ushort x = 0; x < tagCount; x++)
- {
- // Orientation = 0x112, aka 274
- if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // don't care ..
- uint comps = reader.ReadUInt32();
- byte[] tagData = reader.ReadBytes(4);
- int orientation = (int)tagData[0];
- Debug.WriteLine("orientation = " + orientation.ToString());
- return orientation;
- // 6 means rotate clockwise 90 deg
- // 8 means rotate counter-clockwise 90 deg
- // 1 means all is good
- // 3 means flip vertical
- }
- // skip to the next item, 12 bytes each
- reader.BaseStream.Seek(10, SeekOrigin.Current);
- }
- return 0;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/InAppBrowser.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/InAppBrowser.cs b/wp7/template/Plugins/InAppBrowser.cs
deleted file mode 100644
index 2741355..0000000
--- a/wp7/template/Plugins/InAppBrowser.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using WPCordovaClassLib.Cordova;
-using WPCordovaClassLib.Cordova.Commands;
-using WPCordovaClassLib.Cordova.JSON;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class BrowserOptions
- {
- [DataMember]
- public string url;
-
- [DataMember]
- public bool isGeolocationEnabled;
- }
-
- public class InAppBrowser : BaseCommand
- {
-
- private static WebBrowser browser;
- private static ApplicationBarIconButton backButton;
- private static ApplicationBarIconButton fwdButton;
-
- public void open(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
- string urlLoc = args[0];
- string target = args[1];
- /*
- _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
- _blank - always open in the InAppBrowser
- _system - always open in the system web browser
- */
- switch (target)
- {
- case "_blank":
- ShowInAppBrowser(urlLoc);
- break;
- case "_self":
- ShowCordovaBrowser(urlLoc);
- break;
- case "_system":
- ShowSystemBrowser(urlLoc);
- break;
- }
-
-
- }
-
- private void ShowCordovaBrowser(string url)
- {
- Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- CordovaView cView = page.FindName("CordovaView") as CordovaView;
- if (cView != null)
- {
- WebBrowser br = cView.Browser;
- br.Navigate(loc);
- }
- }
-
- }
- });
- }
-
- private void ShowSystemBrowser(string url)
- {
- WebBrowserTask webBrowserTask = new WebBrowserTask();
- webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
- webBrowserTask.Show();
- }
-
-
- private void ShowInAppBrowser(string url)
- {
- Uri loc = new Uri(url);
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (browser != null)
- {
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- browser.Navigate(loc);
- }
- else
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- string baseImageUrl = "Images/";
-
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- browser = new WebBrowser();
- browser.IsScriptEnabled = true;
- browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-
- browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
- browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
- browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
- browser.Navigate(loc);
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- grid.Children.Add(browser);
- }
-
- ApplicationBar bar = new ApplicationBar();
- bar.BackgroundColor = Colors.Gray;
- bar.IsMenuEnabled = false;
-
- backButton = new ApplicationBarIconButton();
- backButton.Text = "Back";
-
- backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
- backButton.Click += new EventHandler(backButton_Click);
- backButton.IsEnabled = false;
- bar.Buttons.Add(backButton);
-
-
- fwdButton = new ApplicationBarIconButton();
- fwdButton.Text = "Forward";
- fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
- fwdButton.Click += new EventHandler(fwdButton_Click);
- fwdButton.IsEnabled = false;
- bar.Buttons.Add(fwdButton);
-
- ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
- closeBtn.Text = "Close";
- closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
- closeBtn.Click += new EventHandler(closeBtn_Click);
- bar.Buttons.Add(closeBtn);
-
- page.ApplicationBar = bar;
- }
-
- }
- }
- });
- }
-
- void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
-
- }
-
- void fwdButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoForward();
- //browser.InvokeScript("execScript", "history.forward();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void backButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoBack();
- //browser.InvokeScript("execScript", "history.back();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void closeBtn_Click(object sender, EventArgs e)
- {
- this.close();
- }
-
-
- public void close(string options = "")
- {
- if (browser != null)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(browser);
- }
- page.ApplicationBar = null;
- }
- }
- browser = null;
- string message = "{\"type\":\"exit\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = false;
- this.DispatchCommandResult(result);
- });
- }
- }
-
- void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (browser != null)
- {
- backButton.IsEnabled = browser.CanGoBack;
- fwdButton.IsEnabled = browser.CanGoForward;
-
- }
- string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
- {
- string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_Navigating(object sender, NavigatingEventArgs e)
- {
- string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/Media.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/Media.cs b/wp7/template/Plugins/Media.cs
deleted file mode 100644
index 5de4884..0000000
--- a/wp7/template/Plugins/Media.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides the ability to record and play back audio files on a device.
- /// </summary>
- public class Media : BaseCommand
- {
- /// <summary>
- /// Audio player objects
- /// </summary>
- private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
- /// <summary>
- /// Represents Media action options.
- /// </summary>
- [DataContract]
- public class MediaOptions
- {
- /// <summary>
- /// Audio id
- /// </summary>
- [DataMember(Name = "id", IsRequired = true)]
- public string Id { get; set; }
-
- /// <summary>
- /// Path to audio file
- /// </summary>
- [DataMember(Name = "src")]
- public string Src { get; set; }
-
- /// <summary>
- /// New track position
- /// </summary>
- [DataMember(Name = "milliseconds")]
- public int Milliseconds { get; set; }
- }
-
- /// <summary>
- /// Releases the audio player instance to save memory.
- /// </summary>
- public void release(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- Media.players.Remove(mediaOptions.Id);
- audio.Dispose();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts recording and save the specified file
- /// </summary>
- public void startRecordingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (mediaOptions != null)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio;
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- audio = Media.players[mediaOptions.Id];
- }
-
- if (audio != null)
- {
- audio.startRecording(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
- }
-
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
-
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Stops recording and save to the file specified when recording started
- /// </summary>
- public void stopRecordingAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopRecording();
- Media.players.Remove(mediaId);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- public void setVolume(string options) // id,volume
- {
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- string id = optionsString[0];
- double volume = double.Parse(optionsString[1]);
-
- if (Media.players.ContainsKey(id))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer player = Media.players[id];
- player.setVolume(volume);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
- return;
- }
- }
-
- // Some Audio Notes:
- // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
- // While playing, a MediaElement stops all other media playback on the phone.
- // Multiple MediaElement controls are NOT supported
-
- // Called when you create a new Media('blah') object in JS.
- public void create(string options)
- {
- // Debug.WriteLine("Creating Audio :: " + options);
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
- return;
- }
-
- AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- public void startPlayingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- if (optionsString.Length > 2 && optionsString[2] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[2]);
- }
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
- audio = Media.players[mediaOptions.Id];
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- audio.startPlaying(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Seeks to a location
- /// </summary>
- public void seekToAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- if (optionsString.Length > 1 && optionsString[1] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[1]);
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- audio.seekToPlaying(mediaOptions.Milliseconds);
- }
- else
- {
- Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlayingAudio(string options)
- {
-
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.pausePlaying();
- }
- else
- {
- Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
-
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlayingAudio(String options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopPlaying();
- }
- else
- {
- Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- public void getCurrentPositionAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
- }
-
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
-
- [Obsolete("This method will be removed shortly")]
- public void getDurationAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = Media.players[mediaOptions.Id];
- }
- else
- {
- Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
- }
-}
[43/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Globalization.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Globalization.cs b/common-items/Plugins/Globalization.cs
deleted file mode 100644
index 2c2f468..0000000
--- a/common-items/Plugins/Globalization.cs
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides information about system locale, culture settings, number formats, ect.
- /// </summary>
- public class Globalization : BaseCommand
- {
-
- #region Globalization errors
-
- /// <summary>
- /// Globalization error codes.
- /// </summary>
- public enum ErrorCode : int
- {
- UnknownError = 0,
- FormattingError = 1,
- ParsingError = 2,
- PatternError = 3
- }
-
- /// <summary>
- /// Represents globalization error object.
- /// </summary>
- [DataContract]
- public class GlobalizationError
- {
- #region Error messages
- /// <summary>
- /// Error messages
- /// </summary>
- public const string UnknownError = "UNKNOWN_ERROR";
- public const string FormattingError = "FORMATTIN_ERROR";
- public const string ParsingError = "PARSING_ERROR";
- public const string PatternError = "PATTERN_ERROR";
-
- #endregion
-
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = false)]
- public ErrorCode Code { get; set; }
-
- /// <summary>
- /// Error message
- /// </summary>
- [DataMember(Name = "message", IsRequired = false)]
- public string Message { get; set; }
-
- /// <summary>
- /// Default constructor
- /// </summary>
- public GlobalizationError()
- {
- this.Code = ErrorCode.UnknownError;
- this.Message = UnknownError;
- }
-
- /// <summary>
- /// Constructor setting error code
- /// </summary>
- public GlobalizationError(ErrorCode error)
- {
- this.Code = error;
-
- switch (error)
- {
- case ErrorCode.ParsingError:
- {
- this.Message = ParsingError;
- break;
- }
- case ErrorCode.FormattingError:
- {
- this.Message = FormattingError;
- break;
- }
- case ErrorCode.PatternError:
- {
- this.Message = PatternError;
- break;
- }
- default:
- {
- this.Message = UnknownError;
- break;
- }
- }
- }
- }
-
- #endregion
-
- #region Globalization options
-
- /// <summary>
- /// Represents globalization options.
- /// </summary>
- [DataContract]
- public class GlobalizationOptions
- {
- #region available option values
- /// <summary>
- /// Number pattern types.
- /// </summary>
- public const string Percent = "percent";
- public const string Currency = "currency";
- public const string Decimal = "decimal";
-
- /// <summary>
- /// Format length types
- /// </summary>
- public const string Short = "short";
- public const string Medium = "medium";
- public const string Long = "long";
- public const string Full = "full";
-
- /// <summary>
- /// Selector types
- /// </summary>
- public const string TimeSelector = "time";
- public const string DateSelector = "date";
- public const string DateAndTimeSelector = "date and time";
-
- /// <summary>
- /// Date name types
- /// </summary>
- public const string Narrow = "narrow";
- public const string Wide = "wide";
-
- /// <summary>
- /// Date name items
- /// </summary>
- public const string Months = "months";
- public const string Days = "days";
-
- #endregion
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "options", IsRequired = false)]
- public Options AdditionalOptions { get; set; }
-
- /// <summary>
- /// Date to convert
- /// </summary>
- [DataMember(Name = "date", IsRequired = false)]
- public long Date { get; set; }
-
- /// <summary>
- /// Date as stirng
- /// </summary>
- [DataMember(Name = "dateString", IsRequired = false)]
- public string DateString { get; set; }
-
- /// <summary>
- /// Currency code
- /// </summary>
- [DataMember(Name = "currencyCode", IsRequired = false)]
- public string CurrencyCode { get; set; }
-
- /// <summary>
- /// Number as string
- /// </summary>
- [DataMember(Name = "numberString", IsRequired = false)]
- public string NumberString { get; set; }
-
- /// <summary>
- /// Number to convert
- /// </summary>
- [DataMember(Name = "number", IsRequired = false)]
- public double Number { get; set; }
- }
-
- /// <summary>
- /// Represents additional options
- /// </summary>
- [DataContract]
- public class Options
- {
- /// <summary>
- /// Pattern type
- /// </summary>
- [DataMember(Name = "type", IsRequired = false)]
- public string Type { get; set; }
-
- /// <summary>
- /// Format length
- /// </summary>
- [DataMember(Name = "formatLength", IsRequired = false)]
- public string FormatLength { get; set; }
-
- /// <summary>
- /// Selector
- /// </summary>
- [DataMember(Name = "selector", IsRequired = false)]
- public string Selector { get; set; }
-
- /// <summary>
- /// Date name item
- /// </summary>
- [DataMember(Name = "item", IsRequired = false)]
- public string Item { get; set; }
- }
-
- #endregion
-
- #region returned objects
-
- #region Number pattern object
-
- /// <summary>
- /// Represents number pattern
- /// </summary>
- [DataContract]
- public class NumberPattern
- {
- /// <summary>
- /// Pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// Symbol
- /// </summary>
- [DataMember(Name = "symbol", IsRequired = false)]
- public string Symbol { get; set; }
-
- /// <summary>
- /// Fraction
- /// </summary>
- [DataMember(Name = "fraction", IsRequired = false)]
- public int Fraction { get; set; }
-
- /// <summary>
- /// Positive
- /// </summary>
- [DataMember(Name = "positive", IsRequired = false)]
- public string Positive { get; set; }
-
- /// <summary>
- /// Negative
- /// </summary>
- [DataMember(Name = "negative", IsRequired = false)]
- public string Negative { get; set; }
-
- /// <summary>
- /// Rounding
- /// </summary>
- [DataMember(Name = "rounding", IsRequired = false)]
- public int Rounding { get; set; }
-
- /// <summary>
- /// Decimal
- /// </summary>
- [DataMember(Name = "decimal", IsRequired = false)]
- public string Decimal { get; set; }
-
- /// <summary>
- /// Grouping
- /// </summary>
- [DataMember(Name = "grouping", IsRequired = false)]
- public string Grouping { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="symbol"></param>
- /// <param name="fraction"></param>
- /// <param name="positive"></param>
- /// <param name="negative"></param>
- /// <param name="rounding"></param>
- /// <param name="dec"></param>
- /// <param name="grouping"></param>
- public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
- {
- this.Pattern = pattern;
- this.Symbol = symbol;
- this.Fraction = fraction;
- this.Positive = positive;
- this.Negative = negative;
- this.Rounding = rounding;
- this.Decimal = dec;
- this.Grouping = grouping;
- }
- }
- #endregion
-
- #region Date format object
-
- /// <summary>
- /// Represents date format
- /// </summary>
- [DataContract]
- public class DateFormat
- {
- /// <summary>
- /// Year
- /// </summary>
- [DataMember(Name = "year", IsRequired = false)]
- public int Year { get; set; }
-
- /// <summary>
- /// Month
- /// </summary>
- [DataMember(Name = "month", IsRequired = false)]
- public int Month { get; set; }
-
- /// <summary>
- /// Day
- /// </summary>
- [DataMember(Name = "day", IsRequired = false)]
- public int Day { get; set; }
-
- /// <summary>
- /// Hour
- /// </summary>
- [DataMember(Name = "hour", IsRequired = false)]
- public int Hour { get; set; }
-
- /// <summary>
- /// Minute
- /// </summary>
- [DataMember(Name = "minute", IsRequired = false)]
- public int Minute { get; set; }
-
- /// <summary>
- /// Second
- /// </summary>
- [DataMember(Name = "second", IsRequired = false)]
- public int Second { get; set; }
-
- /// <summary>
- /// Millisecond
- /// </summary>
- [DataMember(Name = "millisecond", IsRequired = false)]
- public int Millisecond { get; set; }
-
- public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
- {
- this.Year = year;
- this.Month = month;
- this.Day = day;
- this.Hour = hour;
- this.Minute = minute;
- this.Millisecond = millisecond;
- }
-
- }
- #endregion
-
- #region Date pattern object
-
- /// <summary>
- /// Represents date pattern object
- /// </summary>
- [DataContract]
- public class DatePattern
- {
-
- /// <summary>
- /// Date pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// TimeZone
- /// </summary>
- [DataMember(Name = "timezone", IsRequired = false)]
- public string TimeZone { get; set; }
-
- /// <summary>
- /// UTC offset
- /// </summary>
- [DataMember(Name = "utc_offset", IsRequired = false)]
- public double UtcOffset { get; set; }
-
- /// <summary>
- /// Dst offset
- /// </summary>
- [DataMember(Name = "dst_offset", IsRequired = false)]
- public double DstOffset { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="timezone"></param>
- /// <param name="utcOffset"></param>
- /// <param name="dstOffset"></param>
- public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
- {
- this.Pattern = pattern;
- this.TimeZone = timezone;
- this.UtcOffset = utcOffset;
- this.DstOffset = dstOffset;
- }
-
- }
-
- #endregion
-
- #endregion
-
- #region Locale info
-
- /// <summary>
- /// Gets the string identifier for the client's current locale setting.
- /// </summary>
- /// <param name="options"></param>
- public void getLocaleName(string options)
- {
- try
- {
- var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the string identifier for the client's current language.
- /// </summary>
- /// <param name="options"></param>
- public void getPreferredLanguage(string options)
- {
- try
- {
- var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Date and time info
-
- /// <summary>
- /// Gets whether daylight savings time is in effect for a given date using the client's
- /// time zone and calendar.
- /// </summary>
- /// <param name="opitons">Date to daylight savings check.</param>
- public void isDayLightSavingsTime(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the first day of the week according to the client's user preferences and calendar.
- /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
- /// </summary>
- /// <param name="options"></param>
- public void getFirstDayOfWeek(string options)
- {
- try
- {
- // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
- var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Formatting
-
- /// <summary>
- /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client.
- /// </summary>
- /// <param name="options"></param>
- public void dateToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-
- string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
- break;
- }
- case 10: // short date
- {
- format = "{0:d}";
- break;
- }
- case 11: // full date
- {
- format = "{0:D}";
- break;
- }
- case 20: // short time
- {
- format = "{0:t}";
- break;
- }
- case 21: // full time
- {
- format = "{0:T}";
- break;
- }
- default: // short datetime
- {
- format = "{0:M/dd/yy H:m:s}";
- break;
- }
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
- /// </summary>
- /// <param name="options"></param>
- public void stringToDate(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.DateString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string format = "M/dd/yy H:m:s"; // short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "MMMM/dddd/yyyy HH:mm:ss tt";
- break;
- }
- case 10: // short date
- {
- format = "d";
- break;
- }
- case 11: // full date
- {
- format = "D";
- break;
- }
- case 20: // short time
- {
- format = "t";
- break;
- }
- case 21: // full time
- {
- format = "T";
- break;
- }
- default: // short datetime
- {
- format = "M/dd/yy H:m:s";
- break;
- }
- }
- }
-
- DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
- DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getDatePattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
- string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- case 10: // short date
- {
- pattern = dateFormatInfo.ShortDatePattern;
- break;
- }
- case 11: // full date
- {
- pattern = dateFormatInfo.LongDatePattern;
- break;
- }
- case 20: // short time
- {
- pattern = dateFormatInfo.ShortTimePattern;
- break;
- }
- case 21: // full time
- {
- pattern = dateFormatInfo.LongTimePattern;
- break;
- }
- default: // short datetime
- {
- // Seems like C# doesn't support short datetime pattern so we use full format
- // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- }
- }
-
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
- /// </summary>
- /// <param name="options"></param>
- public void getDateNames(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- int type = 0; //default wide
- int item = 0; //default months
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.Type != null)
- {
- string t = globalOptions.AdditionalOptions.Type;
-
- if (t.Equals(GlobalizationOptions.Narrow))
- {
- type++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Item != null)
- {
- string t = globalOptions.AdditionalOptions.Item;
-
- if (t.Equals(GlobalizationOptions.Days))
- {
- item += 10;
- }
- }
- }
-
- //determine return value
- int method = item + type;
- string[] namesArray;
- CultureInfo currentCulture = CultureInfo.CurrentCulture;
-
- if (method == 1) //months and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
- }
- else if (method == 10) //days and wide
- {
- namesArray = currentCulture.DateTimeFormat.DayNames;
- }
- else if (method == 11) //days and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
- }
- else //default: months and wide
- {
- namesArray = currentCulture.DateTimeFormat.MonthNames;
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void numberToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- string format = string.Empty;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- format = "{0:p}";
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- format = "{0:c}";
- break;
- }
-
- default:
- {
- format = "{0:f}";
- break;
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
- /// </summary>
- /// <param name="options"></param>
- public void stringToNumber(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.NumberString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string numberString = globalOptions.NumberString;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- NumberStyles numberStyle;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- numberStyle = NumberStyles.Any;
- numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- numberStyle = NumberStyles.Currency;
- break;
- }
-
- default:
- {
- numberStyle = NumberStyles.Number;
- break;
- }
- }
-
- double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getNumberPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- CultureInfo cultureInfo = CultureInfo.CurrentCulture;
- NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
- NumberPattern pattern = null;
- string symbol;
-
- // TODO find out how to get format pattern and the number of fraction digits
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- symbol = formatInfo.PercentSymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
- break;
- }
- case GlobalizationOptions.Currency:
- {
- symbol = formatInfo.CurrencySymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
- break;
- }
- default:
- {
- symbol = formatInfo.NumberDecimalSeparator;
- pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
- break;
- }
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
- /// </summary>
- /// <param name="options"></param>
- public void getCurrencyPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string currencyCode = globalOptions.CurrencyCode;
-
- // temporary not supported via lack of api required
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
- return;
-
- // TODO find the way to get currency info from currency code
- // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
- // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
- // CultureInfo cultureInfo = new CultureInfo(currencyCode);
- // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- #endregion
-
- #region private methods
-
- /// <summary>
- /// Wraps data into JSON format
- /// </summary>
- /// <param name="data">data</param>
- /// <returns>data formatted as JSON object</returns>
- private string WrapIntoJSON<T>(T data, string keyName = "value")
- {
- string param = "{0}";
- string stringifiedData = data.ToString();
-
- if (data.GetType() == typeof(string))
- {
- param = "\"" + param + "\"";
- }
-
- if (data.GetType() == typeof(bool))
- {
- stringifiedData = stringifiedData.ToLower();
- }
-
- if (data.GetType() == typeof(string[]))
- {
- stringifiedData = JSON.JsonHelper.Serialize(data);
- }
-
- var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
- formattedData = "{" + formattedData + "}";
-
- return formattedData;
- }
-
- #endregion
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/ImageExifHelper.cs b/common-items/Plugins/ImageExifHelper.cs
deleted file mode 100644
index 68ddf87..0000000
--- a/common-items/Plugins/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- 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.
-
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class ImageExifOrientation
- {
- public const int Portrait = 1;
- public const int PortraitUpsideDown = 3;
- public const int LandscapeLeft = 6;
- public const int LandscapeRight = 8;
- }
-
- public class ImageExifHelper
- {
-
- public static Stream RotateStream(Stream stream, int angle)
- {
- stream.Position = 0;
- if (angle % 90 != 0 || angle < 0)
- {
- throw new ArgumentException();
- }
- if (angle % 360 == 0)
- {
- return stream;
- }
-
- angle = angle % 360;
-
- BitmapImage bitmap = new BitmapImage();
- bitmap.SetSource(stream);
- WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
- WriteableBitmap wbTarget = null;
-
- int srcPixelWidth = wbSource.PixelWidth;
- int srcPixelHeight = wbSource.PixelHeight;
-
- if (angle % 180 == 0)
- {
- wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
- }
- else
- {
- wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
- }
-
- int destPixelWidth = wbTarget.PixelWidth;
- int[] srcPxls = wbSource.Pixels;
- int[] destPxls = wbTarget.Pixels;
-
- // this ugly if/else is to avoid a conditional check for every pixel
- if (angle == 90)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 180)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 270)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
-
- MemoryStream targetStream = new MemoryStream();
- wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
- return targetStream;
- }
-
- public static int getImageOrientationFromStream(Stream imgStream)
- {
-
- // 0xFFD8 : jpgHeader
- // 0xFFE1 :
- // 0x???? : length of exif data
- // 0x????, 0x???? : Chars 'E','x','i','f'
- // 0x0000 : 2 empty bytes
- // <== mark beginning of tags SIZE:ID:VALUE
- // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determins littleEndian-ness
- // 0x002A : marker value
- // 0x???? : offset to the Image File Data
-
- // XXXX possible space before actual tag data ... we skip to mark + offset
-
- // 0x???? number of exif tags present
-
- // make sure we are at the begining
- imgStream.Seek(0, SeekOrigin.Begin);
- BinaryReader reader = new BinaryReader(imgStream);
-
- byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
- byte start = reader.ReadByte(); // 0xFF
- byte index = reader.ReadByte(); // 0xE1
-
- while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
- {
- // Get the data length
- ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // skip along
- reader.ReadBytes(dLen - 2);
- start = reader.ReadByte();
- index = reader.ReadByte();
- }
-
- // It's only success if we found the 0xFFE1 marker
- if (start != 0xFF || index != 0xE1)
- {
- // throw new Exception("Could not find Exif data block");
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 byte length of EXIF data
- ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- String exif = ""; // build the string
- for (var n = 0; n < 4; n++)
- {
- exif += reader.ReadChar();
- }
- if (exif != "Exif")
- {
- // did not find exif data ...
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 empty bytes
- //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- reader.ReadBytes(2);
-
- long headerMark = reader.BaseStream.Position; // where are we now <==
-
- //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
- reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
- if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- Debug.WriteLine("Error in data != 0x002A");
- return 0;
- }
-
- // Get the offset to the IFD (image file directory)
- ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
- imgStream.Position = headerMark + imgOffset;
- ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- for (ushort x = 0; x < tagCount; x++)
- {
- // Orientation = 0x112, aka 274
- if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // don't care ..
- uint comps = reader.ReadUInt32();
- byte[] tagData = reader.ReadBytes(4);
- int orientation = (int)tagData[0];
- Debug.WriteLine("orientation = " + orientation.ToString());
- return orientation;
- // 6 means rotate clockwise 90 deg
- // 8 means rotate counter-clockwise 90 deg
- // 1 means all is good
- // 3 means flip vertical
- }
- // skip to the next item, 12 bytes each
- reader.BaseStream.Seek(10, SeekOrigin.Current);
- }
- return 0;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/InAppBrowser.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/InAppBrowser.cs b/common-items/Plugins/InAppBrowser.cs
deleted file mode 100644
index 2741355..0000000
--- a/common-items/Plugins/InAppBrowser.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using WPCordovaClassLib.Cordova;
-using WPCordovaClassLib.Cordova.Commands;
-using WPCordovaClassLib.Cordova.JSON;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class BrowserOptions
- {
- [DataMember]
- public string url;
-
- [DataMember]
- public bool isGeolocationEnabled;
- }
-
- public class InAppBrowser : BaseCommand
- {
-
- private static WebBrowser browser;
- private static ApplicationBarIconButton backButton;
- private static ApplicationBarIconButton fwdButton;
-
- public void open(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
- string urlLoc = args[0];
- string target = args[1];
- /*
- _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
- _blank - always open in the InAppBrowser
- _system - always open in the system web browser
- */
- switch (target)
- {
- case "_blank":
- ShowInAppBrowser(urlLoc);
- break;
- case "_self":
- ShowCordovaBrowser(urlLoc);
- break;
- case "_system":
- ShowSystemBrowser(urlLoc);
- break;
- }
-
-
- }
-
- private void ShowCordovaBrowser(string url)
- {
- Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- CordovaView cView = page.FindName("CordovaView") as CordovaView;
- if (cView != null)
- {
- WebBrowser br = cView.Browser;
- br.Navigate(loc);
- }
- }
-
- }
- });
- }
-
- private void ShowSystemBrowser(string url)
- {
- WebBrowserTask webBrowserTask = new WebBrowserTask();
- webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
- webBrowserTask.Show();
- }
-
-
- private void ShowInAppBrowser(string url)
- {
- Uri loc = new Uri(url);
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (browser != null)
- {
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- browser.Navigate(loc);
- }
- else
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- string baseImageUrl = "Images/";
-
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- browser = new WebBrowser();
- browser.IsScriptEnabled = true;
- browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-
- browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
- browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
- browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
- browser.Navigate(loc);
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- grid.Children.Add(browser);
- }
-
- ApplicationBar bar = new ApplicationBar();
- bar.BackgroundColor = Colors.Gray;
- bar.IsMenuEnabled = false;
-
- backButton = new ApplicationBarIconButton();
- backButton.Text = "Back";
-
- backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
- backButton.Click += new EventHandler(backButton_Click);
- backButton.IsEnabled = false;
- bar.Buttons.Add(backButton);
-
-
- fwdButton = new ApplicationBarIconButton();
- fwdButton.Text = "Forward";
- fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
- fwdButton.Click += new EventHandler(fwdButton_Click);
- fwdButton.IsEnabled = false;
- bar.Buttons.Add(fwdButton);
-
- ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
- closeBtn.Text = "Close";
- closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
- closeBtn.Click += new EventHandler(closeBtn_Click);
- bar.Buttons.Add(closeBtn);
-
- page.ApplicationBar = bar;
- }
-
- }
- }
- });
- }
-
- void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
-
- }
-
- void fwdButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoForward();
- //browser.InvokeScript("execScript", "history.forward();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void backButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoBack();
- //browser.InvokeScript("execScript", "history.back();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void closeBtn_Click(object sender, EventArgs e)
- {
- this.close();
- }
-
-
- public void close(string options = "")
- {
- if (browser != null)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(browser);
- }
- page.ApplicationBar = null;
- }
- }
- browser = null;
- string message = "{\"type\":\"exit\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = false;
- this.DispatchCommandResult(result);
- });
- }
- }
-
- void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (browser != null)
- {
- backButton.IsEnabled = browser.CanGoBack;
- fwdButton.IsEnabled = browser.CanGoForward;
-
- }
- string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
- {
- string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_Navigating(object sender, NavigatingEventArgs e)
- {
- string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Media.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Media.cs b/common-items/Plugins/Media.cs
deleted file mode 100644
index 5de4884..0000000
--- a/common-items/Plugins/Media.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides the ability to record and play back audio files on a device.
- /// </summary>
- public class Media : BaseCommand
- {
- /// <summary>
- /// Audio player objects
- /// </summary>
- private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
- /// <summary>
- /// Represents Media action options.
- /// </summary>
- [DataContract]
- public class MediaOptions
- {
- /// <summary>
- /// Audio id
- /// </summary>
- [DataMember(Name = "id", IsRequired = true)]
- public string Id { get; set; }
-
- /// <summary>
- /// Path to audio file
- /// </summary>
- [DataMember(Name = "src")]
- public string Src { get; set; }
-
- /// <summary>
- /// New track position
- /// </summary>
- [DataMember(Name = "milliseconds")]
- public int Milliseconds { get; set; }
- }
-
- /// <summary>
- /// Releases the audio player instance to save memory.
- /// </summary>
- public void release(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- Media.players.Remove(mediaOptions.Id);
- audio.Dispose();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts recording and save the specified file
- /// </summary>
- public void startRecordingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (mediaOptions != null)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio;
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- audio = Media.players[mediaOptions.Id];
- }
-
- if (audio != null)
- {
- audio.startRecording(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
- }
-
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
-
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Stops recording and save to the file specified when recording started
- /// </summary>
- public void stopRecordingAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopRecording();
- Media.players.Remove(mediaId);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- public void setVolume(string options) // id,volume
- {
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- string id = optionsString[0];
- double volume = double.Parse(optionsString[1]);
-
- if (Media.players.ContainsKey(id))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer player = Media.players[id];
- player.setVolume(volume);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
- return;
- }
- }
-
- // Some Audio Notes:
- // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
- // While playing, a MediaElement stops all other media playback on the phone.
- // Multiple MediaElement controls are NOT supported
-
- // Called when you create a new Media('blah') object in JS.
- public void create(string options)
- {
- // Debug.WriteLine("Creating Audio :: " + options);
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
- return;
- }
-
- AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- public void startPlayingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- if (optionsString.Length > 2 && optionsString[2] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[2]);
- }
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
- audio = Media.players[mediaOptions.Id];
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- audio.startPlaying(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Seeks to a location
- /// </summary>
- public void seekToAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- if (optionsString.Length > 1 && optionsString[1] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[1]);
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- audio.seekToPlaying(mediaOptions.Milliseconds);
- }
- else
- {
- Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlayingAudio(string options)
- {
-
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.pausePlaying();
- }
- else
- {
- Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
-
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlayingAudio(String options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopPlaying();
- }
- else
- {
- Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- public void getCurrentPositionAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
- }
-
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
-
- [Obsolete("This method will be removed shortly")]
- public void getDurationAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = Media.players[mediaOptions.Id];
- }
- else
- {
- Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
- }
-}
[40/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/www/css/index.css
----------------------------------------------------------------------
diff --git a/common-items/www/css/index.css b/common-items/www/css/index.css
deleted file mode 100644
index f1f9d76..0000000
--- a/common-items/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-* {
- -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
- -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
- -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
- -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
-}
-
-body {
- background-color:#E4E4E4;
- background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-webkit-gradient(
- linear,
- left top,
- left bottom,
- color-stop(0, #A7A7A7),
- color-stop(0.51, #E4E4E4)
- );
- background-attachment:fixed;
- font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
- font-size:12px;
- height:100%;
- margin:0px;
- padding:0px;
- text-transform:uppercase;
- width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
- background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
- position:absolute; /* position in the center of the screen */
- left:50%;
- top:50%;
- height:50px; /* text area height */
- width:225px; /* text area width */
- text-align:center;
- padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
- margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
- /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
- .app {
- background-position:left center;
- padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
- margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
- /* offset horizontal: half of image width and text area width */
- }
-}
-
-h1 {
- font-size:24px;
- font-weight:normal;
- margin:0px;
- overflow:visible;
- padding:0px;
- text-align:center;
-}
-
-.event {
- border-radius:4px;
- -webkit-border-radius:4px;
- color:#FFFFFF;
- font-size:12px;
- margin:0px 30px;
- padding:2px 0px;
-}
-
-.event.listening {
- background-color:#333333;
- display:block;
-}
-
-.event.received {
- background-color:#4B946A;
- display:none;
-}
-
-@keyframes fade {
- from { opacity: 1.0; }
- 50% { opacity: 0.4; }
- to { opacity: 1.0; }
-}
-
-@-webkit-keyframes fade {
- from { opacity: 1.0; }
- 50% { opacity: 0.4; }
- to { opacity: 1.0; }
-}
-
-.blink {
- animation:fade 3000ms infinite;
- -webkit-animation:fade 3000ms infinite;
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/www/img/logo.png
----------------------------------------------------------------------
diff --git a/common-items/www/img/logo.png b/common-items/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/common-items/www/img/logo.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/www/index.html
----------------------------------------------------------------------
diff --git a/common-items/www/index.html b/common-items/www/index.html
deleted file mode 100644
index 842b364..0000000
--- a/common-items/www/index.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<!--
- 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.
--->
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="format-detection" content="telephone=no" />
- <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
- <link rel="stylesheet" type="text/css" href="css/index.css" />
- <title>Hello World</title>
- </head>
- <body>
- <div class="app">
- <h1>Apache Cordova</h1>
- <div id="deviceready" class="blink">
- <p class="event listening">Connecting to Device</p>
- <p class="event received">Device is Ready</p>
- </div>
- </div>
- <script type="text/javascript" src="cordova.js"></script>
- <script type="text/javascript" src="js/index.js"></script>
- <script type="text/javascript">
- app.initialize();
- </script>
- </body>
-</html>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/www/js/index.js
----------------------------------------------------------------------
diff --git a/common-items/www/js/index.js b/common-items/www/js/index.js
deleted file mode 100644
index 3b75d3f..0000000
--- a/common-items/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 app = {
- // Application Constructor
- initialize: function() {
- this.bindEvents();
- },
- // Bind Event Listeners
- //
- // Bind any events that are required on startup. Common events are:
- // `load`, `deviceready`, `offline`, and `online`.
- bindEvents: function() {
- document.addEventListener('deviceready', this.onDeviceReady, false);
- },
- // deviceready Event Handler
- //
- // The scope of `this` is the event. In order to call the `receivedEvent`
- // function, we must explicity call `app.receivedEvent(...);`
- onDeviceReady: function() {
- app.receivedEvent('deviceready');
- },
- // Update DOM on a Received Event
- receivedEvent: function(id) {
- var parentElement = document.getElementById(id);
- var listeningElement = parentElement.querySelector('.listening');
- var receivedElement = parentElement.querySelector('.received');
-
- listeningElement.setAttribute('style', 'display:none;');
- receivedElement.setAttribute('style', 'display:block;');
-
- console.log('Received Event: ' + id);
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/ApplicationIcon.png
----------------------------------------------------------------------
diff --git a/common/ApplicationIcon.png b/common/ApplicationIcon.png
new file mode 100644
index 0000000..6b69046
Binary files /dev/null and b/common/ApplicationIcon.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Background.png
----------------------------------------------------------------------
diff --git a/common/Background.png b/common/Background.png
new file mode 100644
index 0000000..2667df4
Binary files /dev/null and b/common/Background.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Images/appbar.back.rest.png
----------------------------------------------------------------------
diff --git a/common/Images/appbar.back.rest.png b/common/Images/appbar.back.rest.png
new file mode 100644
index 0000000..4bc2b92
Binary files /dev/null and b/common/Images/appbar.back.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Images/appbar.close.rest.png
----------------------------------------------------------------------
diff --git a/common/Images/appbar.close.rest.png b/common/Images/appbar.close.rest.png
new file mode 100644
index 0000000..8166a1c
Binary files /dev/null and b/common/Images/appbar.close.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Images/appbar.feature.video.rest.png
----------------------------------------------------------------------
diff --git a/common/Images/appbar.feature.video.rest.png b/common/Images/appbar.feature.video.rest.png
new file mode 100644
index 0000000..baff565
Binary files /dev/null and b/common/Images/appbar.feature.video.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Images/appbar.next.rest.png
----------------------------------------------------------------------
diff --git a/common/Images/appbar.next.rest.png b/common/Images/appbar.next.rest.png
new file mode 100644
index 0000000..ed577d7
Binary files /dev/null and b/common/Images/appbar.next.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Images/appbar.save.rest.png
----------------------------------------------------------------------
diff --git a/common/Images/appbar.save.rest.png b/common/Images/appbar.save.rest.png
new file mode 100644
index 0000000..d49940e
Binary files /dev/null and b/common/Images/appbar.save.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Images/appbar.stop.rest.png
----------------------------------------------------------------------
diff --git a/common/Images/appbar.stop.rest.png b/common/Images/appbar.stop.rest.png
new file mode 100644
index 0000000..4dd724f
Binary files /dev/null and b/common/Images/appbar.stop.rest.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Accelerometer.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Accelerometer.cs b/common/Plugins/Accelerometer.cs
new file mode 100644
index 0000000..cba911c
--- /dev/null
+++ b/common/Plugins/Accelerometer.cs
@@ -0,0 +1,196 @@
+/*
+ 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.
+*/
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading;
+using Microsoft.Devices.Sensors;
+using System.Globalization;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Captures device motion in the x, y, and z direction.
+ /// </summary>
+ public class Accelerometer : BaseCommand
+ {
+ #region AccelerometerOptions class
+ /// <summary>
+ /// Represents Accelerometer options.
+ /// </summary>
+ [DataContract]
+ public class AccelerometerOptions
+ {
+ /// <summary>
+ /// How often to retrieve the Acceleration in milliseconds
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "frequency")]
+ public int Frequency { get; set; }
+
+ /// <summary>
+ /// Watcher id
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "id")]
+ public string Id { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public AccelerometerOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ this.Frequency = 10000;
+ }
+ }
+
+ #endregion
+
+ #region Status codes and Constants
+
+ public const int Stopped = 0;
+ public const int Starting = 1;
+ public const int Running = 2;
+ public const int ErrorFailedToStart = 3;
+
+ public const double gConstant = -9.81;
+
+ #endregion
+
+ #region Static members
+
+ /// <summary>
+ /// Status of listener
+ /// </summary>
+ private static int currentStatus;
+
+ /// <summary>
+ /// Accelerometer
+ /// </summary>
+ private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
+
+ private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
+
+ #endregion
+
+ /// <summary>
+ /// Sensor listener event
+ /// </summary>
+ private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
+ {
+ this.SetStatus(Running);
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+
+ /// <summary>
+ /// Starts listening for acceleration sensor
+ /// </summary>
+ /// <returns>status of listener</returns>
+ public void start(string options)
+ {
+ if ((currentStatus == Running) || (currentStatus == Starting))
+ {
+ return;
+ }
+ try
+ {
+ lock (accelerometer)
+ {
+ accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
+ accelerometer.Start();
+ this.SetStatus(Starting);
+ }
+
+ long timeout = 2000;
+ while ((currentStatus == Starting) && (timeout > 0))
+ {
+ timeout = timeout - 100;
+ Thread.Sleep(100);
+ }
+
+ if (currentStatus != Running)
+ {
+ this.SetStatus(ErrorFailedToStart);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+ return;
+ }
+ }
+ catch (Exception)
+ {
+ this.SetStatus(ErrorFailedToStart);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+ return;
+ }
+ PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+
+ public void stop(string options)
+ {
+ if (currentStatus == Running)
+ {
+ lock (accelerometer)
+ {
+ accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
+ accelerometer.Stop();
+ this.SetStatus(Stopped);
+ }
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+ }
+
+ /// <summary>
+ /// Formats current coordinates into JSON format
+ /// </summary>
+ /// <returns>Coordinates in JSON format</returns>
+ private string GetCurrentAccelerationFormatted()
+ {
+ // convert to unix timestamp
+ // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
+ // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
+ // this resolves an issue with inconsistencies between JS dates and Native DateTime
+ string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
+ (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
+ (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
+ (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
+ return "{" + resultCoordinates + "}";
+ }
+
+ /// <summary>
+ /// Sets current status
+ /// </summary>
+ /// <param name="status">current status</param>
+ private void SetStatus(int status)
+ {
+ currentStatus = status;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/AudioFormatsHelper.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/AudioFormatsHelper.cs b/common/Plugins/AudioFormatsHelper.cs
new file mode 100644
index 0000000..dca7ee6
--- /dev/null
+++ b/common/Plugins/AudioFormatsHelper.cs
@@ -0,0 +1,89 @@
+/*
+ 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.
+
+ */
+
+using System;
+using System.IO;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides extra functionality to support different audio formats.
+ /// </summary>
+ public static class AudioFormatsHelper
+ {
+ #region Wav
+ /// <summary>
+ /// Adds wav file format header to the stream
+ /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ /// </summary>
+ /// <param name="stream">The stream</param>
+ /// <param name="sampleRate">Sample Rate</param>
+ public static void InitializeWavStream(this Stream stream, int sampleRate)
+ {
+ #region args checking
+
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream can't be null or empty");
+ }
+
+ #endregion
+
+ int numBits = 16;
+ int numBytes = numBits / 8;
+
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
+ stream.Write(BitConverter.GetBytes(0), 0, 4);
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
+ stream.Write(BitConverter.GetBytes(16), 0, 4);
+ stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+ stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+ stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
+ stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
+ stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
+ stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
+ stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
+ stream.Write(BitConverter.GetBytes(0), 0, 4);
+ }
+
+ /// <summary>
+ /// Updates wav file format header
+ /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ /// </summary>
+ /// <param name="stream">Wav stream</param>
+ public static void UpdateWavStream(this Stream stream)
+ {
+ #region args checking
+
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream can't be null or empty");
+ }
+
+ #endregion
+
+ var position = stream.Position;
+
+ stream.Seek(4, SeekOrigin.Begin);
+ stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
+ stream.Seek(40, SeekOrigin.Begin);
+ stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
+ stream.Seek(position, SeekOrigin.Begin);
+ }
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/AudioPlayer.cs b/common/Plugins/AudioPlayer.cs
new file mode 100644
index 0000000..a83be5b
--- /dev/null
+++ b/common/Plugins/AudioPlayer.cs
@@ -0,0 +1,620 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Threading;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Media;
+using Microsoft.Phone.Controls;
+using System.Diagnostics;
+using System.Windows.Resources;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Implements audio record and play back functionality.
+ /// </summary>
+ internal class AudioPlayer : IDisposable
+ {
+ #region Constants
+
+ // AudioPlayer states
+ private const int PlayerState_None = 0;
+ private const int PlayerState_Starting = 1;
+ private const int PlayerState_Running = 2;
+ private const int PlayerState_Paused = 3;
+ private const int PlayerState_Stopped = 4;
+
+ // AudioPlayer messages
+ private const int MediaState = 1;
+ private const int MediaDuration = 2;
+ private const int MediaPosition = 3;
+ private const int MediaError = 9;
+
+ // AudioPlayer errors
+ private const int MediaErrorPlayModeSet = 1;
+ private const int MediaErrorAlreadyRecording = 2;
+ private const int MediaErrorStartingRecording = 3;
+ private const int MediaErrorRecordModeSet = 4;
+ private const int MediaErrorStartingPlayback = 5;
+ private const int MediaErrorResumeState = 6;
+ private const int MediaErrorPauseState = 7;
+ private const int MediaErrorStopState = 8;
+
+ //TODO: get rid of this callback, it should be universal
+ //private const string CallbackFunction = "CordovaMediaonStatus";
+
+ #endregion
+
+ /// <summary>
+ /// The AudioHandler object
+ /// </summary>
+ private Media handler;
+
+ /// <summary>
+ /// Temporary buffer to store audio chunk
+ /// </summary>
+ private byte[] buffer;
+
+ /// <summary>
+ /// Xna game loop dispatcher
+ /// </summary>
+ DispatcherTimer dtXna;
+
+ /// <summary>
+ /// Output buffer
+ /// </summary>
+ private MemoryStream memoryStream;
+
+ /// <summary>
+ /// The id of this player (used to identify Media object in JavaScript)
+ /// </summary>
+ private String id;
+
+ /// <summary>
+ /// State of recording or playback
+ /// </summary>
+ private int state = PlayerState_None;
+
+ /// <summary>
+ /// File name to play or record to
+ /// </summary>
+ private String audioFile = null;
+
+ /// <summary>
+ /// Duration of audio
+ /// </summary>
+ private double duration = -1;
+
+ /// <summary>
+ /// Audio player object
+ /// </summary>
+ private MediaElement player = null;
+
+ /// <summary>
+ /// Audio source
+ /// </summary>
+ private Microphone recorder;
+
+ /// <summary>
+ /// Internal flag specified that we should only open audio w/o playing it
+ /// </summary>
+ private bool prepareOnly = false;
+
+ /// <summary>
+ /// Creates AudioPlayer instance
+ /// </summary>
+ /// <param name="handler">Media object</param>
+ /// <param name="id">player id</param>
+ public AudioPlayer(Media handler, String id)
+ {
+ this.handler = handler;
+ this.id = id;
+ }
+
+ /// <summary>
+ /// Destroys player and stop audio playing or recording
+ /// </summary>
+ public void Dispose()
+ {
+ if (this.player != null)
+ {
+ this.stopPlaying();
+ this.player = null;
+ }
+ if (this.recorder != null)
+ {
+ this.stopRecording();
+ this.recorder = null;
+ }
+
+ this.FinalizeXnaGameLoop();
+ }
+
+ private void InvokeCallback(int message, string value, bool removeHandler)
+ {
+ string args = string.Format("('{0}',{1},{2});", this.id, message, value);
+ string callback = @"(function(id,msg,value){
+ try {
+ if (msg == Media.MEDIA_ERROR) {
+ value = {'code':value};
+ }
+ Media.onStatus(id,msg,value);
+ }
+ catch(e) {
+ console.log('Error calling Media.onStatus :: ' + e);
+ }
+ })" + args;
+ this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
+ }
+
+ private void InvokeCallback(int message, int value, bool removeHandler)
+ {
+ InvokeCallback(message, value.ToString(), removeHandler);
+ }
+
+ private void InvokeCallback(int message, double value, bool removeHandler)
+ {
+ InvokeCallback(message, value.ToString(), removeHandler);
+ }
+
+ /// <summary>
+ /// Starts recording, data is stored in memory
+ /// </summary>
+ /// <param name="filePath"></param>
+ public void startRecording(string filePath)
+ {
+ if (this.player != null)
+ {
+ InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
+ }
+ else if (this.recorder == null)
+ {
+ try
+ {
+ this.audioFile = filePath;
+ this.InitializeXnaGameLoop();
+ this.recorder = Microphone.Default;
+ this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
+ this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
+ this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
+ this.memoryStream = new MemoryStream();
+ this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
+ this.recorder.Start();
+ FrameworkDispatcher.Update();
+ this.SetState(PlayerState_Running);
+ }
+ catch (Exception)
+ {
+ InvokeCallback(MediaError, MediaErrorStartingRecording, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
+ }
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
+ }
+ }
+
+ /// <summary>
+ /// Stops recording
+ /// </summary>
+ public void stopRecording()
+ {
+ if (this.recorder != null)
+ {
+ if (this.state == PlayerState_Running)
+ {
+ try
+ {
+ this.recorder.Stop();
+ this.recorder.BufferReady -= recorderBufferReady;
+ this.recorder = null;
+ SaveAudioClipToLocalStorage();
+ this.FinalizeXnaGameLoop();
+ this.SetState(PlayerState_Stopped);
+ }
+ catch (Exception)
+ {
+ //TODO
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Starts or resume playing audio file
+ /// </summary>
+ /// <param name="filePath">The name of the audio file</param>
+ /// <summary>
+ /// Starts or resume playing audio file
+ /// </summary>
+ /// <param name="filePath">The name of the audio file</param>
+ public void startPlaying(string filePath)
+ {
+ if (this.recorder != null)
+ {
+ InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
+ return;
+ }
+
+
+ if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
+ {
+ try
+ {
+ // this.player is a MediaElement, it must be added to the visual tree in order to play
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+
+ this.player = grid.FindName("playerMediaElement") as MediaElement;
+ if (this.player == null) // still null ?
+ {
+ this.player = new MediaElement();
+ this.player.Name = "playerMediaElement";
+ grid.Children.Add(this.player);
+ this.player.Visibility = Visibility.Visible;
+ }
+ if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
+ {
+ this.player.Stop(); // stop it!
+ }
+
+ this.player.Source = null; // Garbage collect it.
+ this.player.MediaOpened += MediaOpened;
+ this.player.MediaEnded += MediaEnded;
+ this.player.MediaFailed += MediaFailed;
+ }
+ }
+ }
+
+ this.audioFile = filePath;
+
+ Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
+ if (uri.IsAbsoluteUri)
+ {
+ this.player.Source = uri;
+ }
+ else
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ // try to unpack it from the dll into isolated storage
+ StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
+ if (fileResourceStreamInfo != null)
+ {
+ using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
+ {
+ byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
+
+ string[] dirParts = filePath.Split('/');
+ string dirName = "";
+ for (int n = 0; n < dirParts.Length - 1; n++)
+ {
+ dirName += dirParts[n] + "/";
+ }
+ if (!isoFile.DirectoryExists(dirName))
+ {
+ isoFile.CreateDirectory(dirName);
+ }
+
+ using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
+ {
+ using (BinaryWriter writer = new BinaryWriter(outFile))
+ {
+ writer.Write(data);
+ }
+ }
+ }
+ }
+ }
+ if (isoFile.FileExists(filePath))
+ {
+ using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
+ {
+ this.player.SetSource(stream);
+ }
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
+ return;
+ }
+ }
+ }
+ this.SetState(PlayerState_Starting);
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
+ InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
+ }
+ }
+ else
+ {
+ if (this.state != PlayerState_Running)
+ {
+ this.player.Play();
+ this.SetState(PlayerState_Running);
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorResumeState, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Callback to be invoked when the media source is ready for playback
+ /// </summary>
+ private void MediaOpened(object sender, RoutedEventArgs arg)
+ {
+ if (this.player != null)
+ {
+ this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
+ InvokeCallback(MediaDuration, this.duration, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
+ if (!this.prepareOnly)
+ {
+ this.player.Play();
+ this.SetState(PlayerState_Running);
+ }
+ this.prepareOnly = false;
+ }
+ else
+ {
+ // TODO: occasionally MediaOpened is signalled, but player is null
+ }
+ }
+
+ /// <summary>
+ /// Callback to be invoked when playback of a media source has completed
+ /// </summary>
+ private void MediaEnded(object sender, RoutedEventArgs arg)
+ {
+ this.SetState(PlayerState_Stopped);
+ }
+
+ /// <summary>
+ /// Callback to be invoked when playback of a media source has failed
+ /// </summary>
+ private void MediaFailed(object sender, RoutedEventArgs arg)
+ {
+ player.Stop();
+ InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
+ }
+
+ /// <summary>
+ /// Seek or jump to a new time in the track
+ /// </summary>
+ /// <param name="milliseconds">The new track position</param>
+ public void seekToPlaying(int milliseconds)
+ {
+ if (this.player != null)
+ {
+ TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
+ this.player.Position = tsPos;
+ InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
+ }
+ }
+
+ /// <summary>
+ /// Set the volume of the player
+ /// </summary>
+ /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
+ public void setVolume(double vol)
+ {
+ if (this.player != null)
+ {
+ this.player.Volume = vol;
+ }
+ }
+
+ /// <summary>
+ /// Pauses playing
+ /// </summary>
+ public void pausePlaying()
+ {
+ if (this.state == PlayerState_Running)
+ {
+ this.player.Pause();
+ this.SetState(PlayerState_Paused);
+ }
+ else
+ {
+ InvokeCallback(MediaError, MediaErrorPauseState, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
+ }
+ }
+
+
+ /// <summary>
+ /// Stops playing the audio file
+ /// </summary>
+ public void stopPlaying()
+ {
+ if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
+ {
+ this.player.Stop();
+
+ this.player.Position = new TimeSpan(0L);
+ this.SetState(PlayerState_Stopped);
+ }
+ //else // Why is it an error to call stop on a stopped media?
+ //{
+ // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
+ //}
+ }
+
+ /// <summary>
+ /// Gets current position of playback
+ /// </summary>
+ /// <returns>current position</returns>
+ public double getCurrentPosition()
+ {
+ if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
+ {
+ double currentPosition = this.player.Position.TotalSeconds;
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
+ return currentPosition;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Gets the duration of the audio file
+ /// </summary>
+ /// <param name="filePath">The name of the audio file</param>
+ /// <returns>track duration</returns>
+ public double getDuration(string filePath)
+ {
+ if (this.recorder != null)
+ {
+ return (-2);
+ }
+
+ if (this.player != null)
+ {
+ return this.duration;
+
+ }
+ else
+ {
+ this.prepareOnly = true;
+ this.startPlaying(filePath);
+ return this.duration;
+ }
+ }
+
+ /// <summary>
+ /// Sets the state and send it to JavaScript
+ /// </summary>
+ /// <param name="state">state</param>
+ private void SetState(int state)
+ {
+ if (this.state != state)
+ {
+ InvokeCallback(MediaState, state, false);
+ //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
+ }
+
+ this.state = state;
+ }
+
+ #region record methods
+
+ /// <summary>
+ /// Copies data from recorder to memory storages and updates recording state
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void recorderBufferReady(object sender, EventArgs e)
+ {
+ this.recorder.GetData(this.buffer);
+ this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
+ }
+
+ /// <summary>
+ /// Writes audio data from memory to isolated storage
+ /// </summary>
+ /// <returns></returns>
+ private void SaveAudioClipToLocalStorage()
+ {
+ if (this.memoryStream == null || this.memoryStream.Length <= 0)
+ {
+ return;
+ }
+
+ this.memoryStream.UpdateWavStream();
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ string directory = Path.GetDirectoryName(audioFile);
+
+ if (!isoFile.DirectoryExists(directory))
+ {
+ isoFile.CreateDirectory(directory);
+ }
+
+ this.memoryStream.Seek(0, SeekOrigin.Begin);
+
+ using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
+ {
+ this.memoryStream.CopyTo(fileStream);
+ }
+ }
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+ #region Xna loop
+ /// <summary>
+ /// Special initialization required for the microphone: XNA game loop
+ /// </summary>
+ private void InitializeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ this.dtXna = new DispatcherTimer();
+ this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
+ this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
+ this.dtXna.Start();
+ }
+ /// <summary>
+ /// Finalizes XNA game loop for microphone
+ /// </summary>
+ private void FinalizeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ if (this.dtXna != null)
+ {
+ this.dtXna.Stop();
+ this.dtXna = null;
+ }
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Battery.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Battery.cs b/common/Plugins/Battery.cs
new file mode 100644
index 0000000..962959e
--- /dev/null
+++ b/common/Plugins/Battery.cs
@@ -0,0 +1,79 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+using Microsoft.Phone.Info;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Listens for changes to the state of the battery on the device.
+ /// Currently only the "isPlugged" parameter available via native APIs.
+ /// </summary>
+ public class Battery : BaseCommand
+ {
+ private bool isPlugged = false;
+ private EventHandler powerChanged;
+
+ public Battery()
+ {
+ powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
+ isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
+ }
+
+ public void start(string options)
+ {
+ // Register power changed event handler
+ DeviceStatus.PowerSourceChanged += powerChanged;
+
+ PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+ public void stop(string options)
+ {
+ // Unregister power changed event handler
+ DeviceStatus.PowerSourceChanged -= powerChanged;
+ }
+
+ private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
+ {
+ isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+
+ private string GetCurrentBatteryStateFormatted()
+ {
+ string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
+ "null",
+ isPlugged ? "true" : "false"
+ );
+ batteryState = "{" + batteryState + "}";
+ return batteryState;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Camera.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Camera.cs b/common/Plugins/Camera.cs
new file mode 100644
index 0000000..5ff8045
--- /dev/null
+++ b/common/Plugins/Camera.cs
@@ -0,0 +1,490 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Collections.Generic;
+using Microsoft.Phone.Tasks;
+using System.Runtime.Serialization;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows.Media.Imaging;
+using Microsoft.Phone;
+using Microsoft.Xna.Framework.Media;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Camera : BaseCommand
+ {
+
+ /// <summary>
+ /// Return base64 encoded string
+ /// </summary>
+ private const int DATA_URL = 0;
+
+ /// <summary>
+ /// Return file uri
+ /// </summary>
+ private const int FILE_URI = 1;
+
+ /// <summary>
+ /// Choose image from picture library
+ /// </summary>
+ private const int PHOTOLIBRARY = 0;
+
+ /// <summary>
+ /// Take picture from camera
+ /// </summary>
+
+ private const int CAMERA = 1;
+
+ /// <summary>
+ /// Choose image from picture library
+ /// </summary>
+ private const int SAVEDPHOTOALBUM = 2;
+
+ /// <summary>
+ /// Take a picture of type JPEG
+ /// </summary>
+ private const int JPEG = 0;
+
+ /// <summary>
+ /// Take a picture of type PNG
+ /// </summary>
+ private const int PNG = 1;
+
+ /// <summary>
+ /// Folder to store captured images
+ /// </summary>
+ private const string isoFolder = "CapturedImagesCache";
+
+ /// <summary>
+ /// Represents captureImage action options.
+ /// </summary>
+ [DataContract]
+ public class CameraOptions
+ {
+ /// <summary>
+ /// Source to getPicture from.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "sourceType")]
+ public int PictureSourceType { get; set; }
+
+ /// <summary>
+ /// Format of image that returned from getPicture.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "destinationType")]
+ public int DestinationType { get; set; }
+
+ /// <summary>
+ /// Quality of saved image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "quality")]
+ public int Quality { get; set; }
+
+ /// <summary>
+ /// Controls whether or not the image is also added to the device photo album.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
+ public bool SaveToPhotoAlbum { get; set; }
+
+ /// <summary>
+ /// Ignored
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "correctOrientation")]
+ public bool CorrectOrientation { get; set; }
+
+
+
+ /// <summary>
+ /// Ignored
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "allowEdit")]
+ public bool AllowEdit { get; set; }
+
+ /// <summary>
+ /// Height in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "encodingType")]
+ public int EncodingType { get; set; }
+
+ /// <summary>
+ /// Height in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "mediaType")]
+ public int MediaType { get; set; }
+
+
+ /// <summary>
+ /// Height in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "targetHeight")]
+ public int TargetHeight { get; set; }
+
+
+ /// <summary>
+ /// Width in pixels to scale image
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "targetWidth")]
+ public int TargetWidth { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public CameraOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ PictureSourceType = CAMERA;
+ DestinationType = FILE_URI;
+ Quality = 80;
+ TargetHeight = -1;
+ TargetWidth = -1;
+ SaveToPhotoAlbum = false;
+ CorrectOrientation = true;
+ AllowEdit = false;
+ MediaType = -1;
+ EncodingType = -1;
+ }
+ }
+
+ /// <summary>
+ /// Used to open photo library
+ /// </summary>
+ PhotoChooserTask photoChooserTask;
+
+ /// <summary>
+ /// Used to open camera application
+ /// </summary>
+ CameraCaptureTask cameraTask;
+
+ /// <summary>
+ /// Camera options
+ /// </summary>
+ CameraOptions cameraOptions;
+
+ public void takePicture(string options)
+ {
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
+ // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
+ this.cameraOptions = new CameraOptions();
+ this.cameraOptions.Quality = int.Parse(args[0]);
+ this.cameraOptions.DestinationType = int.Parse(args[1]);
+ this.cameraOptions.PictureSourceType = int.Parse(args[2]);
+ this.cameraOptions.TargetWidth = int.Parse(args[3]);
+ this.cameraOptions.TargetHeight = int.Parse(args[4]);
+ this.cameraOptions.EncodingType = int.Parse(args[5]);
+ this.cameraOptions.MediaType = int.Parse(args[6]);
+ this.cameraOptions.AllowEdit = bool.Parse(args[7]);
+ this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
+ this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
+
+ //this.cameraOptions = String.IsNullOrEmpty(options) ?
+ // new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ //TODO Check if all the options are acceptable
+
+
+ if (cameraOptions.PictureSourceType == CAMERA)
+ {
+ cameraTask = new CameraCaptureTask();
+ cameraTask.Completed += onCameraTaskCompleted;
+ cameraTask.Show();
+ }
+ else
+ {
+ if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
+ {
+ photoChooserTask = new PhotoChooserTask();
+ photoChooserTask.Completed += onPickerTaskCompleted;
+ photoChooserTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
+ }
+ }
+
+ }
+
+ public void onCameraTaskCompleted(object sender, PhotoResult e)
+ {
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ string imagePathOrContent = string.Empty;
+
+ if (cameraOptions.DestinationType == FILE_URI)
+ {
+ // Save image in media library
+ if (cameraOptions.SaveToPhotoAlbum)
+ {
+ MediaLibrary library = new MediaLibrary();
+ Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
+ }
+
+ int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
+ int newAngle = 0;
+ switch (orient)
+ {
+ case ImageExifOrientation.LandscapeLeft:
+ newAngle = 90;
+ break;
+ case ImageExifOrientation.PortraitUpsideDown:
+ newAngle = 180;
+ break;
+ case ImageExifOrientation.LandscapeRight:
+ newAngle = 270;
+ break;
+ case ImageExifOrientation.Portrait:
+ default: break; // 0 default already set
+ }
+
+ Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
+
+ // we should return stream position back after saving stream to media library
+ rotImageStream.Seek(0, SeekOrigin.Begin);
+
+ WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
+
+ imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
+
+
+ }
+ else if (cameraOptions.DestinationType == DATA_URL)
+ {
+ imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
+ }
+ else
+ {
+ // TODO: shouldn't this happen before we launch the camera-picker?
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
+ return;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
+ break;
+
+ default:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
+ break;
+ }
+
+ }
+
+ public void onPickerTaskCompleted(object sender, PhotoResult e)
+ {
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ string imagePathOrContent = string.Empty;
+
+ if (cameraOptions.DestinationType == FILE_URI)
+ {
+ WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
+ imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
+ }
+ else if (cameraOptions.DestinationType == DATA_URL)
+ {
+ imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
+
+ }
+ else
+ {
+ // TODO: shouldn't this happen before we launch the camera-picker?
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
+ return;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
+
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
+ break;
+
+ default:
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Returns image content in a form of base64 string
+ /// </summary>
+ /// <param name="stream">Image stream</param>
+ /// <returns>Base64 representation of the image</returns>
+ private string GetImageContent(Stream stream)
+ {
+ int streamLength = (int)stream.Length;
+ byte[] fileData = new byte[streamLength + 1];
+ stream.Read(fileData, 0, streamLength);
+
+ //use photo's actual width & height if user doesn't provide width & height
+ if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
+ {
+ stream.Close();
+ return Convert.ToBase64String(fileData);
+ }
+ else
+ {
+ // resize photo
+ byte[] resizedFile = ResizePhoto(stream, fileData);
+ stream.Close();
+ return Convert.ToBase64String(resizedFile);
+ }
+ }
+
+ /// <summary>
+ /// Resize image
+ /// </summary>
+ /// <param name="stream">Image stream</param>
+ /// <param name="fileData">File data</param>
+ /// <returns>resized image</returns>
+ private byte[] ResizePhoto(Stream stream, byte[] fileData)
+ {
+ int streamLength = (int)stream.Length;
+ int intResult = 0;
+
+ byte[] resizedFile;
+
+ stream.Read(fileData, 0, streamLength);
+
+ BitmapImage objBitmap = new BitmapImage();
+ MemoryStream objBitmapStream = new MemoryStream(fileData);
+ MemoryStream objBitmapStreamResized = new MemoryStream();
+ WriteableBitmap objWB;
+ objBitmap.SetSource(stream);
+ objWB = new WriteableBitmap(objBitmap);
+
+ // resize the photo with user defined TargetWidth & TargetHeight
+ Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
+
+ //Convert the resized stream to a byte array.
+ streamLength = (int)objBitmapStreamResized.Length;
+ resizedFile = new Byte[streamLength]; //-1
+ objBitmapStreamResized.Position = 0;
+ //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
+ intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
+
+ return resizedFile;
+ }
+
+ /// <summary>
+ /// Saves captured image in isolated storage
+ /// </summary>
+ /// <param name="imageFileName">image file name</param>
+ /// <returns>Image path</returns>
+ private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
+ {
+
+ if (image == null)
+ {
+ throw new ArgumentNullException("imageBytes");
+ }
+ try
+ {
+
+
+ var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
+
+ if (!isoFile.DirectoryExists(isoFolder))
+ {
+ isoFile.CreateDirectory(isoFolder);
+ }
+
+ string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
+
+ using (var stream = isoFile.CreateFile(filePath))
+ {
+ // resize image if Height and Width defined via options
+ if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
+ {
+ image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
+ }
+ else
+ {
+ image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
+ }
+ }
+
+ return new Uri(filePath, UriKind.Relative).ToString();
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+ }
+}
[23/50] [abbrv] git commit: all your templates are belong to us
Posted by pu...@apache.org.
all your templates are belong to us
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/129c0bd6
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/129c0bd6
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/129c0bd6
Branch: refs/heads/2.9.x
Commit: 129c0bd68b080a155abfa8679bb61426a5b85a71
Parents: 22118ac
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 13:39:49 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 13:39:49 2013 -0700
----------------------------------------------------------------------
createTemplates.bat | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/129c0bd6/createTemplates.bat
----------------------------------------------------------------------
diff --git a/createTemplates.bat b/createTemplates.bat
new file mode 100644
index 0000000..888ce89
--- /dev/null
+++ b/createTemplates.bat
@@ -0,0 +1,3 @@
+
+call wp7/tooling/scripts/createTemplates %1
+call wp8/tooling/scripts/createTemplates %1
\ No newline at end of file
[38/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/File.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/File.cs b/common/Plugins/File.cs
new file mode 100644
index 0000000..cde7a1c
--- /dev/null
+++ b/common/Plugins/File.cs
@@ -0,0 +1,1676 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Text;
+using System.Windows;
+using System.Windows.Resources;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides access to isolated storage
+ /// </summary>
+ public class File : BaseCommand
+ {
+ // Error codes
+ public const int NOT_FOUND_ERR = 1;
+ public const int SECURITY_ERR = 2;
+ public const int ABORT_ERR = 3;
+ public const int NOT_READABLE_ERR = 4;
+ public const int ENCODING_ERR = 5;
+ public const int NO_MODIFICATION_ALLOWED_ERR = 6;
+ public const int INVALID_STATE_ERR = 7;
+ public const int SYNTAX_ERR = 8;
+ public const int INVALID_MODIFICATION_ERR = 9;
+ public const int QUOTA_EXCEEDED_ERR = 10;
+ public const int TYPE_MISMATCH_ERR = 11;
+ public const int PATH_EXISTS_ERR = 12;
+
+ // File system options
+ public const int TEMPORARY = 0;
+ public const int PERSISTENT = 1;
+ public const int RESOURCE = 2;
+ public const int APPLICATION = 3;
+
+ /// <summary>
+ /// Temporary directory name
+ /// </summary>
+ private readonly string TMP_DIRECTORY_NAME = "tmp";
+
+ /// <summary>
+ /// Represents error code for callback
+ /// </summary>
+ [DataContract]
+ public class ErrorCode
+ {
+ /// <summary>
+ /// Error code
+ /// </summary>
+ [DataMember(IsRequired = true, Name = "code")]
+ public int Code { get; set; }
+
+ /// <summary>
+ /// Creates ErrorCode object
+ /// </summary>
+ public ErrorCode(int code)
+ {
+ this.Code = code;
+ }
+ }
+
+ /// <summary>
+ /// Represents File action options.
+ /// </summary>
+ [DataContract]
+ public class FileOptions
+ {
+ /// <summary>
+ /// File path
+ /// </summary>
+ ///
+ private string _fileName;
+ [DataMember(Name = "fileName")]
+ public string FilePath
+ {
+ get
+ {
+ return this._fileName;
+ }
+
+ set
+ {
+ int index = value.IndexOfAny(new char[] { '#', '?' });
+ this._fileName = index > -1 ? value.Substring(0, index) : value;
+ }
+ }
+
+ /// <summary>
+ /// Full entryPath
+ /// </summary>
+ [DataMember(Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ /// <summary>
+ /// Directory name
+ /// </summary>
+ [DataMember(Name = "dirName")]
+ public string DirectoryName { get; set; }
+
+ /// <summary>
+ /// Path to create file/directory
+ /// </summary>
+ [DataMember(Name = "path")]
+ public string Path { get; set; }
+
+ /// <summary>
+ /// The encoding to use to encode the file's content. Default is UTF8.
+ /// </summary>
+ [DataMember(Name = "encoding")]
+ public string Encoding { get; set; }
+
+ /// <summary>
+ /// Uri to get file
+ /// </summary>
+ ///
+ private string _uri;
+ [DataMember(Name = "uri")]
+ public string Uri
+ {
+ get
+ {
+ return this._uri;
+ }
+
+ set
+ {
+ int index = value.IndexOfAny(new char[] { '#', '?' });
+ this._uri = index > -1 ? value.Substring(0, index) : value;
+ }
+ }
+
+ /// <summary>
+ /// Size to truncate file
+ /// </summary>
+ [DataMember(Name = "size")]
+ public long Size { get; set; }
+
+ /// <summary>
+ /// Data to write in file
+ /// </summary>
+ [DataMember(Name = "data")]
+ public string Data { get; set; }
+
+ /// <summary>
+ /// Position the writing starts with
+ /// </summary>
+ [DataMember(Name = "position")]
+ public int Position { get; set; }
+
+ /// <summary>
+ /// Type of file system requested
+ /// </summary>
+ [DataMember(Name = "type")]
+ public int FileSystemType { get; set; }
+
+ /// <summary>
+ /// New file/directory name
+ /// </summary>
+ [DataMember(Name = "newName")]
+ public string NewName { get; set; }
+
+ /// <summary>
+ /// Destination directory to copy/move file/directory
+ /// </summary>
+ [DataMember(Name = "parent")]
+ public string Parent { get; set; }
+
+ /// <summary>
+ /// Options for getFile/getDirectory methods
+ /// </summary>
+ [DataMember(Name = "options")]
+ public CreatingOptions CreatingOpt { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public FileOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ this.Encoding = "UTF-8";
+ this.FilePath = "";
+ this.FileSystemType = -1;
+ }
+ }
+
+ /// <summary>
+ /// Stores image info
+ /// </summary>
+ [DataContract]
+ public class FileMetadata
+ {
+ [DataMember(Name = "fileName")]
+ public string FileName { get; set; }
+
+ [DataMember(Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ [DataMember(Name = "type")]
+ public string Type { get; set; }
+
+ [DataMember(Name = "lastModifiedDate")]
+ public string LastModifiedDate { get; set; }
+
+ [DataMember(Name = "size")]
+ public long Size { get; set; }
+
+ public FileMetadata(string filePath)
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ throw new FileNotFoundException("File doesn't exist");
+ }
+ else if (!isoFile.FileExists(filePath))
+ {
+ // attempt to get it from the resources
+ if (filePath.IndexOf("www") == 0)
+ {
+ Uri fileUri = new Uri(filePath, UriKind.Relative);
+ StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
+ if (streamInfo != null)
+ {
+ this.Size = streamInfo.Stream.Length;
+ this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
+ this.FullPath = filePath;
+ }
+ }
+ else
+ {
+ throw new FileNotFoundException("File doesn't exist");
+ }
+ }
+ else
+ {
+ //TODO get file size the other way if possible
+ using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
+ {
+ this.Size = stream.Length;
+ }
+ this.FullPath = filePath;
+ this.FileName = System.IO.Path.GetFileName(filePath);
+ this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
+ }
+ this.Type = MimeTypeMapper.GetMimeType(this.FileName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents file or directory modification metadata
+ /// </summary>
+ [DataContract]
+ public class ModificationMetadata
+ {
+ /// <summary>
+ /// Modification time
+ /// </summary>
+ [DataMember]
+ public string modificationTime { get; set; }
+ }
+
+ /// <summary>
+ /// Represents file or directory entry
+ /// </summary>
+ [DataContract]
+ public class FileEntry
+ {
+
+ /// <summary>
+ /// File type
+ /// </summary>
+ [DataMember(Name = "isFile")]
+ public bool IsFile { get; set; }
+
+ /// <summary>
+ /// Directory type
+ /// </summary>
+ [DataMember(Name = "isDirectory")]
+ public bool IsDirectory { get; set; }
+
+ /// <summary>
+ /// File/directory name
+ /// </summary>
+ [DataMember(Name = "name")]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Full path to file/directory
+ /// </summary>
+ [DataMember(Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ public bool IsResource { get; set; }
+
+ public static FileEntry GetEntry(string filePath, bool bIsRes=false)
+ {
+ FileEntry entry = null;
+ try
+ {
+ entry = new FileEntry(filePath, bIsRes);
+
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
+ }
+ return entry;
+ }
+
+ /// <summary>
+ /// Creates object and sets necessary properties
+ /// </summary>
+ /// <param name="filePath"></param>
+ public FileEntry(string filePath, bool bIsRes = false)
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ throw new ArgumentException();
+ }
+
+ if(filePath.Contains(" "))
+ {
+ Debug.WriteLine("FilePath with spaces :: " + filePath);
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ IsResource = bIsRes;
+ IsFile = isoFile.FileExists(filePath);
+ IsDirectory = isoFile.DirectoryExists(filePath);
+ if (IsFile)
+ {
+ this.Name = Path.GetFileName(filePath);
+ }
+ else if (IsDirectory)
+ {
+ this.Name = this.GetDirectoryName(filePath);
+ if (string.IsNullOrEmpty(Name))
+ {
+ this.Name = "/";
+ }
+ }
+ else
+ {
+ if (IsResource)
+ {
+ this.Name = Path.GetFileName(filePath);
+ }
+ else
+ {
+ throw new FileNotFoundException();
+ }
+ }
+
+ try
+ {
+ this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
+ }
+ catch (Exception)
+ {
+ this.FullPath = filePath;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Extracts directory name from path string
+ /// Path should refer to a directory, for example \foo\ or /foo.
+ /// </summary>
+ /// <param name="path"></param>
+ /// <returns></returns>
+ private string GetDirectoryName(string path)
+ {
+ if (String.IsNullOrEmpty(path))
+ {
+ return path;
+ }
+
+ string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
+ if (split.Length < 1)
+ {
+ return null;
+ }
+ else
+ {
+ return split[split.Length - 1];
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Represents info about requested file system
+ /// </summary>
+ [DataContract]
+ public class FileSystemInfo
+ {
+ /// <summary>
+ /// file system type
+ /// </summary>
+ [DataMember(Name = "name", IsRequired = true)]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Root directory entry
+ /// </summary>
+ [DataMember(Name = "root", EmitDefaultValue = false)]
+ public FileEntry Root { get; set; }
+
+ /// <summary>
+ /// Creates class instance
+ /// </summary>
+ /// <param name="name"></param>
+ /// <param name="rootEntry"> Root directory</param>
+ public FileSystemInfo(string name, FileEntry rootEntry = null)
+ {
+ Name = name;
+ Root = rootEntry;
+ }
+ }
+
+ [DataContract]
+ public class CreatingOptions
+ {
+ /// <summary>
+ /// Create file/directory if is doesn't exist
+ /// </summary>
+ [DataMember(Name = "create")]
+ public bool Create { get; set; }
+
+ /// <summary>
+ /// Generate an exception if create=true and file/directory already exists
+ /// </summary>
+ [DataMember(Name = "exclusive")]
+ public bool Exclusive { get; set; }
+
+
+ }
+
+ // returns null value if it fails.
+ private string[] getOptionStrings(string options)
+ {
+ string[] optStings = null;
+ try
+ {
+ optStings = JSON.JsonHelper.Deserialize<string[]>(options);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
+ }
+ return optStings;
+ }
+
+ /// <summary>
+ /// Gets amount of free space available for Isolated Storage
+ /// </summary>
+ /// <param name="options">No options is needed for this method</param>
+ public void getFreeDiskSpace(string options)
+ {
+ string callbackId = getOptionStrings(options)[0];
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
+ }
+ }
+ catch (IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Check if file exists
+ /// </summary>
+ /// <param name="options">File path</param>
+ public void testFileExists(string options)
+ {
+ IsDirectoryOrFileExist(options, false);
+ }
+
+ /// <summary>
+ /// Check if directory exists
+ /// </summary>
+ /// <param name="options">directory name</param>
+ public void testDirectoryExists(string options)
+ {
+ IsDirectoryOrFileExist(options, true);
+ }
+
+ /// <summary>
+ /// Check if file or directory exist
+ /// </summary>
+ /// <param name="options">File path/Directory name</param>
+ /// <param name="isDirectory">Flag to recognize what we should check</param>
+ public void IsDirectoryOrFileExist(string options, bool isDirectory)
+ {
+ string[] args = getOptionStrings(options);
+ string callbackId = args[1];
+ FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
+ string filePath = args[0];
+
+ if (fileOptions == null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
+ }
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ bool isExist;
+ if (isDirectory)
+ {
+ isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
+ }
+ else
+ {
+ isExist = isoFile.FileExists(fileOptions.FilePath);
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
+ }
+ }
+ catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+
+ }
+
+ public void readAsDataURL(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ int startPos = int.Parse(optStrings[1]);
+ int endPos = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+
+ if (filePath != null)
+ {
+ try
+ {
+ string base64URL = null;
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+ string mimeType = MimeTypeMapper.GetMimeType(filePath);
+
+ using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
+ {
+ string base64String = GetFileContent(stream);
+ base64URL = "data:" + mimeType + ";base64," + base64String;
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+ }
+
+ public void readAsArrayBuffer(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ int startPos = int.Parse(optStrings[1]);
+ int endPos = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
+ }
+
+ public void readAsBinaryString(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ int startPos = int.Parse(optStrings[1]);
+ int endPos = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
+ }
+
+ public void readAsText(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string filePath = optStrings[0];
+ string encStr = optStrings[1];
+ int startPos = int.Parse(optStrings[2]);
+ int endPos = int.Parse(optStrings[3]);
+ string callbackId = optStrings[4];
+
+ try
+ {
+ string text = "";
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ readResourceAsText(options);
+ return;
+ }
+ Encoding encoding = Encoding.GetEncoding(encStr);
+
+ using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
+ {
+ text = reader.ReadToEnd();
+ if (startPos < 0)
+ {
+ startPos = Math.Max(text.Length + startPos, 0);
+ }
+ else if (startPos > 0)
+ {
+ startPos = Math.Min(text.Length, startPos);
+ }
+
+ if (endPos > 0)
+ {
+ endPos = Math.Min(text.Length, endPos);
+ }
+ else if (endPos < 0)
+ {
+ endPos = Math.Max(endPos + text.Length, 0);
+ }
+
+
+ text = text.Substring(startPos, endPos - startPos);
+
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Reads application resource as a text
+ /// </summary>
+ /// <param name="options">Path to a resource</param>
+ public void readResourceAsText(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+ string pathToResource = optStrings[0];
+ string encStr = optStrings[1];
+ int start = int.Parse(optStrings[2]);
+ int endMarker = int.Parse(optStrings[3]);
+ string callbackId = optStrings[4];
+
+ try
+ {
+ if (pathToResource.StartsWith("/"))
+ {
+ pathToResource = pathToResource.Remove(0, 1);
+ }
+
+ var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
+
+ if (resource == null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ string text;
+ StreamReader streamReader = new StreamReader(resource.Stream);
+ text = streamReader.ReadToEnd();
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ public void truncate(string options)
+ {
+ string[] optStrings = getOptionStrings(options);
+
+ string filePath = optStrings[0];
+ int size = int.Parse(optStrings[1]);
+ string callbackId = optStrings[2];
+
+ try
+ {
+ long streamLength = 0;
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
+ {
+ if (0 <= size && size <= stream.Length)
+ {
+ stream.SetLength(size);
+ }
+ streamLength = stream.Length;
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ //write:["filePath","data","position"],
+ public void write(string options)
+ {
+ // TODO: try/catch
+ string[] optStrings = getOptionStrings(options);
+
+ string filePath = optStrings[0];
+ string data = optStrings[1];
+ int position = int.Parse(optStrings[2]);
+ string callbackId = optStrings[3];
+
+ try
+ {
+ if (string.IsNullOrEmpty(data))
+ {
+ Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ // create the file if not exists
+ if (!isoFile.FileExists(filePath))
+ {
+ var file = isoFile.CreateFile(filePath);
+ file.Close();
+ }
+
+ using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
+ {
+ if (0 <= position && position <= stream.Length)
+ {
+ stream.SetLength(position);
+ }
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Seek(0, SeekOrigin.End);
+ writer.Write(data.ToCharArray());
+ }
+ }
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Look up metadata about this entry.
+ /// </summary>
+ /// <param name="options">filePath to entry</param>
+ public void getMetadata(string options)
+ {
+ string[] optStings = getOptionStrings(options);
+ string filePath = optStings[0];
+ string callbackId = optStings[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.FileExists(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
+ new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
+ }
+ else if (isoFile.DirectoryExists(filePath))
+ {
+ string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+
+ }
+ }
+ catch (IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+
+ }
+
+
+ /// <summary>
+ /// Returns a File that represents the current state of the file that this FileEntry represents.
+ /// </summary>
+ /// <param name="filePath">filePath to entry</param>
+ /// <returns></returns>
+ public void getFileMetadata(string options)
+ {
+ string[] optStings = getOptionStrings(options);
+ string filePath = optStings[0];
+ string callbackId = optStings[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ FileMetadata metaData = new FileMetadata(filePath);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
+ }
+ catch (IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Look up the parent DirectoryEntry containing this Entry.
+ /// If this Entry is the root of IsolatedStorage, its parent is itself.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getParent(string options)
+ {
+ string[] optStings = getOptionStrings(options);
+ string filePath = optStings[0];
+ string callbackId = optStings[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ FileEntry entry;
+
+ if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
+ {
+
+
+ string path = this.GetParentDirectory(filePath);
+ entry = FileEntry.GetEntry(path);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+ }
+ }
+ }
+
+ public void remove(string options)
+ {
+ string[] args = getOptionStrings(options);
+ string filePath = args[0];
+ string callbackId = args[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ if (filePath == "/" || filePath == "" || filePath == @"\")
+ {
+ throw new Exception("Cannot delete root file system") ;
+ }
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.FileExists(filePath))
+ {
+ isoFile.DeleteFile(filePath);
+ }
+ else
+ {
+ if (isoFile.DirectoryExists(filePath))
+ {
+ isoFile.DeleteDirectory(filePath);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ return;
+ }
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ }
+ }
+ }
+ }
+
+ public void removeRecursively(string options)
+ {
+ string[] args = getOptionStrings(options);
+ string filePath = args[0];
+ string callbackId = args[1];
+
+ if (filePath != null)
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
+ }
+ else
+ {
+ if (removeDirRecursively(filePath, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
+ }
+ }
+ }
+ }
+
+ public void readEntries(string options)
+ {
+ string[] args = getOptionStrings(options);
+ string filePath = args[0];
+ string callbackId = args[1];
+
+ if (filePath != null)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(filePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.DirectoryExists(filePath))
+ {
+ string path = File.AddSlashToDirectory(filePath);
+ List<FileEntry> entries = new List<FileEntry>();
+ string[] files = isoFile.GetFileNames(path + "*");
+ string[] dirs = isoFile.GetDirectoryNames(path + "*");
+ foreach (string file in files)
+ {
+ entries.Add(FileEntry.GetEntry(path + file));
+ }
+ foreach (string dir in dirs)
+ {
+ entries.Add(FileEntry.GetEntry(path + dir + "/"));
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ }
+ }
+ }
+ }
+
+ public void requestFileSystem(string options)
+ {
+ // TODO: try/catch
+ string[] optVals = getOptionStrings(options);
+ //FileOptions fileOptions = new FileOptions();
+ int fileSystemType = int.Parse(optVals[0]);
+ double size = double.Parse(optVals[1]);
+ string callbackId = optVals[2];
+
+
+ IsolatedStorageFile.GetUserStoreForApplication();
+
+ if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
+ return;
+ }
+
+ try
+ {
+ if (size != 0)
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ long availableSize = isoFile.AvailableFreeSpace;
+ if (size > availableSize)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
+ return;
+ }
+ }
+ }
+
+ if (fileSystemType == PERSISTENT)
+ {
+ // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
+ }
+ else if (fileSystemType == TEMPORARY)
+ {
+ using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
+ {
+ isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
+ }
+ }
+
+ string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
+ }
+ else if (fileSystemType == RESOURCE)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
+ }
+ else if (fileSystemType == APPLICATION)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+
+ public void resolveLocalFileSystemURI(string options)
+ {
+
+ string[] optVals = getOptionStrings(options);
+ string uri = optVals[0].Split('?')[0];
+ string callbackId = optVals[1];
+
+ if (uri != null)
+ {
+ // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
+ if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+ try
+ {
+ // fix encoded spaces
+ string path = Uri.UnescapeDataString(uri);
+
+ FileEntry uriEntry = FileEntry.GetEntry(path);
+ if (uriEntry != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+ }
+
+ public void copyTo(string options)
+ {
+ TransferTo(options, false);
+ }
+
+ public void moveTo(string options)
+ {
+ TransferTo(options, true);
+ }
+
+ public void getFile(string options)
+ {
+ GetFileOrDirectory(options, false);
+ }
+
+ public void getDirectory(string options)
+ {
+ GetFileOrDirectory(options, true);
+ }
+
+ #region internal functionality
+
+ /// <summary>
+ /// Retrieves the parent directory name of the specified path,
+ /// </summary>
+ /// <param name="path">Path</param>
+ /// <returns>Parent directory name</returns>
+ private string GetParentDirectory(string path)
+ {
+ if (String.IsNullOrEmpty(path) || path == "/")
+ {
+ return "/";
+ }
+
+ if (path.EndsWith(@"/") || path.EndsWith(@"\"))
+ {
+ return this.GetParentDirectory(Path.GetDirectoryName(path));
+ }
+
+ string result = Path.GetDirectoryName(path);
+ if (result == null)
+ {
+ result = "/";
+ }
+
+ return result;
+ }
+
+ private bool removeDirRecursively(string fullPath,string callbackId)
+ {
+ try
+ {
+ if (fullPath == "/")
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ return false;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (isoFile.DirectoryExists(fullPath))
+ {
+ string tempPath = File.AddSlashToDirectory(fullPath);
+ string[] files = isoFile.GetFileNames(tempPath + "*");
+ if (files.Length > 0)
+ {
+ foreach (string file in files)
+ {
+ isoFile.DeleteFile(tempPath + file);
+ }
+ }
+ string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
+ if (dirs.Length > 0)
+ {
+ foreach (string dir in dirs)
+ {
+ if (!removeDirRecursively(tempPath + dir, callbackId))
+ {
+ return false;
+ }
+ }
+ }
+ isoFile.DeleteDirectory(fullPath);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private bool CanonicalCompare(string pathA, string pathB)
+ {
+ string a = pathA.Replace("//", "/");
+ string b = pathB.Replace("//", "/");
+
+ return a.Equals(b, StringComparison.OrdinalIgnoreCase);
+ }
+
+ /*
+ * copyTo:["fullPath","parent", "newName"],
+ * moveTo:["fullPath","parent", "newName"],
+ */
+ private void TransferTo(string options, bool move)
+ {
+ // TODO: try/catch
+ string[] optStrings = getOptionStrings(options);
+ string fullPath = optStrings[0];
+ string parent = optStrings[1];
+ string newFileName = optStrings[2];
+ string callbackId = optStrings[3];
+
+ char[] invalids = Path.GetInvalidPathChars();
+
+ if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+
+ try
+ {
+ if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ string parentPath = File.AddSlashToDirectory(parent);
+ string currentPath = fullPath;
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ bool isFileExist = isoFile.FileExists(currentPath);
+ bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
+ bool isParentExist = isoFile.DirectoryExists(parentPath);
+
+ if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+ string newName;
+ string newPath;
+ if (isFileExist)
+ {
+ newName = (string.IsNullOrEmpty(newFileName))
+ ? Path.GetFileName(currentPath)
+ : newFileName;
+
+ newPath = Path.Combine(parentPath, newName);
+
+ // sanity check ..
+ // cannot copy file onto itself
+ if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
+ return;
+ }
+ else if (isoFile.DirectoryExists(newPath))
+ {
+ // there is already a folder with the same name, operation is not allowed
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
+ return;
+ }
+ else if (isoFile.FileExists(newPath))
+ { // remove destination file if exists, in other case there will be exception
+ isoFile.DeleteFile(newPath);
+ }
+
+ if (move)
+ {
+ isoFile.MoveFile(currentPath, newPath);
+ }
+ else
+ {
+ isoFile.CopyFile(currentPath, newPath, true);
+ }
+ }
+ else
+ {
+ newName = (string.IsNullOrEmpty(newFileName))
+ ? currentPath
+ : newFileName;
+
+ newPath = Path.Combine(parentPath, newName);
+
+ if (move)
+ {
+ // remove destination directory if exists, in other case there will be exception
+ // target directory should be empty
+ if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
+ {
+ isoFile.DeleteDirectory(newPath);
+ }
+
+ isoFile.MoveDirectory(currentPath, newPath);
+ }
+ else
+ {
+ CopyDirectory(currentPath, newPath, isoFile);
+ }
+ }
+ FileEntry entry = FileEntry.GetEntry(newPath);
+ if (entry != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex, callbackId))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+
+ private bool HandleException(Exception ex, string cbId="")
+ {
+ bool handled = false;
+ string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
+ if (ex is SecurityException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is FileNotFoundException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is ArgumentException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is IsolatedStorageException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
+ handled = true;
+ }
+ else if (ex is DirectoryNotFoundException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ handled = true;
+ }
+ return handled;
+ }
+
+ private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
+ {
+ string path = File.AddSlashToDirectory(sourceDir);
+
+ bool bExists = isoFile.DirectoryExists(destDir);
+
+ if (!bExists)
+ {
+ isoFile.CreateDirectory(destDir);
+ }
+
+ destDir = File.AddSlashToDirectory(destDir);
+
+ string[] files = isoFile.GetFileNames(path + "*");
+
+ if (files.Length > 0)
+ {
+ foreach (string file in files)
+ {
+ isoFile.CopyFile(path + file, destDir + file,true);
+ }
+ }
+ string[] dirs = isoFile.GetDirectoryNames(path + "*");
+ if (dirs.Length > 0)
+ {
+ foreach (string dir in dirs)
+ {
+ CopyDirectory(path + dir, destDir + dir, isoFile);
+ }
+ }
+ }
+
+ private void GetFileOrDirectory(string options, bool getDirectory)
+ {
+ FileOptions fOptions = new FileOptions();
+ string[] args = getOptionStrings(options);
+
+ fOptions.FullPath = args[0];
+ fOptions.Path = args[1];
+
+ string callbackId = args[3];
+
+ try
+ {
+ fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
+ return;
+ }
+
+ try
+ {
+ if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+
+ string path;
+
+ if (fOptions.Path.Split(':').Length > 2)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+
+ try
+ {
+ path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
+ return;
+ }
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ bool isFile = isoFile.FileExists(path);
+ bool isDirectory = isoFile.DirectoryExists(path);
+ bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
+ bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
+ if (create)
+ {
+ if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
+ return;
+ }
+
+ // need to make sure the parent exists
+ // it is an error to create a directory whose immediate parent does not yet exist
+ // see issue: https://issues.apache.org/jira/browse/CB-339
+ string[] pathParts = path.Split('/');
+ string builtPath = pathParts[0];
+ for (int n = 1; n < pathParts.Length - 1; n++)
+ {
+ builtPath += "/" + pathParts[n];
+ if (!isoFile.DirectoryExists(builtPath))
+ {
+ Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ return;
+ }
+ }
+
+ if ((getDirectory) && (!isDirectory))
+ {
+ isoFile.CreateDirectory(path);
+ }
+ else
+ {
+ if ((!getDirectory) && (!isFile))
+ {
+
+ IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
+ fileStream.Close();
+ }
+ }
+ }
+ else // (not create)
+ {
+ if ((!isFile) && (!isDirectory))
+ {
+ if (path.IndexOf("//www") == 0)
+ {
+ Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
+ StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
+ if (streamInfo != null)
+ {
+ FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
+
+ //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
+ //{
+ // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
+
+ //}
+
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+
+
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ return;
+ }
+ if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
+ return;
+ }
+ }
+ FileEntry entry = FileEntry.GetEntry(path);
+ if (entry != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!this.HandleException(ex))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
+ }
+ }
+ }
+
+ private static string AddSlashToDirectory(string dirPath)
+ {
+ if (dirPath.EndsWith("/"))
+ {
+ return dirPath;
+ }
+ else
+ {
+ return dirPath + "/";
+ }
+ }
+
+ /// <summary>
+ /// Returns file content in a form of base64 string
+ /// </summary>
+ /// <param name="stream">File stream</param>
+ /// <returns>Base64 representation of the file</returns>
+ private string GetFileContent(Stream stream)
+ {
+ int streamLength = (int)stream.Length;
+ byte[] fileData = new byte[streamLength + 1];
+ stream.Read(fileData, 0, streamLength);
+ stream.Close();
+ return Convert.ToBase64String(fileData);
+ }
+
+ #endregion
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/FileTransfer.cs b/common/Plugins/FileTransfer.cs
new file mode 100644
index 0000000..e585895
--- /dev/null
+++ b/common/Plugins/FileTransfer.cs
@@ -0,0 +1,526 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Net;
+using System.Runtime.Serialization;
+using System.Windows;
+using System.Security;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class FileTransfer : BaseCommand
+ {
+ public class DownloadRequestState
+ {
+ // This class stores the State of the request.
+ public HttpWebRequest request;
+ public DownloadOptions options;
+
+ public DownloadRequestState()
+ {
+ request = null;
+ options = null;
+ }
+ }
+
+ /// <summary>
+ /// Boundary symbol
+ /// </summary>
+ private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
+
+ // Error codes
+ public const int FileNotFoundError = 1;
+ public const int InvalidUrlError = 2;
+ public const int ConnectionError = 3;
+
+ /// <summary>
+ /// Options for downloading file
+ /// </summary>
+ [DataContract]
+ public class DownloadOptions
+ {
+ /// <summary>
+ /// File path to download to
+ /// </summary>
+ [DataMember(Name = "filePath", IsRequired = true)]
+ public string FilePath { get; set; }
+
+ /// <summary>
+ /// Server address to the file to download
+ /// </summary>
+ [DataMember(Name = "url", IsRequired = true)]
+ public string Url { get; set; }
+ }
+
+ /// <summary>
+ /// Options for uploading file
+ /// </summary>
+ [DataContract]
+ public class UploadOptions
+ {
+ /// <summary>
+ /// File path to upload
+ /// </summary>
+ [DataMember(Name = "filePath", IsRequired = true)]
+ public string FilePath { get; set; }
+
+ /// <summary>
+ /// Server address
+ /// </summary>
+ [DataMember(Name = "server", IsRequired = true)]
+ public string Server { get; set; }
+
+ /// <summary>
+ /// File key
+ /// </summary>
+ [DataMember(Name = "fileKey")]
+ public string FileKey { get; set; }
+
+ /// <summary>
+ /// File name on the server
+ /// </summary>
+ [DataMember(Name = "fileName")]
+ public string FileName { get; set; }
+
+ /// <summary>
+ /// File Mime type
+ /// </summary>
+ [DataMember(Name = "mimeType")]
+ public string MimeType { get; set; }
+
+
+ /// <summary>
+ /// Additional options
+ /// </summary>
+ [DataMember(Name = "params")]
+ public string Params { get; set; }
+
+ /// <summary>
+ /// Flag to recognize if we should trust every host (only in debug environments)
+ /// </summary>
+ [DataMember(Name = "debug")]
+ public bool Debug { get; set; }
+
+ /// <summary>
+ /// Creates options object with default parameters
+ /// </summary>
+ public UploadOptions()
+ {
+ this.SetDefaultValues(new StreamingContext());
+ }
+
+ /// <summary>
+ /// Initializes default values for class fields.
+ /// Implemented in separate method because default constructor is not invoked during deserialization.
+ /// </summary>
+ /// <param name="context"></param>
+ [OnDeserializing()]
+ public void SetDefaultValues(StreamingContext context)
+ {
+ this.FileKey = "file";
+ this.FileName = "image.jpg";
+ this.MimeType = "image/jpeg";
+ }
+
+ }
+
+ /// <summary>
+ /// Uploading response info
+ /// </summary>
+ [DataContract]
+ public class FileUploadResult
+ {
+ /// <summary>
+ /// Amount of sent bytes
+ /// </summary>
+ [DataMember(Name = "bytesSent")]
+ public long BytesSent { get; set; }
+
+ /// <summary>
+ /// Server response code
+ /// </summary>
+ [DataMember(Name = "responseCode")]
+ public long ResponseCode { get; set; }
+
+ /// <summary>
+ /// Server response
+ /// </summary>
+ [DataMember(Name = "response", EmitDefaultValue = false)]
+ public string Response { get; set; }
+
+ /// <summary>
+ /// Creates FileUploadResult object with response values
+ /// </summary>
+ /// <param name="bytesSent">Amount of sent bytes</param>
+ /// <param name="responseCode">Server response code</param>
+ /// <param name="response">Server response</param>
+ public FileUploadResult(long bytesSent, long responseCode, string response)
+ {
+ this.BytesSent = bytesSent;
+ this.ResponseCode = responseCode;
+ this.Response = response;
+ }
+ }
+
+ /// <summary>
+ /// Represents transfer error codes for callback
+ /// </summary>
+ [DataContract]
+ public class FileTransferError
+ {
+ /// <summary>
+ /// Error code
+ /// </summary>
+ [DataMember(Name = "code", IsRequired = true)]
+ public int Code { get; set; }
+
+ /// <summary>
+ /// The source URI
+ /// </summary>
+ [DataMember(Name = "source", IsRequired = true)]
+ public string Source { get; set; }
+
+ /// <summary>
+ /// The target URI
+ /// </summary>
+ [DataMember(Name = "target", IsRequired = true)]
+ public string Target { get; set; }
+
+ /// <summary>
+ /// The http status code response from the remote URI
+ /// </summary>
+ [DataMember(Name = "http_status", IsRequired = true)]
+ public int HttpStatus { get; set; }
+
+ /// <summary>
+ /// Creates FileTransferError object
+ /// </summary>
+ /// <param name="errorCode">Error code</param>
+ public FileTransferError(int errorCode)
+ {
+ this.Code = errorCode;
+ this.Source = null;
+ this.Target = null;
+ this.HttpStatus = 0;
+ }
+ public FileTransferError(int errorCode, string source, string target, int status)
+ {
+ this.Code = errorCode;
+ this.Source = source;
+ this.Target = target;
+ this.HttpStatus = status;
+ }
+ }
+
+ /// <summary>
+ /// Upload options
+ /// </summary>
+ private UploadOptions uploadOptions;
+
+ /// <summary>
+ /// Bytes sent
+ /// </summary>
+ private long bytesSent;
+
+ /// <summary>
+ /// sends a file to a server
+ /// </summary>
+ /// <param name="options">Upload options</param>
+ public void upload(string options)
+ {
+ Debug.WriteLine("options = " + options);
+ options = options.Replace("{}", "null");
+
+ try
+ {
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ Uri serverUri;
+ try
+ {
+ serverUri = new Uri(uploadOptions.Server);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
+ return;
+ }
+ HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
+ webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
+ webRequest.Method = "POST";
+ webRequest.BeginGetRequestStream(WriteCallback, webRequest);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+ }
+ }
+
+ public void download(string options)
+ {
+ DownloadOptions downloadOptions = null;
+ HttpWebRequest webRequest = null;
+
+ try
+ {
+ string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+
+ downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
+ downloadOptions.Url = optionStrings[0];
+ downloadOptions.FilePath = optionStrings[1];
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
+ return;
+ }
+
+ if (downloadOptions != null && webRequest != null)
+ {
+ DownloadRequestState state = new DownloadRequestState();
+ state.options = downloadOptions;
+ state.request = webRequest;
+ webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
+ }
+
+
+
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="asynchronousResult"></param>
+ private void downloadCallback(IAsyncResult asynchronousResult)
+ {
+ DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
+ HttpWebRequest request = reqState.request;
+
+ try
+ {
+ HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ // create the file if not exists
+ if (!isoFile.FileExists(reqState.options.FilePath))
+ {
+ var file = isoFile.CreateFile(reqState.options.FilePath);
+ file.Close();
+ }
+
+ using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
+ {
+ long totalBytes = response.ContentLength;
+ int bytesRead = 0;
+ using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
+ {
+
+ using (BinaryWriter writer = new BinaryWriter(fileStream))
+ {
+ int BUFFER_SIZE = 1024;
+ byte[] buffer;
+
+ while (true)
+ {
+ buffer = reader.ReadBytes(BUFFER_SIZE);
+ // fire a progress event ?
+ bytesRead += buffer.Length;
+ if (buffer.Length > 0)
+ {
+ writer.Write(buffer);
+ }
+ else
+ {
+ writer.Close();
+ reader.Close();
+ fileStream.Close();
+ break;
+ }
+ }
+ }
+
+ }
+
+
+ }
+ }
+ WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
+ }
+ catch (IsolatedStorageException)
+ {
+ // Trying to write the file somewhere within the IsoStorage.
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+ }
+ catch (SecurityException)
+ {
+ // Trying to write the file somewhere not allowed.
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+ }
+ catch (WebException webex)
+ {
+ // TODO: probably need better work here to properly respond with all http status codes back to JS
+ // Right now am jumping through hoops just to detect 404.
+ if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
+ {
+ // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
+ // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
+ // FACEPALM
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+ }
+ }
+
+
+
+ /// <summary>
+ /// Read file from Isolated Storage and sends it to server
+ /// </summary>
+ /// <param name="asynchronousResult"></param>
+ private void WriteCallback(IAsyncResult asynchronousResult)
+ {
+ try
+ {
+ HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
+ using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
+ {
+ string lineStart = "--";
+ string lineEnd = Environment.NewLine;
+ byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
+ string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
+
+ if (uploadOptions.Params != null)
+ {
+
+ string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (string param in arrParams)
+ {
+ string[] split = param.Split('=');
+ string key = split[0];
+ string val = split[1];
+ requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+ string formItem = string.Format(formdataTemplate, key, val);
+ byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
+ requestStream.Write(formItemBytes, 0, formItemBytes.Length);
+ }
+ requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+ }
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.FileExists(uploadOptions.FilePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
+ return;
+ }
+
+ using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
+ {
+ string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
+ string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
+ byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
+ requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+ requestStream.Write(headerBytes, 0, headerBytes.Length);
+ byte[] buffer = new byte[4096];
+ int bytesRead = 0;
+
+ while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ requestStream.Write(buffer, 0, bytesRead);
+ bytesSent += bytesRead;
+ }
+ }
+ byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
+ requestStream.Write(endRequest, 0, endRequest.Length);
+ }
+ }
+ webRequest.BeginGetResponse(ReadCallback, webRequest);
+ }
+ catch (Exception)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+ });
+ }
+ }
+
+ /// <summary>
+ /// Reads response into FileUploadResult
+ /// </summary>
+ /// <param name="asynchronousResult"></param>
+ private void ReadCallback(IAsyncResult asynchronousResult)
+ {
+ try
+ {
+ HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
+ using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
+ {
+ using (Stream streamResponse = response.GetResponseStream())
+ {
+ using (StreamReader streamReader = new StreamReader(streamResponse))
+ {
+ string responseString = streamReader.ReadToEnd();
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
+ });
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
+ });
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/GeoLocation.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/GeoLocation.cs b/common/Plugins/GeoLocation.cs
new file mode 100644
index 0000000..c53cb29
--- /dev/null
+++ b/common/Plugins/GeoLocation.cs
@@ -0,0 +1,34 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Device.Location;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
+ /// </summary>
+ public class GeoLocation
+ {
+ /* Unreachable code, by design -jm */
+ private void triggerGeoInclusion()
+ {
+ new GeoCoordinateWatcher();
+ }
+ }
+}
[05/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Globalization.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Globalization.cs b/wp8/template/Plugins/Globalization.cs
deleted file mode 100644
index 2c2f468..0000000
--- a/wp8/template/Plugins/Globalization.cs
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides information about system locale, culture settings, number formats, ect.
- /// </summary>
- public class Globalization : BaseCommand
- {
-
- #region Globalization errors
-
- /// <summary>
- /// Globalization error codes.
- /// </summary>
- public enum ErrorCode : int
- {
- UnknownError = 0,
- FormattingError = 1,
- ParsingError = 2,
- PatternError = 3
- }
-
- /// <summary>
- /// Represents globalization error object.
- /// </summary>
- [DataContract]
- public class GlobalizationError
- {
- #region Error messages
- /// <summary>
- /// Error messages
- /// </summary>
- public const string UnknownError = "UNKNOWN_ERROR";
- public const string FormattingError = "FORMATTIN_ERROR";
- public const string ParsingError = "PARSING_ERROR";
- public const string PatternError = "PATTERN_ERROR";
-
- #endregion
-
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = false)]
- public ErrorCode Code { get; set; }
-
- /// <summary>
- /// Error message
- /// </summary>
- [DataMember(Name = "message", IsRequired = false)]
- public string Message { get; set; }
-
- /// <summary>
- /// Default constructor
- /// </summary>
- public GlobalizationError()
- {
- this.Code = ErrorCode.UnknownError;
- this.Message = UnknownError;
- }
-
- /// <summary>
- /// Constructor setting error code
- /// </summary>
- public GlobalizationError(ErrorCode error)
- {
- this.Code = error;
-
- switch (error)
- {
- case ErrorCode.ParsingError:
- {
- this.Message = ParsingError;
- break;
- }
- case ErrorCode.FormattingError:
- {
- this.Message = FormattingError;
- break;
- }
- case ErrorCode.PatternError:
- {
- this.Message = PatternError;
- break;
- }
- default:
- {
- this.Message = UnknownError;
- break;
- }
- }
- }
- }
-
- #endregion
-
- #region Globalization options
-
- /// <summary>
- /// Represents globalization options.
- /// </summary>
- [DataContract]
- public class GlobalizationOptions
- {
- #region available option values
- /// <summary>
- /// Number pattern types.
- /// </summary>
- public const string Percent = "percent";
- public const string Currency = "currency";
- public const string Decimal = "decimal";
-
- /// <summary>
- /// Format length types
- /// </summary>
- public const string Short = "short";
- public const string Medium = "medium";
- public const string Long = "long";
- public const string Full = "full";
-
- /// <summary>
- /// Selector types
- /// </summary>
- public const string TimeSelector = "time";
- public const string DateSelector = "date";
- public const string DateAndTimeSelector = "date and time";
-
- /// <summary>
- /// Date name types
- /// </summary>
- public const string Narrow = "narrow";
- public const string Wide = "wide";
-
- /// <summary>
- /// Date name items
- /// </summary>
- public const string Months = "months";
- public const string Days = "days";
-
- #endregion
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "options", IsRequired = false)]
- public Options AdditionalOptions { get; set; }
-
- /// <summary>
- /// Date to convert
- /// </summary>
- [DataMember(Name = "date", IsRequired = false)]
- public long Date { get; set; }
-
- /// <summary>
- /// Date as stirng
- /// </summary>
- [DataMember(Name = "dateString", IsRequired = false)]
- public string DateString { get; set; }
-
- /// <summary>
- /// Currency code
- /// </summary>
- [DataMember(Name = "currencyCode", IsRequired = false)]
- public string CurrencyCode { get; set; }
-
- /// <summary>
- /// Number as string
- /// </summary>
- [DataMember(Name = "numberString", IsRequired = false)]
- public string NumberString { get; set; }
-
- /// <summary>
- /// Number to convert
- /// </summary>
- [DataMember(Name = "number", IsRequired = false)]
- public double Number { get; set; }
- }
-
- /// <summary>
- /// Represents additional options
- /// </summary>
- [DataContract]
- public class Options
- {
- /// <summary>
- /// Pattern type
- /// </summary>
- [DataMember(Name = "type", IsRequired = false)]
- public string Type { get; set; }
-
- /// <summary>
- /// Format length
- /// </summary>
- [DataMember(Name = "formatLength", IsRequired = false)]
- public string FormatLength { get; set; }
-
- /// <summary>
- /// Selector
- /// </summary>
- [DataMember(Name = "selector", IsRequired = false)]
- public string Selector { get; set; }
-
- /// <summary>
- /// Date name item
- /// </summary>
- [DataMember(Name = "item", IsRequired = false)]
- public string Item { get; set; }
- }
-
- #endregion
-
- #region returned objects
-
- #region Number pattern object
-
- /// <summary>
- /// Represents number pattern
- /// </summary>
- [DataContract]
- public class NumberPattern
- {
- /// <summary>
- /// Pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// Symbol
- /// </summary>
- [DataMember(Name = "symbol", IsRequired = false)]
- public string Symbol { get; set; }
-
- /// <summary>
- /// Fraction
- /// </summary>
- [DataMember(Name = "fraction", IsRequired = false)]
- public int Fraction { get; set; }
-
- /// <summary>
- /// Positive
- /// </summary>
- [DataMember(Name = "positive", IsRequired = false)]
- public string Positive { get; set; }
-
- /// <summary>
- /// Negative
- /// </summary>
- [DataMember(Name = "negative", IsRequired = false)]
- public string Negative { get; set; }
-
- /// <summary>
- /// Rounding
- /// </summary>
- [DataMember(Name = "rounding", IsRequired = false)]
- public int Rounding { get; set; }
-
- /// <summary>
- /// Decimal
- /// </summary>
- [DataMember(Name = "decimal", IsRequired = false)]
- public string Decimal { get; set; }
-
- /// <summary>
- /// Grouping
- /// </summary>
- [DataMember(Name = "grouping", IsRequired = false)]
- public string Grouping { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="symbol"></param>
- /// <param name="fraction"></param>
- /// <param name="positive"></param>
- /// <param name="negative"></param>
- /// <param name="rounding"></param>
- /// <param name="dec"></param>
- /// <param name="grouping"></param>
- public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
- {
- this.Pattern = pattern;
- this.Symbol = symbol;
- this.Fraction = fraction;
- this.Positive = positive;
- this.Negative = negative;
- this.Rounding = rounding;
- this.Decimal = dec;
- this.Grouping = grouping;
- }
- }
- #endregion
-
- #region Date format object
-
- /// <summary>
- /// Represents date format
- /// </summary>
- [DataContract]
- public class DateFormat
- {
- /// <summary>
- /// Year
- /// </summary>
- [DataMember(Name = "year", IsRequired = false)]
- public int Year { get; set; }
-
- /// <summary>
- /// Month
- /// </summary>
- [DataMember(Name = "month", IsRequired = false)]
- public int Month { get; set; }
-
- /// <summary>
- /// Day
- /// </summary>
- [DataMember(Name = "day", IsRequired = false)]
- public int Day { get; set; }
-
- /// <summary>
- /// Hour
- /// </summary>
- [DataMember(Name = "hour", IsRequired = false)]
- public int Hour { get; set; }
-
- /// <summary>
- /// Minute
- /// </summary>
- [DataMember(Name = "minute", IsRequired = false)]
- public int Minute { get; set; }
-
- /// <summary>
- /// Second
- /// </summary>
- [DataMember(Name = "second", IsRequired = false)]
- public int Second { get; set; }
-
- /// <summary>
- /// Millisecond
- /// </summary>
- [DataMember(Name = "millisecond", IsRequired = false)]
- public int Millisecond { get; set; }
-
- public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
- {
- this.Year = year;
- this.Month = month;
- this.Day = day;
- this.Hour = hour;
- this.Minute = minute;
- this.Millisecond = millisecond;
- }
-
- }
- #endregion
-
- #region Date pattern object
-
- /// <summary>
- /// Represents date pattern object
- /// </summary>
- [DataContract]
- public class DatePattern
- {
-
- /// <summary>
- /// Date pattern
- /// </summary>
- [DataMember(Name = "pattern", IsRequired = false)]
- public string Pattern { get; set; }
-
- /// <summary>
- /// TimeZone
- /// </summary>
- [DataMember(Name = "timezone", IsRequired = false)]
- public string TimeZone { get; set; }
-
- /// <summary>
- /// UTC offset
- /// </summary>
- [DataMember(Name = "utc_offset", IsRequired = false)]
- public double UtcOffset { get; set; }
-
- /// <summary>
- /// Dst offset
- /// </summary>
- [DataMember(Name = "dst_offset", IsRequired = false)]
- public double DstOffset { get; set; }
-
- /// <summary>
- /// Constructor of the class
- /// </summary>
- /// <param name="pattern"></param>
- /// <param name="timezone"></param>
- /// <param name="utcOffset"></param>
- /// <param name="dstOffset"></param>
- public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
- {
- this.Pattern = pattern;
- this.TimeZone = timezone;
- this.UtcOffset = utcOffset;
- this.DstOffset = dstOffset;
- }
-
- }
-
- #endregion
-
- #endregion
-
- #region Locale info
-
- /// <summary>
- /// Gets the string identifier for the client's current locale setting.
- /// </summary>
- /// <param name="options"></param>
- public void getLocaleName(string options)
- {
- try
- {
- var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the string identifier for the client's current language.
- /// </summary>
- /// <param name="options"></param>
- public void getPreferredLanguage(string options)
- {
- try
- {
- var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Date and time info
-
- /// <summary>
- /// Gets whether daylight savings time is in effect for a given date using the client's
- /// time zone and calendar.
- /// </summary>
- /// <param name="opitons">Date to daylight savings check.</param>
- public void isDayLightSavingsTime(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets the first day of the week according to the client's user preferences and calendar.
- /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
- /// </summary>
- /// <param name="options"></param>
- public void getFirstDayOfWeek(string options)
- {
- try
- {
- // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
- var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
- PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
- this.DispatchCommandResult(result);
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- #endregion
-
- #region Formatting
-
- /// <summary>
- /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client.
- /// </summary>
- /// <param name="options"></param>
- public void dateToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-
- string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
- break;
- }
- case 10: // short date
- {
- format = "{0:d}";
- break;
- }
- case 11: // full date
- {
- format = "{0:D}";
- break;
- }
- case 20: // short time
- {
- format = "{0:t}";
- break;
- }
- case 21: // full time
- {
- format = "{0:T}";
- break;
- }
- default: // short datetime
- {
- format = "{0:M/dd/yy H:m:s}";
- break;
- }
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
- /// </summary>
- /// <param name="options"></param>
- public void stringToDate(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.DateString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string format = "M/dd/yy H:m:s"; // short datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- format = "MMMM/dddd/yyyy HH:mm:ss tt";
- break;
- }
- case 10: // short date
- {
- format = "d";
- break;
- }
- case 11: // full date
- {
- format = "D";
- break;
- }
- case 20: // short time
- {
- format = "t";
- break;
- }
- case 21: // full time
- {
- format = "T";
- break;
- }
- default: // short datetime
- {
- format = "M/dd/yy H:m:s";
- break;
- }
- }
- }
-
- DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
- DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getDatePattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
- string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
- int formatLength = 0; //default format
- int selector = 0; //default selector
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.FormatLength != null)
- {
- string t = globalOptions.AdditionalOptions.FormatLength;
-
- if (t.Equals(GlobalizationOptions.Full))
- {
- formatLength++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Selector != null)
- {
- string t = globalOptions.AdditionalOptions.Selector;
-
- if (t.Equals(GlobalizationOptions.DateSelector))
- {
- selector += 10;
- }
- else if (t.Equals(GlobalizationOptions.TimeSelector))
- {
- selector += 20;
- }
- }
-
- //determine return value
- int method = formatLength + selector;
-
- switch (method)
- {
- case 1: // full datetime
- {
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- case 10: // short date
- {
- pattern = dateFormatInfo.ShortDatePattern;
- break;
- }
- case 11: // full date
- {
- pattern = dateFormatInfo.LongDatePattern;
- break;
- }
- case 20: // short time
- {
- pattern = dateFormatInfo.ShortTimePattern;
- break;
- }
- case 21: // full time
- {
- pattern = dateFormatInfo.LongTimePattern;
- break;
- }
- default: // short datetime
- {
- // Seems like C# doesn't support short datetime pattern so we use full format
- // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
- pattern = dateFormatInfo.FullDateTimePattern;
- break;
- }
- }
- }
-
- TimeZoneInfo localZone = TimeZoneInfo.Local;
- DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
- /// </summary>
- /// <param name="options"></param>
- public void getDateNames(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- int type = 0; //default wide
- int item = 0; //default months
-
- if (globalOptions.AdditionalOptions != null)
- {
- if (globalOptions.AdditionalOptions.Type != null)
- {
- string t = globalOptions.AdditionalOptions.Type;
-
- if (t.Equals(GlobalizationOptions.Narrow))
- {
- type++;
- }
- }
-
- if (globalOptions.AdditionalOptions.Item != null)
- {
- string t = globalOptions.AdditionalOptions.Item;
-
- if (t.Equals(GlobalizationOptions.Days))
- {
- item += 10;
- }
- }
- }
-
- //determine return value
- int method = item + type;
- string[] namesArray;
- CultureInfo currentCulture = CultureInfo.CurrentCulture;
-
- if (method == 1) //months and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
- }
- else if (method == 10) //days and wide
- {
- namesArray = currentCulture.DateTimeFormat.DayNames;
- }
- else if (method == 11) //days and narrow
- {
- namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
- }
- else //default: months and wide
- {
- namesArray = currentCulture.DateTimeFormat.MonthNames;
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void numberToString(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- string format = string.Empty;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- format = "{0:p}";
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- format = "{0:c}";
- break;
- }
-
- default:
- {
- format = "{0:f}";
- break;
- }
- }
-
- string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- /// <summary>
- /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
- /// </summary>
- /// <param name="options"></param>
- public void stringToNumber(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.NumberString))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string numberString = globalOptions.NumberString;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
- NumberStyles numberStyle;
-
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- numberStyle = NumberStyles.Any;
- numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
- break;
- }
-
- case GlobalizationOptions.Currency:
- {
- numberStyle = NumberStyles.Currency;
- break;
- }
-
- default:
- {
- numberStyle = NumberStyles.Number;
- break;
- }
- }
-
- double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
-
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
- }
- }
-
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
- /// </summary>
- /// <param name="options"></param>
- public void getNumberPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- CultureInfo cultureInfo = CultureInfo.CurrentCulture;
- NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
- string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
- GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
- NumberPattern pattern = null;
- string symbol;
-
- // TODO find out how to get format pattern and the number of fraction digits
- switch (numberFormatType)
- {
- case GlobalizationOptions.Percent:
- {
- symbol = formatInfo.PercentSymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
- break;
- }
- case GlobalizationOptions.Currency:
- {
- symbol = formatInfo.CurrencySymbol;
- pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
- break;
- }
- default:
- {
- symbol = formatInfo.NumberDecimalSeparator;
- pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
- break;
- }
- }
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
- }
- }
-
- /// <summary>
- /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
- /// </summary>
- /// <param name="options"></param>
- public void getCurrencyPattern(string options)
- {
- GlobalizationOptions globalOptions;
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- string currencyCode = globalOptions.CurrencyCode;
-
- // temporary not supported via lack of api required
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
- return;
-
- // TODO find the way to get currency info from currency code
- // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
- // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
- // CultureInfo cultureInfo = new CultureInfo(currencyCode);
- // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
- }
- }
-
- #endregion
-
- #region private methods
-
- /// <summary>
- /// Wraps data into JSON format
- /// </summary>
- /// <param name="data">data</param>
- /// <returns>data formatted as JSON object</returns>
- private string WrapIntoJSON<T>(T data, string keyName = "value")
- {
- string param = "{0}";
- string stringifiedData = data.ToString();
-
- if (data.GetType() == typeof(string))
- {
- param = "\"" + param + "\"";
- }
-
- if (data.GetType() == typeof(bool))
- {
- stringifiedData = stringifiedData.ToLower();
- }
-
- if (data.GetType() == typeof(string[]))
- {
- stringifiedData = JSON.JsonHelper.Serialize(data);
- }
-
- var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
- formattedData = "{" + formattedData + "}";
-
- return formattedData;
- }
-
- #endregion
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/ImageExifHelper.cs b/wp8/template/Plugins/ImageExifHelper.cs
deleted file mode 100644
index 68ddf87..0000000
--- a/wp8/template/Plugins/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- 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.
-
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class ImageExifOrientation
- {
- public const int Portrait = 1;
- public const int PortraitUpsideDown = 3;
- public const int LandscapeLeft = 6;
- public const int LandscapeRight = 8;
- }
-
- public class ImageExifHelper
- {
-
- public static Stream RotateStream(Stream stream, int angle)
- {
- stream.Position = 0;
- if (angle % 90 != 0 || angle < 0)
- {
- throw new ArgumentException();
- }
- if (angle % 360 == 0)
- {
- return stream;
- }
-
- angle = angle % 360;
-
- BitmapImage bitmap = new BitmapImage();
- bitmap.SetSource(stream);
- WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
- WriteableBitmap wbTarget = null;
-
- int srcPixelWidth = wbSource.PixelWidth;
- int srcPixelHeight = wbSource.PixelHeight;
-
- if (angle % 180 == 0)
- {
- wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
- }
- else
- {
- wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
- }
-
- int destPixelWidth = wbTarget.PixelWidth;
- int[] srcPxls = wbSource.Pixels;
- int[] destPxls = wbTarget.Pixels;
-
- // this ugly if/else is to avoid a conditional check for every pixel
- if (angle == 90)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 180)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
- else if (angle == 270)
- {
- for (int x = 0; x < srcPixelWidth; x++)
- {
- for (int y = 0; y < srcPixelHeight; y++)
- {
- destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
- }
- }
- }
-
- MemoryStream targetStream = new MemoryStream();
- wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
- return targetStream;
- }
-
- public static int getImageOrientationFromStream(Stream imgStream)
- {
-
- // 0xFFD8 : jpgHeader
- // 0xFFE1 :
- // 0x???? : length of exif data
- // 0x????, 0x???? : Chars 'E','x','i','f'
- // 0x0000 : 2 empty bytes
- // <== mark beginning of tags SIZE:ID:VALUE
- // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determins littleEndian-ness
- // 0x002A : marker value
- // 0x???? : offset to the Image File Data
-
- // XXXX possible space before actual tag data ... we skip to mark + offset
-
- // 0x???? number of exif tags present
-
- // make sure we are at the begining
- imgStream.Seek(0, SeekOrigin.Begin);
- BinaryReader reader = new BinaryReader(imgStream);
-
- byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
- byte start = reader.ReadByte(); // 0xFF
- byte index = reader.ReadByte(); // 0xE1
-
- while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
- {
- // Get the data length
- ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // skip along
- reader.ReadBytes(dLen - 2);
- start = reader.ReadByte();
- index = reader.ReadByte();
- }
-
- // It's only success if we found the 0xFFE1 marker
- if (start != 0xFF || index != 0xE1)
- {
- // throw new Exception("Could not find Exif data block");
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 byte length of EXIF data
- ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- String exif = ""; // build the string
- for (var n = 0; n < 4; n++)
- {
- exif += reader.ReadChar();
- }
- if (exif != "Exif")
- {
- // did not find exif data ...
- Debug.WriteLine("Did not find EXIF data");
- return 0;
- }
-
- // read 2 empty bytes
- //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- reader.ReadBytes(2);
-
- long headerMark = reader.BaseStream.Position; // where are we now <==
-
- //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
- reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
- if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- Debug.WriteLine("Error in data != 0x002A");
- return 0;
- }
-
- // Get the offset to the IFD (image file directory)
- ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
- imgStream.Position = headerMark + imgOffset;
- ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- for (ushort x = 0; x < tagCount; x++)
- {
- // Orientation = 0x112, aka 274
- if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
- {
- ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
- // don't care ..
- uint comps = reader.ReadUInt32();
- byte[] tagData = reader.ReadBytes(4);
- int orientation = (int)tagData[0];
- Debug.WriteLine("orientation = " + orientation.ToString());
- return orientation;
- // 6 means rotate clockwise 90 deg
- // 8 means rotate counter-clockwise 90 deg
- // 1 means all is good
- // 3 means flip vertical
- }
- // skip to the next item, 12 bytes each
- reader.BaseStream.Seek(10, SeekOrigin.Current);
- }
- return 0;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/InAppBrowser.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/InAppBrowser.cs b/wp8/template/Plugins/InAppBrowser.cs
deleted file mode 100644
index 2741355..0000000
--- a/wp8/template/Plugins/InAppBrowser.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using WPCordovaClassLib.Cordova;
-using WPCordovaClassLib.Cordova.Commands;
-using WPCordovaClassLib.Cordova.JSON;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class BrowserOptions
- {
- [DataMember]
- public string url;
-
- [DataMember]
- public bool isGeolocationEnabled;
- }
-
- public class InAppBrowser : BaseCommand
- {
-
- private static WebBrowser browser;
- private static ApplicationBarIconButton backButton;
- private static ApplicationBarIconButton fwdButton;
-
- public void open(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
- string urlLoc = args[0];
- string target = args[1];
- /*
- _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
- _blank - always open in the InAppBrowser
- _system - always open in the system web browser
- */
- switch (target)
- {
- case "_blank":
- ShowInAppBrowser(urlLoc);
- break;
- case "_self":
- ShowCordovaBrowser(urlLoc);
- break;
- case "_system":
- ShowSystemBrowser(urlLoc);
- break;
- }
-
-
- }
-
- private void ShowCordovaBrowser(string url)
- {
- Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- CordovaView cView = page.FindName("CordovaView") as CordovaView;
- if (cView != null)
- {
- WebBrowser br = cView.Browser;
- br.Navigate(loc);
- }
- }
-
- }
- });
- }
-
- private void ShowSystemBrowser(string url)
- {
- WebBrowserTask webBrowserTask = new WebBrowserTask();
- webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
- webBrowserTask.Show();
- }
-
-
- private void ShowInAppBrowser(string url)
- {
- Uri loc = new Uri(url);
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (browser != null)
- {
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- browser.Navigate(loc);
- }
- else
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- string baseImageUrl = "Images/";
-
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- browser = new WebBrowser();
- browser.IsScriptEnabled = true;
- browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-
- browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
- browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
- browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
- browser.Navigate(loc);
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- grid.Children.Add(browser);
- }
-
- ApplicationBar bar = new ApplicationBar();
- bar.BackgroundColor = Colors.Gray;
- bar.IsMenuEnabled = false;
-
- backButton = new ApplicationBarIconButton();
- backButton.Text = "Back";
-
- backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
- backButton.Click += new EventHandler(backButton_Click);
- backButton.IsEnabled = false;
- bar.Buttons.Add(backButton);
-
-
- fwdButton = new ApplicationBarIconButton();
- fwdButton.Text = "Forward";
- fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
- fwdButton.Click += new EventHandler(fwdButton_Click);
- fwdButton.IsEnabled = false;
- bar.Buttons.Add(fwdButton);
-
- ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
- closeBtn.Text = "Close";
- closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
- closeBtn.Click += new EventHandler(closeBtn_Click);
- bar.Buttons.Add(closeBtn);
-
- page.ApplicationBar = bar;
- }
-
- }
- }
- });
- }
-
- void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
-
- }
-
- void fwdButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoForward();
- //browser.InvokeScript("execScript", "history.forward();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void backButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
- browser.GoBack();
- //browser.InvokeScript("execScript", "history.back();");
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void closeBtn_Click(object sender, EventArgs e)
- {
- this.close();
- }
-
-
- public void close(string options = "")
- {
- if (browser != null)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(browser);
- }
- page.ApplicationBar = null;
- }
- }
- browser = null;
- string message = "{\"type\":\"exit\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = false;
- this.DispatchCommandResult(result);
- });
- }
- }
-
- void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (browser != null)
- {
- backButton.IsEnabled = browser.CanGoBack;
- fwdButton.IsEnabled = browser.CanGoForward;
-
- }
- string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
- {
- string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- void browser_Navigating(object sender, NavigatingEventArgs e)
- {
- string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Media.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Media.cs b/wp8/template/Plugins/Media.cs
deleted file mode 100644
index 5de4884..0000000
--- a/wp8/template/Plugins/Media.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides the ability to record and play back audio files on a device.
- /// </summary>
- public class Media : BaseCommand
- {
- /// <summary>
- /// Audio player objects
- /// </summary>
- private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
- /// <summary>
- /// Represents Media action options.
- /// </summary>
- [DataContract]
- public class MediaOptions
- {
- /// <summary>
- /// Audio id
- /// </summary>
- [DataMember(Name = "id", IsRequired = true)]
- public string Id { get; set; }
-
- /// <summary>
- /// Path to audio file
- /// </summary>
- [DataMember(Name = "src")]
- public string Src { get; set; }
-
- /// <summary>
- /// New track position
- /// </summary>
- [DataMember(Name = "milliseconds")]
- public int Milliseconds { get; set; }
- }
-
- /// <summary>
- /// Releases the audio player instance to save memory.
- /// </summary>
- public void release(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- Media.players.Remove(mediaOptions.Id);
- audio.Dispose();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts recording and save the specified file
- /// </summary>
- public void startRecordingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (mediaOptions != null)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio;
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- audio = Media.players[mediaOptions.Id];
- }
-
- if (audio != null)
- {
- audio.startRecording(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
- }
-
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
-
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Stops recording and save to the file specified when recording started
- /// </summary>
- public void stopRecordingAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopRecording();
- Media.players.Remove(mediaId);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- public void setVolume(string options) // id,volume
- {
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- string id = optionsString[0];
- double volume = double.Parse(optionsString[1]);
-
- if (Media.players.ContainsKey(id))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer player = Media.players[id];
- player.setVolume(volume);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
- return;
- }
- }
-
- // Some Audio Notes:
- // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
- // While playing, a MediaElement stops all other media playback on the phone.
- // Multiple MediaElement controls are NOT supported
-
- // Called when you create a new Media('blah') object in JS.
- public void create(string options)
- {
- // Debug.WriteLine("Creating Audio :: " + options);
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
- return;
- }
-
- AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- public void startPlayingAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- if (optionsString.Length > 2 && optionsString[2] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[2]);
- }
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
- audio = Media.players[mediaOptions.Id];
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- audio.startPlaying(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Seeks to a location
- /// </summary>
- public void seekToAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- if (optionsString.Length > 1 && optionsString[1] != null)
- {
- mediaOptions.Milliseconds = int.Parse(optionsString[1]);
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- audio.seekToPlaying(mediaOptions.Milliseconds);
- }
- else
- {
- Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlayingAudio(string options)
- {
-
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.pausePlaying();
- }
- else
- {
- Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
-
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlayingAudio(String options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopPlaying();
- }
- else
- {
- Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- public void getCurrentPositionAudio(string options)
- {
- try
- {
- string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
- }
-
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
-
- [Obsolete("This method will be removed shortly")]
- public void getDurationAudio(string options)
- {
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- AudioPlayer audio;
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = Media.players[mediaOptions.Id];
- }
- else
- {
- Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
- }
-}
[27/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Contacts.cs
----------------------------------------------------------------------
diff --git a/plugins/Contacts.cs b/plugins/Contacts.cs
deleted file mode 100644
index af78942..0000000
--- a/plugins/Contacts.cs
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Tasks;
-using Microsoft.Phone.UserData;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Windows;
-using DeviceContacts = Microsoft.Phone.UserData.Contacts;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class SearchOptions
- {
- [DataMember]
- public string filter { get; set; }
- [DataMember]
- public bool multiple { get; set; }
- }
-
- [DataContract]
- public class ContactSearchParams
- {
- [DataMember]
- public string[] fields { get; set; }
- [DataMember]
- public SearchOptions options { get; set; }
- }
-
- [DataContract]
- public class JSONContactAddress
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string streetAddress { get; set; }
- [DataMember]
- public string locality { get; set; }
- [DataMember]
- public string region { get; set; }
- [DataMember]
- public string postalCode { get; set; }
- [DataMember]
- public string country { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactName
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string familyName { get; set; }
- [DataMember]
- public string givenName { get; set; }
- [DataMember]
- public string middleName { get; set; }
- [DataMember]
- public string honorificPrefix { get; set; }
- [DataMember]
- public string honorificSuffix { get; set; }
- }
-
- [DataContract]
- public class JSONContactField
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string value { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactOrganization
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string name { get; set; }
- [DataMember]
- public bool pref { get; set; }
- [DataMember]
- public string department { get; set; }
- [DataMember]
- public string title { get; set; }
- }
-
- [DataContract]
- public class JSONContact
- {
- [DataMember]
- public string id { get; set; }
- [DataMember]
- public string rawId { get; set; }
- [DataMember]
- public string displayName { get; set; }
- [DataMember]
- public string nickname { get; set; }
- [DataMember]
- public string note { get; set; }
-
- [DataMember]
- public JSONContactName name { get; set; }
-
- [DataMember]
- public JSONContactField[] emails { get; set; }
-
- [DataMember]
- public JSONContactField[] phoneNumbers { get; set; }
-
- [DataMember]
- public JSONContactField[] ims { get; set; }
-
- [DataMember]
- public JSONContactField[] photos { get; set; }
-
- [DataMember]
- public JSONContactField[] categories { get; set; }
-
- [DataMember]
- public JSONContactField[] urls { get; set; }
-
- [DataMember]
- public JSONContactOrganization[] organizations { get; set; }
-
- [DataMember]
- public JSONContactAddress[] addresses { get; set; }
- }
-
-
- public class Contacts : BaseCommand
- {
-
- public const int UNKNOWN_ERROR = 0;
- public const int INVALID_ARGUMENT_ERROR = 1;
- public const int TIMEOUT_ERROR = 2;
- public const int PENDING_OPERATION_ERROR = 3;
- public const int IO_ERROR = 4;
- public const int NOT_SUPPORTED_ERROR = 5;
- public const int PERMISSION_DENIED_ERROR = 20;
- public const int SYNTAX_ERR = 8;
-
- public Contacts()
- {
-
- }
-
- // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
- public void save(string jsonContact)
- {
-
- // jsonContact is actually an array of 1 {contact}
- string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
-
-
- JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
-
- SaveContactTask contactTask = new SaveContactTask();
-
- if (contact.nickname != null)
- {
- contactTask.Nickname = contact.nickname;
- }
- if (contact.urls != null && contact.urls.Length > 0)
- {
- contactTask.Website = contact.urls[0].value;
- }
- if (contact.note != null)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.name
- if (contact.name != null)
- {
- if (contact.name.givenName != null)
- contactTask.FirstName = contact.name.givenName;
- if (contact.name.familyName != null)
- contactTask.LastName = contact.name.familyName;
- if (contact.name.middleName != null)
- contactTask.MiddleName = contact.name.middleName;
- if (contact.name.honorificSuffix != null)
- contactTask.Suffix = contact.name.honorificSuffix;
- if (contact.name.honorificPrefix != null)
- contactTask.Title = contact.name.honorificPrefix;
- }
- #endregion
-
- #region contact.org
- if (contact.organizations != null && contact.organizations.Count() > 0)
- {
- contactTask.Company = contact.organizations[0].name;
- contactTask.JobTitle = contact.organizations[0].title;
- }
- #endregion
-
- #region contact.phoneNumbers
- if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
- {
- foreach (JSONContactField field in contact.phoneNumbers)
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkPhone = field.value;
- }
- else if (fieldType == "home")
- {
- contactTask.HomePhone = field.value;
- }
- else if (fieldType == "mobile")
- {
- contactTask.MobilePhone = field.value;
- }
- }
- }
- #endregion
-
- #region contact.emails
-
- if (contact.emails != null && contact.emails.Length > 0)
- {
-
- // set up different email types if they are not explicitly defined
- foreach (string type in new string[] { "personal", "work", "other" })
- {
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null && String.IsNullOrEmpty(field.type))
- {
- field.type = type;
- break;
- }
- }
- }
-
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null)
- {
- if (field.type != null && field.type != "other")
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkEmail = field.value;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.PersonalEmail = field.value;
- }
- }
- else
- {
- contactTask.OtherEmail = field.value;
- }
- }
-
- }
- }
- #endregion
-
- if (contact.note != null && contact.note.Length > 0)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.addresses
- if (contact.addresses != null && contact.addresses.Length > 0)
- {
- foreach (JSONContactAddress address in contact.addresses)
- {
- if (address.type == null)
- {
- address.type = "home"; // set a default
- }
- string fieldType = address.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkAddressCity = address.locality;
- contactTask.WorkAddressCountry = address.country;
- contactTask.WorkAddressState = address.region;
- contactTask.WorkAddressStreet = address.streetAddress;
- contactTask.WorkAddressZipCode = address.postalCode;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.HomeAddressCity = address.locality;
- contactTask.HomeAddressCountry = address.country;
- contactTask.HomeAddressState = address.region;
- contactTask.HomeAddressStreet = address.streetAddress;
- contactTask.HomeAddressZipCode = address.postalCode;
- }
- else
- {
- // no other address fields available ...
- Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
- }
- }
- }
- #endregion
-
-
- contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
- contactTask.Show();
- }
-
- void ContactSaveTaskCompleted(object sender, SaveContactResult e)
- {
- SaveContactTask task = sender as SaveContactTask;
-
- if (e.TaskResult == TaskResult.OK)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
-
- string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
-
- deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
- });
-
-
- }
- else if (e.TaskResult == TaskResult.Cancel)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
- }
- }
-
- void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- if (e.Results.Count() > 0)
- {
- List<Contact> foundContacts = new List<Contact>();
-
- int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
- Contact newContact = (from Contact contact in e.Results
- where contact.GetHashCode() == n
- select contact).First();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
-
-
- public void remove(string id)
- {
- // note id is wrapped in [] and always has exactly one string ...
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
- }
-
- public void search(string searchCriteria)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
-
- ContactSearchParams searchParams = new ContactSearchParams();
- try
- {
- searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
- searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
- return;
- }
-
- if (searchParams.options == null)
- {
- searchParams.options = new SearchOptions();
- searchParams.options.filter = "";
- searchParams.options.multiple = true;
- }
-
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
-
- // default is to search all fields
- FilterKind filterKind = FilterKind.None;
- // if only one field is specified, we will try the 3 available DeviceContact search filters
- if (searchParams.fields.Count() == 1)
- {
- if (searchParams.fields.Contains("name"))
- {
- filterKind = FilterKind.DisplayName;
- }
- else if (searchParams.fields.Contains("emails"))
- {
- filterKind = FilterKind.EmailAddress;
- }
- else if (searchParams.fields.Contains("phoneNumbers"))
- {
- filterKind = FilterKind.PhoneNumber;
- }
- }
-
- try
- {
-
- deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
- }
- catch (Exception ex)
- {
- Debug.WriteLine("search contacts exception :: " + ex.Message);
- }
- }
-
- private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- ContactSearchParams searchParams = (ContactSearchParams)e.State;
-
- List<Contact> foundContacts = null;
-
- // if we have multiple search fields
- if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
- {
- foundContacts = new List<Contact>();
- if (searchParams.fields.Contains("emails"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactEmailAddress a in con.EmailAddresses
- where a.EmailAddress.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("displayName"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.DisplayName.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("name"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("phoneNumbers"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactPhoneNumber a in con.PhoneNumbers
- where a.PhoneNumber.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("urls"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from string a in con.Websites
- where a.Contains(searchParams.options.filter)
- select con);
- }
- }
- else
- {
- foundContacts = new List<Contact>(e.Results);
- }
-
- //List<string> contactList = new List<string>();
-
- string strResult = "";
-
- IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
-
- foreach (Contact contact in distinctContacts)
- {
- strResult += FormatJSONContact(contact, null) + ",";
- //contactList.Add(FormatJSONContact(contact, null));
- if (!searchParams.options.multiple)
- {
- break; // just return the first item
- }
- }
- PluginResult result = new PluginResult(PluginResult.Status.OK);
- result.Message = "[" + strResult.TrimEnd(',') + "]";
- DispatchCommandResult(result);
-
- }
-
- private string FormatJSONPhoneNumbers(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactPhoneNumber number in con.PhoneNumbers)
- {
-
- string contactField = string.Format(contactFieldFormat,
- number.Kind.ToString(),
- number.PhoneNumber);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONEmails(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactEmailAddress address in con.EmailAddresses)
- {
- string contactField = string.Format(contactFieldFormat,
- address.Kind.ToString(),
- address.EmailAddress);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string getFormattedJSONAddress(ContactAddress address, bool isPrefered)
- {
-
- string addressFormatString = "\"pref\":{0}," + // bool
- "\"type\":\"{1}\"," +
- "\"formatted\":\"{2}\"," +
- "\"streetAddress\":\"{3}\"," +
- "\"locality\":\"{4}\"," +
- "\"region\":\"{5}\"," +
- "\"postalCode\":\"{6}\"," +
- "\"country\":\"{7}\"";
-
- string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
- + address.PhysicalAddress.AddressLine2 + " "
- + address.PhysicalAddress.City + " "
- + address.PhysicalAddress.StateProvince + " "
- + address.PhysicalAddress.CountryRegion + " "
- + address.PhysicalAddress.PostalCode;
-
- string jsonAddress = string.Format(addressFormatString,
- isPrefered ? "\"true\"" : "\"false\"",
- address.Kind.ToString(),
- formattedAddress,
- address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
- address.PhysicalAddress.City,
- address.PhysicalAddress.StateProvince,
- address.PhysicalAddress.PostalCode,
- address.PhysicalAddress.CountryRegion);
-
- //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
-
- return "{" + jsonAddress + "}";
- }
-
- private string FormatJSONAddresses(Contact con)
- {
- string retVal = "";
- foreach (ContactAddress address in con.Addresses)
- {
- retVal += this.getFormattedJSONAddress(address, false) + ",";
- }
-
- //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONWebsites(Contact con)
- {
- string retVal = "";
- foreach (string website in con.Websites)
- {
- retVal += "\"" + website + "\",";
- }
- return retVal.TrimEnd(',');
- }
-
- /*
- * formatted: The complete name of the contact. (DOMString)
- familyName: The contacts family name. (DOMString)
- givenName: The contacts given name. (DOMString)
- middleName: The contacts middle name. (DOMString)
- honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
- honorificSuffix: The contacts suffix (example Esq.). (DOMString)
- */
- private string FormatJSONName(Contact con)
- {
- string retVal = "";
- string formatStr = "\"formatted\":\"{0}\"," +
- "\"familyName\":\"{1}\"," +
- "\"givenName\":\"{2}\"," +
- "\"middleName\":\"{3}\"," +
- "\"honorificPrefix\":\"{4}\"," +
- "\"honorificSuffix\":\"{5}\"";
-
- if (con.CompleteName != null)
- {
- retVal = string.Format(formatStr,
- con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
- con.CompleteName.LastName,
- con.CompleteName.FirstName,
- con.CompleteName.MiddleName,
- con.CompleteName.Title,
- con.CompleteName.Suffix);
- }
- else
- {
- retVal = string.Format(formatStr,"","","","","","");
- }
-
- return "{" + retVal + "}";
- }
-
- private string FormatJSONContact(Contact con, string[] fields)
- {
-
- string contactFormatStr = "\"id\":\"{0}\"," +
- "\"displayName\":\"{1}\"," +
- "\"nickname\":\"{2}\"," +
- "\"phoneNumbers\":[{3}]," +
- "\"emails\":[{4}]," +
- "\"addresses\":[{5}]," +
- "\"urls\":[{6}]," +
- "\"name\":{7}," +
- "\"note\":\"{8}\"," +
- "\"birthday\":\"{9}\"";
-
-
- string jsonContact = String.Format(contactFormatStr,
- con.GetHashCode(),
- con.DisplayName,
- con.CompleteName != null ? con.CompleteName.Nickname : "",
- FormatJSONPhoneNumbers(con),
- FormatJSONEmails(con),
- FormatJSONAddresses(con),
- FormatJSONWebsites(con),
- FormatJSONName(con),
- con.Notes.FirstOrDefault(),
- con.Birthdays.FirstOrDefault());
-
- //Debug.WriteLine("jsonContact = " + jsonContact);
- // JSON requires new line characters be escaped
- return "{" + jsonContact.Replace("\n", "\\n") + "}";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/plugins/DebugConsole.cs b/plugins/DebugConsole.cs
deleted file mode 100644
index fa9863a..0000000
--- a/plugins/DebugConsole.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class DebugConsole : BaseCommand
- {
- // warn, error
- public void log(string msg)
- {
- Debug.WriteLine("Log:" + msg);
- }
-
- public void error(string msg)
- {
- Debug.WriteLine("Error:" + msg);
- }
-
- public void warn(string msg)
- {
- Debug.WriteLine("Warn:" + msg);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Device.cs
----------------------------------------------------------------------
diff --git a/plugins/Device.cs b/plugins/Device.cs
deleted file mode 100644
index 8abb4ff..0000000
--- a/plugins/Device.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Info;
-using System.IO.IsolatedStorage;
-using System.Windows.Resources;
-using System.IO;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Device : BaseCommand
- {
- public void getDeviceInfo(string notused)
- {
-
- string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
- this.name,
- this.cordova,
- this.platform,
- this.uuid,
- this.version,
- this.model);
-
-
-
- res = "{" + res + "}";
- //Debug.WriteLine("Result::" + res);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
- }
-
- public string model
- {
- get
- {
- return DeviceStatus.DeviceName;
- //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion);
- }
- }
-
- public string name
- {
- get
- {
- return DeviceStatus.DeviceName;
-
- }
- }
-
- public string cordova
- {
- get
- {
- // TODO: should be able to dynamically read the Cordova version from somewhere...
- return "0.0.0";
- }
- }
-
- public string platform
- {
- get
- {
- return Environment.OSVersion.Platform.ToString();
- }
- }
-
- public string uuid
- {
- get
- {
- string returnVal = "";
- object id;
- UserExtendedProperties.TryGetValue("ANID", out id);
-
- if (id != null)
- {
- returnVal = id.ToString().Substring(2, 32);
- }
- else
- {
- returnVal = "???unknown???";
-
- using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- try
- {
- IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
- using (StreamReader reader = new StreamReader(fileStream))
- {
- returnVal = reader.ReadLine();
- }
- }
- catch (Exception /*ex*/)
- {
-
- }
- }
- }
-
- return returnVal;
- }
- }
-
- public string version
- {
- get
- {
- return Environment.OSVersion.Version.ToString();
- }
- }
-
- }
-}
[08/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/AudioPlayer.cs b/wp8/template/Plugins/AudioPlayer.cs
deleted file mode 100644
index a83be5b..0000000
--- a/wp8/template/Plugins/AudioPlayer.cs
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Implements audio record and play back functionality.
- /// </summary>
- internal class AudioPlayer : IDisposable
- {
- #region Constants
-
- // AudioPlayer states
- private const int PlayerState_None = 0;
- private const int PlayerState_Starting = 1;
- private const int PlayerState_Running = 2;
- private const int PlayerState_Paused = 3;
- private const int PlayerState_Stopped = 4;
-
- // AudioPlayer messages
- private const int MediaState = 1;
- private const int MediaDuration = 2;
- private const int MediaPosition = 3;
- private const int MediaError = 9;
-
- // AudioPlayer errors
- private const int MediaErrorPlayModeSet = 1;
- private const int MediaErrorAlreadyRecording = 2;
- private const int MediaErrorStartingRecording = 3;
- private const int MediaErrorRecordModeSet = 4;
- private const int MediaErrorStartingPlayback = 5;
- private const int MediaErrorResumeState = 6;
- private const int MediaErrorPauseState = 7;
- private const int MediaErrorStopState = 8;
-
- //TODO: get rid of this callback, it should be universal
- //private const string CallbackFunction = "CordovaMediaonStatus";
-
- #endregion
-
- /// <summary>
- /// The AudioHandler object
- /// </summary>
- private Media handler;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// The id of this player (used to identify Media object in JavaScript)
- /// </summary>
- private String id;
-
- /// <summary>
- /// State of recording or playback
- /// </summary>
- private int state = PlayerState_None;
-
- /// <summary>
- /// File name to play or record to
- /// </summary>
- private String audioFile = null;
-
- /// <summary>
- /// Duration of audio
- /// </summary>
- private double duration = -1;
-
- /// <summary>
- /// Audio player object
- /// </summary>
- private MediaElement player = null;
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone recorder;
-
- /// <summary>
- /// Internal flag specified that we should only open audio w/o playing it
- /// </summary>
- private bool prepareOnly = false;
-
- /// <summary>
- /// Creates AudioPlayer instance
- /// </summary>
- /// <param name="handler">Media object</param>
- /// <param name="id">player id</param>
- public AudioPlayer(Media handler, String id)
- {
- this.handler = handler;
- this.id = id;
- }
-
- /// <summary>
- /// Destroys player and stop audio playing or recording
- /// </summary>
- public void Dispose()
- {
- if (this.player != null)
- {
- this.stopPlaying();
- this.player = null;
- }
- if (this.recorder != null)
- {
- this.stopRecording();
- this.recorder = null;
- }
-
- this.FinalizeXnaGameLoop();
- }
-
- private void InvokeCallback(int message, string value, bool removeHandler)
- {
- string args = string.Format("('{0}',{1},{2});", this.id, message, value);
- string callback = @"(function(id,msg,value){
- try {
- if (msg == Media.MEDIA_ERROR) {
- value = {'code':value};
- }
- Media.onStatus(id,msg,value);
- }
- catch(e) {
- console.log('Error calling Media.onStatus :: ' + e);
- }
- })" + args;
- this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
- }
-
- private void InvokeCallback(int message, int value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- private void InvokeCallback(int message, double value, bool removeHandler)
- {
- InvokeCallback(message, value.ToString(), removeHandler);
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- /// <param name="filePath"></param>
- public void startRecording(string filePath)
- {
- if (this.player != null)
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- }
- else if (this.recorder == null)
- {
- try
- {
- this.audioFile = filePath;
- this.InitializeXnaGameLoop();
- this.recorder = Microphone.Default;
- this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
- this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
- this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
- this.recorder.Start();
- FrameworkDispatcher.Update();
- this.SetState(PlayerState_Running);
- }
- catch (Exception)
- {
- InvokeCallback(MediaError, MediaErrorStartingRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
- }
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- public void stopRecording()
- {
- if (this.recorder != null)
- {
- if (this.state == PlayerState_Running)
- {
- try
- {
- this.recorder.Stop();
- this.recorder.BufferReady -= recorderBufferReady;
- this.recorder = null;
- SaveAudioClipToLocalStorage();
- this.FinalizeXnaGameLoop();
- this.SetState(PlayerState_Stopped);
- }
- catch (Exception)
- {
- //TODO
- }
- }
- }
- }
-
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <summary>
- /// Starts or resume playing audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- public void startPlaying(string filePath)
- {
- if (this.recorder != null)
- {
- InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
- return;
- }
-
-
- if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
- {
- try
- {
- // this.player is a MediaElement, it must be added to the visual tree in order to play
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
-
- this.player = grid.FindName("playerMediaElement") as MediaElement;
- if (this.player == null) // still null ?
- {
- this.player = new MediaElement();
- this.player.Name = "playerMediaElement";
- grid.Children.Add(this.player);
- this.player.Visibility = Visibility.Visible;
- }
- if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
- {
- this.player.Stop(); // stop it!
- }
-
- this.player.Source = null; // Garbage collect it.
- this.player.MediaOpened += MediaOpened;
- this.player.MediaEnded += MediaEnded;
- this.player.MediaFailed += MediaFailed;
- }
- }
- }
-
- this.audioFile = filePath;
-
- Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
- if (uri.IsAbsoluteUri)
- {
- this.player.Source = uri;
- }
- else
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- // try to unpack it from the dll into isolated storage
- StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
- if (fileResourceStreamInfo != null)
- {
- using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
- {
- byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
- string[] dirParts = filePath.Split('/');
- string dirName = "";
- for (int n = 0; n < dirParts.Length - 1; n++)
- {
- dirName += dirParts[n] + "/";
- }
- if (!isoFile.DirectoryExists(dirName))
- {
- isoFile.CreateDirectory(dirName);
- }
-
- using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
- {
- using (BinaryWriter writer = new BinaryWriter(outFile))
- {
- writer.Write(data);
- }
- }
- }
- }
- }
- if (isoFile.FileExists(filePath))
- {
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
- {
- this.player.SetSource(stream);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
- return;
- }
- }
- }
- this.SetState(PlayerState_Starting);
- }
- catch (Exception e)
- {
- Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
- }
- }
- else
- {
- if (this.state != PlayerState_Running)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorResumeState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
- }
- }
- }
-
- /// <summary>
- /// Callback to be invoked when the media source is ready for playback
- /// </summary>
- private void MediaOpened(object sender, RoutedEventArgs arg)
- {
- if (this.player != null)
- {
- this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
- InvokeCallback(MediaDuration, this.duration, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
- if (!this.prepareOnly)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- this.prepareOnly = false;
- }
- else
- {
- // TODO: occasionally MediaOpened is signalled, but player is null
- }
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has completed
- /// </summary>
- private void MediaEnded(object sender, RoutedEventArgs arg)
- {
- this.SetState(PlayerState_Stopped);
- }
-
- /// <summary>
- /// Callback to be invoked when playback of a media source has failed
- /// </summary>
- private void MediaFailed(object sender, RoutedEventArgs arg)
- {
- player.Stop();
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
- }
-
- /// <summary>
- /// Seek or jump to a new time in the track
- /// </summary>
- /// <param name="milliseconds">The new track position</param>
- public void seekToPlaying(int milliseconds)
- {
- if (this.player != null)
- {
- TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
- this.player.Position = tsPos;
- InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
- }
- }
-
- /// <summary>
- /// Set the volume of the player
- /// </summary>
- /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
- public void setVolume(double vol)
- {
- if (this.player != null)
- {
- this.player.Volume = vol;
- }
- }
-
- /// <summary>
- /// Pauses playing
- /// </summary>
- public void pausePlaying()
- {
- if (this.state == PlayerState_Running)
- {
- this.player.Pause();
- this.SetState(PlayerState_Paused);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPauseState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
- }
- }
-
-
- /// <summary>
- /// Stops playing the audio file
- /// </summary>
- public void stopPlaying()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- this.player.Stop();
-
- this.player.Position = new TimeSpan(0L);
- this.SetState(PlayerState_Stopped);
- }
- //else // Why is it an error to call stop on a stopped media?
- //{
- // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
- //}
- }
-
- /// <summary>
- /// Gets current position of playback
- /// </summary>
- /// <returns>current position</returns>
- public double getCurrentPosition()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- double currentPosition = this.player.Position.TotalSeconds;
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
- return currentPosition;
- }
- else
- {
- return 0;
- }
- }
-
- /// <summary>
- /// Gets the duration of the audio file
- /// </summary>
- /// <param name="filePath">The name of the audio file</param>
- /// <returns>track duration</returns>
- public double getDuration(string filePath)
- {
- if (this.recorder != null)
- {
- return (-2);
- }
-
- if (this.player != null)
- {
- return this.duration;
-
- }
- else
- {
- this.prepareOnly = true;
- this.startPlaying(filePath);
- return this.duration;
- }
- }
-
- /// <summary>
- /// Sets the state and send it to JavaScript
- /// </summary>
- /// <param name="state">state</param>
- private void SetState(int state)
- {
- if (this.state != state)
- {
- InvokeCallback(MediaState, state, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
- }
-
- this.state = state;
- }
-
- #region record methods
-
- /// <summary>
- /// Copies data from recorder to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void recorderBufferReady(object sender, EventArgs e)
- {
- this.recorder.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private void SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return;
- }
-
- this.memoryStream.UpdateWavStream();
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- string directory = Path.GetDirectoryName(audioFile);
-
- if (!isoFile.DirectoryExists(directory))
- {
- isoFile.CreateDirectory(directory);
- }
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
- {
- this.memoryStream.CopyTo(fileStream);
- }
- }
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- #region Xna loop
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (this.dtXna != null)
- {
- this.dtXna.Stop();
- this.dtXna = null;
- }
- }
-
- #endregion
-
- #endregion
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Battery.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Battery.cs b/wp8/template/Plugins/Battery.cs
deleted file mode 100644
index 962959e..0000000
--- a/wp8/template/Plugins/Battery.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-using Microsoft.Phone.Info;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Listens for changes to the state of the battery on the device.
- /// Currently only the "isPlugged" parameter available via native APIs.
- /// </summary>
- public class Battery : BaseCommand
- {
- private bool isPlugged = false;
- private EventHandler powerChanged;
-
- public Battery()
- {
- powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- }
-
- public void start(string options)
- {
- // Register power changed event handler
- DeviceStatus.PowerSourceChanged += powerChanged;
-
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- public void stop(string options)
- {
- // Unregister power changed event handler
- DeviceStatus.PowerSourceChanged -= powerChanged;
- }
-
- private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
- {
- isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
-
- private string GetCurrentBatteryStateFormatted()
- {
- string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
- "null",
- isPlugged ? "true" : "false"
- );
- batteryState = "{" + batteryState + "}";
- return batteryState;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Camera.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Camera.cs b/wp8/template/Plugins/Camera.cs
deleted file mode 100644
index 5ff8045..0000000
--- a/wp8/template/Plugins/Camera.cs
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Collections.Generic;
-using Microsoft.Phone.Tasks;
-using System.Runtime.Serialization;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Xna.Framework.Media;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Camera : BaseCommand
- {
-
- /// <summary>
- /// Return base64 encoded string
- /// </summary>
- private const int DATA_URL = 0;
-
- /// <summary>
- /// Return file uri
- /// </summary>
- private const int FILE_URI = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int PHOTOLIBRARY = 0;
-
- /// <summary>
- /// Take picture from camera
- /// </summary>
-
- private const int CAMERA = 1;
-
- /// <summary>
- /// Choose image from picture library
- /// </summary>
- private const int SAVEDPHOTOALBUM = 2;
-
- /// <summary>
- /// Take a picture of type JPEG
- /// </summary>
- private const int JPEG = 0;
-
- /// <summary>
- /// Take a picture of type PNG
- /// </summary>
- private const int PNG = 1;
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private const string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CameraOptions
- {
- /// <summary>
- /// Source to getPicture from.
- /// </summary>
- [DataMember(IsRequired = false, Name = "sourceType")]
- public int PictureSourceType { get; set; }
-
- /// <summary>
- /// Format of image that returned from getPicture.
- /// </summary>
- [DataMember(IsRequired = false, Name = "destinationType")]
- public int DestinationType { get; set; }
-
- /// <summary>
- /// Quality of saved image
- /// </summary>
- [DataMember(IsRequired = false, Name = "quality")]
- public int Quality { get; set; }
-
- /// <summary>
- /// Controls whether or not the image is also added to the device photo album.
- /// </summary>
- [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
- public bool SaveToPhotoAlbum { get; set; }
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "correctOrientation")]
- public bool CorrectOrientation { get; set; }
-
-
-
- /// <summary>
- /// Ignored
- /// </summary>
- [DataMember(IsRequired = false, Name = "allowEdit")]
- public bool AllowEdit { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "encodingType")]
- public int EncodingType { get; set; }
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "mediaType")]
- public int MediaType { get; set; }
-
-
- /// <summary>
- /// Height in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetHeight")]
- public int TargetHeight { get; set; }
-
-
- /// <summary>
- /// Width in pixels to scale image
- /// </summary>
- [DataMember(IsRequired = false, Name = "targetWidth")]
- public int TargetWidth { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public CameraOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- PictureSourceType = CAMERA;
- DestinationType = FILE_URI;
- Quality = 80;
- TargetHeight = -1;
- TargetWidth = -1;
- SaveToPhotoAlbum = false;
- CorrectOrientation = true;
- AllowEdit = false;
- MediaType = -1;
- EncodingType = -1;
- }
- }
-
- /// <summary>
- /// Used to open photo library
- /// </summary>
- PhotoChooserTask photoChooserTask;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Camera options
- /// </summary>
- CameraOptions cameraOptions;
-
- public void takePicture(string options)
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
- // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
- this.cameraOptions = new CameraOptions();
- this.cameraOptions.Quality = int.Parse(args[0]);
- this.cameraOptions.DestinationType = int.Parse(args[1]);
- this.cameraOptions.PictureSourceType = int.Parse(args[2]);
- this.cameraOptions.TargetWidth = int.Parse(args[3]);
- this.cameraOptions.TargetHeight = int.Parse(args[4]);
- this.cameraOptions.EncodingType = int.Parse(args[5]);
- this.cameraOptions.MediaType = int.Parse(args[6]);
- this.cameraOptions.AllowEdit = bool.Parse(args[7]);
- this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
- this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
-
- //this.cameraOptions = String.IsNullOrEmpty(options) ?
- // new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- //TODO Check if all the options are acceptable
-
-
- if (cameraOptions.PictureSourceType == CAMERA)
- {
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += onCameraTaskCompleted;
- cameraTask.Show();
- }
- else
- {
- if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
- {
- photoChooserTask = new PhotoChooserTask();
- photoChooserTask.Completed += onPickerTaskCompleted;
- photoChooserTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
- }
-
- public void onCameraTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- // Save image in media library
- if (cameraOptions.SaveToPhotoAlbum)
- {
- MediaLibrary library = new MediaLibrary();
- Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
- }
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
-
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
-
-
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
-
- }
-
- public void onPickerTaskCompleted(object sender, PhotoResult e)
- {
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string imagePathOrContent = string.Empty;
-
- if (cameraOptions.DestinationType == FILE_URI)
- {
- WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
- imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
- }
- else if (cameraOptions.DestinationType == DATA_URL)
- {
- imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
-
- }
- else
- {
- // TODO: shouldn't this happen before we launch the camera-picker?
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
- return;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
- }
- break;
-
- case TaskResult.Cancel:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
- break;
-
- default:
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
- break;
- }
- }
-
- /// <summary>
- /// Returns image content in a form of base64 string
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <returns>Base64 representation of the image</returns>
- private string GetImageContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
-
- //use photo's actual width & height if user doesn't provide width & height
- if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
- {
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
- else
- {
- // resize photo
- byte[] resizedFile = ResizePhoto(stream, fileData);
- stream.Close();
- return Convert.ToBase64String(resizedFile);
- }
- }
-
- /// <summary>
- /// Resize image
- /// </summary>
- /// <param name="stream">Image stream</param>
- /// <param name="fileData">File data</param>
- /// <returns>resized image</returns>
- private byte[] ResizePhoto(Stream stream, byte[] fileData)
- {
- int streamLength = (int)stream.Length;
- int intResult = 0;
-
- byte[] resizedFile;
-
- stream.Read(fileData, 0, streamLength);
-
- BitmapImage objBitmap = new BitmapImage();
- MemoryStream objBitmapStream = new MemoryStream(fileData);
- MemoryStream objBitmapStreamResized = new MemoryStream();
- WriteableBitmap objWB;
- objBitmap.SetSource(stream);
- objWB = new WriteableBitmap(objBitmap);
-
- // resize the photo with user defined TargetWidth & TargetHeight
- Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
-
- //Convert the resized stream to a byte array.
- streamLength = (int)objBitmapStreamResized.Length;
- resizedFile = new Byte[streamLength]; //-1
- objBitmapStreamResized.Position = 0;
- //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
- intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
-
- return resizedFile;
- }
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
- {
-
- if (image == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
-
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(isoFolder))
- {
- isoFile.CreateDirectory(isoFolder);
- }
-
- string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
-
- using (var stream = isoFile.CreateFile(filePath))
- {
- // resize image if Height and Width defined via options
- if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
- {
- image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
- }
- else
- {
- image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
- }
- }
-
- return new Uri(filePath, UriKind.Relative).ToString();
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Capture.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Capture.cs b/wp8/template/Plugins/Capture.cs
deleted file mode 100644
index 5e14a16..0000000
--- a/wp8/template/Plugins/Capture.cs
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework.Media;
-using WPCordovaClassLib.Cordova.UI;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-using System.Windows;
-using System.Diagnostics;
-using Microsoft.Phone.Controls;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to the audio, image, and video capture capabilities of the device
- /// </summary>
- public class Capture : BaseCommand
- {
- #region Internal classes (options and resultant objects)
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CaptureImageOptions
- {
- /// <summary>
- /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureImageOptions Default
- {
- get { return new CaptureImageOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureAudio action options.
- /// </summary>
- [DataContract]
- public class CaptureAudioOptions
- {
- /// <summary>
- /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureAudioOptions Default
- {
- get { return new CaptureAudioOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureVideo action options.
- /// </summary>
- [DataContract]
- public class CaptureVideoOptions
- {
- /// <summary>
- /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureVideoOptions Default
- {
- get { return new CaptureVideoOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents getFormatData action options.
- /// </summary>
- [DataContract]
- public class MediaFormatOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- [DataMember(IsRequired = true, Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// File mime type
- /// </summary>
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class MediaFile
- {
-
- [DataMember(Name = "name")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FilePath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public MediaFile(string filePath, Picture image)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = image.GetImage().Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
-
- }
-
- public MediaFile(string filePath, Stream stream)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = stream.Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
- }
- }
-
- /// <summary>
- /// Stores additional media file data
- /// </summary>
- [DataContract]
- public class MediaFileData
- {
- [DataMember(Name = "height")]
- public int Height { get; set; }
-
- [DataMember(Name = "width")]
- public int Width { get; set; }
-
- [DataMember(Name = "bitrate")]
- public int Bitrate { get; set; }
-
- [DataMember(Name = "duration")]
- public int Duration { get; set; }
-
- [DataMember(Name = "codecs")]
- public string Codecs { get; set; }
-
- public MediaFileData(WriteableBitmap image)
- {
- this.Height = image.PixelHeight;
- this.Width = image.PixelWidth;
- this.Bitrate = 0;
- this.Duration = 0;
- this.Codecs = "";
- }
- }
-
- #endregion
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Capture Image options
- /// </summary>
- protected CaptureImageOptions captureImageOptions;
-
- /// <summary>
- /// Capture Audio options
- /// </summary>
- protected CaptureAudioOptions captureAudioOptions;
-
- /// <summary>
- /// Capture Video options
- /// </summary>
- protected CaptureVideoOptions captureVideoOptions;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- private CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Used for audio recording
- /// </summary>
- private AudioCaptureTask audioCaptureTask;
-
- /// <summary>
- /// Used for video recording
- /// </summary>
- private VideoCaptureTask videoCaptureTask;
-
- /// <summary>
- /// Stores information about captured files
- /// </summary>
- List<MediaFile> files = new List<MediaFile>();
-
- /// <summary>
- /// Launches default camera application to capture image
- /// </summary>
- /// <param name="options">may contains limit or mode parameters</param>
- public void captureImage(string options)
- {
- try
- {
- try
- {
-
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
-
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += this.cameraTask_Completed;
- cameraTask.Show();
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own audio recording control to capture audio
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureAudio(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- audioCaptureTask = new AudioCaptureTask();
- audioCaptureTask.Completed += audioRecordingTask_Completed;
- audioCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own video recording control to capture video
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureVideo(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- videoCaptureTask = new VideoCaptureTask();
- videoCaptureTask.Completed += videoRecordingTask_Completed;
- videoCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Retrieves the format information of the media file.
- /// </summary>
- /// <param name="options"></param>
- public void getFormatData(string options)
- {
- try
- {
- MediaFormatOptions mediaFormatOptions;
- try
- {
- mediaFormatOptions = new MediaFormatOptions();
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaFormatOptions.FullPath = optionStrings[0];
- mediaFormatOptions.Type = optionStrings[1];
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
- string mimeType = mediaFormatOptions.Type;
-
- if (string.IsNullOrEmpty(mimeType))
- {
- mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
- }
-
- if (mimeType.Equals("image/jpeg"))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
-
- if (image == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
- return;
- }
-
- MediaFileData mediaData = new MediaFileData(image);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
-
- /// <summary>
- /// Opens specified file in media player
- /// </summary>
- /// <param name="options">MediaFile to play</param>
- public void play(string options)
- {
- try
- {
- MediaFile file;
-
- try
- {
- file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (file == null || String.IsNullOrEmpty(file.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
- return;
- }
-
- // if url starts with '/' media player throws FileNotFound exception
- Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
-
- MediaPlayerLauncher player = new MediaPlayerLauncher();
- player.Media = fileUri;
- player.Location = MediaLocationType.Data;
- player.Show();
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Handles result of capture to save image information
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured image</param>
- private void cameraTask_Completed(object sender, PhotoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
-
- // Save image in media library
- MediaLibrary library = new MediaLibrary();
- Picture image = library.SavePicture(fileName, e.ChosenPhoto);
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // Save image in isolated storage
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- byte[] imageBytes = new byte[rotImageStream.Length];
- rotImageStream.Read(imageBytes, 0, imageBytes.Length);
- rotImageStream.Dispose();
- string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
- imageBytes = null;
- // Get image data
- MediaFile data = new MediaFile(pathLocalStorage, image);
-
- this.files.Add(data);
-
- if (files.Count < this.captureImageOptions.Limit)
- {
- cameraTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some images were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of audio recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured audio</param>
- private void audioRecordingTask_Completed(object sender, AudioResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureAudioOptions.Limit)
- {
- audioCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some audio clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of video recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured video</param>
- private void videoRecordingTask_Completed(object sender, VideoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureVideoOptions.Limit)
- {
- videoCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some video clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Extract file from Isolated Storage as WriteableBitmap object
- /// </summary>
- /// <param name="filePath"></param>
- /// <returns></returns>
- private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
- {
- try
- {
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- var imageSource = PictureDecoder.DecodeJpeg(imageStream);
- return imageSource;
- }
- }
- catch (Exception)
- {
- return null;
- }
- }
-
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <param name="imageFolder">folder to store images</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
- {
- if (imageBytes == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(imageFolder))
- {
- isoFile.CreateDirectory(imageFolder);
- }
- string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
-
- using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
- {
- stream.Write(imageBytes, 0, imageBytes.Length);
- }
-
- return filePath;
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Compass.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Compass.cs b/wp8/template/Plugins/Compass.cs
deleted file mode 100644
index c9e1c4d..0000000
--- a/wp8/template/Plugins/Compass.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using DeviceCompass = Microsoft.Devices.Sensors.Compass;
-using System.Windows.Threading;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class Compass : BaseCommand
- {
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Id for get getCompass method
- /// </summary>
- private static string getCompassId = "getCompassId";
-
- /// <summary>
- /// Compass
- /// </summary>
- private static DeviceCompass compass = new DeviceCompass();
-
- /// <summary>
- /// Listeners for callbacks
- /// </summary>
- private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
-
- #endregion
-
- #region Status codes
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 4;
- public const int Not_Supported = 20;
-
- /*
- * // Capture error codes
- CompassError.COMPASS_INTERNAL_ERR = 0;
- CompassError.COMPASS_NOT_SUPPORTED = 20;
- * */
-
- #endregion
-
- #region CompassOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class CompassOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// The change in degrees required to initiate a watchHeadingFilter success callback.
- /// </summary>
- [DataMember(IsRequired = false, Name = "filter")]
- public int Filter { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- }
- #endregion
-
-
- /// <summary>
- /// Time the value was last changed
- /// </summary>
- //private DateTime lastValueChangedTime;
-
- /// <summary>
- /// Accelerometer options
- /// </summary>
- private CompassOptions compassOptions;
-
- //bool isDataValid;
-
- //bool calibrating = false;
-
- public Compass()
- {
-
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetHeadingFormatted(CompassReading reading)
- {
- // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
- string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
- reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
- reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
- reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
- return "{" + result + "}";
- }
-
- public void getHeading(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
- }
- else
- {
- //if (compass == null)
- //{
- // // Instantiate the compass.
- // compass = new DeviceCompass();
- // compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
- // compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
- // compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
- //}
-
-
- //compass.Start();
-
- }
-
- try
- {
- if (currentStatus != Running)
- {
- lock (compass)
- {
- compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- lock (compass)
- {
- compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
- if (watchers.Count < 1)
- {
- compass.Stop();
- this.SetStatus(Stopped);
- }
- }
- }
- catch (UnauthorizedAccessException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- }
- }
-
- void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Starts listening for compass sensor
- /// </summary>
- /// <returns>status of listener</returns>
- private int start()
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return currentStatus;
- }
- try
- {
- lock (compass)
- {
- watchers.Add(getCompassId, this);
- compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- }
- return currentStatus;
- }
-
- public void startWatch(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
- }
-
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- lock (compass)
- {
- watchers.Add(compassOptions.Id, this);
- compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- return;
- }
- }
-
- public void stopWatch(string options)
- {
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (currentStatus != Stopped)
- {
- lock (compass)
- {
- Compass watcher = watchers[compassOptions.Id];
- compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
- watchers.Remove(compassOptions.Id);
- watcher.Dispose();
- }
- }
- this.SetStatus(Stopped);
-
- this.DispatchCommandResult();
- }
-
- void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
- {
- //throw new NotImplementedException();
- // TODO: pass calibration error to JS
- }
-
- void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
- result.KeepCallback = true;
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
-
- }
-}
[15/50] [abbrv] git commit: Version file had a newline
Posted by pu...@apache.org.
Version file had a newline
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/a2476e77
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/a2476e77
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/a2476e77
Branch: refs/heads/2.9.x
Commit: a2476e7784c846c86aee0fb6a726b99c8dff6a98
Parents: 744e685
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Jun 18 13:34:10 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 13:34:10 2013 -0700
----------------------------------------------------------------------
VERSION | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/a2476e77/VERSION
----------------------------------------------------------------------
diff --git a/VERSION b/VERSION
index 3af205c..88f28f0 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.9.0rc1
+2.9.0rc1
\ No newline at end of file
[24/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/plugins/MimeTypeMapper.cs b/plugins/MimeTypeMapper.cs
deleted file mode 100644
index a2794f5..0000000
--- a/plugins/MimeTypeMapper.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- 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.
-*/
-
-using System.Collections.Generic;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Represents file extension to mime type mapper.
- /// </summary>
- public static class MimeTypeMapper
- {
- /// <summary>
- /// For unknown type it is recommended to use 'application/octet-stream'
- /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
- /// </summary>
- private static string DefaultMimeType = "application/octet-stream";
-
- /// <summary>
- /// Stores mime type for all necessary extension
- /// </summary>
- private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
- {
- {"avi", "video/x-msvideo"},
- {"bmp", "image/bmp"},
- {"gif", "image/gif"},
- {"html","text/html"},
- {"jpe", "image/jpeg"},
- {"jpeg", "image/jpeg"},
- {"jpg", "image/jpeg"},
- {"js","text/javascript"},
- {"mov", "video/quicktime"},
- {"mp2", "audio/mpeg"},
- {"mp3", "audio/mpeg"},
- {"mp4", "video/mp4"},
- {"mpe", "video/mpeg"},
- {"mpeg", "video/mpeg"},
- {"mpg", "video/mpeg"},
- {"mpga", "audio/mpeg"},
- {"pbm", "image/x-portable-bitmap"},
- {"pcm", "audio/x-pcm"},
- {"pct", "image/pict"},
- {"pgm", "image/x-portable-graymap"},
- {"pic", "image/pict"},
- {"pict", "image/pict"},
- {"png", "image/png"},
- {"pnm", "image/x-portable-anymap"},
- {"pnt", "image/x-macpaint"},
- {"pntg", "image/x-macpaint"},
- {"ppm", "image/x-portable-pixmap"},
- {"qt", "video/quicktime"},
- {"ra", "audio/x-pn-realaudio"},
- {"ram", "audio/x-pn-realaudio"},
- {"ras", "image/x-cmu-raster"},
- {"rgb", "image/x-rgb"},
- {"snd", "audio/basic"},
- {"txt", "text/plain"},
- {"tif", "image/tiff"},
- {"tiff", "image/tiff"},
- {"wav", "audio/x-wav"},
- {"wbmp", "image/vnd.wap.wbmp"},
-
- };
- /// <summary>
- /// Gets mime type by file extension
- /// </summary>
- /// <param name="fileName">file name to extract extension</param>
- /// <returns>mime type</returns>
- public static string GetMimeType(string fileName)
- {
- string ext = Path.GetExtension(fileName);
-
- // invalid extension
- if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
- {
- return DefaultMimeType;
- }
-
- ext = ext.Remove(0, 1);
-
- if (MIMETypesDictionary.ContainsKey(ext))
- {
- return MIMETypesDictionary[ext];
- }
-
- return DefaultMimeType;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/NetworkStatus.cs
----------------------------------------------------------------------
diff --git a/plugins/NetworkStatus.cs b/plugins/NetworkStatus.cs
deleted file mode 100644
index 12eb061..0000000
--- a/plugins/NetworkStatus.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Net.NetworkInformation;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
- // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
-
- public class NetworkStatus : BaseCommand
- {
- const string UNKNOWN = "unknown";
- const string ETHERNET = "ethernet";
- const string WIFI = "wifi";
- const string CELL_2G = "2g";
- const string CELL_3G = "3g";
- const string CELL_4G = "4g";
- const string NONE = "none";
- const string CELL = "cellular";
-
- private bool HasCallback = false;
-
- public NetworkStatus()
- {
- DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
- }
-
- public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
- {
- this.getConnectionInfo("");
- }
-
- public void getConnectionInfo(string empty)
- {
- HasCallback = true;
- updateConnectionType(checkConnectionType());
- }
-
- private string checkConnectionType()
- {
- if (DeviceNetworkInformation.IsNetworkAvailable)
- {
- if (DeviceNetworkInformation.IsWiFiEnabled)
- {
- return WIFI;
- }
- else
- {
- return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
- }
- }
- return NONE;
- }
-
- private string checkConnectionType(NetworkInterfaceSubType type)
- {
- switch (type)
- {
- case NetworkInterfaceSubType.Cellular_1XRTT: //cell
- case NetworkInterfaceSubType.Cellular_GPRS: //cell
- return CELL;
- case NetworkInterfaceSubType.Cellular_EDGE: //2
- return CELL_2G;
- case NetworkInterfaceSubType.Cellular_3G:
- case NetworkInterfaceSubType.Cellular_EVDO: //3
- case NetworkInterfaceSubType.Cellular_EVDV: //3
- case NetworkInterfaceSubType.Cellular_HSPA: //3
- return CELL_3G;
- case NetworkInterfaceSubType.WiFi:
- return WIFI;
- case NetworkInterfaceSubType.Unknown:
- case NetworkInterfaceSubType.Desktop_PassThru:
- default:
- return UNKNOWN;
- }
- }
-
- void ChangeDetected(object sender, NetworkNotificationEventArgs e)
- {
- switch (e.NotificationType)
- {
- case NetworkNotificationType.InterfaceConnected:
- updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
- break;
- case NetworkNotificationType.InterfaceDisconnected:
- updateConnectionType(NONE);
- break;
- default:
- break;
- }
- }
-
- private void updateConnectionType(string type)
- {
- // This should also implicitly fire offline/online events as that is handled on the JS side
- if (this.HasCallback)
- {
- PluginResult result = new PluginResult(PluginResult.Status.OK, type);
- result.KeepCallback = true;
- DispatchCommandResult(result);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/Notification.cs
----------------------------------------------------------------------
diff --git a/plugins/Notification.cs b/plugins/Notification.cs
deleted file mode 100644
index 0759c72..0000000
--- a/plugins/Notification.cs
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Devices;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Windows.Resources;
-using Microsoft.Phone.Controls;
-using Microsoft.Xna.Framework.Audio;
-using WPCordovaClassLib.Cordova.UI;
-using System.Diagnostics;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Notification : BaseCommand
- {
- static ProgressBar progressBar = null;
- const int DEFAULT_DURATION = 5;
-
- private NotificationBox notifyBox;
-
- private PhoneApplicationPage Page
- {
- get
- {
- PhoneApplicationPage page = null;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- page = frame.Content as PhoneApplicationPage;
- }
- return page;
- }
- }
-
- // blink api - doesn't look like there is an equivalent api we can use...
-
- [DataContract]
- public class AlertOptions
- {
- [OnDeserializing]
- public void OnDeserializing(StreamingContext context)
- {
- // set defaults
- this.message = "message";
- this.title = "Alert";
- this.buttonLabel = "ok";
- }
-
- /// <summary>
- /// message to display in the alert box
- /// </summary>
- [DataMember]
- public string message;
-
- /// <summary>
- /// title displayed on the alert window
- /// </summary>
- [DataMember]
- public string title;
-
- /// <summary>
- /// text to display on the button
- /// </summary>
- [DataMember]
- public string buttonLabel;
- }
-
- public void alert(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
- Button btnOK = new Button();
- btnOK.Content = alertOpts.buttonLabel;
- btnOK.Click += new RoutedEventHandler(btnOK_Click);
- btnOK.Tag = 1;
- notifyBox.ButtonPanel.Children.Add(btnOK);
- grid.Children.Add(notifyBox);
-
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- public void confirm(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- AlertOptions alertOpts = new AlertOptions();
- alertOpts.message = args[0];
- alertOpts.title = args[1];
- alertOpts.buttonLabel = args[2];
- string aliasCurrentCommandCallbackId = args[3];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- var previous = notifyBox;
- notifyBox = new NotificationBox();
- notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
- notifyBox.PageTitle.Text = alertOpts.title;
- notifyBox.SubTitle.Text = alertOpts.message;
-
- string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
-
- if (labels == null)
- {
- labels = alertOpts.buttonLabel.Split(',');
- }
-
- for (int n = 0; n < labels.Length; n++)
- {
- Button btn = new Button();
- btn.Content = labels[n];
- btn.Tag = n;
- btn.Click += new RoutedEventHandler(btnOK_Click);
- notifyBox.ButtonPanel.Children.Add(btn);
- }
-
- grid.Children.Add(notifyBox);
- if (previous == null)
- {
- page.BackKeyPress += page_BackKeyPress;
- }
- }
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
- }
- });
- }
-
- void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
- {
- PhoneApplicationPage page = sender as PhoneApplicationPage;
- string callbackId = "";
- if (page != null && notifyBox != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifyBox);
- dynamic notifBoxData = notifyBox.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
- }
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- e.Cancel = true;
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
- }
-
- void btnOK_Click(object sender, RoutedEventArgs e)
- {
- Button btn = sender as Button;
- FrameworkElement notifBoxParent = null;
- int retVal = 0;
- string callbackId = "";
- if (btn != null)
- {
- retVal = (int)btn.Tag + 1;
-
- notifBoxParent = btn.Parent as FrameworkElement;
- while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
- !(notifBoxParent is NotificationBox)) ;
- }
- if (notifBoxParent != null)
- {
- PhoneApplicationPage page = Page;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(notifBoxParent);
- }
-
- dynamic notifBoxData = notifBoxParent.Tag;
- notifyBox = notifBoxData.previous as NotificationBox;
- callbackId = notifBoxData.callbackId as string;
-
- if (notifyBox == null)
- {
- page.BackKeyPress -= page_BackKeyPress;
- }
- }
-
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
- }
-
-
-
- public void beep(string options)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- int times = int.Parse(args[0]);
-
- string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
-
- StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
-
- if (sri != null)
- {
- SoundEffect effect = SoundEffect.FromStream(sri.Stream);
- SoundEffectInstance inst = effect.CreateInstance();
- ThreadPool.QueueUserWorkItem((o) =>
- {
- // cannot interact with UI !!
- do
- {
- inst.Play();
- Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
- }
- while (--times > 0);
-
- });
-
- }
-
- // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
- DispatchCommandResult();
- }
-
- // Display an indeterminate progress indicator
- public void activityStart(string unused)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- if (page != null)
- {
- var temp = page.FindName("LayoutRoot");
- Grid grid = temp as Grid;
- if (grid != null)
- {
- if (progressBar != null)
- {
- grid.Children.Remove(progressBar);
- }
- progressBar = new ProgressBar();
- progressBar.IsIndeterminate = true;
- progressBar.IsEnabled = true;
-
- grid.Children.Add(progressBar);
- }
- }
- }
- });
- }
-
-
- // Remove our indeterminate progress indicator
- public void activityStop(string unused)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (progressBar != null)
- {
- progressBar.IsEnabled = false;
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(progressBar);
- }
- }
- }
- progressBar = null;
- }
- });
- }
-
- public void vibrate(string vibrateDuration)
- {
-
- int msecs = 200; // set default
-
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
-
- msecs = int.Parse(args[0]);
- if (msecs < 1)
- {
- msecs = 1;
- }
- }
- catch (FormatException)
- {
-
- }
-
- VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
-
- // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
- DispatchCommandResult();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/AudioCaptureTask.cs
----------------------------------------------------------------------
diff --git a/plugins/UI/AudioCaptureTask.cs b/plugins/UI/AudioCaptureTask.cs
deleted file mode 100644
index 3d7d60f..0000000
--- a/plugins/UI/AudioCaptureTask.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Audio Recording application.
- /// Use this to allow users to record audio from your application.
- /// </summary>
- public class AudioCaptureTask
- {
- /// <summary>
- /// Represents recorded audio returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
- /// </summary>
- public class AudioResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the AudioResult class.
- /// </summary>
- public AudioResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the AudioResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public AudioResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded audio.
- /// </summary>
- public Stream AudioFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded audio.
- /// </summary>
- public string AudioFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is AudioRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- AudioRecorder audioRecorder = (AudioRecorder)e.Content;
-
- if (audioRecorder != null)
- {
- audioRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new AudioResult(TaskResult.Cancel));
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/AudioRecorder.xaml
----------------------------------------------------------------------
diff --git a/plugins/UI/AudioRecorder.xaml b/plugins/UI/AudioRecorder.xaml
deleted file mode 100644
index 0fd26ab..0000000
--- a/plugins/UI/AudioRecorder.xaml
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Portrait" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Transparent">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
- <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
- </StackPanel>
-
- <!--ContentPanel - place additional content here-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0" VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
- <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
- <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
- </Grid>
- </Grid>
-
- <!--Sample code showing usage of ApplicationBar-->
- <!--<phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
- <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
- <shell:ApplicationBar.MenuItems>
- <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
- <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
- </shell:ApplicationBar.MenuItems>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>-->
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/AudioRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/plugins/UI/AudioRecorder.xaml.cs b/plugins/UI/AudioRecorder.xaml.cs
deleted file mode 100644
index 01a0832..0000000
--- a/plugins/UI/AudioRecorder.xaml.cs
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Threading;
-using WPCordovaClassLib.Cordova.Commands;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Implements Audio Recording application
- /// </summary>
- public partial class AudioRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- private const string RecordingStartCaption = "Start";
- private const string RecordingStopCaption = "Stop";
-
- private const string LocalFolderName = "AudioCache";
- private const string FileNameFormat = "Audio-{0}.wav";
-
- #endregion
-
- #region Callbacks
-
- /// <summary>
- /// Occurs when a audio recording task is completed.
- /// </summary>
- public event EventHandler<AudioResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Audio source
- /// </summary>
- private Microphone microphone;
-
- /// <summary>
- /// Temporary buffer to store audio chunk
- /// </summary>
- private byte[] buffer;
-
- /// <summary>
- /// Recording duration
- /// </summary>
- private TimeSpan duration;
-
- /// <summary>
- /// Output buffer
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Xna game loop dispatcher
- /// </summary>
- DispatcherTimer dtXna;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private AudioResult result = new AudioResult(TaskResult.Cancel);
-
- /// <summary>
- /// Whether we are recording audio now
- /// </summary>
- private bool IsRecording
- {
- get
- {
- return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
- }
- }
-
- #endregion
-
- /// <summary>
- /// Creates new instance of the AudioRecorder class.
- /// </summary>
- public AudioRecorder()
- {
-
- this.InitializeXnaGameLoop();
-
- // microphone requires special XNA initialization to work
- InitializeComponent();
- }
-
- /// <summary>
- /// Starts recording, data is stored in memory
- /// </summary>
- private void StartRecording()
- {
- this.microphone = Microphone.Default;
- this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
-
- this.btnTake.IsEnabled = false;
- this.btnStartStop.Content = RecordingStopCaption;
-
- this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
- this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
-
- this.memoryStream = new MemoryStream();
- this.memoryStream.InitializeWavStream(this.microphone.SampleRate);
-
- this.duration = new TimeSpan(0);
-
- this.microphone.Start();
- }
-
- /// <summary>
- /// Stops recording
- /// </summary>
- private void StopRecording()
- {
- this.microphone.Stop();
-
- this.microphone.BufferReady -= MicrophoneBufferReady;
-
- this.microphone = null;
-
- btnStartStop.Content = RecordingStartCaption;
-
- // check there is some data
- this.btnTake.IsEnabled = true;
- }
-
- /// <summary>
- /// Handles Start/Stop events
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStartStop_Click(object sender, RoutedEventArgs e)
- {
-
- if (this.IsRecording)
- {
- this.StopRecording();
- }
- else
- {
- this.StartRecording();
- }
- }
-
- /// <summary>
- /// Handles Take button click
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnTake_Click(object sender, RoutedEventArgs e)
- {
- this.result = this.SaveAudioClipToLocalStorage();
-
- if (Completed != null)
- {
- Completed(this, result);
- }
-
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Handles page closing event, stops recording if needed and dispatches results.
- /// </summary>
- /// <param name="e"></param>
- protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
- {
- if (IsRecording)
- {
- StopRecording();
- }
-
- this.FinalizeXnaGameLoop();
-
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Copies data from microphone to memory storages and updates recording state
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void MicrophoneBufferReady(object sender, EventArgs e)
- {
- this.microphone.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- TimeSpan bufferDuration = this.microphone.BufferDuration;
-
- this.Dispatcher.BeginInvoke(() =>
- {
- this.duration += bufferDuration;
-
- this.txtDuration.Text = "Duration: " +
- this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
- this.duration.Seconds.ToString().PadLeft(2, '0');
- });
-
- }
-
- /// <summary>
- /// Writes audio data from memory to isolated storage
- /// </summary>
- /// <returns></returns>
- private AudioResult SaveAudioClipToLocalStorage()
- {
- if (this.memoryStream == null || this.memoryStream.Length <= 0)
- {
- return new AudioResult(TaskResult.Cancel);
- }
-
- this.memoryStream.UpdateWavStream();
-
- // save audio data to local isolated storage
-
- string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
-
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
- {
-
- this.memoryStream.CopyTo(fileStream);
- }
-
- AudioResult result = new AudioResult(TaskResult.OK);
- result.AudioFileName = filePath;
-
- result.AudioFile = this.memoryStream;
- result.AudioFile.Seek(0, SeekOrigin.Begin);
-
- return result;
- }
-
-
-
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- /// <summary>
- /// Special initialization required for the microphone: XNA game loop
- /// </summary>
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- /// <summary>
- /// Finalizes XNA game loop for microphone
- /// </summary>
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (dtXna != null)
- {
- dtXna.Stop();
- dtXna = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/ImageCapture.xaml
----------------------------------------------------------------------
diff --git a/plugins/UI/ImageCapture.xaml b/plugins/UI/ImageCapture.xaml
deleted file mode 100644
index a7eee21..0000000
--- a/plugins/UI/ImageCapture.xaml
+++ /dev/null
@@ -1,26 +0,0 @@
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
-
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Yellow">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- </Grid>
-
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/ImageCapture.xaml.cs
----------------------------------------------------------------------
diff --git a/plugins/UI/ImageCapture.xaml.cs b/plugins/UI/ImageCapture.xaml.cs
deleted file mode 100644
index 234b444..0000000
--- a/plugins/UI/ImageCapture.xaml.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- 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.
-*/
-
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class ImageCapture : PhoneApplicationPage
- {
- public ImageCapture()
- {
- InitializeComponent();
- }
- }
-
- public class ImageCaptureTask
- {
- /// <summary>
- /// Represents an image returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
- /// </summary>
- //public class AudioResult : TaskEventArgs
- //{
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class.
- // /// </summary>
- // public AudioResult()
- // { }
-
- // /// <summary>
- // /// Initializes a new instance of the AudioResult class
- // /// with the specified Microsoft.Phone.Tasks.TaskResult.
- // /// </summary>
- // /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- // public AudioResult(TaskResult taskResult)
- // : base(taskResult)
- // { }
-
- // /// <summary>
- // /// Gets the file name of the recorded audio.
- // /// </summary>
- // public Stream AudioFile { get; internal set; }
-
- // /// <summary>
- // /// Gets the stream containing the data for the recorded audio.
- // /// </summary>
- // public string AudioFileName { get; internal set; }
- //}
-
- ///// <summary>
- ///// Occurs when a audio recording task is completed.
- ///// </summary>
- //public event EventHandler<AudioResult> Completed;
-
- /// <summary>
- /// Shows Audio Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- ImageCapture imageCapture = e.Content as ImageCapture;
- if (imageCapture != null)
- {
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- //imageCapture.Completed += this.Completed;
- //else if (this.Completed != null)
- //{
- // this.Completed(this, new AudioResult(TaskResult.Cancel));
- //}
- }
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/NotificationBox.xaml
----------------------------------------------------------------------
diff --git a/plugins/UI/NotificationBox.xaml b/plugins/UI/NotificationBox.xaml
deleted file mode 100644
index 1ca5d5f..0000000
--- a/plugins/UI/NotificationBox.xaml
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
- 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.
--->
-<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
-
- <Grid x:Name="LayoutRoot"
- Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
-
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
-
- <!--TitlePanel contains the name of the application and page title-->
- <StackPanel x:Name="TitlePanel"
- Grid.Row="0"
- Background="{StaticResource PhoneSemitransparentBrush}">
- <TextBlock x:Name="PageTitle"
- Text="Title"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle2Style}"/>
-
- <TextBlock x:Name="SubTitle"
- Text="Subtitle"
- TextWrapping="Wrap"
- Margin="10,10"
- Style="{StaticResource PhoneTextTitle3Style}"/>
-
- <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
- <StackPanel x:Name="ButtonPanel"
- Margin="10,10"
- Orientation="Horizontal"/>
- </ScrollViewer>
-
- </StackPanel>
- </Grid>
-</UserControl>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/NotificationBox.xaml.cs
----------------------------------------------------------------------
diff --git a/plugins/UI/NotificationBox.xaml.cs b/plugins/UI/NotificationBox.xaml.cs
deleted file mode 100644
index 50b2f2a..0000000
--- a/plugins/UI/NotificationBox.xaml.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class NotificationBox : UserControl
- {
- public NotificationBox()
- {
- InitializeComponent();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/VideoCaptureTask.cs
----------------------------------------------------------------------
diff --git a/plugins/UI/VideoCaptureTask.cs b/plugins/UI/VideoCaptureTask.cs
deleted file mode 100644
index 958c05c..0000000
--- a/plugins/UI/VideoCaptureTask.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- /// <summary>
- /// Allows an application to launch the Video Recording application.
- /// Use this to allow users to record video from your application.
- /// </summary>
- public class VideoCaptureTask
- {
- /// <summary>
- /// Represents recorded video returned from a call to the Show method of
- /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
- /// </summary>
- public class VideoResult : TaskEventArgs
- {
- /// <summary>
- /// Initializes a new instance of the VideoResult class.
- /// </summary>
- public VideoResult()
- { }
-
- /// <summary>
- /// Initializes a new instance of the VideoResult class
- /// with the specified Microsoft.Phone.Tasks.TaskResult.
- /// </summary>
- /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
- public VideoResult(TaskResult taskResult)
- : base(taskResult)
- { }
-
- /// <summary>
- /// Gets the file name of the recorded Video.
- /// </summary>
- public Stream VideoFile { get; internal set; }
-
- /// <summary>
- /// Gets the stream containing the data for the recorded Video.
- /// </summary>
- public string VideoFileName { get; internal set; }
- }
-
- /// <summary>
- /// Occurs when a Video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- /// <summary>
- /// Shows Video Recording application
- /// </summary>
- public void Show()
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
- root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
- string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
- // dummy parameter is used to always open a fresh version
- root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
- });
- }
-
- /// <summary>
- /// Performs additional configuration of the recording application.
- /// </summary>
- private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
- if (!(e.Content is VideoRecorder)) return;
-
- (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
- VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
-
- if (VideoRecorder != null)
- {
- VideoRecorder.Completed += this.Completed;
- }
- else if (this.Completed != null)
- {
- this.Completed(this, new VideoResult(TaskResult.Cancel));
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/VideoRecorder.xaml
----------------------------------------------------------------------
diff --git a/plugins/UI/VideoRecorder.xaml b/plugins/UI/VideoRecorder.xaml
deleted file mode 100644
index c78fdb0..0000000
--- a/plugins/UI/VideoRecorder.xaml
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
- 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.
--->
-<phone:PhoneApplicationPage
- x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Landscape" Orientation="LandscapeLeft"
- shell:SystemTray.IsVisible="False">
-
- <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
-
- <Rectangle
- x:Name="viewfinderRectangle"
- Width="640"
- Height="480"
- HorizontalAlignment="Left"
- Canvas.Left="80"/>
-
- </Canvas>
-
- <phone:PhoneApplicationPage.ApplicationBar>
- <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record" x:Name="btnStartRecording" Click="StartRecording_Click" />
- <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>
- </shell:ApplicationBar>
- </phone:PhoneApplicationPage.ApplicationBar>
-
-</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/UI/VideoRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/plugins/UI/VideoRecorder.xaml.cs b/plugins/UI/VideoRecorder.xaml.cs
deleted file mode 100644
index 6ab1cc3..0000000
--- a/plugins/UI/VideoRecorder.xaml.cs
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media;
-using System.Windows.Navigation;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
- public partial class VideoRecorder : PhoneApplicationPage
- {
-
- #region Constants
-
- /// <summary>
- /// Caption for record button in ready state
- /// </summary>
- private const string RecordingStartCaption = "Record";
-
- /// <summary>
- /// Caption for record button in recording state
- /// </summary>
- private const string RecordingStopCaption = "Stop";
-
- /// <summary>
- /// Start record icon URI
- /// </summary>
- private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
-
- /// <summary>
- /// Stop record icon URI
- /// </summary>
- private const string StopIconUri = "/Images/appbar.stop.rest.png";
-
- /// <summary>
- /// Folder to save video clips
- /// </summary>
- private const string LocalFolderName = "VideoCache";
-
- /// <summary>
- /// File name format
- /// </summary>
- private const string FileNameFormat = "Video-{0}.mp4";
-
- /// <summary>
- /// Temporary file name
- /// </summary>
- private const string defaultFileName = "NewVideoFile.mp4";
-
- #endregion
-
- #region Callbacks
- /// <summary>
- /// Occurs when a video recording task is completed.
- /// </summary>
- public event EventHandler<VideoResult> Completed;
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// Viewfinder for capturing video
- /// </summary>
- private VideoBrush videoRecorderBrush;
-
- /// <summary>
- /// Path to save video clip
- /// </summary>
- private string filePath;
-
- /// <summary>
- /// Source for capturing video.
- /// </summary>
- private CaptureSource captureSource;
-
- /// <summary>
- /// Video device
- /// </summary>
- private VideoCaptureDevice videoCaptureDevice;
-
- /// <summary>
- /// File sink so save recording video in Isolated Storage
- /// </summary>
- private FileSink fileSink;
-
- /// <summary>
- /// For managing button and application state
- /// </summary>
- private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
-
- /// <summary>
- /// Current video state
- /// </summary>
- private VideoState currentVideoState;
-
- /// <summary>
- /// Stream to return result
- /// </summary>
- private MemoryStream memoryStream;
-
- /// <summary>
- /// Recording result, dispatched back when recording page is closed
- /// </summary>
- private VideoResult result = new VideoResult(TaskResult.Cancel);
-
- #endregion
-
- /// <summary>
- /// Initializes components
- /// </summary>
- public VideoRecorder()
- {
- InitializeComponent();
-
- PhoneAppBar = (ApplicationBar)ApplicationBar;
- PhoneAppBar.IsVisible = true;
- btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
- btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
- }
-
- /// <summary>
- /// Initializes the video recorder then page is loading
- /// </summary>
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- this.InitializeVideoRecorder();
- }
-
- /// <summary>
- /// Disposes camera and media objects then leave the page
- /// </summary>
- protected override void OnNavigatedFrom(NavigationEventArgs e)
- {
- this.DisposeVideoRecorder();
-
- if (this.Completed != null)
- {
- this.Completed(this, result);
- }
- base.OnNavigatedFrom(e);
- }
-
- /// <summary>
- /// Handles TakeVideo button click
- /// </summary>
- private void TakeVideo_Click(object sender, EventArgs e)
- {
- this.result = this.SaveVideoClip();
- this.NavigateBack();
- }
-
- private void NavigateBack()
- {
- if (this.NavigationService.CanGoBack)
- {
- this.NavigationService.GoBack();
- }
- }
-
- /// <summary>
- /// Resaves video clip from temporary directory to persistent
- /// </summary>
- private VideoResult SaveVideoClip()
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
- {
- return new VideoResult(TaskResult.Cancel);
- }
-
- string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
- string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
- isoFile.CopyFile(filePath, newPath);
- isoFile.DeleteFile(filePath);
-
- memoryStream = new MemoryStream();
- using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
- {
- fileStream.CopyTo(memoryStream);
- }
-
- VideoResult result = new VideoResult(TaskResult.OK);
- result.VideoFileName = newPath;
- result.VideoFile = this.memoryStream;
- result.VideoFile.Seek(0, SeekOrigin.Begin);
- return result;
- }
-
- }
- catch (Exception)
- {
- return new VideoResult(TaskResult.None);
- }
- }
-
- /// <summary>
- /// Updates the buttons on the UI thread based on current state.
- /// </summary>
- /// <param name="currentState">current UI state</param>
- private void UpdateUI(VideoState currentState)
- {
- Dispatcher.BeginInvoke(delegate
- {
- switch (currentState)
- {
- case VideoState.CameraNotSupported:
- btnStartRecording.IsEnabled = false;
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Initialized:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- case VideoState.Ready:
- btnStartRecording.Text = RecordingStartCaption;
- btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = true;
- break;
-
- case VideoState.Recording:
- btnStartRecording.Text = RecordingStopCaption;
- btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
- btnTakeVideo.IsEnabled = false;
- break;
-
- default:
- break;
- }
- currentVideoState = currentState;
- });
- }
-
- /// <summary>
- /// Initializes VideoRecorder
- /// </summary>
- public void InitializeVideoRecorder()
- {
- if (captureSource == null)
- {
- captureSource = new CaptureSource();
- fileSink = new FileSink();
- videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
-
- if (videoCaptureDevice != null)
- {
- videoRecorderBrush = new VideoBrush();
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Initialized);
- }
- else
- {
- this.UpdateUI(VideoState.CameraNotSupported);
- }
- }
- }
-
- /// <summary>
- /// Sets recording state: start recording
- /// </summary>
- private void StartVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = captureSource;
- filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.DirectoryExists(LocalFolderName))
- {
- isoFile.CreateDirectory(LocalFolderName);
- }
-
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- }
-
- fileSink.IsolatedStorageFileName = filePath;
- }
-
- if (captureSource.VideoCaptureDevice != null
- && captureSource.State == CaptureState.Stopped)
- {
- captureSource.Start();
- }
- this.UpdateUI(VideoState.Recording);
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: stop recording
- /// </summary>
- private void StopVideoRecording()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- fileSink.CaptureSource = null;
- fileSink.IsolatedStorageFileName = null;
- this.StartVideoPreview();
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Sets the recording state: display the video on the viewfinder.
- /// </summary>
- private void StartVideoPreview()
- {
- try
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
- {
- videoRecorderBrush.SetSource(captureSource);
- viewfinderRectangle.Fill = videoRecorderBrush;
- captureSource.Start();
- this.UpdateUI(VideoState.Ready);
- }
- }
- catch (Exception)
- {
- this.result = new VideoResult(TaskResult.None);
- this.NavigateBack();
- }
- }
-
- /// <summary>
- /// Starts video recording
- /// </summary>
- private void StartRecording_Click(object sender, EventArgs e)
- {
- if (currentVideoState == VideoState.Recording)
- {
- this.StopVideoRecording();
- }
- else
- {
- this.StartVideoRecording();
- }
- }
-
- /// <summary>
- /// Releases resources
- /// </summary>
- private void DisposeVideoRecorder()
- {
- if (captureSource != null)
- {
- if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
- {
- captureSource.Stop();
- }
- captureSource = null;
- videoCaptureDevice = null;
- fileSink = null;
- videoRecorderBrush = null;
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/wp8/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp8/tooling/scripts/createTemplates.js b/wp8/tooling/scripts/createTemplates.js
index 6b8f6cd..ea31195 100644
--- a/wp8/tooling/scripts/createTemplates.js
+++ b/wp8/tooling/scripts/createTemplates.js
@@ -196,7 +196,7 @@ function package_templates()
deleteFileIfExists(platformRoot + templatePath + "\\CordovaWP8Solution.v11.suo");
- exec('%comspec% /c xcopy /Y /E /I ' + repoRoot + '\\Plugins ' + platformRoot + templatePath + '\\Plugins');
+ //exec('%comspec% /c xcopy /Y /E /I ' + repoRoot + '\\Plugins ' + platformRoot + templatePath + '\\Plugins');
copyCommonItemsToTemplate();
@@ -271,7 +271,6 @@ function zip_project(zip_path, project_path) {
function cleanUp() {
removeCommonItems();
deleteFileIfExists(platformRoot + templatePath + "\\VERSION");
- deleteFolderIfExists(platformRoot + templatePath + '\\Plugins');
}
function parseArgs() {
[45/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Capture.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Capture.cs b/common-items/Plugins/Capture.cs
deleted file mode 100644
index 5e14a16..0000000
--- a/common-items/Plugins/Capture.cs
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework.Media;
-using WPCordovaClassLib.Cordova.UI;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-using System.Windows;
-using System.Diagnostics;
-using Microsoft.Phone.Controls;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to the audio, image, and video capture capabilities of the device
- /// </summary>
- public class Capture : BaseCommand
- {
- #region Internal classes (options and resultant objects)
-
- /// <summary>
- /// Represents captureImage action options.
- /// </summary>
- [DataContract]
- public class CaptureImageOptions
- {
- /// <summary>
- /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureImageOptions Default
- {
- get { return new CaptureImageOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureAudio action options.
- /// </summary>
- [DataContract]
- public class CaptureAudioOptions
- {
- /// <summary>
- /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureAudioOptions Default
- {
- get { return new CaptureAudioOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents captureVideo action options.
- /// </summary>
- [DataContract]
- public class CaptureVideoOptions
- {
- /// <summary>
- /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
- /// </summary>
- [DataMember(IsRequired = false, Name = "limit")]
- public int Limit { get; set; }
-
- public static CaptureVideoOptions Default
- {
- get { return new CaptureVideoOptions() { Limit = 1 }; }
- }
- }
-
- /// <summary>
- /// Represents getFormatData action options.
- /// </summary>
- [DataContract]
- public class MediaFormatOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- [DataMember(IsRequired = true, Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// File mime type
- /// </summary>
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class MediaFile
- {
-
- [DataMember(Name = "name")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FilePath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public MediaFile(string filePath, Picture image)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = image.GetImage().Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
-
- }
-
- public MediaFile(string filePath, Stream stream)
- {
- this.FilePath = filePath;
- this.FileName = System.IO.Path.GetFileName(this.FilePath);
- this.Type = MimeTypeMapper.GetMimeType(FileName);
- this.Size = stream.Length;
-
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
- }
- }
- }
-
- /// <summary>
- /// Stores additional media file data
- /// </summary>
- [DataContract]
- public class MediaFileData
- {
- [DataMember(Name = "height")]
- public int Height { get; set; }
-
- [DataMember(Name = "width")]
- public int Width { get; set; }
-
- [DataMember(Name = "bitrate")]
- public int Bitrate { get; set; }
-
- [DataMember(Name = "duration")]
- public int Duration { get; set; }
-
- [DataMember(Name = "codecs")]
- public string Codecs { get; set; }
-
- public MediaFileData(WriteableBitmap image)
- {
- this.Height = image.PixelHeight;
- this.Width = image.PixelWidth;
- this.Bitrate = 0;
- this.Duration = 0;
- this.Codecs = "";
- }
- }
-
- #endregion
-
- /// <summary>
- /// Folder to store captured images
- /// </summary>
- private string isoFolder = "CapturedImagesCache";
-
- /// <summary>
- /// Capture Image options
- /// </summary>
- protected CaptureImageOptions captureImageOptions;
-
- /// <summary>
- /// Capture Audio options
- /// </summary>
- protected CaptureAudioOptions captureAudioOptions;
-
- /// <summary>
- /// Capture Video options
- /// </summary>
- protected CaptureVideoOptions captureVideoOptions;
-
- /// <summary>
- /// Used to open camera application
- /// </summary>
- private CameraCaptureTask cameraTask;
-
- /// <summary>
- /// Used for audio recording
- /// </summary>
- private AudioCaptureTask audioCaptureTask;
-
- /// <summary>
- /// Used for video recording
- /// </summary>
- private VideoCaptureTask videoCaptureTask;
-
- /// <summary>
- /// Stores information about captured files
- /// </summary>
- List<MediaFile> files = new List<MediaFile>();
-
- /// <summary>
- /// Launches default camera application to capture image
- /// </summary>
- /// <param name="options">may contains limit or mode parameters</param>
- public void captureImage(string options)
- {
- try
- {
- try
- {
-
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
-
- cameraTask = new CameraCaptureTask();
- cameraTask.Completed += this.cameraTask_Completed;
- cameraTask.Show();
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own audio recording control to capture audio
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureAudio(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- audioCaptureTask = new AudioCaptureTask();
- audioCaptureTask.Completed += audioRecordingTask_Completed;
- audioCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Launches our own video recording control to capture video
- /// </summary>
- /// <param name="options">may contains additional parameters</param>
- public void captureVideo(string options)
- {
- try
- {
- try
- {
- string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
- this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- videoCaptureTask = new VideoCaptureTask();
- videoCaptureTask.Completed += videoRecordingTask_Completed;
- videoCaptureTask.Show();
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
- /// <summary>
- /// Retrieves the format information of the media file.
- /// </summary>
- /// <param name="options"></param>
- public void getFormatData(string options)
- {
- try
- {
- MediaFormatOptions mediaFormatOptions;
- try
- {
- mediaFormatOptions = new MediaFormatOptions();
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
- mediaFormatOptions.FullPath = optionStrings[0];
- mediaFormatOptions.Type = optionStrings[1];
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- }
-
- string mimeType = mediaFormatOptions.Type;
-
- if (string.IsNullOrEmpty(mimeType))
- {
- mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
- }
-
- if (mimeType.Equals("image/jpeg"))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
-
- if (image == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
- return;
- }
-
- MediaFileData mediaData = new MediaFileData(image);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- }
- }
-
- /// <summary>
- /// Opens specified file in media player
- /// </summary>
- /// <param name="options">MediaFile to play</param>
- public void play(string options)
- {
- try
- {
- MediaFile file;
-
- try
- {
- file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
-
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (file == null || String.IsNullOrEmpty(file.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
- return;
- }
-
- // if url starts with '/' media player throws FileNotFound exception
- Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
-
- MediaPlayerLauncher player = new MediaPlayerLauncher();
- player.Media = fileUri;
- player.Location = MediaLocationType.Data;
- player.Show();
-
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
- }
- }
-
-
- /// <summary>
- /// Handles result of capture to save image information
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured image</param>
- private void cameraTask_Completed(object sender, PhotoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
-
- // Save image in media library
- MediaLibrary library = new MediaLibrary();
- Picture image = library.SavePicture(fileName, e.ChosenPhoto);
-
- int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
- int newAngle = 0;
- switch (orient)
- {
- case ImageExifOrientation.LandscapeLeft:
- newAngle = 90;
- break;
- case ImageExifOrientation.PortraitUpsideDown:
- newAngle = 180;
- break;
- case ImageExifOrientation.LandscapeRight:
- newAngle = 270;
- break;
- case ImageExifOrientation.Portrait:
- default: break; // 0 default already set
- }
-
- Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
- // Save image in isolated storage
-
- // we should return stream position back after saving stream to media library
- rotImageStream.Seek(0, SeekOrigin.Begin);
-
- byte[] imageBytes = new byte[rotImageStream.Length];
- rotImageStream.Read(imageBytes, 0, imageBytes.Length);
- rotImageStream.Dispose();
- string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
- imageBytes = null;
- // Get image data
- MediaFile data = new MediaFile(pathLocalStorage, image);
-
- this.files.Add(data);
-
- if (files.Count < this.captureImageOptions.Limit)
- {
- cameraTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some images were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of audio recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured audio</param>
- private void audioRecordingTask_Completed(object sender, AudioResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureAudioOptions.Limit)
- {
- audioCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some audio clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Handles result of video recording tasks
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e">stores information about current captured video</param>
- private void videoRecordingTask_Completed(object sender, VideoResult e)
- {
-
- if (e.Error != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
- return;
- }
-
- switch (e.TaskResult)
- {
- case TaskResult.OK:
- try
- {
- // Get image data
- MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
-
- this.files.Add(data);
-
- if (files.Count < this.captureVideoOptions.Limit)
- {
- videoCaptureTask.Show();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
- }
- break;
-
- case TaskResult.Cancel:
- if (files.Count > 0)
- {
- // User canceled operation, but some video clips were made
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
- }
- break;
-
- default:
- if (files.Count > 0)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
- files.Clear();
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
- }
- break;
- }
- }
-
- /// <summary>
- /// Extract file from Isolated Storage as WriteableBitmap object
- /// </summary>
- /// <param name="filePath"></param>
- /// <returns></returns>
- private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
- {
- try
- {
-
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- var imageSource = PictureDecoder.DecodeJpeg(imageStream);
- return imageSource;
- }
- }
- catch (Exception)
- {
- return null;
- }
- }
-
-
- /// <summary>
- /// Saves captured image in isolated storage
- /// </summary>
- /// <param name="imageFileName">image file name</param>
- /// <param name="imageFolder">folder to store images</param>
- /// <returns>Image path</returns>
- private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
- {
- if (imageBytes == null)
- {
- throw new ArgumentNullException("imageBytes");
- }
- try
- {
- var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
- if (!isoFile.DirectoryExists(imageFolder))
- {
- isoFile.CreateDirectory(imageFolder);
- }
- string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
-
- using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
- {
- stream.Write(imageBytes, 0, imageBytes.Length);
- }
-
- return filePath;
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Compass.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Compass.cs b/common-items/Plugins/Compass.cs
deleted file mode 100644
index c9e1c4d..0000000
--- a/common-items/Plugins/Compass.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using DeviceCompass = Microsoft.Devices.Sensors.Compass;
-using System.Windows.Threading;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class Compass : BaseCommand
- {
- #region Static members
-
- /// <summary>
- /// Status of listener
- /// </summary>
- private static int currentStatus;
-
- /// <summary>
- /// Id for get getCompass method
- /// </summary>
- private static string getCompassId = "getCompassId";
-
- /// <summary>
- /// Compass
- /// </summary>
- private static DeviceCompass compass = new DeviceCompass();
-
- /// <summary>
- /// Listeners for callbacks
- /// </summary>
- private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
-
- #endregion
-
- #region Status codes
-
- public const int Stopped = 0;
- public const int Starting = 1;
- public const int Running = 2;
- public const int ErrorFailedToStart = 4;
- public const int Not_Supported = 20;
-
- /*
- * // Capture error codes
- CompassError.COMPASS_INTERNAL_ERR = 0;
- CompassError.COMPASS_NOT_SUPPORTED = 20;
- * */
-
- #endregion
-
- #region CompassOptions class
- /// <summary>
- /// Represents Accelerometer options.
- /// </summary>
- [DataContract]
- public class CompassOptions
- {
- /// <summary>
- /// How often to retrieve the Acceleration in milliseconds
- /// </summary>
- [DataMember(IsRequired = false, Name = "frequency")]
- public int Frequency { get; set; }
-
- /// <summary>
- /// The change in degrees required to initiate a watchHeadingFilter success callback.
- /// </summary>
- [DataMember(IsRequired = false, Name = "filter")]
- public int Filter { get; set; }
-
- /// <summary>
- /// Watcher id
- /// </summary>
- [DataMember(IsRequired = false, Name = "id")]
- public string Id { get; set; }
-
- }
- #endregion
-
-
- /// <summary>
- /// Time the value was last changed
- /// </summary>
- //private DateTime lastValueChangedTime;
-
- /// <summary>
- /// Accelerometer options
- /// </summary>
- private CompassOptions compassOptions;
-
- //bool isDataValid;
-
- //bool calibrating = false;
-
- public Compass()
- {
-
- }
-
- /// <summary>
- /// Formats current coordinates into JSON format
- /// </summary>
- /// <returns>Coordinates in JSON format</returns>
- private string GetHeadingFormatted(CompassReading reading)
- {
- // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
- string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
- reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
- reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
- reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
- return "{" + result + "}";
- }
-
- public void getHeading(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
- }
- else
- {
- //if (compass == null)
- //{
- // // Instantiate the compass.
- // compass = new DeviceCompass();
- // compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
- // compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
- // compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
- //}
-
-
- //compass.Start();
-
- }
-
- try
- {
- if (currentStatus != Running)
- {
- lock (compass)
- {
- compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
-
- long timeout = 2000;
- while ((currentStatus == Starting) && (timeout > 0))
- {
- timeout = timeout - 100;
- Thread.Sleep(100);
- }
-
- if (currentStatus != Running)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
- return;
- }
- }
- lock (compass)
- {
- compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
- if (watchers.Count < 1)
- {
- compass.Stop();
- this.SetStatus(Stopped);
- }
- }
- }
- catch (UnauthorizedAccessException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- }
- }
-
- void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Starts listening for compass sensor
- /// </summary>
- /// <returns>status of listener</returns>
- private int start()
- {
- if ((currentStatus == Running) || (currentStatus == Starting))
- {
- return currentStatus;
- }
- try
- {
- lock (compass)
- {
- watchers.Add(getCompassId, this);
- compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.SetStatus(ErrorFailedToStart);
- }
- return currentStatus;
- }
-
- public void startWatch(string options)
- {
- if (!DeviceCompass.IsSupported)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
- }
-
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- lock (compass)
- {
- watchers.Add(compassOptions.Id, this);
- compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
- compass.Start();
- this.SetStatus(Starting);
- }
- }
- catch (Exception)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
- return;
- }
- }
-
- public void stopWatch(string options)
- {
- try
- {
- compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
- }
- catch (Exception ex)
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
- return;
- }
-
- if (string.IsNullOrEmpty(compassOptions.Id))
- {
- this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- if (currentStatus != Stopped)
- {
- lock (compass)
- {
- Compass watcher = watchers[compassOptions.Id];
- compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
- watchers.Remove(compassOptions.Id);
- watcher.Dispose();
- }
- }
- this.SetStatus(Stopped);
-
- this.DispatchCommandResult();
- }
-
- void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
- {
- //throw new NotImplementedException();
- // TODO: pass calibration error to JS
- }
-
- void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
- {
- this.SetStatus(Running);
- if (compass.IsDataValid)
- {
- // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
- // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
- // A negative value indicates that the true heading could not be determined.
- // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
- //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
- //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
- PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
- result.KeepCallback = true;
-
- DispatchCommandResult(result);
- }
- }
-
- /// <summary>
- /// Sets current status
- /// </summary>
- /// <param name="status">current status</param>
- private void SetStatus(int status)
- {
- currentStatus = status;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Contacts.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Contacts.cs b/common-items/Plugins/Contacts.cs
deleted file mode 100644
index af78942..0000000
--- a/common-items/Plugins/Contacts.cs
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Tasks;
-using Microsoft.Phone.UserData;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Windows;
-using DeviceContacts = Microsoft.Phone.UserData.Contacts;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class SearchOptions
- {
- [DataMember]
- public string filter { get; set; }
- [DataMember]
- public bool multiple { get; set; }
- }
-
- [DataContract]
- public class ContactSearchParams
- {
- [DataMember]
- public string[] fields { get; set; }
- [DataMember]
- public SearchOptions options { get; set; }
- }
-
- [DataContract]
- public class JSONContactAddress
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string streetAddress { get; set; }
- [DataMember]
- public string locality { get; set; }
- [DataMember]
- public string region { get; set; }
- [DataMember]
- public string postalCode { get; set; }
- [DataMember]
- public string country { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactName
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string familyName { get; set; }
- [DataMember]
- public string givenName { get; set; }
- [DataMember]
- public string middleName { get; set; }
- [DataMember]
- public string honorificPrefix { get; set; }
- [DataMember]
- public string honorificSuffix { get; set; }
- }
-
- [DataContract]
- public class JSONContactField
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string value { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactOrganization
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string name { get; set; }
- [DataMember]
- public bool pref { get; set; }
- [DataMember]
- public string department { get; set; }
- [DataMember]
- public string title { get; set; }
- }
-
- [DataContract]
- public class JSONContact
- {
- [DataMember]
- public string id { get; set; }
- [DataMember]
- public string rawId { get; set; }
- [DataMember]
- public string displayName { get; set; }
- [DataMember]
- public string nickname { get; set; }
- [DataMember]
- public string note { get; set; }
-
- [DataMember]
- public JSONContactName name { get; set; }
-
- [DataMember]
- public JSONContactField[] emails { get; set; }
-
- [DataMember]
- public JSONContactField[] phoneNumbers { get; set; }
-
- [DataMember]
- public JSONContactField[] ims { get; set; }
-
- [DataMember]
- public JSONContactField[] photos { get; set; }
-
- [DataMember]
- public JSONContactField[] categories { get; set; }
-
- [DataMember]
- public JSONContactField[] urls { get; set; }
-
- [DataMember]
- public JSONContactOrganization[] organizations { get; set; }
-
- [DataMember]
- public JSONContactAddress[] addresses { get; set; }
- }
-
-
- public class Contacts : BaseCommand
- {
-
- public const int UNKNOWN_ERROR = 0;
- public const int INVALID_ARGUMENT_ERROR = 1;
- public const int TIMEOUT_ERROR = 2;
- public const int PENDING_OPERATION_ERROR = 3;
- public const int IO_ERROR = 4;
- public const int NOT_SUPPORTED_ERROR = 5;
- public const int PERMISSION_DENIED_ERROR = 20;
- public const int SYNTAX_ERR = 8;
-
- public Contacts()
- {
-
- }
-
- // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
- public void save(string jsonContact)
- {
-
- // jsonContact is actually an array of 1 {contact}
- string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
-
-
- JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
-
- SaveContactTask contactTask = new SaveContactTask();
-
- if (contact.nickname != null)
- {
- contactTask.Nickname = contact.nickname;
- }
- if (contact.urls != null && contact.urls.Length > 0)
- {
- contactTask.Website = contact.urls[0].value;
- }
- if (contact.note != null)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.name
- if (contact.name != null)
- {
- if (contact.name.givenName != null)
- contactTask.FirstName = contact.name.givenName;
- if (contact.name.familyName != null)
- contactTask.LastName = contact.name.familyName;
- if (contact.name.middleName != null)
- contactTask.MiddleName = contact.name.middleName;
- if (contact.name.honorificSuffix != null)
- contactTask.Suffix = contact.name.honorificSuffix;
- if (contact.name.honorificPrefix != null)
- contactTask.Title = contact.name.honorificPrefix;
- }
- #endregion
-
- #region contact.org
- if (contact.organizations != null && contact.organizations.Count() > 0)
- {
- contactTask.Company = contact.organizations[0].name;
- contactTask.JobTitle = contact.organizations[0].title;
- }
- #endregion
-
- #region contact.phoneNumbers
- if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
- {
- foreach (JSONContactField field in contact.phoneNumbers)
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkPhone = field.value;
- }
- else if (fieldType == "home")
- {
- contactTask.HomePhone = field.value;
- }
- else if (fieldType == "mobile")
- {
- contactTask.MobilePhone = field.value;
- }
- }
- }
- #endregion
-
- #region contact.emails
-
- if (contact.emails != null && contact.emails.Length > 0)
- {
-
- // set up different email types if they are not explicitly defined
- foreach (string type in new string[] { "personal", "work", "other" })
- {
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null && String.IsNullOrEmpty(field.type))
- {
- field.type = type;
- break;
- }
- }
- }
-
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null)
- {
- if (field.type != null && field.type != "other")
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkEmail = field.value;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.PersonalEmail = field.value;
- }
- }
- else
- {
- contactTask.OtherEmail = field.value;
- }
- }
-
- }
- }
- #endregion
-
- if (contact.note != null && contact.note.Length > 0)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.addresses
- if (contact.addresses != null && contact.addresses.Length > 0)
- {
- foreach (JSONContactAddress address in contact.addresses)
- {
- if (address.type == null)
- {
- address.type = "home"; // set a default
- }
- string fieldType = address.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkAddressCity = address.locality;
- contactTask.WorkAddressCountry = address.country;
- contactTask.WorkAddressState = address.region;
- contactTask.WorkAddressStreet = address.streetAddress;
- contactTask.WorkAddressZipCode = address.postalCode;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.HomeAddressCity = address.locality;
- contactTask.HomeAddressCountry = address.country;
- contactTask.HomeAddressState = address.region;
- contactTask.HomeAddressStreet = address.streetAddress;
- contactTask.HomeAddressZipCode = address.postalCode;
- }
- else
- {
- // no other address fields available ...
- Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
- }
- }
- }
- #endregion
-
-
- contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
- contactTask.Show();
- }
-
- void ContactSaveTaskCompleted(object sender, SaveContactResult e)
- {
- SaveContactTask task = sender as SaveContactTask;
-
- if (e.TaskResult == TaskResult.OK)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
-
- string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
-
- deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
- });
-
-
- }
- else if (e.TaskResult == TaskResult.Cancel)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
- }
- }
-
- void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- if (e.Results.Count() > 0)
- {
- List<Contact> foundContacts = new List<Contact>();
-
- int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
- Contact newContact = (from Contact contact in e.Results
- where contact.GetHashCode() == n
- select contact).First();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
-
-
- public void remove(string id)
- {
- // note id is wrapped in [] and always has exactly one string ...
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
- }
-
- public void search(string searchCriteria)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
-
- ContactSearchParams searchParams = new ContactSearchParams();
- try
- {
- searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
- searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
- return;
- }
-
- if (searchParams.options == null)
- {
- searchParams.options = new SearchOptions();
- searchParams.options.filter = "";
- searchParams.options.multiple = true;
- }
-
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
-
- // default is to search all fields
- FilterKind filterKind = FilterKind.None;
- // if only one field is specified, we will try the 3 available DeviceContact search filters
- if (searchParams.fields.Count() == 1)
- {
- if (searchParams.fields.Contains("name"))
- {
- filterKind = FilterKind.DisplayName;
- }
- else if (searchParams.fields.Contains("emails"))
- {
- filterKind = FilterKind.EmailAddress;
- }
- else if (searchParams.fields.Contains("phoneNumbers"))
- {
- filterKind = FilterKind.PhoneNumber;
- }
- }
-
- try
- {
-
- deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
- }
- catch (Exception ex)
- {
- Debug.WriteLine("search contacts exception :: " + ex.Message);
- }
- }
-
- private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- ContactSearchParams searchParams = (ContactSearchParams)e.State;
-
- List<Contact> foundContacts = null;
-
- // if we have multiple search fields
- if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
- {
- foundContacts = new List<Contact>();
- if (searchParams.fields.Contains("emails"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactEmailAddress a in con.EmailAddresses
- where a.EmailAddress.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("displayName"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.DisplayName.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("name"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("phoneNumbers"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactPhoneNumber a in con.PhoneNumbers
- where a.PhoneNumber.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("urls"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from string a in con.Websites
- where a.Contains(searchParams.options.filter)
- select con);
- }
- }
- else
- {
- foundContacts = new List<Contact>(e.Results);
- }
-
- //List<string> contactList = new List<string>();
-
- string strResult = "";
-
- IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
-
- foreach (Contact contact in distinctContacts)
- {
- strResult += FormatJSONContact(contact, null) + ",";
- //contactList.Add(FormatJSONContact(contact, null));
- if (!searchParams.options.multiple)
- {
- break; // just return the first item
- }
- }
- PluginResult result = new PluginResult(PluginResult.Status.OK);
- result.Message = "[" + strResult.TrimEnd(',') + "]";
- DispatchCommandResult(result);
-
- }
-
- private string FormatJSONPhoneNumbers(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactPhoneNumber number in con.PhoneNumbers)
- {
-
- string contactField = string.Format(contactFieldFormat,
- number.Kind.ToString(),
- number.PhoneNumber);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONEmails(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactEmailAddress address in con.EmailAddresses)
- {
- string contactField = string.Format(contactFieldFormat,
- address.Kind.ToString(),
- address.EmailAddress);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string getFormattedJSONAddress(ContactAddress address, bool isPrefered)
- {
-
- string addressFormatString = "\"pref\":{0}," + // bool
- "\"type\":\"{1}\"," +
- "\"formatted\":\"{2}\"," +
- "\"streetAddress\":\"{3}\"," +
- "\"locality\":\"{4}\"," +
- "\"region\":\"{5}\"," +
- "\"postalCode\":\"{6}\"," +
- "\"country\":\"{7}\"";
-
- string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
- + address.PhysicalAddress.AddressLine2 + " "
- + address.PhysicalAddress.City + " "
- + address.PhysicalAddress.StateProvince + " "
- + address.PhysicalAddress.CountryRegion + " "
- + address.PhysicalAddress.PostalCode;
-
- string jsonAddress = string.Format(addressFormatString,
- isPrefered ? "\"true\"" : "\"false\"",
- address.Kind.ToString(),
- formattedAddress,
- address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
- address.PhysicalAddress.City,
- address.PhysicalAddress.StateProvince,
- address.PhysicalAddress.PostalCode,
- address.PhysicalAddress.CountryRegion);
-
- //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
-
- return "{" + jsonAddress + "}";
- }
-
- private string FormatJSONAddresses(Contact con)
- {
- string retVal = "";
- foreach (ContactAddress address in con.Addresses)
- {
- retVal += this.getFormattedJSONAddress(address, false) + ",";
- }
-
- //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONWebsites(Contact con)
- {
- string retVal = "";
- foreach (string website in con.Websites)
- {
- retVal += "\"" + website + "\",";
- }
- return retVal.TrimEnd(',');
- }
-
- /*
- * formatted: The complete name of the contact. (DOMString)
- familyName: The contacts family name. (DOMString)
- givenName: The contacts given name. (DOMString)
- middleName: The contacts middle name. (DOMString)
- honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
- honorificSuffix: The contacts suffix (example Esq.). (DOMString)
- */
- private string FormatJSONName(Contact con)
- {
- string retVal = "";
- string formatStr = "\"formatted\":\"{0}\"," +
- "\"familyName\":\"{1}\"," +
- "\"givenName\":\"{2}\"," +
- "\"middleName\":\"{3}\"," +
- "\"honorificPrefix\":\"{4}\"," +
- "\"honorificSuffix\":\"{5}\"";
-
- if (con.CompleteName != null)
- {
- retVal = string.Format(formatStr,
- con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
- con.CompleteName.LastName,
- con.CompleteName.FirstName,
- con.CompleteName.MiddleName,
- con.CompleteName.Title,
- con.CompleteName.Suffix);
- }
- else
- {
- retVal = string.Format(formatStr,"","","","","","");
- }
-
- return "{" + retVal + "}";
- }
-
- private string FormatJSONContact(Contact con, string[] fields)
- {
-
- string contactFormatStr = "\"id\":\"{0}\"," +
- "\"displayName\":\"{1}\"," +
- "\"nickname\":\"{2}\"," +
- "\"phoneNumbers\":[{3}]," +
- "\"emails\":[{4}]," +
- "\"addresses\":[{5}]," +
- "\"urls\":[{6}]," +
- "\"name\":{7}," +
- "\"note\":\"{8}\"," +
- "\"birthday\":\"{9}\"";
-
-
- string jsonContact = String.Format(contactFormatStr,
- con.GetHashCode(),
- con.DisplayName,
- con.CompleteName != null ? con.CompleteName.Nickname : "",
- FormatJSONPhoneNumbers(con),
- FormatJSONEmails(con),
- FormatJSONAddresses(con),
- FormatJSONWebsites(con),
- FormatJSONName(con),
- con.Notes.FirstOrDefault(),
- con.Birthdays.FirstOrDefault());
-
- //Debug.WriteLine("jsonContact = " + jsonContact);
- // JSON requires new line characters be escaped
- return "{" + jsonContact.Replace("\n", "\\n") + "}";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/DebugConsole.cs b/common-items/Plugins/DebugConsole.cs
deleted file mode 100644
index fa9863a..0000000
--- a/common-items/Plugins/DebugConsole.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class DebugConsole : BaseCommand
- {
- // warn, error
- public void log(string msg)
- {
- Debug.WriteLine("Log:" + msg);
- }
-
- public void error(string msg)
- {
- Debug.WriteLine("Error:" + msg);
- }
-
- public void warn(string msg)
- {
- Debug.WriteLine("Warn:" + msg);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common-items/Plugins/Device.cs
----------------------------------------------------------------------
diff --git a/common-items/Plugins/Device.cs b/common-items/Plugins/Device.cs
deleted file mode 100644
index 8abb4ff..0000000
--- a/common-items/Plugins/Device.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Info;
-using System.IO.IsolatedStorage;
-using System.Windows.Resources;
-using System.IO;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Device : BaseCommand
- {
- public void getDeviceInfo(string notused)
- {
-
- string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
- this.name,
- this.cordova,
- this.platform,
- this.uuid,
- this.version,
- this.model);
-
-
-
- res = "{" + res + "}";
- //Debug.WriteLine("Result::" + res);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
- }
-
- public string model
- {
- get
- {
- return DeviceStatus.DeviceName;
- //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion);
- }
- }
-
- public string name
- {
- get
- {
- return DeviceStatus.DeviceName;
-
- }
- }
-
- public string cordova
- {
- get
- {
- // TODO: should be able to dynamically read the Cordova version from somewhere...
- return "0.0.0";
- }
- }
-
- public string platform
- {
- get
- {
- return Environment.OSVersion.Platform.ToString();
- }
- }
-
- public string uuid
- {
- get
- {
- string returnVal = "";
- object id;
- UserExtendedProperties.TryGetValue("ANID", out id);
-
- if (id != null)
- {
- returnVal = id.ToString().Substring(2, 32);
- }
- else
- {
- returnVal = "???unknown???";
-
- using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- try
- {
- IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
- using (StreamReader reader = new StreamReader(fileStream))
- {
- returnVal = reader.ReadLine();
- }
- }
- catch (Exception /*ex*/)
- {
-
- }
- }
- }
-
- return returnVal;
- }
- }
-
- public string version
- {
- get
- {
- return Environment.OSVersion.Version.ToString();
- }
- }
-
- }
-}
[14/50] [abbrv] git commit: Set VERSION to 2.9.0rc1
Posted by pu...@apache.org.
Set VERSION to 2.9.0rc1
Project: http://git-wip-us.apache.org/repos/asf/cordova-wp8/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-wp8/commit/744e685a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-wp8/tree/744e685a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-wp8/diff/744e685a
Branch: refs/heads/2.9.x
Commit: 744e685a8f7553855c0dd1b18552ae281311bed6
Parents: dec32ea
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jun 18 13:54:47 2013 -0400
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Tue Jun 18 12:35:16 2013 -0700
----------------------------------------------------------------------
VERSION | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/744e685a/VERSION
----------------------------------------------------------------------
diff --git a/VERSION b/VERSION
index bd52db8..3af205c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.0
\ No newline at end of file
+2.9.0rc1
[26/50] [abbrv] moved plugins to common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/File.cs
----------------------------------------------------------------------
diff --git a/plugins/File.cs b/plugins/File.cs
deleted file mode 100644
index cde7a1c..0000000
--- a/plugins/File.cs
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to isolated storage
- /// </summary>
- public class File : BaseCommand
- {
- // Error codes
- public const int NOT_FOUND_ERR = 1;
- public const int SECURITY_ERR = 2;
- public const int ABORT_ERR = 3;
- public const int NOT_READABLE_ERR = 4;
- public const int ENCODING_ERR = 5;
- public const int NO_MODIFICATION_ALLOWED_ERR = 6;
- public const int INVALID_STATE_ERR = 7;
- public const int SYNTAX_ERR = 8;
- public const int INVALID_MODIFICATION_ERR = 9;
- public const int QUOTA_EXCEEDED_ERR = 10;
- public const int TYPE_MISMATCH_ERR = 11;
- public const int PATH_EXISTS_ERR = 12;
-
- // File system options
- public const int TEMPORARY = 0;
- public const int PERSISTENT = 1;
- public const int RESOURCE = 2;
- public const int APPLICATION = 3;
-
- /// <summary>
- /// Temporary directory name
- /// </summary>
- private readonly string TMP_DIRECTORY_NAME = "tmp";
-
- /// <summary>
- /// Represents error code for callback
- /// </summary>
- [DataContract]
- public class ErrorCode
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(IsRequired = true, Name = "code")]
- public int Code { get; set; }
-
- /// <summary>
- /// Creates ErrorCode object
- /// </summary>
- public ErrorCode(int code)
- {
- this.Code = code;
- }
- }
-
- /// <summary>
- /// Represents File action options.
- /// </summary>
- [DataContract]
- public class FileOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- ///
- private string _fileName;
- [DataMember(Name = "fileName")]
- public string FilePath
- {
- get
- {
- return this._fileName;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._fileName = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Full entryPath
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// Directory name
- /// </summary>
- [DataMember(Name = "dirName")]
- public string DirectoryName { get; set; }
-
- /// <summary>
- /// Path to create file/directory
- /// </summary>
- [DataMember(Name = "path")]
- public string Path { get; set; }
-
- /// <summary>
- /// The encoding to use to encode the file's content. Default is UTF8.
- /// </summary>
- [DataMember(Name = "encoding")]
- public string Encoding { get; set; }
-
- /// <summary>
- /// Uri to get file
- /// </summary>
- ///
- private string _uri;
- [DataMember(Name = "uri")]
- public string Uri
- {
- get
- {
- return this._uri;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._uri = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Size to truncate file
- /// </summary>
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- /// <summary>
- /// Data to write in file
- /// </summary>
- [DataMember(Name = "data")]
- public string Data { get; set; }
-
- /// <summary>
- /// Position the writing starts with
- /// </summary>
- [DataMember(Name = "position")]
- public int Position { get; set; }
-
- /// <summary>
- /// Type of file system requested
- /// </summary>
- [DataMember(Name = "type")]
- public int FileSystemType { get; set; }
-
- /// <summary>
- /// New file/directory name
- /// </summary>
- [DataMember(Name = "newName")]
- public string NewName { get; set; }
-
- /// <summary>
- /// Destination directory to copy/move file/directory
- /// </summary>
- [DataMember(Name = "parent")]
- public string Parent { get; set; }
-
- /// <summary>
- /// Options for getFile/getDirectory methods
- /// </summary>
- [DataMember(Name = "options")]
- public CreatingOptions CreatingOpt { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public FileOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Encoding = "UTF-8";
- this.FilePath = "";
- this.FileSystemType = -1;
- }
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class FileMetadata
- {
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public FileMetadata(string filePath)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- else if (!isoFile.FileExists(filePath))
- {
- // attempt to get it from the resources
- if (filePath.IndexOf("www") == 0)
- {
- Uri fileUri = new Uri(filePath, UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- this.Size = streamInfo.Stream.Length;
- this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
- this.FullPath = filePath;
- }
- }
- else
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- }
- else
- {
- //TODO get file size the other way if possible
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
- {
- this.Size = stream.Length;
- }
- this.FullPath = filePath;
- this.FileName = System.IO.Path.GetFileName(filePath);
- this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- }
- this.Type = MimeTypeMapper.GetMimeType(this.FileName);
- }
- }
- }
-
- /// <summary>
- /// Represents file or directory modification metadata
- /// </summary>
- [DataContract]
- public class ModificationMetadata
- {
- /// <summary>
- /// Modification time
- /// </summary>
- [DataMember]
- public string modificationTime { get; set; }
- }
-
- /// <summary>
- /// Represents file or directory entry
- /// </summary>
- [DataContract]
- public class FileEntry
- {
-
- /// <summary>
- /// File type
- /// </summary>
- [DataMember(Name = "isFile")]
- public bool IsFile { get; set; }
-
- /// <summary>
- /// Directory type
- /// </summary>
- [DataMember(Name = "isDirectory")]
- public bool IsDirectory { get; set; }
-
- /// <summary>
- /// File/directory name
- /// </summary>
- [DataMember(Name = "name")]
- public string Name { get; set; }
-
- /// <summary>
- /// Full path to file/directory
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- public bool IsResource { get; set; }
-
- public static FileEntry GetEntry(string filePath, bool bIsRes=false)
- {
- FileEntry entry = null;
- try
- {
- entry = new FileEntry(filePath, bIsRes);
-
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
- }
- return entry;
- }
-
- /// <summary>
- /// Creates object and sets necessary properties
- /// </summary>
- /// <param name="filePath"></param>
- public FileEntry(string filePath, bool bIsRes = false)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new ArgumentException();
- }
-
- if(filePath.Contains(" "))
- {
- Debug.WriteLine("FilePath with spaces :: " + filePath);
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- IsResource = bIsRes;
- IsFile = isoFile.FileExists(filePath);
- IsDirectory = isoFile.DirectoryExists(filePath);
- if (IsFile)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else if (IsDirectory)
- {
- this.Name = this.GetDirectoryName(filePath);
- if (string.IsNullOrEmpty(Name))
- {
- this.Name = "/";
- }
- }
- else
- {
- if (IsResource)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else
- {
- throw new FileNotFoundException();
- }
- }
-
- try
- {
- this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
- }
- catch (Exception)
- {
- this.FullPath = filePath;
- }
- }
- }
-
- /// <summary>
- /// Extracts directory name from path string
- /// Path should refer to a directory, for example \foo\ or /foo.
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- private string GetDirectoryName(string path)
- {
- if (String.IsNullOrEmpty(path))
- {
- return path;
- }
-
- string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
- if (split.Length < 1)
- {
- return null;
- }
- else
- {
- return split[split.Length - 1];
- }
- }
- }
-
-
- /// <summary>
- /// Represents info about requested file system
- /// </summary>
- [DataContract]
- public class FileSystemInfo
- {
- /// <summary>
- /// file system type
- /// </summary>
- [DataMember(Name = "name", IsRequired = true)]
- public string Name { get; set; }
-
- /// <summary>
- /// Root directory entry
- /// </summary>
- [DataMember(Name = "root", EmitDefaultValue = false)]
- public FileEntry Root { get; set; }
-
- /// <summary>
- /// Creates class instance
- /// </summary>
- /// <param name="name"></param>
- /// <param name="rootEntry"> Root directory</param>
- public FileSystemInfo(string name, FileEntry rootEntry = null)
- {
- Name = name;
- Root = rootEntry;
- }
- }
-
- [DataContract]
- public class CreatingOptions
- {
- /// <summary>
- /// Create file/directory if is doesn't exist
- /// </summary>
- [DataMember(Name = "create")]
- public bool Create { get; set; }
-
- /// <summary>
- /// Generate an exception if create=true and file/directory already exists
- /// </summary>
- [DataMember(Name = "exclusive")]
- public bool Exclusive { get; set; }
-
-
- }
-
- // returns null value if it fails.
- private string[] getOptionStrings(string options)
- {
- string[] optStings = null;
- try
- {
- optStings = JSON.JsonHelper.Deserialize<string[]>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
- }
- return optStings;
- }
-
- /// <summary>
- /// Gets amount of free space available for Isolated Storage
- /// </summary>
- /// <param name="options">No options is needed for this method</param>
- public void getFreeDiskSpace(string options)
- {
- string callbackId = getOptionStrings(options)[0];
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Check if file exists
- /// </summary>
- /// <param name="options">File path</param>
- public void testFileExists(string options)
- {
- IsDirectoryOrFileExist(options, false);
- }
-
- /// <summary>
- /// Check if directory exists
- /// </summary>
- /// <param name="options">directory name</param>
- public void testDirectoryExists(string options)
- {
- IsDirectoryOrFileExist(options, true);
- }
-
- /// <summary>
- /// Check if file or directory exist
- /// </summary>
- /// <param name="options">File path/Directory name</param>
- /// <param name="isDirectory">Flag to recognize what we should check</param>
- public void IsDirectoryOrFileExist(string options, bool isDirectory)
- {
- string[] args = getOptionStrings(options);
- string callbackId = args[1];
- FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
- string filePath = args[0];
-
- if (fileOptions == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isExist;
- if (isDirectory)
- {
- isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
- }
- else
- {
- isExist = isoFile.FileExists(fileOptions.FilePath);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
- }
- }
- catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
-
- public void readAsDataURL(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- if (filePath != null)
- {
- try
- {
- string base64URL = null;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string mimeType = MimeTypeMapper.GetMimeType(filePath);
-
- using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- string base64String = GetFileContent(stream);
- base64URL = "data:" + mimeType + ";base64," + base64String;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- public void readAsArrayBuffer(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsBinaryString(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- string encStr = optStrings[1];
- int startPos = int.Parse(optStrings[2]);
- int endPos = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- string text = "";
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- readResourceAsText(options);
- return;
- }
- Encoding encoding = Encoding.GetEncoding(encStr);
-
- using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
- {
- text = reader.ReadToEnd();
- if (startPos < 0)
- {
- startPos = Math.Max(text.Length + startPos, 0);
- }
- else if (startPos > 0)
- {
- startPos = Math.Min(text.Length, startPos);
- }
-
- if (endPos > 0)
- {
- endPos = Math.Min(text.Length, endPos);
- }
- else if (endPos < 0)
- {
- endPos = Math.Max(endPos + text.Length, 0);
- }
-
-
- text = text.Substring(startPos, endPos - startPos);
-
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Reads application resource as a text
- /// </summary>
- /// <param name="options">Path to a resource</param>
- public void readResourceAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string pathToResource = optStrings[0];
- string encStr = optStrings[1];
- int start = int.Parse(optStrings[2]);
- int endMarker = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- if (pathToResource.StartsWith("/"))
- {
- pathToResource = pathToResource.Remove(0, 1);
- }
-
- var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
-
- if (resource == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string text;
- StreamReader streamReader = new StreamReader(resource.Stream);
- text = streamReader.ReadToEnd();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- public void truncate(string options)
- {
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- int size = int.Parse(optStrings[1]);
- string callbackId = optStrings[2];
-
- try
- {
- long streamLength = 0;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= size && size <= stream.Length)
- {
- stream.SetLength(size);
- }
- streamLength = stream.Length;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- //write:["filePath","data","position"],
- public void write(string options)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- string data = optStrings[1];
- int position = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- try
- {
- if (string.IsNullOrEmpty(data))
- {
- Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(filePath))
- {
- var file = isoFile.CreateFile(filePath);
- file.Close();
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= position && position <= stream.Length)
- {
- stream.SetLength(position);
- }
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- writer.Seek(0, SeekOrigin.End);
- writer.Write(data.ToCharArray());
- }
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Look up metadata about this entry.
- /// </summary>
- /// <param name="options">filePath to entry</param>
- public void getMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
- new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
- }
- else if (isoFile.DirectoryExists(filePath))
- {
- string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- }
-
-
- /// <summary>
- /// Returns a File that represents the current state of the file that this FileEntry represents.
- /// </summary>
- /// <param name="filePath">filePath to entry</param>
- /// <returns></returns>
- public void getFileMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- FileMetadata metaData = new FileMetadata(filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- /// <summary>
- /// Look up the parent DirectoryEntry containing this Entry.
- /// If this Entry is the root of IsolatedStorage, its parent is itself.
- /// </summary>
- /// <param name="options"></param>
- public void getParent(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- FileEntry entry;
-
- if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
- {
-
-
- string path = this.GetParentDirectory(filePath);
- entry = FileEntry.GetEntry(path);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
-
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- }
-
- public void remove(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (filePath == "/" || filePath == "" || filePath == @"\")
- {
- throw new Exception("Cannot delete root file system") ;
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- else
- {
- if (isoFile.DirectoryExists(filePath))
- {
- isoFile.DeleteDirectory(filePath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- return;
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void removeRecursively(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- }
- else
- {
- if (removeDirRecursively(filePath, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- }
- }
- }
-
- public void readEntries(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(filePath))
- {
- string path = File.AddSlashToDirectory(filePath);
- List<FileEntry> entries = new List<FileEntry>();
- string[] files = isoFile.GetFileNames(path + "*");
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- foreach (string file in files)
- {
- entries.Add(FileEntry.GetEntry(path + file));
- }
- foreach (string dir in dirs)
- {
- entries.Add(FileEntry.GetEntry(path + dir + "/"));
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void requestFileSystem(string options)
- {
- // TODO: try/catch
- string[] optVals = getOptionStrings(options);
- //FileOptions fileOptions = new FileOptions();
- int fileSystemType = int.Parse(optVals[0]);
- double size = double.Parse(optVals[1]);
- string callbackId = optVals[2];
-
-
- IsolatedStorageFile.GetUserStoreForApplication();
-
- if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
-
- try
- {
- if (size != 0)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- long availableSize = isoFile.AvailableFreeSpace;
- if (size > availableSize)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
- }
- }
-
- if (fileSystemType == PERSISTENT)
- {
- // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
- }
- else if (fileSystemType == TEMPORARY)
- {
- using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
- {
- isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
- }
- }
-
- string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
- }
- else if (fileSystemType == RESOURCE)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
- }
- else if (fileSystemType == APPLICATION)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- public void resolveLocalFileSystemURI(string options)
- {
-
- string[] optVals = getOptionStrings(options);
- string uri = optVals[0].Split('?')[0];
- string callbackId = optVals[1];
-
- if (uri != null)
- {
- // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
- if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
- try
- {
- // fix encoded spaces
- string path = Uri.UnescapeDataString(uri);
-
- FileEntry uriEntry = FileEntry.GetEntry(path);
- if (uriEntry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
- }
-
- public void copyTo(string options)
- {
- TransferTo(options, false);
- }
-
- public void moveTo(string options)
- {
- TransferTo(options, true);
- }
-
- public void getFile(string options)
- {
- GetFileOrDirectory(options, false);
- }
-
- public void getDirectory(string options)
- {
- GetFileOrDirectory(options, true);
- }
-
- #region internal functionality
-
- /// <summary>
- /// Retrieves the parent directory name of the specified path,
- /// </summary>
- /// <param name="path">Path</param>
- /// <returns>Parent directory name</returns>
- private string GetParentDirectory(string path)
- {
- if (String.IsNullOrEmpty(path) || path == "/")
- {
- return "/";
- }
-
- if (path.EndsWith(@"/") || path.EndsWith(@"\"))
- {
- return this.GetParentDirectory(Path.GetDirectoryName(path));
- }
-
- string result = Path.GetDirectoryName(path);
- if (result == null)
- {
- result = "/";
- }
-
- return result;
- }
-
- private bool removeDirRecursively(string fullPath,string callbackId)
- {
- try
- {
- if (fullPath == "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(fullPath))
- {
- string tempPath = File.AddSlashToDirectory(fullPath);
- string[] files = isoFile.GetFileNames(tempPath + "*");
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.DeleteFile(tempPath + file);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- if (!removeDirRecursively(tempPath + dir, callbackId))
- {
- return false;
- }
- }
- }
- isoFile.DeleteDirectory(fullPath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
- }
- return true;
- }
-
- private bool CanonicalCompare(string pathA, string pathB)
- {
- string a = pathA.Replace("//", "/");
- string b = pathB.Replace("//", "/");
-
- return a.Equals(b, StringComparison.OrdinalIgnoreCase);
- }
-
- /*
- * copyTo:["fullPath","parent", "newName"],
- * moveTo:["fullPath","parent", "newName"],
- */
- private void TransferTo(string options, bool move)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
- string fullPath = optStrings[0];
- string parent = optStrings[1];
- string newFileName = optStrings[2];
- string callbackId = optStrings[3];
-
- char[] invalids = Path.GetInvalidPathChars();
-
- if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string parentPath = File.AddSlashToDirectory(parent);
- string currentPath = fullPath;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFileExist = isoFile.FileExists(currentPath);
- bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
- bool isParentExist = isoFile.DirectoryExists(parentPath);
-
- if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string newName;
- string newPath;
- if (isFileExist)
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? Path.GetFileName(currentPath)
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- // sanity check ..
- // cannot copy file onto itself
- if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.DirectoryExists(newPath))
- {
- // there is already a folder with the same name, operation is not allowed
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.FileExists(newPath))
- { // remove destination file if exists, in other case there will be exception
- isoFile.DeleteFile(newPath);
- }
-
- if (move)
- {
- isoFile.MoveFile(currentPath, newPath);
- }
- else
- {
- isoFile.CopyFile(currentPath, newPath, true);
- }
- }
- else
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? currentPath
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- if (move)
- {
- // remove destination directory if exists, in other case there will be exception
- // target directory should be empty
- if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
- {
- isoFile.DeleteDirectory(newPath);
- }
-
- isoFile.MoveDirectory(currentPath, newPath);
- }
- else
- {
- CopyDirectory(currentPath, newPath, isoFile);
- }
- }
- FileEntry entry = FileEntry.GetEntry(newPath);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private bool HandleException(Exception ex, string cbId="")
- {
- bool handled = false;
- string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
- if (ex is SecurityException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
- handled = true;
- }
- else if (ex is FileNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- else if (ex is ArgumentException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- handled = true;
- }
- else if (ex is IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- handled = true;
- }
- else if (ex is DirectoryNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- return handled;
- }
-
- private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
- {
- string path = File.AddSlashToDirectory(sourceDir);
-
- bool bExists = isoFile.DirectoryExists(destDir);
-
- if (!bExists)
- {
- isoFile.CreateDirectory(destDir);
- }
-
- destDir = File.AddSlashToDirectory(destDir);
-
- string[] files = isoFile.GetFileNames(path + "*");
-
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.CopyFile(path + file, destDir + file,true);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- CopyDirectory(path + dir, destDir + dir, isoFile);
- }
- }
- }
-
- private void GetFileOrDirectory(string options, bool getDirectory)
- {
- FileOptions fOptions = new FileOptions();
- string[] args = getOptionStrings(options);
-
- fOptions.FullPath = args[0];
- fOptions.Path = args[1];
-
- string callbackId = args[3];
-
- try
- {
- fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- try
- {
- if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string path;
-
- if (fOptions.Path.Split(':').Length > 2)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFile = isoFile.FileExists(path);
- bool isDirectory = isoFile.DirectoryExists(path);
- bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
- bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
- if (create)
- {
- if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
- return;
- }
-
- // need to make sure the parent exists
- // it is an error to create a directory whose immediate parent does not yet exist
- // see issue: https://issues.apache.org/jira/browse/CB-339
- string[] pathParts = path.Split('/');
- string builtPath = pathParts[0];
- for (int n = 1; n < pathParts.Length - 1; n++)
- {
- builtPath += "/" + pathParts[n];
- if (!isoFile.DirectoryExists(builtPath))
- {
- Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- }
-
- if ((getDirectory) && (!isDirectory))
- {
- isoFile.CreateDirectory(path);
- }
- else
- {
- if ((!getDirectory) && (!isFile))
- {
-
- IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
- fileStream.Close();
- }
- }
- }
- else // (not create)
- {
- if ((!isFile) && (!isDirectory))
- {
- if (path.IndexOf("//www") == 0)
- {
- Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
-
- //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
- //{
- // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
-
- //}
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- return;
- }
- if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
- return;
- }
- }
- FileEntry entry = FileEntry.GetEntry(path);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private static string AddSlashToDirectory(string dirPath)
- {
- if (dirPath.EndsWith("/"))
- {
- return dirPath;
- }
- else
- {
- return dirPath + "/";
- }
- }
-
- /// <summary>
- /// Returns file content in a form of base64 string
- /// </summary>
- /// <param name="stream">File stream</param>
- /// <returns>Base64 representation of the file</returns>
- private string GetFileContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
-
- #endregion
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/plugins/FileTransfer.cs b/plugins/FileTransfer.cs
deleted file mode 100644
index e585895..0000000
--- a/plugins/FileTransfer.cs
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Net;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Security;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class FileTransfer : BaseCommand
- {
- public class DownloadRequestState
- {
- // This class stores the State of the request.
- public HttpWebRequest request;
- public DownloadOptions options;
-
- public DownloadRequestState()
- {
- request = null;
- options = null;
- }
- }
-
- /// <summary>
- /// Boundary symbol
- /// </summary>
- private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
-
- // Error codes
- public const int FileNotFoundError = 1;
- public const int InvalidUrlError = 2;
- public const int ConnectionError = 3;
-
- /// <summary>
- /// Options for downloading file
- /// </summary>
- [DataContract]
- public class DownloadOptions
- {
- /// <summary>
- /// File path to download to
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address to the file to download
- /// </summary>
- [DataMember(Name = "url", IsRequired = true)]
- public string Url { get; set; }
- }
-
- /// <summary>
- /// Options for uploading file
- /// </summary>
- [DataContract]
- public class UploadOptions
- {
- /// <summary>
- /// File path to upload
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address
- /// </summary>
- [DataMember(Name = "server", IsRequired = true)]
- public string Server { get; set; }
-
- /// <summary>
- /// File key
- /// </summary>
- [DataMember(Name = "fileKey")]
- public string FileKey { get; set; }
-
- /// <summary>
- /// File name on the server
- /// </summary>
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- /// <summary>
- /// File Mime type
- /// </summary>
- [DataMember(Name = "mimeType")]
- public string MimeType { get; set; }
-
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "params")]
- public string Params { get; set; }
-
- /// <summary>
- /// Flag to recognize if we should trust every host (only in debug environments)
- /// </summary>
- [DataMember(Name = "debug")]
- public bool Debug { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public UploadOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.FileKey = "file";
- this.FileName = "image.jpg";
- this.MimeType = "image/jpeg";
- }
-
- }
-
- /// <summary>
- /// Uploading response info
- /// </summary>
- [DataContract]
- public class FileUploadResult
- {
- /// <summary>
- /// Amount of sent bytes
- /// </summary>
- [DataMember(Name = "bytesSent")]
- public long BytesSent { get; set; }
-
- /// <summary>
- /// Server response code
- /// </summary>
- [DataMember(Name = "responseCode")]
- public long ResponseCode { get; set; }
-
- /// <summary>
- /// Server response
- /// </summary>
- [DataMember(Name = "response", EmitDefaultValue = false)]
- public string Response { get; set; }
-
- /// <summary>
- /// Creates FileUploadResult object with response values
- /// </summary>
- /// <param name="bytesSent">Amount of sent bytes</param>
- /// <param name="responseCode">Server response code</param>
- /// <param name="response">Server response</param>
- public FileUploadResult(long bytesSent, long responseCode, string response)
- {
- this.BytesSent = bytesSent;
- this.ResponseCode = responseCode;
- this.Response = response;
- }
- }
-
- /// <summary>
- /// Represents transfer error codes for callback
- /// </summary>
- [DataContract]
- public class FileTransferError
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = true)]
- public int Code { get; set; }
-
- /// <summary>
- /// The source URI
- /// </summary>
- [DataMember(Name = "source", IsRequired = true)]
- public string Source { get; set; }
-
- /// <summary>
- /// The target URI
- /// </summary>
- [DataMember(Name = "target", IsRequired = true)]
- public string Target { get; set; }
-
- /// <summary>
- /// The http status code response from the remote URI
- /// </summary>
- [DataMember(Name = "http_status", IsRequired = true)]
- public int HttpStatus { get; set; }
-
- /// <summary>
- /// Creates FileTransferError object
- /// </summary>
- /// <param name="errorCode">Error code</param>
- public FileTransferError(int errorCode)
- {
- this.Code = errorCode;
- this.Source = null;
- this.Target = null;
- this.HttpStatus = 0;
- }
- public FileTransferError(int errorCode, string source, string target, int status)
- {
- this.Code = errorCode;
- this.Source = source;
- this.Target = target;
- this.HttpStatus = status;
- }
- }
-
- /// <summary>
- /// Upload options
- /// </summary>
- private UploadOptions uploadOptions;
-
- /// <summary>
- /// Bytes sent
- /// </summary>
- private long bytesSent;
-
- /// <summary>
- /// sends a file to a server
- /// </summary>
- /// <param name="options">Upload options</param>
- public void upload(string options)
- {
- Debug.WriteLine("options = " + options);
- options = options.Replace("{}", "null");
-
- try
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Uri serverUri;
- try
- {
- serverUri = new Uri(uploadOptions.Server);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
- return;
- }
- HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
- webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
- webRequest.Method = "POST";
- webRequest.BeginGetRequestStream(WriteCallback, webRequest);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
-
- public void download(string options)
- {
- DownloadOptions downloadOptions = null;
- HttpWebRequest webRequest = null;
-
- try
- {
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-
- downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
- downloadOptions.Url = optionStrings[0];
- downloadOptions.FilePath = optionStrings[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
- return;
- }
-
- if (downloadOptions != null && webRequest != null)
- {
- DownloadRequestState state = new DownloadRequestState();
- state.options = downloadOptions;
- state.request = webRequest;
- webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
- }
-
-
-
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void downloadCallback(IAsyncResult asynchronousResult)
- {
- DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
- HttpWebRequest request = reqState.request;
-
- try
- {
- HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(reqState.options.FilePath))
- {
- var file = isoFile.CreateFile(reqState.options.FilePath);
- file.Close();
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
- {
- long totalBytes = response.ContentLength;
- int bytesRead = 0;
- using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
- {
-
- using (BinaryWriter writer = new BinaryWriter(fileStream))
- {
- int BUFFER_SIZE = 1024;
- byte[] buffer;
-
- while (true)
- {
- buffer = reader.ReadBytes(BUFFER_SIZE);
- // fire a progress event ?
- bytesRead += buffer.Length;
- if (buffer.Length > 0)
- {
- writer.Write(buffer);
- }
- else
- {
- writer.Close();
- reader.Close();
- fileStream.Close();
- break;
- }
- }
- }
-
- }
-
-
- }
- }
- WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
- }
- catch (IsolatedStorageException)
- {
- // Trying to write the file somewhere within the IsoStorage.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (SecurityException)
- {
- // Trying to write the file somewhere not allowed.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (WebException webex)
- {
- // TODO: probably need better work here to properly respond with all http status codes back to JS
- // Right now am jumping through hoops just to detect 404.
- if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
- {
- // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
- // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
- // FACEPALM
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- }
-
-
-
- /// <summary>
- /// Read file from Isolated Storage and sends it to server
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void WriteCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
- {
- string lineStart = "--";
- string lineEnd = Environment.NewLine;
- byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
- string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
-
- if (uploadOptions.Params != null)
- {
-
- string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
-
- foreach (string param in arrParams)
- {
- string[] split = param.Split('=');
- string key = split[0];
- string val = split[1];
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- string formItem = string.Format(formdataTemplate, key, val);
- byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
- requestStream.Write(formItemBytes, 0, formItemBytes.Length);
- }
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(uploadOptions.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
- return;
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
- {
- string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
- string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
- byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- requestStream.Write(headerBytes, 0, headerBytes.Length);
- byte[] buffer = new byte[4096];
- int bytesRead = 0;
-
- while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
- {
- requestStream.Write(buffer, 0, bytesRead);
- bytesSent += bytesRead;
- }
- }
- byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
- requestStream.Write(endRequest, 0, endRequest.Length);
- }
- }
- webRequest.BeginGetResponse(ReadCallback, webRequest);
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- });
- }
- }
-
- /// <summary>
- /// Reads response into FileUploadResult
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void ReadCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
- {
- using (Stream streamResponse = response.GetResponseStream())
- {
- using (StreamReader streamReader = new StreamReader(streamResponse))
- {
- string responseString = streamReader.ReadToEnd();
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
- });
- }
- }
- }
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
- });
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/765c8158/plugins/GeoLocation.cs
----------------------------------------------------------------------
diff --git a/plugins/GeoLocation.cs b/plugins/GeoLocation.cs
deleted file mode 100644
index c53cb29..0000000
--- a/plugins/GeoLocation.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Device.Location;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
- /// </summary>
- public class GeoLocation
- {
- /* Unreachable code, by design -jm */
- private void triggerGeoInclusion()
- {
- new GeoCoordinateWatcher();
- }
- }
-}
[36/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/MimeTypeMapper.cs b/common/Plugins/MimeTypeMapper.cs
new file mode 100644
index 0000000..a2794f5
--- /dev/null
+++ b/common/Plugins/MimeTypeMapper.cs
@@ -0,0 +1,101 @@
+/*
+ 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.
+*/
+
+using System.Collections.Generic;
+using System.IO;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Represents file extension to mime type mapper.
+ /// </summary>
+ public static class MimeTypeMapper
+ {
+ /// <summary>
+ /// For unknown type it is recommended to use 'application/octet-stream'
+ /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
+ /// </summary>
+ private static string DefaultMimeType = "application/octet-stream";
+
+ /// <summary>
+ /// Stores mime type for all necessary extension
+ /// </summary>
+ private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
+ {
+ {"avi", "video/x-msvideo"},
+ {"bmp", "image/bmp"},
+ {"gif", "image/gif"},
+ {"html","text/html"},
+ {"jpe", "image/jpeg"},
+ {"jpeg", "image/jpeg"},
+ {"jpg", "image/jpeg"},
+ {"js","text/javascript"},
+ {"mov", "video/quicktime"},
+ {"mp2", "audio/mpeg"},
+ {"mp3", "audio/mpeg"},
+ {"mp4", "video/mp4"},
+ {"mpe", "video/mpeg"},
+ {"mpeg", "video/mpeg"},
+ {"mpg", "video/mpeg"},
+ {"mpga", "audio/mpeg"},
+ {"pbm", "image/x-portable-bitmap"},
+ {"pcm", "audio/x-pcm"},
+ {"pct", "image/pict"},
+ {"pgm", "image/x-portable-graymap"},
+ {"pic", "image/pict"},
+ {"pict", "image/pict"},
+ {"png", "image/png"},
+ {"pnm", "image/x-portable-anymap"},
+ {"pnt", "image/x-macpaint"},
+ {"pntg", "image/x-macpaint"},
+ {"ppm", "image/x-portable-pixmap"},
+ {"qt", "video/quicktime"},
+ {"ra", "audio/x-pn-realaudio"},
+ {"ram", "audio/x-pn-realaudio"},
+ {"ras", "image/x-cmu-raster"},
+ {"rgb", "image/x-rgb"},
+ {"snd", "audio/basic"},
+ {"txt", "text/plain"},
+ {"tif", "image/tiff"},
+ {"tiff", "image/tiff"},
+ {"wav", "audio/x-wav"},
+ {"wbmp", "image/vnd.wap.wbmp"},
+
+ };
+ /// <summary>
+ /// Gets mime type by file extension
+ /// </summary>
+ /// <param name="fileName">file name to extract extension</param>
+ /// <returns>mime type</returns>
+ public static string GetMimeType(string fileName)
+ {
+ string ext = Path.GetExtension(fileName);
+
+ // invalid extension
+ if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
+ {
+ return DefaultMimeType;
+ }
+
+ ext = ext.Remove(0, 1);
+
+ if (MIMETypesDictionary.ContainsKey(ext))
+ {
+ return MIMETypesDictionary[ext];
+ }
+
+ return DefaultMimeType;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/NetworkStatus.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/NetworkStatus.cs b/common/Plugins/NetworkStatus.cs
new file mode 100644
index 0000000..12eb061
--- /dev/null
+++ b/common/Plugins/NetworkStatus.cs
@@ -0,0 +1,129 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Diagnostics;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Net.NetworkInformation;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+ // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
+ // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
+
+ public class NetworkStatus : BaseCommand
+ {
+ const string UNKNOWN = "unknown";
+ const string ETHERNET = "ethernet";
+ const string WIFI = "wifi";
+ const string CELL_2G = "2g";
+ const string CELL_3G = "3g";
+ const string CELL_4G = "4g";
+ const string NONE = "none";
+ const string CELL = "cellular";
+
+ private bool HasCallback = false;
+
+ public NetworkStatus()
+ {
+ DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
+ }
+
+ public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
+ {
+ this.getConnectionInfo("");
+ }
+
+ public void getConnectionInfo(string empty)
+ {
+ HasCallback = true;
+ updateConnectionType(checkConnectionType());
+ }
+
+ private string checkConnectionType()
+ {
+ if (DeviceNetworkInformation.IsNetworkAvailable)
+ {
+ if (DeviceNetworkInformation.IsWiFiEnabled)
+ {
+ return WIFI;
+ }
+ else
+ {
+ return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
+ }
+ }
+ return NONE;
+ }
+
+ private string checkConnectionType(NetworkInterfaceSubType type)
+ {
+ switch (type)
+ {
+ case NetworkInterfaceSubType.Cellular_1XRTT: //cell
+ case NetworkInterfaceSubType.Cellular_GPRS: //cell
+ return CELL;
+ case NetworkInterfaceSubType.Cellular_EDGE: //2
+ return CELL_2G;
+ case NetworkInterfaceSubType.Cellular_3G:
+ case NetworkInterfaceSubType.Cellular_EVDO: //3
+ case NetworkInterfaceSubType.Cellular_EVDV: //3
+ case NetworkInterfaceSubType.Cellular_HSPA: //3
+ return CELL_3G;
+ case NetworkInterfaceSubType.WiFi:
+ return WIFI;
+ case NetworkInterfaceSubType.Unknown:
+ case NetworkInterfaceSubType.Desktop_PassThru:
+ default:
+ return UNKNOWN;
+ }
+ }
+
+ void ChangeDetected(object sender, NetworkNotificationEventArgs e)
+ {
+ switch (e.NotificationType)
+ {
+ case NetworkNotificationType.InterfaceConnected:
+ updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
+ break;
+ case NetworkNotificationType.InterfaceDisconnected:
+ updateConnectionType(NONE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void updateConnectionType(string type)
+ {
+ // This should also implicitly fire offline/online events as that is handled on the JS side
+ if (this.HasCallback)
+ {
+ PluginResult result = new PluginResult(PluginResult.Status.OK, type);
+ result.KeepCallback = true;
+ DispatchCommandResult(result);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Notification.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Notification.cs b/common/Plugins/Notification.cs
new file mode 100644
index 0000000..0759c72
--- /dev/null
+++ b/common/Plugins/Notification.cs
@@ -0,0 +1,361 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using Microsoft.Devices;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Windows.Resources;
+using Microsoft.Phone.Controls;
+using Microsoft.Xna.Framework.Audio;
+using WPCordovaClassLib.Cordova.UI;
+using System.Diagnostics;
+
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Notification : BaseCommand
+ {
+ static ProgressBar progressBar = null;
+ const int DEFAULT_DURATION = 5;
+
+ private NotificationBox notifyBox;
+
+ private PhoneApplicationPage Page
+ {
+ get
+ {
+ PhoneApplicationPage page = null;
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ page = frame.Content as PhoneApplicationPage;
+ }
+ return page;
+ }
+ }
+
+ // blink api - doesn't look like there is an equivalent api we can use...
+
+ [DataContract]
+ public class AlertOptions
+ {
+ [OnDeserializing]
+ public void OnDeserializing(StreamingContext context)
+ {
+ // set defaults
+ this.message = "message";
+ this.title = "Alert";
+ this.buttonLabel = "ok";
+ }
+
+ /// <summary>
+ /// message to display in the alert box
+ /// </summary>
+ [DataMember]
+ public string message;
+
+ /// <summary>
+ /// title displayed on the alert window
+ /// </summary>
+ [DataMember]
+ public string title;
+
+ /// <summary>
+ /// text to display on the button
+ /// </summary>
+ [DataMember]
+ public string buttonLabel;
+ }
+
+ public void alert(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ AlertOptions alertOpts = new AlertOptions();
+ alertOpts.message = args[0];
+ alertOpts.title = args[1];
+ alertOpts.buttonLabel = args[2];
+ string aliasCurrentCommandCallbackId = args[3];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = alertOpts.title;
+ notifyBox.SubTitle.Text = alertOpts.message;
+ Button btnOK = new Button();
+ btnOK.Content = alertOpts.buttonLabel;
+ btnOK.Click += new RoutedEventHandler(btnOK_Click);
+ btnOK.Tag = 1;
+ notifyBox.ButtonPanel.Children.Add(btnOK);
+ grid.Children.Add(notifyBox);
+
+ if (previous == null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ public void confirm(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ AlertOptions alertOpts = new AlertOptions();
+ alertOpts.message = args[0];
+ alertOpts.title = args[1];
+ alertOpts.buttonLabel = args[2];
+ string aliasCurrentCommandCallbackId = args[3];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = alertOpts.title;
+ notifyBox.SubTitle.Text = alertOpts.message;
+
+ string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
+
+ if (labels == null)
+ {
+ labels = alertOpts.buttonLabel.Split(',');
+ }
+
+ for (int n = 0; n < labels.Length; n++)
+ {
+ Button btn = new Button();
+ btn.Content = labels[n];
+ btn.Tag = n;
+ btn.Click += new RoutedEventHandler(btnOK_Click);
+ notifyBox.ButtonPanel.Children.Add(btn);
+ }
+
+ grid.Children.Add(notifyBox);
+ if (previous == null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ PhoneApplicationPage page = sender as PhoneApplicationPage;
+ string callbackId = "";
+ if (page != null && notifyBox != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(notifyBox);
+ dynamic notifBoxData = notifyBox.Tag;
+ notifyBox = notifBoxData.previous as NotificationBox;
+ callbackId = notifBoxData.callbackId as string;
+ }
+ if (notifyBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ e.Cancel = true;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
+ }
+
+ void btnOK_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ FrameworkElement notifBoxParent = null;
+ int retVal = 0;
+ string callbackId = "";
+ if (btn != null)
+ {
+ retVal = (int)btn.Tag + 1;
+
+ notifBoxParent = btn.Parent as FrameworkElement;
+ while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
+ !(notifBoxParent is NotificationBox)) ;
+ }
+ if (notifBoxParent != null)
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(notifBoxParent);
+ }
+
+ dynamic notifBoxData = notifBoxParent.Tag;
+ notifyBox = notifBoxData.previous as NotificationBox;
+ callbackId = notifBoxData.callbackId as string;
+
+ if (notifyBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ }
+
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
+ }
+
+
+
+ public void beep(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ int times = int.Parse(args[0]);
+
+ string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
+
+ StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
+
+ if (sri != null)
+ {
+ SoundEffect effect = SoundEffect.FromStream(sri.Stream);
+ SoundEffectInstance inst = effect.CreateInstance();
+ ThreadPool.QueueUserWorkItem((o) =>
+ {
+ // cannot interact with UI !!
+ do
+ {
+ inst.Play();
+ Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
+ }
+ while (--times > 0);
+
+ });
+
+ }
+
+ // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
+ DispatchCommandResult();
+ }
+
+ // Display an indeterminate progress indicator
+ public void activityStart(string unused)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+
+ if (page != null)
+ {
+ var temp = page.FindName("LayoutRoot");
+ Grid grid = temp as Grid;
+ if (grid != null)
+ {
+ if (progressBar != null)
+ {
+ grid.Children.Remove(progressBar);
+ }
+ progressBar = new ProgressBar();
+ progressBar.IsIndeterminate = true;
+ progressBar.IsEnabled = true;
+
+ grid.Children.Add(progressBar);
+ }
+ }
+ }
+ });
+ }
+
+
+ // Remove our indeterminate progress indicator
+ public void activityStop(string unused)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ if (progressBar != null)
+ {
+ progressBar.IsEnabled = false;
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(progressBar);
+ }
+ }
+ }
+ progressBar = null;
+ }
+ });
+ }
+
+ public void vibrate(string vibrateDuration)
+ {
+
+ int msecs = 200; // set default
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
+
+ msecs = int.Parse(args[0]);
+ if (msecs < 1)
+ {
+ msecs = 1;
+ }
+ }
+ catch (FormatException)
+ {
+
+ }
+
+ VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
+
+ // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
+ DispatchCommandResult();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/AudioCaptureTask.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/AudioCaptureTask.cs b/common/Plugins/UI/AudioCaptureTask.cs
new file mode 100644
index 0000000..3d7d60f
--- /dev/null
+++ b/common/Plugins/UI/AudioCaptureTask.cs
@@ -0,0 +1,107 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.Windows;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ /// <summary>
+ /// Allows an application to launch the Audio Recording application.
+ /// Use this to allow users to record audio from your application.
+ /// </summary>
+ public class AudioCaptureTask
+ {
+ /// <summary>
+ /// Represents recorded audio returned from a call to the Show method of
+ /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
+ /// </summary>
+ public class AudioResult : TaskEventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the AudioResult class.
+ /// </summary>
+ public AudioResult()
+ { }
+
+ /// <summary>
+ /// Initializes a new instance of the AudioResult class
+ /// with the specified Microsoft.Phone.Tasks.TaskResult.
+ /// </summary>
+ /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
+ public AudioResult(TaskResult taskResult)
+ : base(taskResult)
+ { }
+
+ /// <summary>
+ /// Gets the file name of the recorded audio.
+ /// </summary>
+ public Stream AudioFile { get; internal set; }
+
+ /// <summary>
+ /// Gets the stream containing the data for the recorded audio.
+ /// </summary>
+ public string AudioFileName { get; internal set; }
+ }
+
+ /// <summary>
+ /// Occurs when a audio recording task is completed.
+ /// </summary>
+ public event EventHandler<AudioResult> Completed;
+
+ /// <summary>
+ /// Shows Audio Recording application
+ /// </summary>
+ public void Show()
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ var root = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
+
+ string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
+ // dummy parameter is used to always open a fresh version
+ root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
+
+ });
+ }
+
+ /// <summary>
+ /// Performs additional configuration of the recording application.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (!(e.Content is AudioRecorder)) return;
+
+ (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
+
+ AudioRecorder audioRecorder = (AudioRecorder)e.Content;
+
+ if (audioRecorder != null)
+ {
+ audioRecorder.Completed += this.Completed;
+ }
+ else if (this.Completed != null)
+ {
+ this.Completed(this, new AudioResult(TaskResult.Cancel));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/AudioRecorder.xaml
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/AudioRecorder.xaml b/common/Plugins/UI/AudioRecorder.xaml
new file mode 100644
index 0000000..0fd26ab
--- /dev/null
+++ b/common/Plugins/UI/AudioRecorder.xaml
@@ -0,0 +1,66 @@
+<!--
+ 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.
+-->
+<phone:PhoneApplicationPage
+ x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
+ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ SupportedOrientations="Portrait" Orientation="Portrait"
+ mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
+ shell:SystemTray.IsVisible="True">
+
+ <!--LayoutRoot is the root grid where all page content is placed-->
+ <Grid x:Name="LayoutRoot" Background="Transparent">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ <!--TitlePanel contains the name of the application and page title-->
+ <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
+ <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
+ </StackPanel>
+
+ <!--ContentPanel - place additional content here-->
+ <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
+ <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0" VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
+ <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
+ <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
+ </Grid>
+ </Grid>
+
+ <!--Sample code showing usage of ApplicationBar-->
+ <!--<phone:PhoneApplicationPage.ApplicationBar>
+ <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
+ <shell:ApplicationBar.MenuItems>
+ <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
+ <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
+ </shell:ApplicationBar.MenuItems>
+ </shell:ApplicationBar>
+ </phone:PhoneApplicationPage.ApplicationBar>-->
+
+</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/AudioRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/AudioRecorder.xaml.cs b/common/Plugins/UI/AudioRecorder.xaml.cs
new file mode 100644
index 0000000..01a0832
--- /dev/null
+++ b/common/Plugins/UI/AudioRecorder.xaml.cs
@@ -0,0 +1,307 @@
+/*
+ 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.
+*/
+
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows;
+using System.Windows.Threading;
+using WPCordovaClassLib.Cordova.Commands;
+using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ /// <summary>
+ /// Implements Audio Recording application
+ /// </summary>
+ public partial class AudioRecorder : PhoneApplicationPage
+ {
+
+ #region Constants
+
+ private const string RecordingStartCaption = "Start";
+ private const string RecordingStopCaption = "Stop";
+
+ private const string LocalFolderName = "AudioCache";
+ private const string FileNameFormat = "Audio-{0}.wav";
+
+ #endregion
+
+ #region Callbacks
+
+ /// <summary>
+ /// Occurs when a audio recording task is completed.
+ /// </summary>
+ public event EventHandler<AudioResult> Completed;
+
+ #endregion
+
+ #region Fields
+
+ /// <summary>
+ /// Audio source
+ /// </summary>
+ private Microphone microphone;
+
+ /// <summary>
+ /// Temporary buffer to store audio chunk
+ /// </summary>
+ private byte[] buffer;
+
+ /// <summary>
+ /// Recording duration
+ /// </summary>
+ private TimeSpan duration;
+
+ /// <summary>
+ /// Output buffer
+ /// </summary>
+ private MemoryStream memoryStream;
+
+ /// <summary>
+ /// Xna game loop dispatcher
+ /// </summary>
+ DispatcherTimer dtXna;
+
+ /// <summary>
+ /// Recording result, dispatched back when recording page is closed
+ /// </summary>
+ private AudioResult result = new AudioResult(TaskResult.Cancel);
+
+ /// <summary>
+ /// Whether we are recording audio now
+ /// </summary>
+ private bool IsRecording
+ {
+ get
+ {
+ return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Creates new instance of the AudioRecorder class.
+ /// </summary>
+ public AudioRecorder()
+ {
+
+ this.InitializeXnaGameLoop();
+
+ // microphone requires special XNA initialization to work
+ InitializeComponent();
+ }
+
+ /// <summary>
+ /// Starts recording, data is stored in memory
+ /// </summary>
+ private void StartRecording()
+ {
+ this.microphone = Microphone.Default;
+ this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
+
+ this.btnTake.IsEnabled = false;
+ this.btnStartStop.Content = RecordingStopCaption;
+
+ this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
+ this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
+
+ this.memoryStream = new MemoryStream();
+ this.memoryStream.InitializeWavStream(this.microphone.SampleRate);
+
+ this.duration = new TimeSpan(0);
+
+ this.microphone.Start();
+ }
+
+ /// <summary>
+ /// Stops recording
+ /// </summary>
+ private void StopRecording()
+ {
+ this.microphone.Stop();
+
+ this.microphone.BufferReady -= MicrophoneBufferReady;
+
+ this.microphone = null;
+
+ btnStartStop.Content = RecordingStartCaption;
+
+ // check there is some data
+ this.btnTake.IsEnabled = true;
+ }
+
+ /// <summary>
+ /// Handles Start/Stop events
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void btnStartStop_Click(object sender, RoutedEventArgs e)
+ {
+
+ if (this.IsRecording)
+ {
+ this.StopRecording();
+ }
+ else
+ {
+ this.StartRecording();
+ }
+ }
+
+ /// <summary>
+ /// Handles Take button click
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void btnTake_Click(object sender, RoutedEventArgs e)
+ {
+ this.result = this.SaveAudioClipToLocalStorage();
+
+ if (Completed != null)
+ {
+ Completed(this, result);
+ }
+
+ if (this.NavigationService.CanGoBack)
+ {
+ this.NavigationService.GoBack();
+ }
+ }
+
+ /// <summary>
+ /// Handles page closing event, stops recording if needed and dispatches results.
+ /// </summary>
+ /// <param name="e"></param>
+ protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (IsRecording)
+ {
+ StopRecording();
+ }
+
+ this.FinalizeXnaGameLoop();
+
+ base.OnNavigatedFrom(e);
+ }
+
+ /// <summary>
+ /// Copies data from microphone to memory storages and updates recording state
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void MicrophoneBufferReady(object sender, EventArgs e)
+ {
+ this.microphone.GetData(this.buffer);
+ this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
+ TimeSpan bufferDuration = this.microphone.BufferDuration;
+
+ this.Dispatcher.BeginInvoke(() =>
+ {
+ this.duration += bufferDuration;
+
+ this.txtDuration.Text = "Duration: " +
+ this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
+ this.duration.Seconds.ToString().PadLeft(2, '0');
+ });
+
+ }
+
+ /// <summary>
+ /// Writes audio data from memory to isolated storage
+ /// </summary>
+ /// <returns></returns>
+ private AudioResult SaveAudioClipToLocalStorage()
+ {
+ if (this.memoryStream == null || this.memoryStream.Length <= 0)
+ {
+ return new AudioResult(TaskResult.Cancel);
+ }
+
+ this.memoryStream.UpdateWavStream();
+
+ // save audio data to local isolated storage
+
+ string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
+
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+
+ if (!isoFile.DirectoryExists(LocalFolderName))
+ {
+ isoFile.CreateDirectory(LocalFolderName);
+ }
+
+ string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
+
+ this.memoryStream.Seek(0, SeekOrigin.Begin);
+
+ using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
+ {
+
+ this.memoryStream.CopyTo(fileStream);
+ }
+
+ AudioResult result = new AudioResult(TaskResult.OK);
+ result.AudioFileName = filePath;
+
+ result.AudioFile = this.memoryStream;
+ result.AudioFile.Seek(0, SeekOrigin.Begin);
+
+ return result;
+ }
+
+
+
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Special initialization required for the microphone: XNA game loop
+ /// </summary>
+ private void InitializeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ this.dtXna = new DispatcherTimer();
+ this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
+ this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
+ this.dtXna.Start();
+ }
+ /// <summary>
+ /// Finalizes XNA game loop for microphone
+ /// </summary>
+ private void FinalizeXnaGameLoop()
+ {
+ // Timer to simulate the XNA game loop (Microphone is from XNA)
+ if (dtXna != null)
+ {
+ dtXna.Stop();
+ dtXna = null;
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/ImageCapture.xaml
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/ImageCapture.xaml b/common/Plugins/UI/ImageCapture.xaml
new file mode 100644
index 0000000..a7eee21
--- /dev/null
+++ b/common/Plugins/UI/ImageCapture.xaml
@@ -0,0 +1,26 @@
+<phone:PhoneApplicationPage
+ x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
+ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
+ mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
+ shell:SystemTray.IsVisible="True">
+
+ <!--LayoutRoot is the root grid where all page content is placed-->
+ <Grid x:Name="LayoutRoot" Background="Yellow">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ </Grid>
+
+
+</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/ImageCapture.xaml.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/ImageCapture.xaml.cs b/common/Plugins/UI/ImageCapture.xaml.cs
new file mode 100644
index 0000000..234b444
--- /dev/null
+++ b/common/Plugins/UI/ImageCapture.xaml.cs
@@ -0,0 +1,109 @@
+/*
+ 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.
+*/
+
+
+using System;
+using System.IO;
+using System.Windows;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class ImageCapture : PhoneApplicationPage
+ {
+ public ImageCapture()
+ {
+ InitializeComponent();
+ }
+ }
+
+ public class ImageCaptureTask
+ {
+ /// <summary>
+ /// Represents an image returned from a call to the Show method of
+ /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
+ /// </summary>
+ //public class AudioResult : TaskEventArgs
+ //{
+ // /// <summary>
+ // /// Initializes a new instance of the AudioResult class.
+ // /// </summary>
+ // public AudioResult()
+ // { }
+
+ // /// <summary>
+ // /// Initializes a new instance of the AudioResult class
+ // /// with the specified Microsoft.Phone.Tasks.TaskResult.
+ // /// </summary>
+ // /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
+ // public AudioResult(TaskResult taskResult)
+ // : base(taskResult)
+ // { }
+
+ // /// <summary>
+ // /// Gets the file name of the recorded audio.
+ // /// </summary>
+ // public Stream AudioFile { get; internal set; }
+
+ // /// <summary>
+ // /// Gets the stream containing the data for the recorded audio.
+ // /// </summary>
+ // public string AudioFileName { get; internal set; }
+ //}
+
+ ///// <summary>
+ ///// Occurs when a audio recording task is completed.
+ ///// </summary>
+ //public event EventHandler<AudioResult> Completed;
+
+ /// <summary>
+ /// Shows Audio Recording application
+ /// </summary>
+ public void Show()
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ var root = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
+
+ string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
+
+ // dummy parameter is used to always open a fresh version
+ root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
+ });
+ }
+
+ /// <summary>
+ /// Performs additional configuration of the recording application.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ ImageCapture imageCapture = e.Content as ImageCapture;
+ if (imageCapture != null)
+ {
+ (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
+
+ //imageCapture.Completed += this.Completed;
+ //else if (this.Completed != null)
+ //{
+ // this.Completed(this, new AudioResult(TaskResult.Cancel));
+ //}
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/NotificationBox.xaml
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/NotificationBox.xaml b/common/Plugins/UI/NotificationBox.xaml
new file mode 100644
index 0000000..1ca5d5f
--- /dev/null
+++ b/common/Plugins/UI/NotificationBox.xaml
@@ -0,0 +1,62 @@
+<!--
+ 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.
+-->
+<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
+
+ <Grid x:Name="LayoutRoot"
+ Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+
+ <!--TitlePanel contains the name of the application and page title-->
+ <StackPanel x:Name="TitlePanel"
+ Grid.Row="0"
+ Background="{StaticResource PhoneSemitransparentBrush}">
+ <TextBlock x:Name="PageTitle"
+ Text="Title"
+ Margin="10,10"
+ Style="{StaticResource PhoneTextTitle2Style}"/>
+
+ <TextBlock x:Name="SubTitle"
+ Text="Subtitle"
+ TextWrapping="Wrap"
+ Margin="10,10"
+ Style="{StaticResource PhoneTextTitle3Style}"/>
+
+ <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
+ <StackPanel x:Name="ButtonPanel"
+ Margin="10,10"
+ Orientation="Horizontal"/>
+ </ScrollViewer>
+
+ </StackPanel>
+ </Grid>
+</UserControl>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/NotificationBox.xaml.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/NotificationBox.xaml.cs b/common/Plugins/UI/NotificationBox.xaml.cs
new file mode 100644
index 0000000..50b2f2a
--- /dev/null
+++ b/common/Plugins/UI/NotificationBox.xaml.cs
@@ -0,0 +1,41 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class NotificationBox : UserControl
+ {
+ public NotificationBox()
+ {
+ InitializeComponent();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/VideoCaptureTask.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/VideoCaptureTask.cs b/common/Plugins/UI/VideoCaptureTask.cs
new file mode 100644
index 0000000..958c05c
--- /dev/null
+++ b/common/Plugins/UI/VideoCaptureTask.cs
@@ -0,0 +1,105 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.Windows;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Tasks;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ /// <summary>
+ /// Allows an application to launch the Video Recording application.
+ /// Use this to allow users to record video from your application.
+ /// </summary>
+ public class VideoCaptureTask
+ {
+ /// <summary>
+ /// Represents recorded video returned from a call to the Show method of
+ /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
+ /// </summary>
+ public class VideoResult : TaskEventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the VideoResult class.
+ /// </summary>
+ public VideoResult()
+ { }
+
+ /// <summary>
+ /// Initializes a new instance of the VideoResult class
+ /// with the specified Microsoft.Phone.Tasks.TaskResult.
+ /// </summary>
+ /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
+ public VideoResult(TaskResult taskResult)
+ : base(taskResult)
+ { }
+
+ /// <summary>
+ /// Gets the file name of the recorded Video.
+ /// </summary>
+ public Stream VideoFile { get; internal set; }
+
+ /// <summary>
+ /// Gets the stream containing the data for the recorded Video.
+ /// </summary>
+ public string VideoFileName { get; internal set; }
+ }
+
+ /// <summary>
+ /// Occurs when a Video recording task is completed.
+ /// </summary>
+ public event EventHandler<VideoResult> Completed;
+
+ /// <summary>
+ /// Shows Video Recording application
+ /// </summary>
+ public void Show()
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ var root = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
+
+ string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
+ // dummy parameter is used to always open a fresh version
+ root.Navigate(new System.Uri( baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
+ });
+ }
+
+ /// <summary>
+ /// Performs additional configuration of the recording application.
+ /// </summary>
+ private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ if (!(e.Content is VideoRecorder)) return;
+
+ (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
+
+ VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
+
+ if (VideoRecorder != null)
+ {
+ VideoRecorder.Completed += this.Completed;
+ }
+ else if (this.Completed != null)
+ {
+ this.Completed(this, new VideoResult(TaskResult.Cancel));
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/VideoRecorder.xaml
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/VideoRecorder.xaml b/common/Plugins/UI/VideoRecorder.xaml
new file mode 100644
index 0000000..c78fdb0
--- /dev/null
+++ b/common/Plugins/UI/VideoRecorder.xaml
@@ -0,0 +1,52 @@
+<!--
+ 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.
+-->
+<phone:PhoneApplicationPage
+ x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
+ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ SupportedOrientations="Landscape" Orientation="LandscapeLeft"
+ shell:SystemTray.IsVisible="False">
+
+ <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
+
+ <Rectangle
+ x:Name="viewfinderRectangle"
+ Width="640"
+ Height="480"
+ HorizontalAlignment="Left"
+ Canvas.Left="80"/>
+
+ </Canvas>
+
+ <phone:PhoneApplicationPage.ApplicationBar>
+ <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record" x:Name="btnStartRecording" Click="StartRecording_Click" />
+ <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>
+ </shell:ApplicationBar>
+ </phone:PhoneApplicationPage.ApplicationBar>
+
+</phone:PhoneApplicationPage>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/UI/VideoRecorder.xaml.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/UI/VideoRecorder.xaml.cs b/common/Plugins/UI/VideoRecorder.xaml.cs
new file mode 100644
index 0000000..6ab1cc3
--- /dev/null
+++ b/common/Plugins/UI/VideoRecorder.xaml.cs
@@ -0,0 +1,405 @@
+/*
+ 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.
+*/
+
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows.Media;
+using System.Windows.Navigation;
+using Microsoft.Phone.Controls;
+using Microsoft.Phone.Shell;
+using Microsoft.Phone.Tasks;
+using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class VideoRecorder : PhoneApplicationPage
+ {
+
+ #region Constants
+
+ /// <summary>
+ /// Caption for record button in ready state
+ /// </summary>
+ private const string RecordingStartCaption = "Record";
+
+ /// <summary>
+ /// Caption for record button in recording state
+ /// </summary>
+ private const string RecordingStopCaption = "Stop";
+
+ /// <summary>
+ /// Start record icon URI
+ /// </summary>
+ private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
+
+ /// <summary>
+ /// Stop record icon URI
+ /// </summary>
+ private const string StopIconUri = "/Images/appbar.stop.rest.png";
+
+ /// <summary>
+ /// Folder to save video clips
+ /// </summary>
+ private const string LocalFolderName = "VideoCache";
+
+ /// <summary>
+ /// File name format
+ /// </summary>
+ private const string FileNameFormat = "Video-{0}.mp4";
+
+ /// <summary>
+ /// Temporary file name
+ /// </summary>
+ private const string defaultFileName = "NewVideoFile.mp4";
+
+ #endregion
+
+ #region Callbacks
+ /// <summary>
+ /// Occurs when a video recording task is completed.
+ /// </summary>
+ public event EventHandler<VideoResult> Completed;
+
+ #endregion
+
+ #region Fields
+
+ /// <summary>
+ /// Viewfinder for capturing video
+ /// </summary>
+ private VideoBrush videoRecorderBrush;
+
+ /// <summary>
+ /// Path to save video clip
+ /// </summary>
+ private string filePath;
+
+ /// <summary>
+ /// Source for capturing video.
+ /// </summary>
+ private CaptureSource captureSource;
+
+ /// <summary>
+ /// Video device
+ /// </summary>
+ private VideoCaptureDevice videoCaptureDevice;
+
+ /// <summary>
+ /// File sink so save recording video in Isolated Storage
+ /// </summary>
+ private FileSink fileSink;
+
+ /// <summary>
+ /// For managing button and application state
+ /// </summary>
+ private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
+
+ /// <summary>
+ /// Current video state
+ /// </summary>
+ private VideoState currentVideoState;
+
+ /// <summary>
+ /// Stream to return result
+ /// </summary>
+ private MemoryStream memoryStream;
+
+ /// <summary>
+ /// Recording result, dispatched back when recording page is closed
+ /// </summary>
+ private VideoResult result = new VideoResult(TaskResult.Cancel);
+
+ #endregion
+
+ /// <summary>
+ /// Initializes components
+ /// </summary>
+ public VideoRecorder()
+ {
+ InitializeComponent();
+
+ PhoneAppBar = (ApplicationBar)ApplicationBar;
+ PhoneAppBar.IsVisible = true;
+ btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
+ btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
+ }
+
+ /// <summary>
+ /// Initializes the video recorder then page is loading
+ /// </summary>
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ base.OnNavigatedTo(e);
+ this.InitializeVideoRecorder();
+ }
+
+ /// <summary>
+ /// Disposes camera and media objects then leave the page
+ /// </summary>
+ protected override void OnNavigatedFrom(NavigationEventArgs e)
+ {
+ this.DisposeVideoRecorder();
+
+ if (this.Completed != null)
+ {
+ this.Completed(this, result);
+ }
+ base.OnNavigatedFrom(e);
+ }
+
+ /// <summary>
+ /// Handles TakeVideo button click
+ /// </summary>
+ private void TakeVideo_Click(object sender, EventArgs e)
+ {
+ this.result = this.SaveVideoClip();
+ this.NavigateBack();
+ }
+
+ private void NavigateBack()
+ {
+ if (this.NavigationService.CanGoBack)
+ {
+ this.NavigationService.GoBack();
+ }
+ }
+
+ /// <summary>
+ /// Resaves video clip from temporary directory to persistent
+ /// </summary>
+ private VideoResult SaveVideoClip()
+ {
+ try
+ {
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
+ {
+ return new VideoResult(TaskResult.Cancel);
+ }
+
+ string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
+ string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
+ isoFile.CopyFile(filePath, newPath);
+ isoFile.DeleteFile(filePath);
+
+ memoryStream = new MemoryStream();
+ using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
+ {
+ fileStream.CopyTo(memoryStream);
+ }
+
+ VideoResult result = new VideoResult(TaskResult.OK);
+ result.VideoFileName = newPath;
+ result.VideoFile = this.memoryStream;
+ result.VideoFile.Seek(0, SeekOrigin.Begin);
+ return result;
+ }
+
+ }
+ catch (Exception)
+ {
+ return new VideoResult(TaskResult.None);
+ }
+ }
+
+ /// <summary>
+ /// Updates the buttons on the UI thread based on current state.
+ /// </summary>
+ /// <param name="currentState">current UI state</param>
+ private void UpdateUI(VideoState currentState)
+ {
+ Dispatcher.BeginInvoke(delegate
+ {
+ switch (currentState)
+ {
+ case VideoState.CameraNotSupported:
+ btnStartRecording.IsEnabled = false;
+ btnTakeVideo.IsEnabled = false;
+ break;
+
+ case VideoState.Initialized:
+ btnStartRecording.Text = RecordingStartCaption;
+ btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
+ btnTakeVideo.IsEnabled = false;
+ break;
+
+ case VideoState.Ready:
+ btnStartRecording.Text = RecordingStartCaption;
+ btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
+ btnTakeVideo.IsEnabled = true;
+ break;
+
+ case VideoState.Recording:
+ btnStartRecording.Text = RecordingStopCaption;
+ btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
+ btnTakeVideo.IsEnabled = false;
+ break;
+
+ default:
+ break;
+ }
+ currentVideoState = currentState;
+ });
+ }
+
+ /// <summary>
+ /// Initializes VideoRecorder
+ /// </summary>
+ public void InitializeVideoRecorder()
+ {
+ if (captureSource == null)
+ {
+ captureSource = new CaptureSource();
+ fileSink = new FileSink();
+ videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
+
+ if (videoCaptureDevice != null)
+ {
+ videoRecorderBrush = new VideoBrush();
+ videoRecorderBrush.SetSource(captureSource);
+ viewfinderRectangle.Fill = videoRecorderBrush;
+ captureSource.Start();
+ this.UpdateUI(VideoState.Initialized);
+ }
+ else
+ {
+ this.UpdateUI(VideoState.CameraNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets recording state: start recording
+ /// </summary>
+ private void StartVideoRecording()
+ {
+ try
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
+ {
+ captureSource.Stop();
+ fileSink.CaptureSource = captureSource;
+ filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
+
+ using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!isoFile.DirectoryExists(LocalFolderName))
+ {
+ isoFile.CreateDirectory(LocalFolderName);
+ }
+
+ if (isoFile.FileExists(filePath))
+ {
+ isoFile.DeleteFile(filePath);
+ }
+ }
+
+ fileSink.IsolatedStorageFileName = filePath;
+ }
+
+ if (captureSource.VideoCaptureDevice != null
+ && captureSource.State == CaptureState.Stopped)
+ {
+ captureSource.Start();
+ }
+ this.UpdateUI(VideoState.Recording);
+ }
+ catch (Exception)
+ {
+ this.result = new VideoResult(TaskResult.None);
+ this.NavigateBack();
+ }
+ }
+
+ /// <summary>
+ /// Sets the recording state: stop recording
+ /// </summary>
+ private void StopVideoRecording()
+ {
+ try
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
+ {
+ captureSource.Stop();
+ fileSink.CaptureSource = null;
+ fileSink.IsolatedStorageFileName = null;
+ this.StartVideoPreview();
+ }
+ }
+ catch (Exception)
+ {
+ this.result = new VideoResult(TaskResult.None);
+ this.NavigateBack();
+ }
+ }
+
+ /// <summary>
+ /// Sets the recording state: display the video on the viewfinder.
+ /// </summary>
+ private void StartVideoPreview()
+ {
+ try
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
+ {
+ videoRecorderBrush.SetSource(captureSource);
+ viewfinderRectangle.Fill = videoRecorderBrush;
+ captureSource.Start();
+ this.UpdateUI(VideoState.Ready);
+ }
+ }
+ catch (Exception)
+ {
+ this.result = new VideoResult(TaskResult.None);
+ this.NavigateBack();
+ }
+ }
+
+ /// <summary>
+ /// Starts video recording
+ /// </summary>
+ private void StartRecording_Click(object sender, EventArgs e)
+ {
+ if (currentVideoState == VideoState.Recording)
+ {
+ this.StopVideoRecording();
+ }
+ else
+ {
+ this.StartVideoRecording();
+ }
+ }
+
+ /// <summary>
+ /// Releases resources
+ /// </summary>
+ private void DisposeVideoRecorder()
+ {
+ if (captureSource != null)
+ {
+ if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
+ {
+ captureSource.Stop();
+ }
+ captureSource = null;
+ videoCaptureDevice = null;
+ fileSink = null;
+ videoRecorderBrush = null;
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/SplashScreenImage.jpg
----------------------------------------------------------------------
diff --git a/common/SplashScreenImage.jpg b/common/SplashScreenImage.jpg
new file mode 100644
index 0000000..d35501d
Binary files /dev/null and b/common/SplashScreenImage.jpg differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/__PreviewImage.jpg
----------------------------------------------------------------------
diff --git a/common/__PreviewImage.jpg b/common/__PreviewImage.jpg
new file mode 100644
index 0000000..1d72941
Binary files /dev/null and b/common/__PreviewImage.jpg differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/__TemplateIcon.png
----------------------------------------------------------------------
diff --git a/common/__TemplateIcon.png b/common/__TemplateIcon.png
new file mode 100644
index 0000000..75c17c7
Binary files /dev/null and b/common/__TemplateIcon.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/resources/notification-beep.wav
----------------------------------------------------------------------
diff --git a/common/resources/notification-beep.wav b/common/resources/notification-beep.wav
new file mode 100644
index 0000000..d0ad085
Binary files /dev/null and b/common/resources/notification-beep.wav differ
[20/50] [abbrv] moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/www/css/index.css
----------------------------------------------------------------------
diff --git a/common-items/www/css/index.css b/common-items/www/css/index.css
new file mode 100644
index 0000000..f1f9d76
--- /dev/null
+++ b/common-items/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+* {
+ -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
+ -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
+ -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+ -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
+}
+
+body {
+ background-color:#E4E4E4;
+ background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ color-stop(0, #A7A7A7),
+ color-stop(0.51, #E4E4E4)
+ );
+ background-attachment:fixed;
+ font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+ font-size:12px;
+ height:100%;
+ margin:0px;
+ padding:0px;
+ text-transform:uppercase;
+ width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+ background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+ position:absolute; /* position in the center of the screen */
+ left:50%;
+ top:50%;
+ height:50px; /* text area height */
+ width:225px; /* text area width */
+ text-align:center;
+ padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
+ margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
+ /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+ .app {
+ background-position:left center;
+ padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
+ margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
+ /* offset horizontal: half of image width and text area width */
+ }
+}
+
+h1 {
+ font-size:24px;
+ font-weight:normal;
+ margin:0px;
+ overflow:visible;
+ padding:0px;
+ text-align:center;
+}
+
+.event {
+ border-radius:4px;
+ -webkit-border-radius:4px;
+ color:#FFFFFF;
+ font-size:12px;
+ margin:0px 30px;
+ padding:2px 0px;
+}
+
+.event.listening {
+ background-color:#333333;
+ display:block;
+}
+
+.event.received {
+ background-color:#4B946A;
+ display:none;
+}
+
+@keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+@-webkit-keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+.blink {
+ animation:fade 3000ms infinite;
+ -webkit-animation:fade 3000ms infinite;
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/www/img/logo.png
----------------------------------------------------------------------
diff --git a/common-items/www/img/logo.png b/common-items/www/img/logo.png
new file mode 100644
index 0000000..9519e7d
Binary files /dev/null and b/common-items/www/img/logo.png differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/www/index.html
----------------------------------------------------------------------
diff --git a/common-items/www/index.html b/common-items/www/index.html
new file mode 100644
index 0000000..842b364
--- /dev/null
+++ b/common-items/www/index.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="format-detection" content="telephone=no" />
+ <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+ <link rel="stylesheet" type="text/css" href="css/index.css" />
+ <title>Hello World</title>
+ </head>
+ <body>
+ <div class="app">
+ <h1>Apache Cordova</h1>
+ <div id="deviceready" class="blink">
+ <p class="event listening">Connecting to Device</p>
+ <p class="event received">Device is Ready</p>
+ </div>
+ </div>
+ <script type="text/javascript" src="cordova.js"></script>
+ <script type="text/javascript" src="js/index.js"></script>
+ <script type="text/javascript">
+ app.initialize();
+ </script>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/common-items/www/js/index.js
----------------------------------------------------------------------
diff --git a/common-items/www/js/index.js b/common-items/www/js/index.js
new file mode 100644
index 0000000..3b75d3f
--- /dev/null
+++ b/common-items/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * 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 app = {
+ // Application Constructor
+ initialize: function() {
+ this.bindEvents();
+ },
+ // Bind Event Listeners
+ //
+ // Bind any events that are required on startup. Common events are:
+ // `load`, `deviceready`, `offline`, and `online`.
+ bindEvents: function() {
+ document.addEventListener('deviceready', this.onDeviceReady, false);
+ },
+ // deviceready Event Handler
+ //
+ // The scope of `this` is the event. In order to call the `receivedEvent`
+ // function, we must explicity call `app.receivedEvent(...);`
+ onDeviceReady: function() {
+ app.receivedEvent('deviceready');
+ },
+ // Update DOM on a Received Event
+ receivedEvent: function(id) {
+ var parentElement = document.getElementById(id);
+ var listeningElement = parentElement.querySelector('.listening');
+ var receivedElement = parentElement.querySelector('.received');
+
+ listeningElement.setAttribute('style', 'display:none;');
+ receivedElement.setAttribute('style', 'display:block;');
+
+ console.log('Received Event: ' + id);
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/ApplicationIcon.png
----------------------------------------------------------------------
diff --git a/wp7/template/ApplicationIcon.png b/wp7/template/ApplicationIcon.png
deleted file mode 100644
index 6b69046..0000000
Binary files a/wp7/template/ApplicationIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Background.png
----------------------------------------------------------------------
diff --git a/wp7/template/Background.png b/wp7/template/Background.png
deleted file mode 100644
index 2667df4..0000000
Binary files a/wp7/template/Background.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Images/appbar.back.rest.png
----------------------------------------------------------------------
diff --git a/wp7/template/Images/appbar.back.rest.png b/wp7/template/Images/appbar.back.rest.png
deleted file mode 100644
index 4bc2b92..0000000
Binary files a/wp7/template/Images/appbar.back.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Images/appbar.close.rest.png
----------------------------------------------------------------------
diff --git a/wp7/template/Images/appbar.close.rest.png b/wp7/template/Images/appbar.close.rest.png
deleted file mode 100644
index 8166a1c..0000000
Binary files a/wp7/template/Images/appbar.close.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Images/appbar.feature.video.rest.png
----------------------------------------------------------------------
diff --git a/wp7/template/Images/appbar.feature.video.rest.png b/wp7/template/Images/appbar.feature.video.rest.png
deleted file mode 100644
index baff565..0000000
Binary files a/wp7/template/Images/appbar.feature.video.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Images/appbar.next.rest.png
----------------------------------------------------------------------
diff --git a/wp7/template/Images/appbar.next.rest.png b/wp7/template/Images/appbar.next.rest.png
deleted file mode 100644
index ed577d7..0000000
Binary files a/wp7/template/Images/appbar.next.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Images/appbar.save.rest.png
----------------------------------------------------------------------
diff --git a/wp7/template/Images/appbar.save.rest.png b/wp7/template/Images/appbar.save.rest.png
deleted file mode 100644
index d49940e..0000000
Binary files a/wp7/template/Images/appbar.save.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/Images/appbar.stop.rest.png
----------------------------------------------------------------------
diff --git a/wp7/template/Images/appbar.stop.rest.png b/wp7/template/Images/appbar.stop.rest.png
deleted file mode 100644
index 4dd724f..0000000
Binary files a/wp7/template/Images/appbar.stop.rest.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/MyTemplate.vstemplate
----------------------------------------------------------------------
diff --git a/wp7/template/MyTemplate.vstemplate b/wp7/template/MyTemplate.vstemplate
index 7f28665..27d6100 100644
--- a/wp7/template/MyTemplate.vstemplate
+++ b/wp7/template/MyTemplate.vstemplate
@@ -1,13 +1,19 @@
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
<TemplateData>
- <Name>CordovaWP7_0_0_0</Name>
+ <Name>CordovaWP7_2_9_0rc1
+
+
+</Name>
<Description>Starter project for building a Cordova app for Windows Phone version: 0.0.0</Description>
<ProjectType>CSharp</ProjectType>
<ProjectSubType>
</ProjectSubType>
<SortOrder>1000</SortOrder>
<CreateNewFolder>true</CreateNewFolder>
- <DefaultName>CordovaWP7_0_0_0</DefaultName>
+ <DefaultName>CordovaWP7_2_9_0rc1
+
+
+</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<LocationField>Enabled</LocationField>
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/SplashScreenImage.jpg
----------------------------------------------------------------------
diff --git a/wp7/template/SplashScreenImage.jpg b/wp7/template/SplashScreenImage.jpg
deleted file mode 100644
index d35501d..0000000
Binary files a/wp7/template/SplashScreenImage.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/VERSION
----------------------------------------------------------------------
diff --git a/wp7/template/VERSION b/wp7/template/VERSION
deleted file mode 100644
index bd52db8..0000000
--- a/wp7/template/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.0.0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/__PreviewImage.jpg
----------------------------------------------------------------------
diff --git a/wp7/template/__PreviewImage.jpg b/wp7/template/__PreviewImage.jpg
deleted file mode 100644
index 1d72941..0000000
Binary files a/wp7/template/__PreviewImage.jpg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/__TemplateIcon.png
----------------------------------------------------------------------
diff --git a/wp7/template/__TemplateIcon.png b/wp7/template/__TemplateIcon.png
deleted file mode 100644
index 75c17c7..0000000
Binary files a/wp7/template/__TemplateIcon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp7/template/resources/notification-beep.wav
----------------------------------------------------------------------
diff --git a/wp7/template/resources/notification-beep.wav b/wp7/template/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
Binary files a/wp7/template/resources/notification-beep.wav and /dev/null differ
[39/50] [abbrv] renamed common-items to just common
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Capture.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Capture.cs b/common/Plugins/Capture.cs
new file mode 100644
index 0000000..5e14a16
--- /dev/null
+++ b/common/Plugins/Capture.cs
@@ -0,0 +1,736 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Runtime.Serialization;
+using System.Windows.Media.Imaging;
+using Microsoft.Phone;
+using Microsoft.Phone.Tasks;
+using Microsoft.Xna.Framework.Media;
+using WPCordovaClassLib.Cordova.UI;
+using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
+using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
+using System.Windows;
+using System.Diagnostics;
+using Microsoft.Phone.Controls;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// Provides access to the audio, image, and video capture capabilities of the device
+ /// </summary>
+ public class Capture : BaseCommand
+ {
+ #region Internal classes (options and resultant objects)
+
+ /// <summary>
+ /// Represents captureImage action options.
+ /// </summary>
+ [DataContract]
+ public class CaptureImageOptions
+ {
+ /// <summary>
+ /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "limit")]
+ public int Limit { get; set; }
+
+ public static CaptureImageOptions Default
+ {
+ get { return new CaptureImageOptions() { Limit = 1 }; }
+ }
+ }
+
+ /// <summary>
+ /// Represents captureAudio action options.
+ /// </summary>
+ [DataContract]
+ public class CaptureAudioOptions
+ {
+ /// <summary>
+ /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "limit")]
+ public int Limit { get; set; }
+
+ public static CaptureAudioOptions Default
+ {
+ get { return new CaptureAudioOptions() { Limit = 1 }; }
+ }
+ }
+
+ /// <summary>
+ /// Represents captureVideo action options.
+ /// </summary>
+ [DataContract]
+ public class CaptureVideoOptions
+ {
+ /// <summary>
+ /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "limit")]
+ public int Limit { get; set; }
+
+ public static CaptureVideoOptions Default
+ {
+ get { return new CaptureVideoOptions() { Limit = 1 }; }
+ }
+ }
+
+ /// <summary>
+ /// Represents getFormatData action options.
+ /// </summary>
+ [DataContract]
+ public class MediaFormatOptions
+ {
+ /// <summary>
+ /// File path
+ /// </summary>
+ [DataMember(IsRequired = true, Name = "fullPath")]
+ public string FullPath { get; set; }
+
+ /// <summary>
+ /// File mime type
+ /// </summary>
+ [DataMember(Name = "type")]
+ public string Type { get; set; }
+
+ }
+
+ /// <summary>
+ /// Stores image info
+ /// </summary>
+ [DataContract]
+ public class MediaFile
+ {
+
+ [DataMember(Name = "name")]
+ public string FileName { get; set; }
+
+ [DataMember(Name = "fullPath")]
+ public string FilePath { get; set; }
+
+ [DataMember(Name = "type")]
+ public string Type { get; set; }
+
+ [DataMember(Name = "lastModifiedDate")]
+ public string LastModifiedDate { get; set; }
+
+ [DataMember(Name = "size")]
+ public long Size { get; set; }
+
+ public MediaFile(string filePath, Picture image)
+ {
+ this.FilePath = filePath;
+ this.FileName = System.IO.Path.GetFileName(this.FilePath);
+ this.Type = MimeTypeMapper.GetMimeType(FileName);
+ this.Size = image.GetImage().Length;
+
+ using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
+ }
+
+ }
+
+ public MediaFile(string filePath, Stream stream)
+ {
+ this.FilePath = filePath;
+ this.FileName = System.IO.Path.GetFileName(this.FilePath);
+ this.Type = MimeTypeMapper.GetMimeType(FileName);
+ this.Size = stream.Length;
+
+ using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Stores additional media file data
+ /// </summary>
+ [DataContract]
+ public class MediaFileData
+ {
+ [DataMember(Name = "height")]
+ public int Height { get; set; }
+
+ [DataMember(Name = "width")]
+ public int Width { get; set; }
+
+ [DataMember(Name = "bitrate")]
+ public int Bitrate { get; set; }
+
+ [DataMember(Name = "duration")]
+ public int Duration { get; set; }
+
+ [DataMember(Name = "codecs")]
+ public string Codecs { get; set; }
+
+ public MediaFileData(WriteableBitmap image)
+ {
+ this.Height = image.PixelHeight;
+ this.Width = image.PixelWidth;
+ this.Bitrate = 0;
+ this.Duration = 0;
+ this.Codecs = "";
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Folder to store captured images
+ /// </summary>
+ private string isoFolder = "CapturedImagesCache";
+
+ /// <summary>
+ /// Capture Image options
+ /// </summary>
+ protected CaptureImageOptions captureImageOptions;
+
+ /// <summary>
+ /// Capture Audio options
+ /// </summary>
+ protected CaptureAudioOptions captureAudioOptions;
+
+ /// <summary>
+ /// Capture Video options
+ /// </summary>
+ protected CaptureVideoOptions captureVideoOptions;
+
+ /// <summary>
+ /// Used to open camera application
+ /// </summary>
+ private CameraCaptureTask cameraTask;
+
+ /// <summary>
+ /// Used for audio recording
+ /// </summary>
+ private AudioCaptureTask audioCaptureTask;
+
+ /// <summary>
+ /// Used for video recording
+ /// </summary>
+ private VideoCaptureTask videoCaptureTask;
+
+ /// <summary>
+ /// Stores information about captured files
+ /// </summary>
+ List<MediaFile> files = new List<MediaFile>();
+
+ /// <summary>
+ /// Launches default camera application to capture image
+ /// </summary>
+ /// <param name="options">may contains limit or mode parameters</param>
+ public void captureImage(string options)
+ {
+ try
+ {
+ try
+ {
+
+ string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+
+ cameraTask = new CameraCaptureTask();
+ cameraTask.Completed += this.cameraTask_Completed;
+ cameraTask.Show();
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Launches our own audio recording control to capture audio
+ /// </summary>
+ /// <param name="options">may contains additional parameters</param>
+ public void captureAudio(string options)
+ {
+ try
+ {
+ try
+ {
+ string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ audioCaptureTask = new AudioCaptureTask();
+ audioCaptureTask.Completed += audioRecordingTask_Completed;
+ audioCaptureTask.Show();
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Launches our own video recording control to capture video
+ /// </summary>
+ /// <param name="options">may contains additional parameters</param>
+ public void captureVideo(string options)
+ {
+ try
+ {
+ try
+ {
+ string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+ this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ videoCaptureTask = new VideoCaptureTask();
+ videoCaptureTask.Completed += videoRecordingTask_Completed;
+ videoCaptureTask.Show();
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the format information of the media file.
+ /// </summary>
+ /// <param name="options"></param>
+ public void getFormatData(string options)
+ {
+ try
+ {
+ MediaFormatOptions mediaFormatOptions;
+ try
+ {
+ mediaFormatOptions = new MediaFormatOptions();
+ string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+ mediaFormatOptions.FullPath = optionStrings[0];
+ mediaFormatOptions.Type = optionStrings[1];
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ }
+
+ string mimeType = mediaFormatOptions.Type;
+
+ if (string.IsNullOrEmpty(mimeType))
+ {
+ mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
+ }
+
+ if (mimeType.Equals("image/jpeg"))
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
+
+ if (image == null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
+ return;
+ }
+
+ MediaFileData mediaData = new MediaFileData(image);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
+ });
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ }
+ }
+
+ /// <summary>
+ /// Opens specified file in media player
+ /// </summary>
+ /// <param name="options">MediaFile to play</param>
+ public void play(string options)
+ {
+ try
+ {
+ MediaFile file;
+
+ try
+ {
+ file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
+
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (file == null || String.IsNullOrEmpty(file.FilePath))
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
+ return;
+ }
+
+ // if url starts with '/' media player throws FileNotFound exception
+ Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
+
+ MediaPlayerLauncher player = new MediaPlayerLauncher();
+ player.Media = fileUri;
+ player.Location = MediaLocationType.Data;
+ player.Show();
+
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+
+ }
+ catch (Exception e)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+ }
+ }
+
+
+ /// <summary>
+ /// Handles result of capture to save image information
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">stores information about current captured image</param>
+ private void cameraTask_Completed(object sender, PhotoResult e)
+ {
+
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
+
+ // Save image in media library
+ MediaLibrary library = new MediaLibrary();
+ Picture image = library.SavePicture(fileName, e.ChosenPhoto);
+
+ int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
+ int newAngle = 0;
+ switch (orient)
+ {
+ case ImageExifOrientation.LandscapeLeft:
+ newAngle = 90;
+ break;
+ case ImageExifOrientation.PortraitUpsideDown:
+ newAngle = 180;
+ break;
+ case ImageExifOrientation.LandscapeRight:
+ newAngle = 270;
+ break;
+ case ImageExifOrientation.Portrait:
+ default: break; // 0 default already set
+ }
+
+ Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
+
+ // Save image in isolated storage
+
+ // we should return stream position back after saving stream to media library
+ rotImageStream.Seek(0, SeekOrigin.Begin);
+
+ byte[] imageBytes = new byte[rotImageStream.Length];
+ rotImageStream.Read(imageBytes, 0, imageBytes.Length);
+ rotImageStream.Dispose();
+ string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
+ imageBytes = null;
+ // Get image data
+ MediaFile data = new MediaFile(pathLocalStorage, image);
+
+ this.files.Add(data);
+
+ if (files.Count < this.captureImageOptions.Limit)
+ {
+ cameraTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ if (files.Count > 0)
+ {
+ // User canceled operation, but some images were made
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
+ }
+ break;
+
+ default:
+ if (files.Count > 0)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Handles result of audio recording tasks
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">stores information about current captured audio</param>
+ private void audioRecordingTask_Completed(object sender, AudioResult e)
+ {
+
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ // Get image data
+ MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
+
+ this.files.Add(data);
+
+ if (files.Count < this.captureAudioOptions.Limit)
+ {
+ audioCaptureTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ if (files.Count > 0)
+ {
+ // User canceled operation, but some audio clips were made
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
+ }
+ break;
+
+ default:
+ if (files.Count > 0)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Handles result of video recording tasks
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e">stores information about current captured video</param>
+ private void videoRecordingTask_Completed(object sender, VideoResult e)
+ {
+
+ if (e.Error != null)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
+ return;
+ }
+
+ switch (e.TaskResult)
+ {
+ case TaskResult.OK:
+ try
+ {
+ // Get image data
+ MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
+
+ this.files.Add(data);
+
+ if (files.Count < this.captureVideoOptions.Limit)
+ {
+ videoCaptureTask.Show();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
+ }
+ break;
+
+ case TaskResult.Cancel:
+ if (files.Count > 0)
+ {
+ // User canceled operation, but some video clips were made
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
+ }
+ break;
+
+ default:
+ if (files.Count > 0)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
+ files.Clear();
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Extract file from Isolated Storage as WriteableBitmap object
+ /// </summary>
+ /// <param name="filePath"></param>
+ /// <returns></returns>
+ private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
+ {
+ try
+ {
+
+ var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
+
+ using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
+ {
+ var imageSource = PictureDecoder.DecodeJpeg(imageStream);
+ return imageSource;
+ }
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+
+ /// <summary>
+ /// Saves captured image in isolated storage
+ /// </summary>
+ /// <param name="imageFileName">image file name</param>
+ /// <param name="imageFolder">folder to store images</param>
+ /// <returns>Image path</returns>
+ private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
+ {
+ if (imageBytes == null)
+ {
+ throw new ArgumentNullException("imageBytes");
+ }
+ try
+ {
+ var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
+
+ if (!isoFile.DirectoryExists(imageFolder))
+ {
+ isoFile.CreateDirectory(imageFolder);
+ }
+ string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
+
+ using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
+ {
+ stream.Write(imageBytes, 0, imageBytes.Length);
+ }
+
+ return filePath;
+ }
+ catch (Exception)
+ {
+ //TODO: log or do something else
+ throw;
+ }
+ }
+
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Compass.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Compass.cs b/common/Plugins/Compass.cs
new file mode 100644
index 0000000..c9e1c4d
--- /dev/null
+++ b/common/Plugins/Compass.cs
@@ -0,0 +1,362 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using DeviceCompass = Microsoft.Devices.Sensors.Compass;
+using System.Windows.Threading;
+using System.Runtime.Serialization;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Threading;
+using Microsoft.Devices.Sensors;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+ public class Compass : BaseCommand
+ {
+ #region Static members
+
+ /// <summary>
+ /// Status of listener
+ /// </summary>
+ private static int currentStatus;
+
+ /// <summary>
+ /// Id for get getCompass method
+ /// </summary>
+ private static string getCompassId = "getCompassId";
+
+ /// <summary>
+ /// Compass
+ /// </summary>
+ private static DeviceCompass compass = new DeviceCompass();
+
+ /// <summary>
+ /// Listeners for callbacks
+ /// </summary>
+ private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
+
+ #endregion
+
+ #region Status codes
+
+ public const int Stopped = 0;
+ public const int Starting = 1;
+ public const int Running = 2;
+ public const int ErrorFailedToStart = 4;
+ public const int Not_Supported = 20;
+
+ /*
+ * // Capture error codes
+ CompassError.COMPASS_INTERNAL_ERR = 0;
+ CompassError.COMPASS_NOT_SUPPORTED = 20;
+ * */
+
+ #endregion
+
+ #region CompassOptions class
+ /// <summary>
+ /// Represents Accelerometer options.
+ /// </summary>
+ [DataContract]
+ public class CompassOptions
+ {
+ /// <summary>
+ /// How often to retrieve the Acceleration in milliseconds
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "frequency")]
+ public int Frequency { get; set; }
+
+ /// <summary>
+ /// The change in degrees required to initiate a watchHeadingFilter success callback.
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "filter")]
+ public int Filter { get; set; }
+
+ /// <summary>
+ /// Watcher id
+ /// </summary>
+ [DataMember(IsRequired = false, Name = "id")]
+ public string Id { get; set; }
+
+ }
+ #endregion
+
+
+ /// <summary>
+ /// Time the value was last changed
+ /// </summary>
+ //private DateTime lastValueChangedTime;
+
+ /// <summary>
+ /// Accelerometer options
+ /// </summary>
+ private CompassOptions compassOptions;
+
+ //bool isDataValid;
+
+ //bool calibrating = false;
+
+ public Compass()
+ {
+
+ }
+
+ /// <summary>
+ /// Formats current coordinates into JSON format
+ /// </summary>
+ /// <returns>Coordinates in JSON format</returns>
+ private string GetHeadingFormatted(CompassReading reading)
+ {
+ // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
+ string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
+ reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
+ reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
+ reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
+ return "{" + result + "}";
+ }
+
+ public void getHeading(string options)
+ {
+ if (!DeviceCompass.IsSupported)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
+ }
+ else
+ {
+ //if (compass == null)
+ //{
+ // // Instantiate the compass.
+ // compass = new DeviceCompass();
+ // compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
+ // compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
+ // compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
+ //}
+
+
+ //compass.Start();
+
+ }
+
+ try
+ {
+ if (currentStatus != Running)
+ {
+ lock (compass)
+ {
+ compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
+ compass.Start();
+ this.SetStatus(Starting);
+ }
+
+ long timeout = 2000;
+ while ((currentStatus == Starting) && (timeout > 0))
+ {
+ timeout = timeout - 100;
+ Thread.Sleep(100);
+ }
+
+ if (currentStatus != Running)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+ return;
+ }
+ }
+ lock (compass)
+ {
+ compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
+ if (watchers.Count < 1)
+ {
+ compass.Stop();
+ this.SetStatus(Stopped);
+ }
+ }
+ }
+ catch (UnauthorizedAccessException)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+ }
+ }
+
+ void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
+ {
+ this.SetStatus(Running);
+ if (compass.IsDataValid)
+ {
+ // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
+ // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
+ // A negative value indicates that the true heading could not be determined.
+ // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
+ //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
+
+ //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
+
+ DispatchCommandResult(result);
+ }
+ }
+
+ /// <summary>
+ /// Starts listening for compass sensor
+ /// </summary>
+ /// <returns>status of listener</returns>
+ private int start()
+ {
+ if ((currentStatus == Running) || (currentStatus == Starting))
+ {
+ return currentStatus;
+ }
+ try
+ {
+ lock (compass)
+ {
+ watchers.Add(getCompassId, this);
+ compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
+ compass.Start();
+ this.SetStatus(Starting);
+ }
+ }
+ catch (Exception)
+ {
+ this.SetStatus(ErrorFailedToStart);
+ }
+ return currentStatus;
+ }
+
+ public void startWatch(string options)
+ {
+ if (!DeviceCompass.IsSupported)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
+ }
+
+ try
+ {
+ compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (string.IsNullOrEmpty(compassOptions.Id))
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ try
+ {
+ lock (compass)
+ {
+ watchers.Add(compassOptions.Id, this);
+ compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
+ compass.Start();
+ this.SetStatus(Starting);
+ }
+ }
+ catch (Exception)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+ return;
+ }
+ }
+
+ public void stopWatch(string options)
+ {
+ try
+ {
+ compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
+ }
+ catch (Exception ex)
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+ return;
+ }
+
+ if (string.IsNullOrEmpty(compassOptions.Id))
+ {
+ this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+
+ if (currentStatus != Stopped)
+ {
+ lock (compass)
+ {
+ Compass watcher = watchers[compassOptions.Id];
+ compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
+ watchers.Remove(compassOptions.Id);
+ watcher.Dispose();
+ }
+ }
+ this.SetStatus(Stopped);
+
+ this.DispatchCommandResult();
+ }
+
+ void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
+ {
+ //throw new NotImplementedException();
+ // TODO: pass calibration error to JS
+ }
+
+ void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
+ {
+ this.SetStatus(Running);
+ if (compass.IsDataValid)
+ {
+ // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
+ // magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
+ // A negative value indicates that the true heading could not be determined.
+ // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
+ //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
+
+ //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
+ result.KeepCallback = true;
+
+ DispatchCommandResult(result);
+ }
+ }
+
+ /// <summary>
+ /// Sets current status
+ /// </summary>
+ /// <param name="status">current status</param>
+ private void SetStatus(int status)
+ {
+ currentStatus = status;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Contacts.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Contacts.cs b/common/Plugins/Contacts.cs
new file mode 100644
index 0000000..af78942
--- /dev/null
+++ b/common/Plugins/Contacts.cs
@@ -0,0 +1,664 @@
+/*
+ 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.
+*/
+
+using Microsoft.Phone.Tasks;
+using Microsoft.Phone.UserData;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Windows;
+using DeviceContacts = Microsoft.Phone.UserData.Contacts;
+
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ [DataContract]
+ public class SearchOptions
+ {
+ [DataMember]
+ public string filter { get; set; }
+ [DataMember]
+ public bool multiple { get; set; }
+ }
+
+ [DataContract]
+ public class ContactSearchParams
+ {
+ [DataMember]
+ public string[] fields { get; set; }
+ [DataMember]
+ public SearchOptions options { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactAddress
+ {
+ [DataMember]
+ public string formatted { get; set; }
+ [DataMember]
+ public string type { get; set; }
+ [DataMember]
+ public string streetAddress { get; set; }
+ [DataMember]
+ public string locality { get; set; }
+ [DataMember]
+ public string region { get; set; }
+ [DataMember]
+ public string postalCode { get; set; }
+ [DataMember]
+ public string country { get; set; }
+ [DataMember]
+ public bool pref { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactName
+ {
+ [DataMember]
+ public string formatted { get; set; }
+ [DataMember]
+ public string familyName { get; set; }
+ [DataMember]
+ public string givenName { get; set; }
+ [DataMember]
+ public string middleName { get; set; }
+ [DataMember]
+ public string honorificPrefix { get; set; }
+ [DataMember]
+ public string honorificSuffix { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactField
+ {
+ [DataMember]
+ public string type { get; set; }
+ [DataMember]
+ public string value { get; set; }
+ [DataMember]
+ public bool pref { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContactOrganization
+ {
+ [DataMember]
+ public string type { get; set; }
+ [DataMember]
+ public string name { get; set; }
+ [DataMember]
+ public bool pref { get; set; }
+ [DataMember]
+ public string department { get; set; }
+ [DataMember]
+ public string title { get; set; }
+ }
+
+ [DataContract]
+ public class JSONContact
+ {
+ [DataMember]
+ public string id { get; set; }
+ [DataMember]
+ public string rawId { get; set; }
+ [DataMember]
+ public string displayName { get; set; }
+ [DataMember]
+ public string nickname { get; set; }
+ [DataMember]
+ public string note { get; set; }
+
+ [DataMember]
+ public JSONContactName name { get; set; }
+
+ [DataMember]
+ public JSONContactField[] emails { get; set; }
+
+ [DataMember]
+ public JSONContactField[] phoneNumbers { get; set; }
+
+ [DataMember]
+ public JSONContactField[] ims { get; set; }
+
+ [DataMember]
+ public JSONContactField[] photos { get; set; }
+
+ [DataMember]
+ public JSONContactField[] categories { get; set; }
+
+ [DataMember]
+ public JSONContactField[] urls { get; set; }
+
+ [DataMember]
+ public JSONContactOrganization[] organizations { get; set; }
+
+ [DataMember]
+ public JSONContactAddress[] addresses { get; set; }
+ }
+
+
+ public class Contacts : BaseCommand
+ {
+
+ public const int UNKNOWN_ERROR = 0;
+ public const int INVALID_ARGUMENT_ERROR = 1;
+ public const int TIMEOUT_ERROR = 2;
+ public const int PENDING_OPERATION_ERROR = 3;
+ public const int IO_ERROR = 4;
+ public const int NOT_SUPPORTED_ERROR = 5;
+ public const int PERMISSION_DENIED_ERROR = 20;
+ public const int SYNTAX_ERR = 8;
+
+ public Contacts()
+ {
+
+ }
+
+ // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
+ public void save(string jsonContact)
+ {
+
+ // jsonContact is actually an array of 1 {contact}
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
+
+
+ JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
+
+ SaveContactTask contactTask = new SaveContactTask();
+
+ if (contact.nickname != null)
+ {
+ contactTask.Nickname = contact.nickname;
+ }
+ if (contact.urls != null && contact.urls.Length > 0)
+ {
+ contactTask.Website = contact.urls[0].value;
+ }
+ if (contact.note != null)
+ {
+ contactTask.Notes = contact.note;
+ }
+
+ #region contact.name
+ if (contact.name != null)
+ {
+ if (contact.name.givenName != null)
+ contactTask.FirstName = contact.name.givenName;
+ if (contact.name.familyName != null)
+ contactTask.LastName = contact.name.familyName;
+ if (contact.name.middleName != null)
+ contactTask.MiddleName = contact.name.middleName;
+ if (contact.name.honorificSuffix != null)
+ contactTask.Suffix = contact.name.honorificSuffix;
+ if (contact.name.honorificPrefix != null)
+ contactTask.Title = contact.name.honorificPrefix;
+ }
+ #endregion
+
+ #region contact.org
+ if (contact.organizations != null && contact.organizations.Count() > 0)
+ {
+ contactTask.Company = contact.organizations[0].name;
+ contactTask.JobTitle = contact.organizations[0].title;
+ }
+ #endregion
+
+ #region contact.phoneNumbers
+ if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
+ {
+ foreach (JSONContactField field in contact.phoneNumbers)
+ {
+ string fieldType = field.type.ToLower();
+ if (fieldType == "work")
+ {
+ contactTask.WorkPhone = field.value;
+ }
+ else if (fieldType == "home")
+ {
+ contactTask.HomePhone = field.value;
+ }
+ else if (fieldType == "mobile")
+ {
+ contactTask.MobilePhone = field.value;
+ }
+ }
+ }
+ #endregion
+
+ #region contact.emails
+
+ if (contact.emails != null && contact.emails.Length > 0)
+ {
+
+ // set up different email types if they are not explicitly defined
+ foreach (string type in new string[] { "personal", "work", "other" })
+ {
+ foreach (JSONContactField field in contact.emails)
+ {
+ if (field != null && String.IsNullOrEmpty(field.type))
+ {
+ field.type = type;
+ break;
+ }
+ }
+ }
+
+ foreach (JSONContactField field in contact.emails)
+ {
+ if (field != null)
+ {
+ if (field.type != null && field.type != "other")
+ {
+ string fieldType = field.type.ToLower();
+ if (fieldType == "work")
+ {
+ contactTask.WorkEmail = field.value;
+ }
+ else if (fieldType == "home" || fieldType == "personal")
+ {
+ contactTask.PersonalEmail = field.value;
+ }
+ }
+ else
+ {
+ contactTask.OtherEmail = field.value;
+ }
+ }
+
+ }
+ }
+ #endregion
+
+ if (contact.note != null && contact.note.Length > 0)
+ {
+ contactTask.Notes = contact.note;
+ }
+
+ #region contact.addresses
+ if (contact.addresses != null && contact.addresses.Length > 0)
+ {
+ foreach (JSONContactAddress address in contact.addresses)
+ {
+ if (address.type == null)
+ {
+ address.type = "home"; // set a default
+ }
+ string fieldType = address.type.ToLower();
+ if (fieldType == "work")
+ {
+ contactTask.WorkAddressCity = address.locality;
+ contactTask.WorkAddressCountry = address.country;
+ contactTask.WorkAddressState = address.region;
+ contactTask.WorkAddressStreet = address.streetAddress;
+ contactTask.WorkAddressZipCode = address.postalCode;
+ }
+ else if (fieldType == "home" || fieldType == "personal")
+ {
+ contactTask.HomeAddressCity = address.locality;
+ contactTask.HomeAddressCountry = address.country;
+ contactTask.HomeAddressState = address.region;
+ contactTask.HomeAddressStreet = address.streetAddress;
+ contactTask.HomeAddressZipCode = address.postalCode;
+ }
+ else
+ {
+ // no other address fields available ...
+ Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
+ }
+ }
+ }
+ #endregion
+
+
+ contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
+ contactTask.Show();
+ }
+
+ void ContactSaveTaskCompleted(object sender, SaveContactResult e)
+ {
+ SaveContactTask task = sender as SaveContactTask;
+
+ if (e.TaskResult == TaskResult.OK)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ DeviceContacts deviceContacts = new DeviceContacts();
+ deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
+
+ string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
+
+ deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
+ });
+
+
+ }
+ else if (e.TaskResult == TaskResult.Cancel)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
+ }
+ }
+
+ void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
+ {
+ if (e.Results.Count() > 0)
+ {
+ List<Contact> foundContacts = new List<Contact>();
+
+ int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
+ Contact newContact = (from Contact contact in e.Results
+ where contact.GetHashCode() == n
+ select contact).First();
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
+ }
+ }
+
+
+
+ public void remove(string id)
+ {
+ // note id is wrapped in [] and always has exactly one string ...
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
+ }
+
+ public void search(string searchCriteria)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
+
+ ContactSearchParams searchParams = new ContactSearchParams();
+ try
+ {
+ searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
+ searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
+ }
+ catch (Exception)
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
+ return;
+ }
+
+ if (searchParams.options == null)
+ {
+ searchParams.options = new SearchOptions();
+ searchParams.options.filter = "";
+ searchParams.options.multiple = true;
+ }
+
+ DeviceContacts deviceContacts = new DeviceContacts();
+ deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
+
+ // default is to search all fields
+ FilterKind filterKind = FilterKind.None;
+ // if only one field is specified, we will try the 3 available DeviceContact search filters
+ if (searchParams.fields.Count() == 1)
+ {
+ if (searchParams.fields.Contains("name"))
+ {
+ filterKind = FilterKind.DisplayName;
+ }
+ else if (searchParams.fields.Contains("emails"))
+ {
+ filterKind = FilterKind.EmailAddress;
+ }
+ else if (searchParams.fields.Contains("phoneNumbers"))
+ {
+ filterKind = FilterKind.PhoneNumber;
+ }
+ }
+
+ try
+ {
+
+ deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("search contacts exception :: " + ex.Message);
+ }
+ }
+
+ private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
+ {
+ ContactSearchParams searchParams = (ContactSearchParams)e.State;
+
+ List<Contact> foundContacts = null;
+
+ // if we have multiple search fields
+ if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
+ {
+ foundContacts = new List<Contact>();
+ if (searchParams.fields.Contains("emails"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ from ContactEmailAddress a in con.EmailAddresses
+ where a.EmailAddress.Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("displayName"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ where con.DisplayName.Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("name"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("phoneNumbers"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ from ContactPhoneNumber a in con.PhoneNumbers
+ where a.PhoneNumber.Contains(searchParams.options.filter)
+ select con);
+ }
+ if (searchParams.fields.Contains("urls"))
+ {
+ foundContacts.AddRange(from Contact con in e.Results
+ from string a in con.Websites
+ where a.Contains(searchParams.options.filter)
+ select con);
+ }
+ }
+ else
+ {
+ foundContacts = new List<Contact>(e.Results);
+ }
+
+ //List<string> contactList = new List<string>();
+
+ string strResult = "";
+
+ IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
+
+ foreach (Contact contact in distinctContacts)
+ {
+ strResult += FormatJSONContact(contact, null) + ",";
+ //contactList.Add(FormatJSONContact(contact, null));
+ if (!searchParams.options.multiple)
+ {
+ break; // just return the first item
+ }
+ }
+ PluginResult result = new PluginResult(PluginResult.Status.OK);
+ result.Message = "[" + strResult.TrimEnd(',') + "]";
+ DispatchCommandResult(result);
+
+ }
+
+ private string FormatJSONPhoneNumbers(Contact con)
+ {
+ string retVal = "";
+ string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
+ foreach (ContactPhoneNumber number in con.PhoneNumbers)
+ {
+
+ string contactField = string.Format(contactFieldFormat,
+ number.Kind.ToString(),
+ number.PhoneNumber);
+
+ retVal += "{" + contactField + "},";
+ }
+ return retVal.TrimEnd(',');
+ }
+
+ private string FormatJSONEmails(Contact con)
+ {
+ string retVal = "";
+ string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
+ foreach (ContactEmailAddress address in con.EmailAddresses)
+ {
+ string contactField = string.Format(contactFieldFormat,
+ address.Kind.ToString(),
+ address.EmailAddress);
+
+ retVal += "{" + contactField + "},";
+ }
+ return retVal.TrimEnd(',');
+ }
+
+ private string getFormattedJSONAddress(ContactAddress address, bool isPrefered)
+ {
+
+ string addressFormatString = "\"pref\":{0}," + // bool
+ "\"type\":\"{1}\"," +
+ "\"formatted\":\"{2}\"," +
+ "\"streetAddress\":\"{3}\"," +
+ "\"locality\":\"{4}\"," +
+ "\"region\":\"{5}\"," +
+ "\"postalCode\":\"{6}\"," +
+ "\"country\":\"{7}\"";
+
+ string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
+ + address.PhysicalAddress.AddressLine2 + " "
+ + address.PhysicalAddress.City + " "
+ + address.PhysicalAddress.StateProvince + " "
+ + address.PhysicalAddress.CountryRegion + " "
+ + address.PhysicalAddress.PostalCode;
+
+ string jsonAddress = string.Format(addressFormatString,
+ isPrefered ? "\"true\"" : "\"false\"",
+ address.Kind.ToString(),
+ formattedAddress,
+ address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
+ address.PhysicalAddress.City,
+ address.PhysicalAddress.StateProvince,
+ address.PhysicalAddress.PostalCode,
+ address.PhysicalAddress.CountryRegion);
+
+ //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
+
+ return "{" + jsonAddress + "}";
+ }
+
+ private string FormatJSONAddresses(Contact con)
+ {
+ string retVal = "";
+ foreach (ContactAddress address in con.Addresses)
+ {
+ retVal += this.getFormattedJSONAddress(address, false) + ",";
+ }
+
+ //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
+ return retVal.TrimEnd(',');
+ }
+
+ private string FormatJSONWebsites(Contact con)
+ {
+ string retVal = "";
+ foreach (string website in con.Websites)
+ {
+ retVal += "\"" + website + "\",";
+ }
+ return retVal.TrimEnd(',');
+ }
+
+ /*
+ * formatted: The complete name of the contact. (DOMString)
+ familyName: The contacts family name. (DOMString)
+ givenName: The contacts given name. (DOMString)
+ middleName: The contacts middle name. (DOMString)
+ honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
+ honorificSuffix: The contacts suffix (example Esq.). (DOMString)
+ */
+ private string FormatJSONName(Contact con)
+ {
+ string retVal = "";
+ string formatStr = "\"formatted\":\"{0}\"," +
+ "\"familyName\":\"{1}\"," +
+ "\"givenName\":\"{2}\"," +
+ "\"middleName\":\"{3}\"," +
+ "\"honorificPrefix\":\"{4}\"," +
+ "\"honorificSuffix\":\"{5}\"";
+
+ if (con.CompleteName != null)
+ {
+ retVal = string.Format(formatStr,
+ con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
+ con.CompleteName.LastName,
+ con.CompleteName.FirstName,
+ con.CompleteName.MiddleName,
+ con.CompleteName.Title,
+ con.CompleteName.Suffix);
+ }
+ else
+ {
+ retVal = string.Format(formatStr,"","","","","","");
+ }
+
+ return "{" + retVal + "}";
+ }
+
+ private string FormatJSONContact(Contact con, string[] fields)
+ {
+
+ string contactFormatStr = "\"id\":\"{0}\"," +
+ "\"displayName\":\"{1}\"," +
+ "\"nickname\":\"{2}\"," +
+ "\"phoneNumbers\":[{3}]," +
+ "\"emails\":[{4}]," +
+ "\"addresses\":[{5}]," +
+ "\"urls\":[{6}]," +
+ "\"name\":{7}," +
+ "\"note\":\"{8}\"," +
+ "\"birthday\":\"{9}\"";
+
+
+ string jsonContact = String.Format(contactFormatStr,
+ con.GetHashCode(),
+ con.DisplayName,
+ con.CompleteName != null ? con.CompleteName.Nickname : "",
+ FormatJSONPhoneNumbers(con),
+ FormatJSONEmails(con),
+ FormatJSONAddresses(con),
+ FormatJSONWebsites(con),
+ FormatJSONName(con),
+ con.Notes.FirstOrDefault(),
+ con.Birthdays.FirstOrDefault());
+
+ //Debug.WriteLine("jsonContact = " + jsonContact);
+ // JSON requires new line characters be escaped
+ return "{" + jsonContact.Replace("\n", "\\n") + "}";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/DebugConsole.cs b/common/Plugins/DebugConsole.cs
new file mode 100644
index 0000000..fa9863a
--- /dev/null
+++ b/common/Plugins/DebugConsole.cs
@@ -0,0 +1,49 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+ public class DebugConsole : BaseCommand
+ {
+ // warn, error
+ public void log(string msg)
+ {
+ Debug.WriteLine("Log:" + msg);
+ }
+
+ public void error(string msg)
+ {
+ Debug.WriteLine("Error:" + msg);
+ }
+
+ public void warn(string msg)
+ {
+ Debug.WriteLine("Warn:" + msg);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/d4f359a3/common/Plugins/Device.cs
----------------------------------------------------------------------
diff --git a/common/Plugins/Device.cs b/common/Plugins/Device.cs
new file mode 100644
index 0000000..8abb4ff
--- /dev/null
+++ b/common/Plugins/Device.cs
@@ -0,0 +1,135 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Info;
+using System.IO.IsolatedStorage;
+using System.Windows.Resources;
+using System.IO;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Device : BaseCommand
+ {
+ public void getDeviceInfo(string notused)
+ {
+
+ string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
+ this.name,
+ this.cordova,
+ this.platform,
+ this.uuid,
+ this.version,
+ this.model);
+
+
+
+ res = "{" + res + "}";
+ //Debug.WriteLine("Result::" + res);
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
+ }
+
+ public string model
+ {
+ get
+ {
+ return DeviceStatus.DeviceName;
+ //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion);
+ }
+ }
+
+ public string name
+ {
+ get
+ {
+ return DeviceStatus.DeviceName;
+
+ }
+ }
+
+ public string cordova
+ {
+ get
+ {
+ // TODO: should be able to dynamically read the Cordova version from somewhere...
+ return "0.0.0";
+ }
+ }
+
+ public string platform
+ {
+ get
+ {
+ return Environment.OSVersion.Platform.ToString();
+ }
+ }
+
+ public string uuid
+ {
+ get
+ {
+ string returnVal = "";
+ object id;
+ UserExtendedProperties.TryGetValue("ANID", out id);
+
+ if (id != null)
+ {
+ returnVal = id.ToString().Substring(2, 32);
+ }
+ else
+ {
+ returnVal = "???unknown???";
+
+ using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ try
+ {
+ IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
+
+ using (StreamReader reader = new StreamReader(fileStream))
+ {
+ returnVal = reader.ReadLine();
+ }
+ }
+ catch (Exception /*ex*/)
+ {
+
+ }
+ }
+ }
+
+ return returnVal;
+ }
+ }
+
+ public string version
+ {
+ get
+ {
+ return Environment.OSVersion.Version.ToString();
+ }
+ }
+
+ }
+}
[16/50] [abbrv] moved all common app stuff to own folder,
template builder copies it over
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/www/css/index.css
----------------------------------------------------------------------
diff --git a/wp8/template/www/css/index.css b/wp8/template/www/css/index.css
deleted file mode 100644
index f1f9d76..0000000
--- a/wp8/template/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-* {
- -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
- -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
- -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
- -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
-}
-
-body {
- background-color:#E4E4E4;
- background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
- background-image:-webkit-gradient(
- linear,
- left top,
- left bottom,
- color-stop(0, #A7A7A7),
- color-stop(0.51, #E4E4E4)
- );
- background-attachment:fixed;
- font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
- font-size:12px;
- height:100%;
- margin:0px;
- padding:0px;
- text-transform:uppercase;
- width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
- background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
- position:absolute; /* position in the center of the screen */
- left:50%;
- top:50%;
- height:50px; /* text area height */
- width:225px; /* text area width */
- text-align:center;
- padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
- margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
- /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
- .app {
- background-position:left center;
- padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
- margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
- /* offset horizontal: half of image width and text area width */
- }
-}
-
-h1 {
- font-size:24px;
- font-weight:normal;
- margin:0px;
- overflow:visible;
- padding:0px;
- text-align:center;
-}
-
-.event {
- border-radius:4px;
- -webkit-border-radius:4px;
- color:#FFFFFF;
- font-size:12px;
- margin:0px 30px;
- padding:2px 0px;
-}
-
-.event.listening {
- background-color:#333333;
- display:block;
-}
-
-.event.received {
- background-color:#4B946A;
- display:none;
-}
-
-@keyframes fade {
- from { opacity: 1.0; }
- 50% { opacity: 0.4; }
- to { opacity: 1.0; }
-}
-
-@-webkit-keyframes fade {
- from { opacity: 1.0; }
- 50% { opacity: 0.4; }
- to { opacity: 1.0; }
-}
-
-.blink {
- animation:fade 3000ms infinite;
- -webkit-animation:fade 3000ms infinite;
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/www/img/logo.png
----------------------------------------------------------------------
diff --git a/wp8/template/www/img/logo.png b/wp8/template/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/wp8/template/www/img/logo.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/www/index.html
----------------------------------------------------------------------
diff --git a/wp8/template/www/index.html b/wp8/template/www/index.html
deleted file mode 100644
index 842b364..0000000
--- a/wp8/template/www/index.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<!--
- 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.
--->
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="format-detection" content="telephone=no" />
- <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
- <link rel="stylesheet" type="text/css" href="css/index.css" />
- <title>Hello World</title>
- </head>
- <body>
- <div class="app">
- <h1>Apache Cordova</h1>
- <div id="deviceready" class="blink">
- <p class="event listening">Connecting to Device</p>
- <p class="event received">Device is Ready</p>
- </div>
- </div>
- <script type="text/javascript" src="cordova.js"></script>
- <script type="text/javascript" src="js/index.js"></script>
- <script type="text/javascript">
- app.initialize();
- </script>
- </body>
-</html>
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/template/www/js/index.js
----------------------------------------------------------------------
diff --git a/wp8/template/www/js/index.js b/wp8/template/www/js/index.js
deleted file mode 100644
index 3b75d3f..0000000
--- a/wp8/template/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 app = {
- // Application Constructor
- initialize: function() {
- this.bindEvents();
- },
- // Bind Event Listeners
- //
- // Bind any events that are required on startup. Common events are:
- // `load`, `deviceready`, `offline`, and `online`.
- bindEvents: function() {
- document.addEventListener('deviceready', this.onDeviceReady, false);
- },
- // deviceready Event Handler
- //
- // The scope of `this` is the event. In order to call the `receivedEvent`
- // function, we must explicity call `app.receivedEvent(...);`
- onDeviceReady: function() {
- app.receivedEvent('deviceready');
- },
- // Update DOM on a Received Event
- receivedEvent: function(id) {
- var parentElement = document.getElementById(id);
- var listeningElement = parentElement.querySelector('.listening');
- var receivedElement = parentElement.querySelector('.received');
-
- listeningElement.setAttribute('style', 'display:none;');
- receivedElement.setAttribute('style', 'display:block;');
-
- console.log('Received Event: ' + id);
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/22118ac7/wp8/tooling/scripts/createTemplates.js
----------------------------------------------------------------------
diff --git a/wp8/tooling/scripts/createTemplates.js b/wp8/tooling/scripts/createTemplates.js
index b25a19a..6b8f6cd 100644
--- a/wp8/tooling/scripts/createTemplates.js
+++ b/wp8/tooling/scripts/createTemplates.js
@@ -147,6 +147,38 @@ function copyFile(src,dest) {
exec('%comspec% /c copy /Y ' + src + ' ' + dest);
}
+function copyCommonItemsToTemplate() {
+ var srcPath = repoRoot + '\\common-items';
+ var destPath = platformRoot + templatePath;
+
+ var folder = fso.GetFolder(srcPath);
+ // iterate over the files in the folder
+ for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
+ //Log("File: " + srcPath + "\\" + files.item().name);
+ copyFile(srcPath + "\\" + files.item().name, destPath + "\\" + files.item().name);
+ }
+ // iterate over the child folders in the folder
+ for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
+ Log("Folder: " + srcPath + "\\" + subFlds.item().name);
+ exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " "
+ + destPath + "\\" + subFlds.item().name);
+ }
+}
+
+// delete desination items
+function removeCommonItems() {
+ var srcPath = repoRoot + '\\common-items';
+ var destPath = platformRoot + templatePath;
+ var folder = fso.GetFolder(srcPath);
+ // iterate over the files in the folder
+ for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
+ deleteFileIfExists(destPath + "\\" + files.item().name);
+ }
+ // iterate over the child folders in the folder
+ for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
+ deleteFolderIfExists(destPath + "\\" + subFlds.item().name);
+ }
+}
// packages templates into .zip
function package_templates()
@@ -165,6 +197,9 @@ function package_templates()
deleteFileIfExists(platformRoot + templatePath + "\\CordovaWP8Solution.v11.suo");
exec('%comspec% /c xcopy /Y /E /I ' + repoRoot + '\\Plugins ' + platformRoot + templatePath + '\\Plugins');
+
+ copyCommonItemsToTemplate();
+
copyFile(repoRoot + '\\VERSION',platformRoot + templatePath);
// update .vstemplate files for the template zips.
@@ -234,7 +269,9 @@ function zip_project(zip_path, project_path) {
// delete any unneeded files when finished
function cleanUp() {
-
+ removeCommonItems();
+ deleteFileIfExists(platformRoot + templatePath + "\\VERSION");
+ deleteFolderIfExists(platformRoot + templatePath + '\\Plugins');
}
function parseArgs() {
[11/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/File.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/File.cs b/wp7/template/Plugins/File.cs
deleted file mode 100644
index cde7a1c..0000000
--- a/wp7/template/Plugins/File.cs
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to isolated storage
- /// </summary>
- public class File : BaseCommand
- {
- // Error codes
- public const int NOT_FOUND_ERR = 1;
- public const int SECURITY_ERR = 2;
- public const int ABORT_ERR = 3;
- public const int NOT_READABLE_ERR = 4;
- public const int ENCODING_ERR = 5;
- public const int NO_MODIFICATION_ALLOWED_ERR = 6;
- public const int INVALID_STATE_ERR = 7;
- public const int SYNTAX_ERR = 8;
- public const int INVALID_MODIFICATION_ERR = 9;
- public const int QUOTA_EXCEEDED_ERR = 10;
- public const int TYPE_MISMATCH_ERR = 11;
- public const int PATH_EXISTS_ERR = 12;
-
- // File system options
- public const int TEMPORARY = 0;
- public const int PERSISTENT = 1;
- public const int RESOURCE = 2;
- public const int APPLICATION = 3;
-
- /// <summary>
- /// Temporary directory name
- /// </summary>
- private readonly string TMP_DIRECTORY_NAME = "tmp";
-
- /// <summary>
- /// Represents error code for callback
- /// </summary>
- [DataContract]
- public class ErrorCode
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(IsRequired = true, Name = "code")]
- public int Code { get; set; }
-
- /// <summary>
- /// Creates ErrorCode object
- /// </summary>
- public ErrorCode(int code)
- {
- this.Code = code;
- }
- }
-
- /// <summary>
- /// Represents File action options.
- /// </summary>
- [DataContract]
- public class FileOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- ///
- private string _fileName;
- [DataMember(Name = "fileName")]
- public string FilePath
- {
- get
- {
- return this._fileName;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._fileName = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Full entryPath
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// Directory name
- /// </summary>
- [DataMember(Name = "dirName")]
- public string DirectoryName { get; set; }
-
- /// <summary>
- /// Path to create file/directory
- /// </summary>
- [DataMember(Name = "path")]
- public string Path { get; set; }
-
- /// <summary>
- /// The encoding to use to encode the file's content. Default is UTF8.
- /// </summary>
- [DataMember(Name = "encoding")]
- public string Encoding { get; set; }
-
- /// <summary>
- /// Uri to get file
- /// </summary>
- ///
- private string _uri;
- [DataMember(Name = "uri")]
- public string Uri
- {
- get
- {
- return this._uri;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._uri = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Size to truncate file
- /// </summary>
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- /// <summary>
- /// Data to write in file
- /// </summary>
- [DataMember(Name = "data")]
- public string Data { get; set; }
-
- /// <summary>
- /// Position the writing starts with
- /// </summary>
- [DataMember(Name = "position")]
- public int Position { get; set; }
-
- /// <summary>
- /// Type of file system requested
- /// </summary>
- [DataMember(Name = "type")]
- public int FileSystemType { get; set; }
-
- /// <summary>
- /// New file/directory name
- /// </summary>
- [DataMember(Name = "newName")]
- public string NewName { get; set; }
-
- /// <summary>
- /// Destination directory to copy/move file/directory
- /// </summary>
- [DataMember(Name = "parent")]
- public string Parent { get; set; }
-
- /// <summary>
- /// Options for getFile/getDirectory methods
- /// </summary>
- [DataMember(Name = "options")]
- public CreatingOptions CreatingOpt { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public FileOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Encoding = "UTF-8";
- this.FilePath = "";
- this.FileSystemType = -1;
- }
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class FileMetadata
- {
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public FileMetadata(string filePath)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- else if (!isoFile.FileExists(filePath))
- {
- // attempt to get it from the resources
- if (filePath.IndexOf("www") == 0)
- {
- Uri fileUri = new Uri(filePath, UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- this.Size = streamInfo.Stream.Length;
- this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
- this.FullPath = filePath;
- }
- }
- else
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- }
- else
- {
- //TODO get file size the other way if possible
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
- {
- this.Size = stream.Length;
- }
- this.FullPath = filePath;
- this.FileName = System.IO.Path.GetFileName(filePath);
- this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- }
- this.Type = MimeTypeMapper.GetMimeType(this.FileName);
- }
- }
- }
-
- /// <summary>
- /// Represents file or directory modification metadata
- /// </summary>
- [DataContract]
- public class ModificationMetadata
- {
- /// <summary>
- /// Modification time
- /// </summary>
- [DataMember]
- public string modificationTime { get; set; }
- }
-
- /// <summary>
- /// Represents file or directory entry
- /// </summary>
- [DataContract]
- public class FileEntry
- {
-
- /// <summary>
- /// File type
- /// </summary>
- [DataMember(Name = "isFile")]
- public bool IsFile { get; set; }
-
- /// <summary>
- /// Directory type
- /// </summary>
- [DataMember(Name = "isDirectory")]
- public bool IsDirectory { get; set; }
-
- /// <summary>
- /// File/directory name
- /// </summary>
- [DataMember(Name = "name")]
- public string Name { get; set; }
-
- /// <summary>
- /// Full path to file/directory
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- public bool IsResource { get; set; }
-
- public static FileEntry GetEntry(string filePath, bool bIsRes=false)
- {
- FileEntry entry = null;
- try
- {
- entry = new FileEntry(filePath, bIsRes);
-
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
- }
- return entry;
- }
-
- /// <summary>
- /// Creates object and sets necessary properties
- /// </summary>
- /// <param name="filePath"></param>
- public FileEntry(string filePath, bool bIsRes = false)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new ArgumentException();
- }
-
- if(filePath.Contains(" "))
- {
- Debug.WriteLine("FilePath with spaces :: " + filePath);
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- IsResource = bIsRes;
- IsFile = isoFile.FileExists(filePath);
- IsDirectory = isoFile.DirectoryExists(filePath);
- if (IsFile)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else if (IsDirectory)
- {
- this.Name = this.GetDirectoryName(filePath);
- if (string.IsNullOrEmpty(Name))
- {
- this.Name = "/";
- }
- }
- else
- {
- if (IsResource)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else
- {
- throw new FileNotFoundException();
- }
- }
-
- try
- {
- this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
- }
- catch (Exception)
- {
- this.FullPath = filePath;
- }
- }
- }
-
- /// <summary>
- /// Extracts directory name from path string
- /// Path should refer to a directory, for example \foo\ or /foo.
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- private string GetDirectoryName(string path)
- {
- if (String.IsNullOrEmpty(path))
- {
- return path;
- }
-
- string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
- if (split.Length < 1)
- {
- return null;
- }
- else
- {
- return split[split.Length - 1];
- }
- }
- }
-
-
- /// <summary>
- /// Represents info about requested file system
- /// </summary>
- [DataContract]
- public class FileSystemInfo
- {
- /// <summary>
- /// file system type
- /// </summary>
- [DataMember(Name = "name", IsRequired = true)]
- public string Name { get; set; }
-
- /// <summary>
- /// Root directory entry
- /// </summary>
- [DataMember(Name = "root", EmitDefaultValue = false)]
- public FileEntry Root { get; set; }
-
- /// <summary>
- /// Creates class instance
- /// </summary>
- /// <param name="name"></param>
- /// <param name="rootEntry"> Root directory</param>
- public FileSystemInfo(string name, FileEntry rootEntry = null)
- {
- Name = name;
- Root = rootEntry;
- }
- }
-
- [DataContract]
- public class CreatingOptions
- {
- /// <summary>
- /// Create file/directory if is doesn't exist
- /// </summary>
- [DataMember(Name = "create")]
- public bool Create { get; set; }
-
- /// <summary>
- /// Generate an exception if create=true and file/directory already exists
- /// </summary>
- [DataMember(Name = "exclusive")]
- public bool Exclusive { get; set; }
-
-
- }
-
- // returns null value if it fails.
- private string[] getOptionStrings(string options)
- {
- string[] optStings = null;
- try
- {
- optStings = JSON.JsonHelper.Deserialize<string[]>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
- }
- return optStings;
- }
-
- /// <summary>
- /// Gets amount of free space available for Isolated Storage
- /// </summary>
- /// <param name="options">No options is needed for this method</param>
- public void getFreeDiskSpace(string options)
- {
- string callbackId = getOptionStrings(options)[0];
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Check if file exists
- /// </summary>
- /// <param name="options">File path</param>
- public void testFileExists(string options)
- {
- IsDirectoryOrFileExist(options, false);
- }
-
- /// <summary>
- /// Check if directory exists
- /// </summary>
- /// <param name="options">directory name</param>
- public void testDirectoryExists(string options)
- {
- IsDirectoryOrFileExist(options, true);
- }
-
- /// <summary>
- /// Check if file or directory exist
- /// </summary>
- /// <param name="options">File path/Directory name</param>
- /// <param name="isDirectory">Flag to recognize what we should check</param>
- public void IsDirectoryOrFileExist(string options, bool isDirectory)
- {
- string[] args = getOptionStrings(options);
- string callbackId = args[1];
- FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
- string filePath = args[0];
-
- if (fileOptions == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isExist;
- if (isDirectory)
- {
- isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
- }
- else
- {
- isExist = isoFile.FileExists(fileOptions.FilePath);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
- }
- }
- catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
-
- public void readAsDataURL(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- if (filePath != null)
- {
- try
- {
- string base64URL = null;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string mimeType = MimeTypeMapper.GetMimeType(filePath);
-
- using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- string base64String = GetFileContent(stream);
- base64URL = "data:" + mimeType + ";base64," + base64String;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- public void readAsArrayBuffer(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsBinaryString(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- string encStr = optStrings[1];
- int startPos = int.Parse(optStrings[2]);
- int endPos = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- string text = "";
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- readResourceAsText(options);
- return;
- }
- Encoding encoding = Encoding.GetEncoding(encStr);
-
- using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
- {
- text = reader.ReadToEnd();
- if (startPos < 0)
- {
- startPos = Math.Max(text.Length + startPos, 0);
- }
- else if (startPos > 0)
- {
- startPos = Math.Min(text.Length, startPos);
- }
-
- if (endPos > 0)
- {
- endPos = Math.Min(text.Length, endPos);
- }
- else if (endPos < 0)
- {
- endPos = Math.Max(endPos + text.Length, 0);
- }
-
-
- text = text.Substring(startPos, endPos - startPos);
-
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Reads application resource as a text
- /// </summary>
- /// <param name="options">Path to a resource</param>
- public void readResourceAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string pathToResource = optStrings[0];
- string encStr = optStrings[1];
- int start = int.Parse(optStrings[2]);
- int endMarker = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- if (pathToResource.StartsWith("/"))
- {
- pathToResource = pathToResource.Remove(0, 1);
- }
-
- var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
-
- if (resource == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string text;
- StreamReader streamReader = new StreamReader(resource.Stream);
- text = streamReader.ReadToEnd();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- public void truncate(string options)
- {
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- int size = int.Parse(optStrings[1]);
- string callbackId = optStrings[2];
-
- try
- {
- long streamLength = 0;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= size && size <= stream.Length)
- {
- stream.SetLength(size);
- }
- streamLength = stream.Length;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- //write:["filePath","data","position"],
- public void write(string options)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- string data = optStrings[1];
- int position = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- try
- {
- if (string.IsNullOrEmpty(data))
- {
- Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(filePath))
- {
- var file = isoFile.CreateFile(filePath);
- file.Close();
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= position && position <= stream.Length)
- {
- stream.SetLength(position);
- }
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- writer.Seek(0, SeekOrigin.End);
- writer.Write(data.ToCharArray());
- }
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Look up metadata about this entry.
- /// </summary>
- /// <param name="options">filePath to entry</param>
- public void getMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
- new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
- }
- else if (isoFile.DirectoryExists(filePath))
- {
- string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- }
-
-
- /// <summary>
- /// Returns a File that represents the current state of the file that this FileEntry represents.
- /// </summary>
- /// <param name="filePath">filePath to entry</param>
- /// <returns></returns>
- public void getFileMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- FileMetadata metaData = new FileMetadata(filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- /// <summary>
- /// Look up the parent DirectoryEntry containing this Entry.
- /// If this Entry is the root of IsolatedStorage, its parent is itself.
- /// </summary>
- /// <param name="options"></param>
- public void getParent(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- FileEntry entry;
-
- if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
- {
-
-
- string path = this.GetParentDirectory(filePath);
- entry = FileEntry.GetEntry(path);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
-
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- }
-
- public void remove(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (filePath == "/" || filePath == "" || filePath == @"\")
- {
- throw new Exception("Cannot delete root file system") ;
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- else
- {
- if (isoFile.DirectoryExists(filePath))
- {
- isoFile.DeleteDirectory(filePath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- return;
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void removeRecursively(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- }
- else
- {
- if (removeDirRecursively(filePath, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- }
- }
- }
-
- public void readEntries(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(filePath))
- {
- string path = File.AddSlashToDirectory(filePath);
- List<FileEntry> entries = new List<FileEntry>();
- string[] files = isoFile.GetFileNames(path + "*");
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- foreach (string file in files)
- {
- entries.Add(FileEntry.GetEntry(path + file));
- }
- foreach (string dir in dirs)
- {
- entries.Add(FileEntry.GetEntry(path + dir + "/"));
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void requestFileSystem(string options)
- {
- // TODO: try/catch
- string[] optVals = getOptionStrings(options);
- //FileOptions fileOptions = new FileOptions();
- int fileSystemType = int.Parse(optVals[0]);
- double size = double.Parse(optVals[1]);
- string callbackId = optVals[2];
-
-
- IsolatedStorageFile.GetUserStoreForApplication();
-
- if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
-
- try
- {
- if (size != 0)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- long availableSize = isoFile.AvailableFreeSpace;
- if (size > availableSize)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
- }
- }
-
- if (fileSystemType == PERSISTENT)
- {
- // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
- }
- else if (fileSystemType == TEMPORARY)
- {
- using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
- {
- isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
- }
- }
-
- string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
- }
- else if (fileSystemType == RESOURCE)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
- }
- else if (fileSystemType == APPLICATION)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- public void resolveLocalFileSystemURI(string options)
- {
-
- string[] optVals = getOptionStrings(options);
- string uri = optVals[0].Split('?')[0];
- string callbackId = optVals[1];
-
- if (uri != null)
- {
- // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
- if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
- try
- {
- // fix encoded spaces
- string path = Uri.UnescapeDataString(uri);
-
- FileEntry uriEntry = FileEntry.GetEntry(path);
- if (uriEntry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
- }
-
- public void copyTo(string options)
- {
- TransferTo(options, false);
- }
-
- public void moveTo(string options)
- {
- TransferTo(options, true);
- }
-
- public void getFile(string options)
- {
- GetFileOrDirectory(options, false);
- }
-
- public void getDirectory(string options)
- {
- GetFileOrDirectory(options, true);
- }
-
- #region internal functionality
-
- /// <summary>
- /// Retrieves the parent directory name of the specified path,
- /// </summary>
- /// <param name="path">Path</param>
- /// <returns>Parent directory name</returns>
- private string GetParentDirectory(string path)
- {
- if (String.IsNullOrEmpty(path) || path == "/")
- {
- return "/";
- }
-
- if (path.EndsWith(@"/") || path.EndsWith(@"\"))
- {
- return this.GetParentDirectory(Path.GetDirectoryName(path));
- }
-
- string result = Path.GetDirectoryName(path);
- if (result == null)
- {
- result = "/";
- }
-
- return result;
- }
-
- private bool removeDirRecursively(string fullPath,string callbackId)
- {
- try
- {
- if (fullPath == "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(fullPath))
- {
- string tempPath = File.AddSlashToDirectory(fullPath);
- string[] files = isoFile.GetFileNames(tempPath + "*");
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.DeleteFile(tempPath + file);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- if (!removeDirRecursively(tempPath + dir, callbackId))
- {
- return false;
- }
- }
- }
- isoFile.DeleteDirectory(fullPath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
- }
- return true;
- }
-
- private bool CanonicalCompare(string pathA, string pathB)
- {
- string a = pathA.Replace("//", "/");
- string b = pathB.Replace("//", "/");
-
- return a.Equals(b, StringComparison.OrdinalIgnoreCase);
- }
-
- /*
- * copyTo:["fullPath","parent", "newName"],
- * moveTo:["fullPath","parent", "newName"],
- */
- private void TransferTo(string options, bool move)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
- string fullPath = optStrings[0];
- string parent = optStrings[1];
- string newFileName = optStrings[2];
- string callbackId = optStrings[3];
-
- char[] invalids = Path.GetInvalidPathChars();
-
- if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string parentPath = File.AddSlashToDirectory(parent);
- string currentPath = fullPath;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFileExist = isoFile.FileExists(currentPath);
- bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
- bool isParentExist = isoFile.DirectoryExists(parentPath);
-
- if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string newName;
- string newPath;
- if (isFileExist)
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? Path.GetFileName(currentPath)
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- // sanity check ..
- // cannot copy file onto itself
- if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.DirectoryExists(newPath))
- {
- // there is already a folder with the same name, operation is not allowed
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.FileExists(newPath))
- { // remove destination file if exists, in other case there will be exception
- isoFile.DeleteFile(newPath);
- }
-
- if (move)
- {
- isoFile.MoveFile(currentPath, newPath);
- }
- else
- {
- isoFile.CopyFile(currentPath, newPath, true);
- }
- }
- else
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? currentPath
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- if (move)
- {
- // remove destination directory if exists, in other case there will be exception
- // target directory should be empty
- if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
- {
- isoFile.DeleteDirectory(newPath);
- }
-
- isoFile.MoveDirectory(currentPath, newPath);
- }
- else
- {
- CopyDirectory(currentPath, newPath, isoFile);
- }
- }
- FileEntry entry = FileEntry.GetEntry(newPath);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private bool HandleException(Exception ex, string cbId="")
- {
- bool handled = false;
- string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
- if (ex is SecurityException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
- handled = true;
- }
- else if (ex is FileNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- else if (ex is ArgumentException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- handled = true;
- }
- else if (ex is IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- handled = true;
- }
- else if (ex is DirectoryNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- return handled;
- }
-
- private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
- {
- string path = File.AddSlashToDirectory(sourceDir);
-
- bool bExists = isoFile.DirectoryExists(destDir);
-
- if (!bExists)
- {
- isoFile.CreateDirectory(destDir);
- }
-
- destDir = File.AddSlashToDirectory(destDir);
-
- string[] files = isoFile.GetFileNames(path + "*");
-
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.CopyFile(path + file, destDir + file,true);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- CopyDirectory(path + dir, destDir + dir, isoFile);
- }
- }
- }
-
- private void GetFileOrDirectory(string options, bool getDirectory)
- {
- FileOptions fOptions = new FileOptions();
- string[] args = getOptionStrings(options);
-
- fOptions.FullPath = args[0];
- fOptions.Path = args[1];
-
- string callbackId = args[3];
-
- try
- {
- fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- try
- {
- if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string path;
-
- if (fOptions.Path.Split(':').Length > 2)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFile = isoFile.FileExists(path);
- bool isDirectory = isoFile.DirectoryExists(path);
- bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
- bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
- if (create)
- {
- if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
- return;
- }
-
- // need to make sure the parent exists
- // it is an error to create a directory whose immediate parent does not yet exist
- // see issue: https://issues.apache.org/jira/browse/CB-339
- string[] pathParts = path.Split('/');
- string builtPath = pathParts[0];
- for (int n = 1; n < pathParts.Length - 1; n++)
- {
- builtPath += "/" + pathParts[n];
- if (!isoFile.DirectoryExists(builtPath))
- {
- Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- }
-
- if ((getDirectory) && (!isDirectory))
- {
- isoFile.CreateDirectory(path);
- }
- else
- {
- if ((!getDirectory) && (!isFile))
- {
-
- IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
- fileStream.Close();
- }
- }
- }
- else // (not create)
- {
- if ((!isFile) && (!isDirectory))
- {
- if (path.IndexOf("//www") == 0)
- {
- Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
-
- //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
- //{
- // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
-
- //}
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- return;
- }
- if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
- return;
- }
- }
- FileEntry entry = FileEntry.GetEntry(path);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private static string AddSlashToDirectory(string dirPath)
- {
- if (dirPath.EndsWith("/"))
- {
- return dirPath;
- }
- else
- {
- return dirPath + "/";
- }
- }
-
- /// <summary>
- /// Returns file content in a form of base64 string
- /// </summary>
- /// <param name="stream">File stream</param>
- /// <returns>Base64 representation of the file</returns>
- private string GetFileContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
-
- #endregion
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/FileTransfer.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/FileTransfer.cs b/wp7/template/Plugins/FileTransfer.cs
deleted file mode 100644
index e585895..0000000
--- a/wp7/template/Plugins/FileTransfer.cs
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Net;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Security;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class FileTransfer : BaseCommand
- {
- public class DownloadRequestState
- {
- // This class stores the State of the request.
- public HttpWebRequest request;
- public DownloadOptions options;
-
- public DownloadRequestState()
- {
- request = null;
- options = null;
- }
- }
-
- /// <summary>
- /// Boundary symbol
- /// </summary>
- private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
-
- // Error codes
- public const int FileNotFoundError = 1;
- public const int InvalidUrlError = 2;
- public const int ConnectionError = 3;
-
- /// <summary>
- /// Options for downloading file
- /// </summary>
- [DataContract]
- public class DownloadOptions
- {
- /// <summary>
- /// File path to download to
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address to the file to download
- /// </summary>
- [DataMember(Name = "url", IsRequired = true)]
- public string Url { get; set; }
- }
-
- /// <summary>
- /// Options for uploading file
- /// </summary>
- [DataContract]
- public class UploadOptions
- {
- /// <summary>
- /// File path to upload
- /// </summary>
- [DataMember(Name = "filePath", IsRequired = true)]
- public string FilePath { get; set; }
-
- /// <summary>
- /// Server address
- /// </summary>
- [DataMember(Name = "server", IsRequired = true)]
- public string Server { get; set; }
-
- /// <summary>
- /// File key
- /// </summary>
- [DataMember(Name = "fileKey")]
- public string FileKey { get; set; }
-
- /// <summary>
- /// File name on the server
- /// </summary>
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- /// <summary>
- /// File Mime type
- /// </summary>
- [DataMember(Name = "mimeType")]
- public string MimeType { get; set; }
-
-
- /// <summary>
- /// Additional options
- /// </summary>
- [DataMember(Name = "params")]
- public string Params { get; set; }
-
- /// <summary>
- /// Flag to recognize if we should trust every host (only in debug environments)
- /// </summary>
- [DataMember(Name = "debug")]
- public bool Debug { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public UploadOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.FileKey = "file";
- this.FileName = "image.jpg";
- this.MimeType = "image/jpeg";
- }
-
- }
-
- /// <summary>
- /// Uploading response info
- /// </summary>
- [DataContract]
- public class FileUploadResult
- {
- /// <summary>
- /// Amount of sent bytes
- /// </summary>
- [DataMember(Name = "bytesSent")]
- public long BytesSent { get; set; }
-
- /// <summary>
- /// Server response code
- /// </summary>
- [DataMember(Name = "responseCode")]
- public long ResponseCode { get; set; }
-
- /// <summary>
- /// Server response
- /// </summary>
- [DataMember(Name = "response", EmitDefaultValue = false)]
- public string Response { get; set; }
-
- /// <summary>
- /// Creates FileUploadResult object with response values
- /// </summary>
- /// <param name="bytesSent">Amount of sent bytes</param>
- /// <param name="responseCode">Server response code</param>
- /// <param name="response">Server response</param>
- public FileUploadResult(long bytesSent, long responseCode, string response)
- {
- this.BytesSent = bytesSent;
- this.ResponseCode = responseCode;
- this.Response = response;
- }
- }
-
- /// <summary>
- /// Represents transfer error codes for callback
- /// </summary>
- [DataContract]
- public class FileTransferError
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(Name = "code", IsRequired = true)]
- public int Code { get; set; }
-
- /// <summary>
- /// The source URI
- /// </summary>
- [DataMember(Name = "source", IsRequired = true)]
- public string Source { get; set; }
-
- /// <summary>
- /// The target URI
- /// </summary>
- [DataMember(Name = "target", IsRequired = true)]
- public string Target { get; set; }
-
- /// <summary>
- /// The http status code response from the remote URI
- /// </summary>
- [DataMember(Name = "http_status", IsRequired = true)]
- public int HttpStatus { get; set; }
-
- /// <summary>
- /// Creates FileTransferError object
- /// </summary>
- /// <param name="errorCode">Error code</param>
- public FileTransferError(int errorCode)
- {
- this.Code = errorCode;
- this.Source = null;
- this.Target = null;
- this.HttpStatus = 0;
- }
- public FileTransferError(int errorCode, string source, string target, int status)
- {
- this.Code = errorCode;
- this.Source = source;
- this.Target = target;
- this.HttpStatus = status;
- }
- }
-
- /// <summary>
- /// Upload options
- /// </summary>
- private UploadOptions uploadOptions;
-
- /// <summary>
- /// Bytes sent
- /// </summary>
- private long bytesSent;
-
- /// <summary>
- /// sends a file to a server
- /// </summary>
- /// <param name="options">Upload options</param>
- public void upload(string options)
- {
- Debug.WriteLine("options = " + options);
- options = options.Replace("{}", "null");
-
- try
- {
- try
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- Uri serverUri;
- try
- {
- serverUri = new Uri(uploadOptions.Server);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
- return;
- }
- HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
- webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
- webRequest.Method = "POST";
- webRequest.BeginGetRequestStream(WriteCallback, webRequest);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
-
- public void download(string options)
- {
- DownloadOptions downloadOptions = null;
- HttpWebRequest webRequest = null;
-
- try
- {
- string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-
- downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
- downloadOptions.Url = optionStrings[0];
- downloadOptions.FilePath = optionStrings[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
- return;
- }
-
- try
- {
- webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
- return;
- }
-
- if (downloadOptions != null && webRequest != null)
- {
- DownloadRequestState state = new DownloadRequestState();
- state.options = downloadOptions;
- state.request = webRequest;
- webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
- }
-
-
-
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void downloadCallback(IAsyncResult asynchronousResult)
- {
- DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
- HttpWebRequest request = reqState.request;
-
- try
- {
- HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(reqState.options.FilePath))
- {
- var file = isoFile.CreateFile(reqState.options.FilePath);
- file.Close();
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
- {
- long totalBytes = response.ContentLength;
- int bytesRead = 0;
- using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
- {
-
- using (BinaryWriter writer = new BinaryWriter(fileStream))
- {
- int BUFFER_SIZE = 1024;
- byte[] buffer;
-
- while (true)
- {
- buffer = reader.ReadBytes(BUFFER_SIZE);
- // fire a progress event ?
- bytesRead += buffer.Length;
- if (buffer.Length > 0)
- {
- writer.Write(buffer);
- }
- else
- {
- writer.Close();
- reader.Close();
- fileStream.Close();
- break;
- }
- }
- }
-
- }
-
-
- }
- }
- WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
- }
- catch (IsolatedStorageException)
- {
- // Trying to write the file somewhere within the IsoStorage.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (SecurityException)
- {
- // Trying to write the file somewhere not allowed.
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- catch (WebException webex)
- {
- // TODO: probably need better work here to properly respond with all http status codes back to JS
- // Right now am jumping through hoops just to detect 404.
- if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
- {
- // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
- // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
- // FACEPALM
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
- }
- }
-
-
-
- /// <summary>
- /// Read file from Isolated Storage and sends it to server
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void WriteCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
- {
- string lineStart = "--";
- string lineEnd = Environment.NewLine;
- byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
- string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
-
- if (uploadOptions.Params != null)
- {
-
- string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
-
- foreach (string param in arrParams)
- {
- string[] split = param.Split('=');
- string key = split[0];
- string val = split[1];
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- string formItem = string.Format(formdataTemplate, key, val);
- byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
- requestStream.Write(formItemBytes, 0, formItemBytes.Length);
- }
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(uploadOptions.FilePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
- return;
- }
-
- using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
- {
- string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
- string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
- byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- requestStream.Write(headerBytes, 0, headerBytes.Length);
- byte[] buffer = new byte[4096];
- int bytesRead = 0;
-
- while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
- {
- requestStream.Write(buffer, 0, bytesRead);
- bytesSent += bytesRead;
- }
- }
- byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
- requestStream.Write(endRequest, 0, endRequest.Length);
- }
- }
- webRequest.BeginGetResponse(ReadCallback, webRequest);
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
- });
- }
- }
-
- /// <summary>
- /// Reads response into FileUploadResult
- /// </summary>
- /// <param name="asynchronousResult"></param>
- private void ReadCallback(IAsyncResult asynchronousResult)
- {
- try
- {
- HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
- using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
- {
- using (Stream streamResponse = response.GetResponseStream())
- {
- using (StreamReader streamReader = new StreamReader(streamResponse))
- {
- string responseString = streamReader.ReadToEnd();
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
- });
- }
- }
- }
- }
- catch (Exception)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
- });
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp7/template/Plugins/GeoLocation.cs
----------------------------------------------------------------------
diff --git a/wp7/template/Plugins/GeoLocation.cs b/wp7/template/Plugins/GeoLocation.cs
deleted file mode 100644
index c53cb29..0000000
--- a/wp7/template/Plugins/GeoLocation.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Device.Location;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
- /// </summary>
- public class GeoLocation
- {
- /* Unreachable code, by design -jm */
- private void triggerGeoInclusion()
- {
- new GeoCoordinateWatcher();
- }
- }
-}
[07/50] [abbrv] plugin code becomes common code
Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Contacts.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Contacts.cs b/wp8/template/Plugins/Contacts.cs
deleted file mode 100644
index af78942..0000000
--- a/wp8/template/Plugins/Contacts.cs
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- 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.
-*/
-
-using Microsoft.Phone.Tasks;
-using Microsoft.Phone.UserData;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Windows;
-using DeviceContacts = Microsoft.Phone.UserData.Contacts;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class SearchOptions
- {
- [DataMember]
- public string filter { get; set; }
- [DataMember]
- public bool multiple { get; set; }
- }
-
- [DataContract]
- public class ContactSearchParams
- {
- [DataMember]
- public string[] fields { get; set; }
- [DataMember]
- public SearchOptions options { get; set; }
- }
-
- [DataContract]
- public class JSONContactAddress
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string streetAddress { get; set; }
- [DataMember]
- public string locality { get; set; }
- [DataMember]
- public string region { get; set; }
- [DataMember]
- public string postalCode { get; set; }
- [DataMember]
- public string country { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactName
- {
- [DataMember]
- public string formatted { get; set; }
- [DataMember]
- public string familyName { get; set; }
- [DataMember]
- public string givenName { get; set; }
- [DataMember]
- public string middleName { get; set; }
- [DataMember]
- public string honorificPrefix { get; set; }
- [DataMember]
- public string honorificSuffix { get; set; }
- }
-
- [DataContract]
- public class JSONContactField
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string value { get; set; }
- [DataMember]
- public bool pref { get; set; }
- }
-
- [DataContract]
- public class JSONContactOrganization
- {
- [DataMember]
- public string type { get; set; }
- [DataMember]
- public string name { get; set; }
- [DataMember]
- public bool pref { get; set; }
- [DataMember]
- public string department { get; set; }
- [DataMember]
- public string title { get; set; }
- }
-
- [DataContract]
- public class JSONContact
- {
- [DataMember]
- public string id { get; set; }
- [DataMember]
- public string rawId { get; set; }
- [DataMember]
- public string displayName { get; set; }
- [DataMember]
- public string nickname { get; set; }
- [DataMember]
- public string note { get; set; }
-
- [DataMember]
- public JSONContactName name { get; set; }
-
- [DataMember]
- public JSONContactField[] emails { get; set; }
-
- [DataMember]
- public JSONContactField[] phoneNumbers { get; set; }
-
- [DataMember]
- public JSONContactField[] ims { get; set; }
-
- [DataMember]
- public JSONContactField[] photos { get; set; }
-
- [DataMember]
- public JSONContactField[] categories { get; set; }
-
- [DataMember]
- public JSONContactField[] urls { get; set; }
-
- [DataMember]
- public JSONContactOrganization[] organizations { get; set; }
-
- [DataMember]
- public JSONContactAddress[] addresses { get; set; }
- }
-
-
- public class Contacts : BaseCommand
- {
-
- public const int UNKNOWN_ERROR = 0;
- public const int INVALID_ARGUMENT_ERROR = 1;
- public const int TIMEOUT_ERROR = 2;
- public const int PENDING_OPERATION_ERROR = 3;
- public const int IO_ERROR = 4;
- public const int NOT_SUPPORTED_ERROR = 5;
- public const int PERMISSION_DENIED_ERROR = 20;
- public const int SYNTAX_ERR = 8;
-
- public Contacts()
- {
-
- }
-
- // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
- public void save(string jsonContact)
- {
-
- // jsonContact is actually an array of 1 {contact}
- string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
-
-
- JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
-
- SaveContactTask contactTask = new SaveContactTask();
-
- if (contact.nickname != null)
- {
- contactTask.Nickname = contact.nickname;
- }
- if (contact.urls != null && contact.urls.Length > 0)
- {
- contactTask.Website = contact.urls[0].value;
- }
- if (contact.note != null)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.name
- if (contact.name != null)
- {
- if (contact.name.givenName != null)
- contactTask.FirstName = contact.name.givenName;
- if (contact.name.familyName != null)
- contactTask.LastName = contact.name.familyName;
- if (contact.name.middleName != null)
- contactTask.MiddleName = contact.name.middleName;
- if (contact.name.honorificSuffix != null)
- contactTask.Suffix = contact.name.honorificSuffix;
- if (contact.name.honorificPrefix != null)
- contactTask.Title = contact.name.honorificPrefix;
- }
- #endregion
-
- #region contact.org
- if (contact.organizations != null && contact.organizations.Count() > 0)
- {
- contactTask.Company = contact.organizations[0].name;
- contactTask.JobTitle = contact.organizations[0].title;
- }
- #endregion
-
- #region contact.phoneNumbers
- if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
- {
- foreach (JSONContactField field in contact.phoneNumbers)
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkPhone = field.value;
- }
- else if (fieldType == "home")
- {
- contactTask.HomePhone = field.value;
- }
- else if (fieldType == "mobile")
- {
- contactTask.MobilePhone = field.value;
- }
- }
- }
- #endregion
-
- #region contact.emails
-
- if (contact.emails != null && contact.emails.Length > 0)
- {
-
- // set up different email types if they are not explicitly defined
- foreach (string type in new string[] { "personal", "work", "other" })
- {
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null && String.IsNullOrEmpty(field.type))
- {
- field.type = type;
- break;
- }
- }
- }
-
- foreach (JSONContactField field in contact.emails)
- {
- if (field != null)
- {
- if (field.type != null && field.type != "other")
- {
- string fieldType = field.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkEmail = field.value;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.PersonalEmail = field.value;
- }
- }
- else
- {
- contactTask.OtherEmail = field.value;
- }
- }
-
- }
- }
- #endregion
-
- if (contact.note != null && contact.note.Length > 0)
- {
- contactTask.Notes = contact.note;
- }
-
- #region contact.addresses
- if (contact.addresses != null && contact.addresses.Length > 0)
- {
- foreach (JSONContactAddress address in contact.addresses)
- {
- if (address.type == null)
- {
- address.type = "home"; // set a default
- }
- string fieldType = address.type.ToLower();
- if (fieldType == "work")
- {
- contactTask.WorkAddressCity = address.locality;
- contactTask.WorkAddressCountry = address.country;
- contactTask.WorkAddressState = address.region;
- contactTask.WorkAddressStreet = address.streetAddress;
- contactTask.WorkAddressZipCode = address.postalCode;
- }
- else if (fieldType == "home" || fieldType == "personal")
- {
- contactTask.HomeAddressCity = address.locality;
- contactTask.HomeAddressCountry = address.country;
- contactTask.HomeAddressState = address.region;
- contactTask.HomeAddressStreet = address.streetAddress;
- contactTask.HomeAddressZipCode = address.postalCode;
- }
- else
- {
- // no other address fields available ...
- Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
- }
- }
- }
- #endregion
-
-
- contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
- contactTask.Show();
- }
-
- void ContactSaveTaskCompleted(object sender, SaveContactResult e)
- {
- SaveContactTask task = sender as SaveContactTask;
-
- if (e.TaskResult == TaskResult.OK)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
-
- string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
-
- deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
- });
-
-
- }
- else if (e.TaskResult == TaskResult.Cancel)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
- }
- }
-
- void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- if (e.Results.Count() > 0)
- {
- List<Contact> foundContacts = new List<Contact>();
-
- int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
- Contact newContact = (from Contact contact in e.Results
- where contact.GetHashCode() == n
- select contact).First();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
- }
- }
-
-
-
- public void remove(string id)
- {
- // note id is wrapped in [] and always has exactly one string ...
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
- }
-
- public void search(string searchCriteria)
- {
- string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
-
- ContactSearchParams searchParams = new ContactSearchParams();
- try
- {
- searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
- searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
- return;
- }
-
- if (searchParams.options == null)
- {
- searchParams.options = new SearchOptions();
- searchParams.options.filter = "";
- searchParams.options.multiple = true;
- }
-
- DeviceContacts deviceContacts = new DeviceContacts();
- deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
-
- // default is to search all fields
- FilterKind filterKind = FilterKind.None;
- // if only one field is specified, we will try the 3 available DeviceContact search filters
- if (searchParams.fields.Count() == 1)
- {
- if (searchParams.fields.Contains("name"))
- {
- filterKind = FilterKind.DisplayName;
- }
- else if (searchParams.fields.Contains("emails"))
- {
- filterKind = FilterKind.EmailAddress;
- }
- else if (searchParams.fields.Contains("phoneNumbers"))
- {
- filterKind = FilterKind.PhoneNumber;
- }
- }
-
- try
- {
-
- deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
- }
- catch (Exception ex)
- {
- Debug.WriteLine("search contacts exception :: " + ex.Message);
- }
- }
-
- private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
- {
- ContactSearchParams searchParams = (ContactSearchParams)e.State;
-
- List<Contact> foundContacts = null;
-
- // if we have multiple search fields
- if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
- {
- foundContacts = new List<Contact>();
- if (searchParams.fields.Contains("emails"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactEmailAddress a in con.EmailAddresses
- where a.EmailAddress.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("displayName"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.DisplayName.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("name"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("phoneNumbers"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from ContactPhoneNumber a in con.PhoneNumbers
- where a.PhoneNumber.Contains(searchParams.options.filter)
- select con);
- }
- if (searchParams.fields.Contains("urls"))
- {
- foundContacts.AddRange(from Contact con in e.Results
- from string a in con.Websites
- where a.Contains(searchParams.options.filter)
- select con);
- }
- }
- else
- {
- foundContacts = new List<Contact>(e.Results);
- }
-
- //List<string> contactList = new List<string>();
-
- string strResult = "";
-
- IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
-
- foreach (Contact contact in distinctContacts)
- {
- strResult += FormatJSONContact(contact, null) + ",";
- //contactList.Add(FormatJSONContact(contact, null));
- if (!searchParams.options.multiple)
- {
- break; // just return the first item
- }
- }
- PluginResult result = new PluginResult(PluginResult.Status.OK);
- result.Message = "[" + strResult.TrimEnd(',') + "]";
- DispatchCommandResult(result);
-
- }
-
- private string FormatJSONPhoneNumbers(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactPhoneNumber number in con.PhoneNumbers)
- {
-
- string contactField = string.Format(contactFieldFormat,
- number.Kind.ToString(),
- number.PhoneNumber);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONEmails(Contact con)
- {
- string retVal = "";
- string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
- foreach (ContactEmailAddress address in con.EmailAddresses)
- {
- string contactField = string.Format(contactFieldFormat,
- address.Kind.ToString(),
- address.EmailAddress);
-
- retVal += "{" + contactField + "},";
- }
- return retVal.TrimEnd(',');
- }
-
- private string getFormattedJSONAddress(ContactAddress address, bool isPrefered)
- {
-
- string addressFormatString = "\"pref\":{0}," + // bool
- "\"type\":\"{1}\"," +
- "\"formatted\":\"{2}\"," +
- "\"streetAddress\":\"{3}\"," +
- "\"locality\":\"{4}\"," +
- "\"region\":\"{5}\"," +
- "\"postalCode\":\"{6}\"," +
- "\"country\":\"{7}\"";
-
- string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
- + address.PhysicalAddress.AddressLine2 + " "
- + address.PhysicalAddress.City + " "
- + address.PhysicalAddress.StateProvince + " "
- + address.PhysicalAddress.CountryRegion + " "
- + address.PhysicalAddress.PostalCode;
-
- string jsonAddress = string.Format(addressFormatString,
- isPrefered ? "\"true\"" : "\"false\"",
- address.Kind.ToString(),
- formattedAddress,
- address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
- address.PhysicalAddress.City,
- address.PhysicalAddress.StateProvince,
- address.PhysicalAddress.PostalCode,
- address.PhysicalAddress.CountryRegion);
-
- //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
-
- return "{" + jsonAddress + "}";
- }
-
- private string FormatJSONAddresses(Contact con)
- {
- string retVal = "";
- foreach (ContactAddress address in con.Addresses)
- {
- retVal += this.getFormattedJSONAddress(address, false) + ",";
- }
-
- //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
- return retVal.TrimEnd(',');
- }
-
- private string FormatJSONWebsites(Contact con)
- {
- string retVal = "";
- foreach (string website in con.Websites)
- {
- retVal += "\"" + website + "\",";
- }
- return retVal.TrimEnd(',');
- }
-
- /*
- * formatted: The complete name of the contact. (DOMString)
- familyName: The contacts family name. (DOMString)
- givenName: The contacts given name. (DOMString)
- middleName: The contacts middle name. (DOMString)
- honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
- honorificSuffix: The contacts suffix (example Esq.). (DOMString)
- */
- private string FormatJSONName(Contact con)
- {
- string retVal = "";
- string formatStr = "\"formatted\":\"{0}\"," +
- "\"familyName\":\"{1}\"," +
- "\"givenName\":\"{2}\"," +
- "\"middleName\":\"{3}\"," +
- "\"honorificPrefix\":\"{4}\"," +
- "\"honorificSuffix\":\"{5}\"";
-
- if (con.CompleteName != null)
- {
- retVal = string.Format(formatStr,
- con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
- con.CompleteName.LastName,
- con.CompleteName.FirstName,
- con.CompleteName.MiddleName,
- con.CompleteName.Title,
- con.CompleteName.Suffix);
- }
- else
- {
- retVal = string.Format(formatStr,"","","","","","");
- }
-
- return "{" + retVal + "}";
- }
-
- private string FormatJSONContact(Contact con, string[] fields)
- {
-
- string contactFormatStr = "\"id\":\"{0}\"," +
- "\"displayName\":\"{1}\"," +
- "\"nickname\":\"{2}\"," +
- "\"phoneNumbers\":[{3}]," +
- "\"emails\":[{4}]," +
- "\"addresses\":[{5}]," +
- "\"urls\":[{6}]," +
- "\"name\":{7}," +
- "\"note\":\"{8}\"," +
- "\"birthday\":\"{9}\"";
-
-
- string jsonContact = String.Format(contactFormatStr,
- con.GetHashCode(),
- con.DisplayName,
- con.CompleteName != null ? con.CompleteName.Nickname : "",
- FormatJSONPhoneNumbers(con),
- FormatJSONEmails(con),
- FormatJSONAddresses(con),
- FormatJSONWebsites(con),
- FormatJSONName(con),
- con.Notes.FirstOrDefault(),
- con.Birthdays.FirstOrDefault());
-
- //Debug.WriteLine("jsonContact = " + jsonContact);
- // JSON requires new line characters be escaped
- return "{" + jsonContact.Replace("\n", "\\n") + "}";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/DebugConsole.cs b/wp8/template/Plugins/DebugConsole.cs
deleted file mode 100644
index fa9863a..0000000
--- a/wp8/template/Plugins/DebugConsole.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- public class DebugConsole : BaseCommand
- {
- // warn, error
- public void log(string msg)
- {
- Debug.WriteLine("Log:" + msg);
- }
-
- public void error(string msg)
- {
- Debug.WriteLine("Error:" + msg);
- }
-
- public void warn(string msg)
- {
- Debug.WriteLine("Warn:" + msg);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/dec32ea1/wp8/template/Plugins/Device.cs
----------------------------------------------------------------------
diff --git a/wp8/template/Plugins/Device.cs b/wp8/template/Plugins/Device.cs
deleted file mode 100644
index 8abb4ff..0000000
--- a/wp8/template/Plugins/Device.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Info;
-using System.IO.IsolatedStorage;
-using System.Windows.Resources;
-using System.IO;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- public class Device : BaseCommand
- {
- public void getDeviceInfo(string notused)
- {
-
- string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
- this.name,
- this.cordova,
- this.platform,
- this.uuid,
- this.version,
- this.model);
-
-
-
- res = "{" + res + "}";
- //Debug.WriteLine("Result::" + res);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
- }
-
- public string model
- {
- get
- {
- return DeviceStatus.DeviceName;
- //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion);
- }
- }
-
- public string name
- {
- get
- {
- return DeviceStatus.DeviceName;
-
- }
- }
-
- public string cordova
- {
- get
- {
- // TODO: should be able to dynamically read the Cordova version from somewhere...
- return "0.0.0";
- }
- }
-
- public string platform
- {
- get
- {
- return Environment.OSVersion.Platform.ToString();
- }
- }
-
- public string uuid
- {
- get
- {
- string returnVal = "";
- object id;
- UserExtendedProperties.TryGetValue("ANID", out id);
-
- if (id != null)
- {
- returnVal = id.ToString().Substring(2, 32);
- }
- else
- {
- returnVal = "???unknown???";
-
- using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- try
- {
- IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
- using (StreamReader reader = new StreamReader(fileStream))
- {
- returnVal = reader.ReadLine();
- }
- }
- catch (Exception /*ex*/)
- {
-
- }
- }
- }
-
- return returnVal;
- }
- }
-
- public string version
- {
- get
- {
- return Environment.OSVersion.Version.ToString();
- }
- }
-
- }
-}