You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2015/01/07 01:45:15 UTC
[01/10] ios commit: CB-5706 convert some of the bash scripts to
nodejs (closes #118)
Repository: cordova-ios
Updated Branches:
refs/heads/wkwebview 1d4ba9778 -> e0dc7443b
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/q.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/q.js b/bin/node_modules/q/q.js
new file mode 100644
index 0000000..df36027
--- /dev/null
+++ b/bin/node_modules/q/q.js
@@ -0,0 +1,1904 @@
+// vim:ts=4:sts=4:sw=4:
+/*!
+ *
+ * Copyright 2009-2012 Kris Kowal under the terms of the MIT
+ * license found at http://github.com/kriskowal/q/raw/master/LICENSE
+ *
+ * With parts by Tyler Close
+ * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
+ * at http://www.opensource.org/licenses/mit-license.html
+ * Forked at ref_send.js version: 2009-05-11
+ *
+ * With parts by Mark Miller
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 (definition) {
+ // Turn off strict mode for this function so we can assign to global.Q
+ /* jshint strict: false */
+
+ // This file will function properly as a <script> tag, or a module
+ // using CommonJS and NodeJS or RequireJS module formats. In
+ // Common/Node/RequireJS, the module exports the Q API and when
+ // executed as a simple <script>, it creates a Q global instead.
+
+ // Montage Require
+ if (typeof bootstrap === "function") {
+ bootstrap("promise", definition);
+
+ // CommonJS
+ } else if (typeof exports === "object") {
+ module.exports = definition();
+
+ // RequireJS
+ } else if (typeof define === "function" && define.amd) {
+ define(definition);
+
+ // SES (Secure EcmaScript)
+ } else if (typeof ses !== "undefined") {
+ if (!ses.ok()) {
+ return;
+ } else {
+ ses.makeQ = definition;
+ }
+
+ // <script>
+ } else {
+ Q = definition();
+ }
+
+})(function () {
+"use strict";
+
+var hasStacks = false;
+try {
+ throw new Error();
+} catch (e) {
+ hasStacks = !!e.stack;
+}
+
+// All code after this point will be filtered from stack traces reported
+// by Q.
+var qStartingLine = captureLine();
+var qFileName;
+
+// shims
+
+// used for fallback in "allResolved"
+var noop = function () {};
+
+// Use the fastest possible means to execute a task in a future turn
+// of the event loop.
+var nextTick =(function () {
+ // linked list of tasks (single, with head node)
+ var head = {task: void 0, next: null};
+ var tail = head;
+ var flushing = false;
+ var requestTick = void 0;
+ var isNodeJS = false;
+
+ function flush() {
+ /* jshint loopfunc: true */
+
+ while (head.next) {
+ head = head.next;
+ var task = head.task;
+ head.task = void 0;
+ var domain = head.domain;
+
+ if (domain) {
+ head.domain = void 0;
+ domain.enter();
+ }
+
+ try {
+ task();
+
+ } catch (e) {
+ if (isNodeJS) {
+ // In node, uncaught exceptions are considered fatal errors.
+ // Re-throw them synchronously to interrupt flushing!
+
+ // Ensure continuation if the uncaught exception is suppressed
+ // listening "uncaughtException" events (as domains does).
+ // Continue in next event to avoid tick recursion.
+ if (domain) {
+ domain.exit();
+ }
+ setTimeout(flush, 0);
+ if (domain) {
+ domain.enter();
+ }
+
+ throw e;
+
+ } else {
+ // In browsers, uncaught exceptions are not fatal.
+ // Re-throw them asynchronously to avoid slow-downs.
+ setTimeout(function() {
+ throw e;
+ }, 0);
+ }
+ }
+
+ if (domain) {
+ domain.exit();
+ }
+ }
+
+ flushing = false;
+ }
+
+ nextTick = function (task) {
+ tail = tail.next = {
+ task: task,
+ domain: isNodeJS && process.domain,
+ next: null
+ };
+
+ if (!flushing) {
+ flushing = true;
+ requestTick();
+ }
+ };
+
+ if (typeof process !== "undefined" && process.nextTick) {
+ // Node.js before 0.9. Note that some fake-Node environments, like the
+ // Mocha test runner, introduce a `process` global without a `nextTick`.
+ isNodeJS = true;
+
+ requestTick = function () {
+ process.nextTick(flush);
+ };
+
+ } else if (typeof setImmediate === "function") {
+ // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
+ if (typeof window !== "undefined") {
+ requestTick = setImmediate.bind(window, flush);
+ } else {
+ requestTick = function () {
+ setImmediate(flush);
+ };
+ }
+
+ } else if (typeof MessageChannel !== "undefined") {
+ // modern browsers
+ // http://www.nonblocking.io/2011/06/windownexttick.html
+ var channel = new MessageChannel();
+ // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
+ // working message ports the first time a page loads.
+ channel.port1.onmessage = function () {
+ requestTick = requestPortTick;
+ channel.port1.onmessage = flush;
+ flush();
+ };
+ var requestPortTick = function () {
+ // Opera requires us to provide a message payload, regardless of
+ // whether we use it.
+ channel.port2.postMessage(0);
+ };
+ requestTick = function () {
+ setTimeout(flush, 0);
+ requestPortTick();
+ };
+
+ } else {
+ // old browsers
+ requestTick = function () {
+ setTimeout(flush, 0);
+ };
+ }
+
+ return nextTick;
+})();
+
+// Attempt to make generics safe in the face of downstream
+// modifications.
+// There is no situation where this is necessary.
+// If you need a security guarantee, these primordials need to be
+// deeply frozen anyway, and if you don’t need a security guarantee,
+// this is just plain paranoid.
+// However, this **might** have the nice side-effect of reducing the size of
+// the minified code by reducing x.call() to merely x()
+// See Mark Miller’s explanation of what this does.
+// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
+var call = Function.call;
+function uncurryThis(f) {
+ return function () {
+ return call.apply(f, arguments);
+ };
+}
+// This is equivalent, but slower:
+// uncurryThis = Function_bind.bind(Function_bind.call);
+// http://jsperf.com/uncurrythis
+
+var array_slice = uncurryThis(Array.prototype.slice);
+
+var array_reduce = uncurryThis(
+ Array.prototype.reduce || function (callback, basis) {
+ var index = 0,
+ length = this.length;
+ // concerning the initial value, if one is not provided
+ if (arguments.length === 1) {
+ // seek to the first value in the array, accounting
+ // for the possibility that is is a sparse array
+ do {
+ if (index in this) {
+ basis = this[index++];
+ break;
+ }
+ if (++index >= length) {
+ throw new TypeError();
+ }
+ } while (1);
+ }
+ // reduce
+ for (; index < length; index++) {
+ // account for the possibility that the array is sparse
+ if (index in this) {
+ basis = callback(basis, this[index], index);
+ }
+ }
+ return basis;
+ }
+);
+
+var array_indexOf = uncurryThis(
+ Array.prototype.indexOf || function (value) {
+ // not a very good shim, but good enough for our one use of it
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] === value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+);
+
+var array_map = uncurryThis(
+ Array.prototype.map || function (callback, thisp) {
+ var self = this;
+ var collect = [];
+ array_reduce(self, function (undefined, value, index) {
+ collect.push(callback.call(thisp, value, index, self));
+ }, void 0);
+ return collect;
+ }
+);
+
+var object_create = Object.create || function (prototype) {
+ function Type() { }
+ Type.prototype = prototype;
+ return new Type();
+};
+
+var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
+
+var object_keys = Object.keys || function (object) {
+ var keys = [];
+ for (var key in object) {
+ if (object_hasOwnProperty(object, key)) {
+ keys.push(key);
+ }
+ }
+ return keys;
+};
+
+var object_toString = uncurryThis(Object.prototype.toString);
+
+function isObject(value) {
+ return value === Object(value);
+}
+
+// generator related shims
+
+// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
+function isStopIteration(exception) {
+ return (
+ object_toString(exception) === "[object StopIteration]" ||
+ exception instanceof QReturnValue
+ );
+}
+
+// FIXME: Remove this helper and Q.return once ES6 generators are in
+// SpiderMonkey.
+var QReturnValue;
+if (typeof ReturnValue !== "undefined") {
+ QReturnValue = ReturnValue;
+} else {
+ QReturnValue = function (value) {
+ this.value = value;
+ };
+}
+
+// long stack traces
+
+var STACK_JUMP_SEPARATOR = "From previous event:";
+
+function makeStackTraceLong(error, promise) {
+ // If possible, transform the error stack trace by removing Node and Q
+ // cruft, then concatenating with the stack trace of `promise`. See #57.
+ if (hasStacks &&
+ promise.stack &&
+ typeof error === "object" &&
+ error !== null &&
+ error.stack &&
+ error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
+ ) {
+ var stacks = [];
+ for (var p = promise; !!p; p = p.source) {
+ if (p.stack) {
+ stacks.unshift(p.stack);
+ }
+ }
+ stacks.unshift(error.stack);
+
+ var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
+ error.stack = filterStackString(concatedStacks);
+ }
+}
+
+function filterStackString(stackString) {
+ var lines = stackString.split("\n");
+ var desiredLines = [];
+ for (var i = 0; i < lines.length; ++i) {
+ var line = lines[i];
+
+ if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
+ desiredLines.push(line);
+ }
+ }
+ return desiredLines.join("\n");
+}
+
+function isNodeFrame(stackLine) {
+ return stackLine.indexOf("(module.js:") !== -1 ||
+ stackLine.indexOf("(node.js:") !== -1;
+}
+
+function getFileNameAndLineNumber(stackLine) {
+ // Named functions: "at functionName (filename:lineNumber:columnNumber)"
+ // In IE10 function name can have spaces ("Anonymous function") O_o
+ var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
+ if (attempt1) {
+ return [attempt1[1], Number(attempt1[2])];
+ }
+
+ // Anonymous functions: "at filename:lineNumber:columnNumber"
+ var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
+ if (attempt2) {
+ return [attempt2[1], Number(attempt2[2])];
+ }
+
+ // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
+ var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
+ if (attempt3) {
+ return [attempt3[1], Number(attempt3[2])];
+ }
+}
+
+function isInternalFrame(stackLine) {
+ var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
+
+ if (!fileNameAndLineNumber) {
+ return false;
+ }
+
+ var fileName = fileNameAndLineNumber[0];
+ var lineNumber = fileNameAndLineNumber[1];
+
+ return fileName === qFileName &&
+ lineNumber >= qStartingLine &&
+ lineNumber <= qEndingLine;
+}
+
+// discover own file name and line number range for filtering stack
+// traces
+function captureLine() {
+ if (!hasStacks) {
+ return;
+ }
+
+ try {
+ throw new Error();
+ } catch (e) {
+ var lines = e.stack.split("\n");
+ var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
+ var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
+ if (!fileNameAndLineNumber) {
+ return;
+ }
+
+ qFileName = fileNameAndLineNumber[0];
+ return fileNameAndLineNumber[1];
+ }
+}
+
+function deprecate(callback, name, alternative) {
+ return function () {
+ if (typeof console !== "undefined" &&
+ typeof console.warn === "function") {
+ console.warn(name + " is deprecated, use " + alternative +
+ " instead.", new Error("").stack);
+ }
+ return callback.apply(callback, arguments);
+ };
+}
+
+// end of shims
+// beginning of real work
+
+/**
+ * Constructs a promise for an immediate reference, passes promises through, or
+ * coerces promises from different systems.
+ * @param value immediate reference or promise
+ */
+function Q(value) {
+ // If the object is already a Promise, return it directly. This enables
+ // the resolve function to both be used to created references from objects,
+ // but to tolerably coerce non-promises to promises.
+ if (isPromise(value)) {
+ return value;
+ }
+
+ // assimilate thenables
+ if (isPromiseAlike(value)) {
+ return coerce(value);
+ } else {
+ return fulfill(value);
+ }
+}
+Q.resolve = Q;
+
+/**
+ * Performs a task in a future turn of the event loop.
+ * @param {Function} task
+ */
+Q.nextTick = nextTick;
+
+/**
+ * Controls whether or not long stack traces will be on
+ */
+Q.longStackSupport = false;
+
+/**
+ * Constructs a {promise, resolve, reject} object.
+ *
+ * `resolve` is a callback to invoke with a more resolved value for the
+ * promise. To fulfill the promise, invoke `resolve` with any value that is
+ * not a thenable. To reject the promise, invoke `resolve` with a rejected
+ * thenable, or invoke `reject` with the reason directly. To resolve the
+ * promise to another thenable, thus putting it in the same state, invoke
+ * `resolve` with that other thenable.
+ */
+Q.defer = defer;
+function defer() {
+ // if "messages" is an "Array", that indicates that the promise has not yet
+ // been resolved. If it is "undefined", it has been resolved. Each
+ // element of the messages array is itself an array of complete arguments to
+ // forward to the resolved promise. We coerce the resolution value to a
+ // promise using the `resolve` function because it handles both fully
+ // non-thenable values and other thenables gracefully.
+ var messages = [], progressListeners = [], resolvedPromise;
+
+ var deferred = object_create(defer.prototype);
+ var promise = object_create(Promise.prototype);
+
+ promise.promiseDispatch = function (resolve, op, operands) {
+ var args = array_slice(arguments);
+ if (messages) {
+ messages.push(args);
+ if (op === "when" && operands[1]) { // progress operand
+ progressListeners.push(operands[1]);
+ }
+ } else {
+ nextTick(function () {
+ resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
+ });
+ }
+ };
+
+ // XXX deprecated
+ promise.valueOf = function () {
+ if (messages) {
+ return promise;
+ }
+ var nearerValue = nearer(resolvedPromise);
+ if (isPromise(nearerValue)) {
+ resolvedPromise = nearerValue; // shorten chain
+ }
+ return nearerValue;
+ };
+
+ promise.inspect = function () {
+ if (!resolvedPromise) {
+ return { state: "pending" };
+ }
+ return resolvedPromise.inspect();
+ };
+
+ if (Q.longStackSupport && hasStacks) {
+ try {
+ throw new Error();
+ } catch (e) {
+ // NOTE: don't try to use `Error.captureStackTrace` or transfer the
+ // accessor around; that causes memory leaks as per GH-111. Just
+ // reify the stack trace as a string ASAP.
+ //
+ // At the same time, cut off the first line; it's always just
+ // "[object Promise]\n", as per the `toString`.
+ promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
+ }
+ }
+
+ // NOTE: we do the checks for `resolvedPromise` in each method, instead of
+ // consolidating them into `become`, since otherwise we'd create new
+ // promises with the lines `become(whatever(value))`. See e.g. GH-252.
+
+ function become(newPromise) {
+ resolvedPromise = newPromise;
+ promise.source = newPromise;
+
+ array_reduce(messages, function (undefined, message) {
+ nextTick(function () {
+ newPromise.promiseDispatch.apply(newPromise, message);
+ });
+ }, void 0);
+
+ messages = void 0;
+ progressListeners = void 0;
+ }
+
+ deferred.promise = promise;
+ deferred.resolve = function (value) {
+ if (resolvedPromise) {
+ return;
+ }
+
+ become(Q(value));
+ };
+
+ deferred.fulfill = function (value) {
+ if (resolvedPromise) {
+ return;
+ }
+
+ become(fulfill(value));
+ };
+ deferred.reject = function (reason) {
+ if (resolvedPromise) {
+ return;
+ }
+
+ become(reject(reason));
+ };
+ deferred.notify = function (progress) {
+ if (resolvedPromise) {
+ return;
+ }
+
+ array_reduce(progressListeners, function (undefined, progressListener) {
+ nextTick(function () {
+ progressListener(progress);
+ });
+ }, void 0);
+ };
+
+ return deferred;
+}
+
+/**
+ * Creates a Node-style callback that will resolve or reject the deferred
+ * promise.
+ * @returns a nodeback
+ */
+defer.prototype.makeNodeResolver = function () {
+ var self = this;
+ return function (error, value) {
+ if (error) {
+ self.reject(error);
+ } else if (arguments.length > 2) {
+ self.resolve(array_slice(arguments, 1));
+ } else {
+ self.resolve(value);
+ }
+ };
+};
+
+/**
+ * @param resolver {Function} a function that returns nothing and accepts
+ * the resolve, reject, and notify functions for a deferred.
+ * @returns a promise that may be resolved with the given resolve and reject
+ * functions, or rejected by a thrown exception in resolver
+ */
+Q.Promise = promise; // ES6
+Q.promise = promise;
+function promise(resolver) {
+ if (typeof resolver !== "function") {
+ throw new TypeError("resolver must be a function.");
+ }
+ var deferred = defer();
+ try {
+ resolver(deferred.resolve, deferred.reject, deferred.notify);
+ } catch (reason) {
+ deferred.reject(reason);
+ }
+ return deferred.promise;
+}
+
+promise.race = race; // ES6
+promise.all = all; // ES6
+promise.reject = reject; // ES6
+promise.resolve = Q; // ES6
+
+// XXX experimental. This method is a way to denote that a local value is
+// serializable and should be immediately dispatched to a remote upon request,
+// instead of passing a reference.
+Q.passByCopy = function (object) {
+ //freeze(object);
+ //passByCopies.set(object, true);
+ return object;
+};
+
+Promise.prototype.passByCopy = function () {
+ //freeze(object);
+ //passByCopies.set(object, true);
+ return this;
+};
+
+/**
+ * If two promises eventually fulfill to the same value, promises that value,
+ * but otherwise rejects.
+ * @param x {Any*}
+ * @param y {Any*}
+ * @returns {Any*} a promise for x and y if they are the same, but a rejection
+ * otherwise.
+ *
+ */
+Q.join = function (x, y) {
+ return Q(x).join(y);
+};
+
+Promise.prototype.join = function (that) {
+ return Q([this, that]).spread(function (x, y) {
+ if (x === y) {
+ // TODO: "===" should be Object.is or equiv
+ return x;
+ } else {
+ throw new Error("Can't join: not the same: " + x + " " + y);
+ }
+ });
+};
+
+/**
+ * Returns a promise for the first of an array of promises to become fulfilled.
+ * @param answers {Array[Any*]} promises to race
+ * @returns {Any*} the first promise to be fulfilled
+ */
+Q.race = race;
+function race(answerPs) {
+ return promise(function(resolve, reject) {
+ // Switch to this once we can assume at least ES5
+ // answerPs.forEach(function(answerP) {
+ // Q(answerP).then(resolve, reject);
+ // });
+ // Use this in the meantime
+ for (var i = 0, len = answerPs.length; i < len; i++) {
+ Q(answerPs[i]).then(resolve, reject);
+ }
+ });
+}
+
+Promise.prototype.race = function () {
+ return this.then(Q.race);
+};
+
+/**
+ * Constructs a Promise with a promise descriptor object and optional fallback
+ * function. The descriptor contains methods like when(rejected), get(name),
+ * set(name, value), post(name, args), and delete(name), which all
+ * return either a value, a promise for a value, or a rejection. The fallback
+ * accepts the operation name, a resolver, and any further arguments that would
+ * have been forwarded to the appropriate method above had a method been
+ * provided with the proper name. The API makes no guarantees about the nature
+ * of the returned object, apart from that it is usable whereever promises are
+ * bought and sold.
+ */
+Q.makePromise = Promise;
+function Promise(descriptor, fallback, inspect) {
+ if (fallback === void 0) {
+ fallback = function (op) {
+ return reject(new Error(
+ "Promise does not support operation: " + op
+ ));
+ };
+ }
+ if (inspect === void 0) {
+ inspect = function () {
+ return {state: "unknown"};
+ };
+ }
+
+ var promise = object_create(Promise.prototype);
+
+ promise.promiseDispatch = function (resolve, op, args) {
+ var result;
+ try {
+ if (descriptor[op]) {
+ result = descriptor[op].apply(promise, args);
+ } else {
+ result = fallback.call(promise, op, args);
+ }
+ } catch (exception) {
+ result = reject(exception);
+ }
+ if (resolve) {
+ resolve(result);
+ }
+ };
+
+ promise.inspect = inspect;
+
+ // XXX deprecated `valueOf` and `exception` support
+ if (inspect) {
+ var inspected = inspect();
+ if (inspected.state === "rejected") {
+ promise.exception = inspected.reason;
+ }
+
+ promise.valueOf = function () {
+ var inspected = inspect();
+ if (inspected.state === "pending" ||
+ inspected.state === "rejected") {
+ return promise;
+ }
+ return inspected.value;
+ };
+ }
+
+ return promise;
+}
+
+Promise.prototype.toString = function () {
+ return "[object Promise]";
+};
+
+Promise.prototype.then = function (fulfilled, rejected, progressed) {
+ var self = this;
+ var deferred = defer();
+ var done = false; // ensure the untrusted promise makes at most a
+ // single call to one of the callbacks
+
+ function _fulfilled(value) {
+ try {
+ return typeof fulfilled === "function" ? fulfilled(value) : value;
+ } catch (exception) {
+ return reject(exception);
+ }
+ }
+
+ function _rejected(exception) {
+ if (typeof rejected === "function") {
+ makeStackTraceLong(exception, self);
+ try {
+ return rejected(exception);
+ } catch (newException) {
+ return reject(newException);
+ }
+ }
+ return reject(exception);
+ }
+
+ function _progressed(value) {
+ return typeof progressed === "function" ? progressed(value) : value;
+ }
+
+ nextTick(function () {
+ self.promiseDispatch(function (value) {
+ if (done) {
+ return;
+ }
+ done = true;
+
+ deferred.resolve(_fulfilled(value));
+ }, "when", [function (exception) {
+ if (done) {
+ return;
+ }
+ done = true;
+
+ deferred.resolve(_rejected(exception));
+ }]);
+ });
+
+ // Progress propagator need to be attached in the current tick.
+ self.promiseDispatch(void 0, "when", [void 0, function (value) {
+ var newValue;
+ var threw = false;
+ try {
+ newValue = _progressed(value);
+ } catch (e) {
+ threw = true;
+ if (Q.onerror) {
+ Q.onerror(e);
+ } else {
+ throw e;
+ }
+ }
+
+ if (!threw) {
+ deferred.notify(newValue);
+ }
+ }]);
+
+ return deferred.promise;
+};
+
+/**
+ * Registers an observer on a promise.
+ *
+ * Guarantees:
+ *
+ * 1. that fulfilled and rejected will be called only once.
+ * 2. that either the fulfilled callback or the rejected callback will be
+ * called, but not both.
+ * 3. that fulfilled and rejected will not be called in this turn.
+ *
+ * @param value promise or immediate reference to observe
+ * @param fulfilled function to be called with the fulfilled value
+ * @param rejected function to be called with the rejection exception
+ * @param progressed function to be called on any progress notifications
+ * @return promise for the return value from the invoked callback
+ */
+Q.when = when;
+function when(value, fulfilled, rejected, progressed) {
+ return Q(value).then(fulfilled, rejected, progressed);
+}
+
+Promise.prototype.thenResolve = function (value) {
+ return this.then(function () { return value; });
+};
+
+Q.thenResolve = function (promise, value) {
+ return Q(promise).thenResolve(value);
+};
+
+Promise.prototype.thenReject = function (reason) {
+ return this.then(function () { throw reason; });
+};
+
+Q.thenReject = function (promise, reason) {
+ return Q(promise).thenReject(reason);
+};
+
+/**
+ * If an object is not a promise, it is as "near" as possible.
+ * If a promise is rejected, it is as "near" as possible too.
+ * If it’s a fulfilled promise, the fulfillment value is nearer.
+ * If it’s a deferred promise and the deferred has been resolved, the
+ * resolution is "nearer".
+ * @param object
+ * @returns most resolved (nearest) form of the object
+ */
+
+// XXX should we re-do this?
+Q.nearer = nearer;
+function nearer(value) {
+ if (isPromise(value)) {
+ var inspected = value.inspect();
+ if (inspected.state === "fulfilled") {
+ return inspected.value;
+ }
+ }
+ return value;
+}
+
+/**
+ * @returns whether the given object is a promise.
+ * Otherwise it is a fulfilled value.
+ */
+Q.isPromise = isPromise;
+function isPromise(object) {
+ return isObject(object) &&
+ typeof object.promiseDispatch === "function" &&
+ typeof object.inspect === "function";
+}
+
+Q.isPromiseAlike = isPromiseAlike;
+function isPromiseAlike(object) {
+ return isObject(object) && typeof object.then === "function";
+}
+
+/**
+ * @returns whether the given object is a pending promise, meaning not
+ * fulfilled or rejected.
+ */
+Q.isPending = isPending;
+function isPending(object) {
+ return isPromise(object) && object.inspect().state === "pending";
+}
+
+Promise.prototype.isPending = function () {
+ return this.inspect().state === "pending";
+};
+
+/**
+ * @returns whether the given object is a value or fulfilled
+ * promise.
+ */
+Q.isFulfilled = isFulfilled;
+function isFulfilled(object) {
+ return !isPromise(object) || object.inspect().state === "fulfilled";
+}
+
+Promise.prototype.isFulfilled = function () {
+ return this.inspect().state === "fulfilled";
+};
+
+/**
+ * @returns whether the given object is a rejected promise.
+ */
+Q.isRejected = isRejected;
+function isRejected(object) {
+ return isPromise(object) && object.inspect().state === "rejected";
+}
+
+Promise.prototype.isRejected = function () {
+ return this.inspect().state === "rejected";
+};
+
+//// BEGIN UNHANDLED REJECTION TRACKING
+
+// This promise library consumes exceptions thrown in handlers so they can be
+// handled by a subsequent promise. The exceptions get added to this array when
+// they are created, and removed when they are handled. Note that in ES6 or
+// shimmed environments, this would naturally be a `Set`.
+var unhandledReasons = [];
+var unhandledRejections = [];
+var trackUnhandledRejections = true;
+
+function resetUnhandledRejections() {
+ unhandledReasons.length = 0;
+ unhandledRejections.length = 0;
+
+ if (!trackUnhandledRejections) {
+ trackUnhandledRejections = true;
+ }
+}
+
+function trackRejection(promise, reason) {
+ if (!trackUnhandledRejections) {
+ return;
+ }
+
+ unhandledRejections.push(promise);
+ if (reason && typeof reason.stack !== "undefined") {
+ unhandledReasons.push(reason.stack);
+ } else {
+ unhandledReasons.push("(no stack) " + reason);
+ }
+}
+
+function untrackRejection(promise) {
+ if (!trackUnhandledRejections) {
+ return;
+ }
+
+ var at = array_indexOf(unhandledRejections, promise);
+ if (at !== -1) {
+ unhandledRejections.splice(at, 1);
+ unhandledReasons.splice(at, 1);
+ }
+}
+
+Q.resetUnhandledRejections = resetUnhandledRejections;
+
+Q.getUnhandledReasons = function () {
+ // Make a copy so that consumers can't interfere with our internal state.
+ return unhandledReasons.slice();
+};
+
+Q.stopUnhandledRejectionTracking = function () {
+ resetUnhandledRejections();
+ trackUnhandledRejections = false;
+};
+
+resetUnhandledRejections();
+
+//// END UNHANDLED REJECTION TRACKING
+
+/**
+ * Constructs a rejected promise.
+ * @param reason value describing the failure
+ */
+Q.reject = reject;
+function reject(reason) {
+ var rejection = Promise({
+ "when": function (rejected) {
+ // note that the error has been handled
+ if (rejected) {
+ untrackRejection(this);
+ }
+ return rejected ? rejected(reason) : this;
+ }
+ }, function fallback() {
+ return this;
+ }, function inspect() {
+ return { state: "rejected", reason: reason };
+ });
+
+ // Note that the reason has not been handled.
+ trackRejection(rejection, reason);
+
+ return rejection;
+}
+
+/**
+ * Constructs a fulfilled promise for an immediate reference.
+ * @param value immediate reference
+ */
+Q.fulfill = fulfill;
+function fulfill(value) {
+ return Promise({
+ "when": function () {
+ return value;
+ },
+ "get": function (name) {
+ return value[name];
+ },
+ "set": function (name, rhs) {
+ value[name] = rhs;
+ },
+ "delete": function (name) {
+ delete value[name];
+ },
+ "post": function (name, args) {
+ // Mark Miller proposes that post with no name should apply a
+ // promised function.
+ if (name === null || name === void 0) {
+ return value.apply(void 0, args);
+ } else {
+ return value[name].apply(value, args);
+ }
+ },
+ "apply": function (thisp, args) {
+ return value.apply(thisp, args);
+ },
+ "keys": function () {
+ return object_keys(value);
+ }
+ }, void 0, function inspect() {
+ return { state: "fulfilled", value: value };
+ });
+}
+
+/**
+ * Converts thenables to Q promises.
+ * @param promise thenable promise
+ * @returns a Q promise
+ */
+function coerce(promise) {
+ var deferred = defer();
+ nextTick(function () {
+ try {
+ promise.then(deferred.resolve, deferred.reject, deferred.notify);
+ } catch (exception) {
+ deferred.reject(exception);
+ }
+ });
+ return deferred.promise;
+}
+
+/**
+ * Annotates an object such that it will never be
+ * transferred away from this process over any promise
+ * communication channel.
+ * @param object
+ * @returns promise a wrapping of that object that
+ * additionally responds to the "isDef" message
+ * without a rejection.
+ */
+Q.master = master;
+function master(object) {
+ return Promise({
+ "isDef": function () {}
+ }, function fallback(op, args) {
+ return dispatch(object, op, args);
+ }, function () {
+ return Q(object).inspect();
+ });
+}
+
+/**
+ * Spreads the values of a promised array of arguments into the
+ * fulfillment callback.
+ * @param fulfilled callback that receives variadic arguments from the
+ * promised array
+ * @param rejected callback that receives the exception if the promise
+ * is rejected.
+ * @returns a promise for the return value or thrown exception of
+ * either callback.
+ */
+Q.spread = spread;
+function spread(value, fulfilled, rejected) {
+ return Q(value).spread(fulfilled, rejected);
+}
+
+Promise.prototype.spread = function (fulfilled, rejected) {
+ return this.all().then(function (array) {
+ return fulfilled.apply(void 0, array);
+ }, rejected);
+};
+
+/**
+ * The async function is a decorator for generator functions, turning
+ * them into asynchronous generators. Although generators are only part
+ * of the newest ECMAScript 6 drafts, this code does not cause syntax
+ * errors in older engines. This code should continue to work and will
+ * in fact improve over time as the language improves.
+ *
+ * ES6 generators are currently part of V8 version 3.19 with the
+ * --harmony-generators runtime flag enabled. SpiderMonkey has had them
+ * for longer, but under an older Python-inspired form. This function
+ * works on both kinds of generators.
+ *
+ * Decorates a generator function such that:
+ * - it may yield promises
+ * - execution will continue when that promise is fulfilled
+ * - the value of the yield expression will be the fulfilled value
+ * - it returns a promise for the return value (when the generator
+ * stops iterating)
+ * - the decorated function returns a promise for the return value
+ * of the generator or the first rejected promise among those
+ * yielded.
+ * - if an error is thrown in the generator, it propagates through
+ * every following yield until it is caught, or until it escapes
+ * the generator function altogether, and is translated into a
+ * rejection for the promise returned by the decorated generator.
+ */
+Q.async = async;
+function async(makeGenerator) {
+ return function () {
+ // when verb is "send", arg is a value
+ // when verb is "throw", arg is an exception
+ function continuer(verb, arg) {
+ var result;
+
+ // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
+ // engine that has a deployed base of browsers that support generators.
+ // However, SM's generators use the Python-inspired semantics of
+ // outdated ES6 drafts. We would like to support ES6, but we'd also
+ // like to make it possible to use generators in deployed browsers, so
+ // we also support Python-style generators. At some point we can remove
+ // this block.
+
+ if (typeof StopIteration === "undefined") {
+ // ES6 Generators
+ try {
+ result = generator[verb](arg);
+ } catch (exception) {
+ return reject(exception);
+ }
+ if (result.done) {
+ return result.value;
+ } else {
+ return when(result.value, callback, errback);
+ }
+ } else {
+ // SpiderMonkey Generators
+ // FIXME: Remove this case when SM does ES6 generators.
+ try {
+ result = generator[verb](arg);
+ } catch (exception) {
+ if (isStopIteration(exception)) {
+ return exception.value;
+ } else {
+ return reject(exception);
+ }
+ }
+ return when(result, callback, errback);
+ }
+ }
+ var generator = makeGenerator.apply(this, arguments);
+ var callback = continuer.bind(continuer, "next");
+ var errback = continuer.bind(continuer, "throw");
+ return callback();
+ };
+}
+
+/**
+ * The spawn function is a small wrapper around async that immediately
+ * calls the generator and also ends the promise chain, so that any
+ * unhandled errors are thrown instead of forwarded to the error
+ * handler. This is useful because it's extremely common to run
+ * generators at the top-level to work with libraries.
+ */
+Q.spawn = spawn;
+function spawn(makeGenerator) {
+ Q.done(Q.async(makeGenerator)());
+}
+
+// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
+/**
+ * Throws a ReturnValue exception to stop an asynchronous generator.
+ *
+ * This interface is a stop-gap measure to support generator return
+ * values in older Firefox/SpiderMonkey. In browsers that support ES6
+ * generators like Chromium 29, just use "return" in your generator
+ * functions.
+ *
+ * @param value the return value for the surrounding generator
+ * @throws ReturnValue exception with the value.
+ * @example
+ * // ES6 style
+ * Q.async(function* () {
+ * var foo = yield getFooPromise();
+ * var bar = yield getBarPromise();
+ * return foo + bar;
+ * })
+ * // Older SpiderMonkey style
+ * Q.async(function () {
+ * var foo = yield getFooPromise();
+ * var bar = yield getBarPromise();
+ * Q.return(foo + bar);
+ * })
+ */
+Q["return"] = _return;
+function _return(value) {
+ throw new QReturnValue(value);
+}
+
+/**
+ * The promised function decorator ensures that any promise arguments
+ * are settled and passed as values (`this` is also settled and passed
+ * as a value). It will also ensure that the result of a function is
+ * always a promise.
+ *
+ * @example
+ * var add = Q.promised(function (a, b) {
+ * return a + b;
+ * });
+ * add(Q(a), Q(B));
+ *
+ * @param {function} callback The function to decorate
+ * @returns {function} a function that has been decorated.
+ */
+Q.promised = promised;
+function promised(callback) {
+ return function () {
+ return spread([this, all(arguments)], function (self, args) {
+ return callback.apply(self, args);
+ });
+ };
+}
+
+/**
+ * sends a message to a value in a future turn
+ * @param object* the recipient
+ * @param op the name of the message operation, e.g., "when",
+ * @param args further arguments to be forwarded to the operation
+ * @returns result {Promise} a promise for the result of the operation
+ */
+Q.dispatch = dispatch;
+function dispatch(object, op, args) {
+ return Q(object).dispatch(op, args);
+}
+
+Promise.prototype.dispatch = function (op, args) {
+ var self = this;
+ var deferred = defer();
+ nextTick(function () {
+ self.promiseDispatch(deferred.resolve, op, args);
+ });
+ return deferred.promise;
+};
+
+/**
+ * Gets the value of a property in a future turn.
+ * @param object promise or immediate reference for target object
+ * @param name name of property to get
+ * @return promise for the property value
+ */
+Q.get = function (object, key) {
+ return Q(object).dispatch("get", [key]);
+};
+
+Promise.prototype.get = function (key) {
+ return this.dispatch("get", [key]);
+};
+
+/**
+ * Sets the value of a property in a future turn.
+ * @param object promise or immediate reference for object object
+ * @param name name of property to set
+ * @param value new value of property
+ * @return promise for the return value
+ */
+Q.set = function (object, key, value) {
+ return Q(object).dispatch("set", [key, value]);
+};
+
+Promise.prototype.set = function (key, value) {
+ return this.dispatch("set", [key, value]);
+};
+
+/**
+ * Deletes a property in a future turn.
+ * @param object promise or immediate reference for target object
+ * @param name name of property to delete
+ * @return promise for the return value
+ */
+Q.del = // XXX legacy
+Q["delete"] = function (object, key) {
+ return Q(object).dispatch("delete", [key]);
+};
+
+Promise.prototype.del = // XXX legacy
+Promise.prototype["delete"] = function (key) {
+ return this.dispatch("delete", [key]);
+};
+
+/**
+ * Invokes a method in a future turn.
+ * @param object promise or immediate reference for target object
+ * @param name name of method to invoke
+ * @param value a value to post, typically an array of
+ * invocation arguments for promises that
+ * are ultimately backed with `resolve` values,
+ * as opposed to those backed with URLs
+ * wherein the posted value can be any
+ * JSON serializable object.
+ * @return promise for the return value
+ */
+// bound locally because it is used by other methods
+Q.mapply = // XXX As proposed by "Redsandro"
+Q.post = function (object, name, args) {
+ return Q(object).dispatch("post", [name, args]);
+};
+
+Promise.prototype.mapply = // XXX As proposed by "Redsandro"
+Promise.prototype.post = function (name, args) {
+ return this.dispatch("post", [name, args]);
+};
+
+/**
+ * Invokes a method in a future turn.
+ * @param object promise or immediate reference for target object
+ * @param name name of method to invoke
+ * @param ...args array of invocation arguments
+ * @return promise for the return value
+ */
+Q.send = // XXX Mark Miller's proposed parlance
+Q.mcall = // XXX As proposed by "Redsandro"
+Q.invoke = function (object, name /*...args*/) {
+ return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
+};
+
+Promise.prototype.send = // XXX Mark Miller's proposed parlance
+Promise.prototype.mcall = // XXX As proposed by "Redsandro"
+Promise.prototype.invoke = function (name /*...args*/) {
+ return this.dispatch("post", [name, array_slice(arguments, 1)]);
+};
+
+/**
+ * Applies the promised function in a future turn.
+ * @param object promise or immediate reference for target function
+ * @param args array of application arguments
+ */
+Q.fapply = function (object, args) {
+ return Q(object).dispatch("apply", [void 0, args]);
+};
+
+Promise.prototype.fapply = function (args) {
+ return this.dispatch("apply", [void 0, args]);
+};
+
+/**
+ * Calls the promised function in a future turn.
+ * @param object promise or immediate reference for target function
+ * @param ...args array of application arguments
+ */
+Q["try"] =
+Q.fcall = function (object /* ...args*/) {
+ return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
+};
+
+Promise.prototype.fcall = function (/*...args*/) {
+ return this.dispatch("apply", [void 0, array_slice(arguments)]);
+};
+
+/**
+ * Binds the promised function, transforming return values into a fulfilled
+ * promise and thrown errors into a rejected one.
+ * @param object promise or immediate reference for target function
+ * @param ...args array of application arguments
+ */
+Q.fbind = function (object /*...args*/) {
+ var promise = Q(object);
+ var args = array_slice(arguments, 1);
+ return function fbound() {
+ return promise.dispatch("apply", [
+ this,
+ args.concat(array_slice(arguments))
+ ]);
+ };
+};
+Promise.prototype.fbind = function (/*...args*/) {
+ var promise = this;
+ var args = array_slice(arguments);
+ return function fbound() {
+ return promise.dispatch("apply", [
+ this,
+ args.concat(array_slice(arguments))
+ ]);
+ };
+};
+
+/**
+ * Requests the names of the owned properties of a promised
+ * object in a future turn.
+ * @param object promise or immediate reference for target object
+ * @return promise for the keys of the eventually settled object
+ */
+Q.keys = function (object) {
+ return Q(object).dispatch("keys", []);
+};
+
+Promise.prototype.keys = function () {
+ return this.dispatch("keys", []);
+};
+
+/**
+ * Turns an array of promises into a promise for an array. If any of
+ * the promises gets rejected, the whole array is rejected immediately.
+ * @param {Array*} an array (or promise for an array) of values (or
+ * promises for values)
+ * @returns a promise for an array of the corresponding values
+ */
+// By Mark Miller
+// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
+Q.all = all;
+function all(promises) {
+ return when(promises, function (promises) {
+ var countDown = 0;
+ var deferred = defer();
+ array_reduce(promises, function (undefined, promise, index) {
+ var snapshot;
+ if (
+ isPromise(promise) &&
+ (snapshot = promise.inspect()).state === "fulfilled"
+ ) {
+ promises[index] = snapshot.value;
+ } else {
+ ++countDown;
+ when(
+ promise,
+ function (value) {
+ promises[index] = value;
+ if (--countDown === 0) {
+ deferred.resolve(promises);
+ }
+ },
+ deferred.reject,
+ function (progress) {
+ deferred.notify({ index: index, value: progress });
+ }
+ );
+ }
+ }, void 0);
+ if (countDown === 0) {
+ deferred.resolve(promises);
+ }
+ return deferred.promise;
+ });
+}
+
+Promise.prototype.all = function () {
+ return all(this);
+};
+
+/**
+ * Waits for all promises to be settled, either fulfilled or
+ * rejected. This is distinct from `all` since that would stop
+ * waiting at the first rejection. The promise returned by
+ * `allResolved` will never be rejected.
+ * @param promises a promise for an array (or an array) of promises
+ * (or values)
+ * @return a promise for an array of promises
+ */
+Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
+function allResolved(promises) {
+ return when(promises, function (promises) {
+ promises = array_map(promises, Q);
+ return when(all(array_map(promises, function (promise) {
+ return when(promise, noop, noop);
+ })), function () {
+ return promises;
+ });
+ });
+}
+
+Promise.prototype.allResolved = function () {
+ return allResolved(this);
+};
+
+/**
+ * @see Promise#allSettled
+ */
+Q.allSettled = allSettled;
+function allSettled(promises) {
+ return Q(promises).allSettled();
+}
+
+/**
+ * Turns an array of promises into a promise for an array of their states (as
+ * returned by `inspect`) when they have all settled.
+ * @param {Array[Any*]} values an array (or promise for an array) of values (or
+ * promises for values)
+ * @returns {Array[State]} an array of states for the respective values.
+ */
+Promise.prototype.allSettled = function () {
+ return this.then(function (promises) {
+ return all(array_map(promises, function (promise) {
+ promise = Q(promise);
+ function regardless() {
+ return promise.inspect();
+ }
+ return promise.then(regardless, regardless);
+ }));
+ });
+};
+
+/**
+ * Captures the failure of a promise, giving an oportunity to recover
+ * with a callback. If the given promise is fulfilled, the returned
+ * promise is fulfilled.
+ * @param {Any*} promise for something
+ * @param {Function} callback to fulfill the returned promise if the
+ * given promise is rejected
+ * @returns a promise for the return value of the callback
+ */
+Q.fail = // XXX legacy
+Q["catch"] = function (object, rejected) {
+ return Q(object).then(void 0, rejected);
+};
+
+Promise.prototype.fail = // XXX legacy
+Promise.prototype["catch"] = function (rejected) {
+ return this.then(void 0, rejected);
+};
+
+/**
+ * Attaches a listener that can respond to progress notifications from a
+ * promise's originating deferred. This listener receives the exact arguments
+ * passed to ``deferred.notify``.
+ * @param {Any*} promise for something
+ * @param {Function} callback to receive any progress notifications
+ * @returns the given promise, unchanged
+ */
+Q.progress = progress;
+function progress(object, progressed) {
+ return Q(object).then(void 0, void 0, progressed);
+}
+
+Promise.prototype.progress = function (progressed) {
+ return this.then(void 0, void 0, progressed);
+};
+
+/**
+ * Provides an opportunity to observe the settling of a promise,
+ * regardless of whether the promise is fulfilled or rejected. Forwards
+ * the resolution to the returned promise when the callback is done.
+ * The callback can return a promise to defer completion.
+ * @param {Any*} promise
+ * @param {Function} callback to observe the resolution of the given
+ * promise, takes no arguments.
+ * @returns a promise for the resolution of the given promise when
+ * ``fin`` is done.
+ */
+Q.fin = // XXX legacy
+Q["finally"] = function (object, callback) {
+ return Q(object)["finally"](callback);
+};
+
+Promise.prototype.fin = // XXX legacy
+Promise.prototype["finally"] = function (callback) {
+ callback = Q(callback);
+ return this.then(function (value) {
+ return callback.fcall().then(function () {
+ return value;
+ });
+ }, function (reason) {
+ // TODO attempt to recycle the rejection with "this".
+ return callback.fcall().then(function () {
+ throw reason;
+ });
+ });
+};
+
+/**
+ * Terminates a chain of promises, forcing rejections to be
+ * thrown as exceptions.
+ * @param {Any*} promise at the end of a chain of promises
+ * @returns nothing
+ */
+Q.done = function (object, fulfilled, rejected, progress) {
+ return Q(object).done(fulfilled, rejected, progress);
+};
+
+Promise.prototype.done = function (fulfilled, rejected, progress) {
+ var onUnhandledError = function (error) {
+ // forward to a future turn so that ``when``
+ // does not catch it and turn it into a rejection.
+ nextTick(function () {
+ makeStackTraceLong(error, promise);
+ if (Q.onerror) {
+ Q.onerror(error);
+ } else {
+ throw error;
+ }
+ });
+ };
+
+ // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
+ var promise = fulfilled || rejected || progress ?
+ this.then(fulfilled, rejected, progress) :
+ this;
+
+ if (typeof process === "object" && process && process.domain) {
+ onUnhandledError = process.domain.bind(onUnhandledError);
+ }
+
+ promise.then(void 0, onUnhandledError);
+};
+
+/**
+ * Causes a promise to be rejected if it does not get fulfilled before
+ * some milliseconds time out.
+ * @param {Any*} promise
+ * @param {Number} milliseconds timeout
+ * @param {String} custom error message (optional)
+ * @returns a promise for the resolution of the given promise if it is
+ * fulfilled before the timeout, otherwise rejected.
+ */
+Q.timeout = function (object, ms, message) {
+ return Q(object).timeout(ms, message);
+};
+
+Promise.prototype.timeout = function (ms, message) {
+ var deferred = defer();
+ var timeoutId = setTimeout(function () {
+ deferred.reject(new Error(message || "Timed out after " + ms + " ms"));
+ }, ms);
+
+ this.then(function (value) {
+ clearTimeout(timeoutId);
+ deferred.resolve(value);
+ }, function (exception) {
+ clearTimeout(timeoutId);
+ deferred.reject(exception);
+ }, deferred.notify);
+
+ return deferred.promise;
+};
+
+/**
+ * Returns a promise for the given value (or promised value), some
+ * milliseconds after it resolved. Passes rejections immediately.
+ * @param {Any*} promise
+ * @param {Number} milliseconds
+ * @returns a promise for the resolution of the given promise after milliseconds
+ * time has elapsed since the resolution of the given promise.
+ * If the given promise rejects, that is passed immediately.
+ */
+Q.delay = function (object, timeout) {
+ if (timeout === void 0) {
+ timeout = object;
+ object = void 0;
+ }
+ return Q(object).delay(timeout);
+};
+
+Promise.prototype.delay = function (timeout) {
+ return this.then(function (value) {
+ var deferred = defer();
+ setTimeout(function () {
+ deferred.resolve(value);
+ }, timeout);
+ return deferred.promise;
+ });
+};
+
+/**
+ * Passes a continuation to a Node function, which is called with the given
+ * arguments provided as an array, and returns a promise.
+ *
+ * Q.nfapply(FS.readFile, [__filename])
+ * .then(function (content) {
+ * })
+ *
+ */
+Q.nfapply = function (callback, args) {
+ return Q(callback).nfapply(args);
+};
+
+Promise.prototype.nfapply = function (args) {
+ var deferred = defer();
+ var nodeArgs = array_slice(args);
+ nodeArgs.push(deferred.makeNodeResolver());
+ this.fapply(nodeArgs).fail(deferred.reject);
+ return deferred.promise;
+};
+
+/**
+ * Passes a continuation to a Node function, which is called with the given
+ * arguments provided individually, and returns a promise.
+ * @example
+ * Q.nfcall(FS.readFile, __filename)
+ * .then(function (content) {
+ * })
+ *
+ */
+Q.nfcall = function (callback /*...args*/) {
+ var args = array_slice(arguments, 1);
+ return Q(callback).nfapply(args);
+};
+
+Promise.prototype.nfcall = function (/*...args*/) {
+ var nodeArgs = array_slice(arguments);
+ var deferred = defer();
+ nodeArgs.push(deferred.makeNodeResolver());
+ this.fapply(nodeArgs).fail(deferred.reject);
+ return deferred.promise;
+};
+
+/**
+ * Wraps a NodeJS continuation passing function and returns an equivalent
+ * version that returns a promise.
+ * @example
+ * Q.nfbind(FS.readFile, __filename)("utf-8")
+ * .then(console.log)
+ * .done()
+ */
+Q.nfbind =
+Q.denodeify = function (callback /*...args*/) {
+ var baseArgs = array_slice(arguments, 1);
+ return function () {
+ var nodeArgs = baseArgs.concat(array_slice(arguments));
+ var deferred = defer();
+ nodeArgs.push(deferred.makeNodeResolver());
+ Q(callback).fapply(nodeArgs).fail(deferred.reject);
+ return deferred.promise;
+ };
+};
+
+Promise.prototype.nfbind =
+Promise.prototype.denodeify = function (/*...args*/) {
+ var args = array_slice(arguments);
+ args.unshift(this);
+ return Q.denodeify.apply(void 0, args);
+};
+
+Q.nbind = function (callback, thisp /*...args*/) {
+ var baseArgs = array_slice(arguments, 2);
+ return function () {
+ var nodeArgs = baseArgs.concat(array_slice(arguments));
+ var deferred = defer();
+ nodeArgs.push(deferred.makeNodeResolver());
+ function bound() {
+ return callback.apply(thisp, arguments);
+ }
+ Q(bound).fapply(nodeArgs).fail(deferred.reject);
+ return deferred.promise;
+ };
+};
+
+Promise.prototype.nbind = function (/*thisp, ...args*/) {
+ var args = array_slice(arguments, 0);
+ args.unshift(this);
+ return Q.nbind.apply(void 0, args);
+};
+
+/**
+ * Calls a method of a Node-style object that accepts a Node-style
+ * callback with a given array of arguments, plus a provided callback.
+ * @param object an object that has the named method
+ * @param {String} name name of the method of object
+ * @param {Array} args arguments to pass to the method; the callback
+ * will be provided by Q and appended to these arguments.
+ * @returns a promise for the value or error
+ */
+Q.nmapply = // XXX As proposed by "Redsandro"
+Q.npost = function (object, name, args) {
+ return Q(object).npost(name, args);
+};
+
+Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
+Promise.prototype.npost = function (name, args) {
+ var nodeArgs = array_slice(args || []);
+ var deferred = defer();
+ nodeArgs.push(deferred.makeNodeResolver());
+ this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+ return deferred.promise;
+};
+
+/**
+ * Calls a method of a Node-style object that accepts a Node-style
+ * callback, forwarding the given variadic arguments, plus a provided
+ * callback argument.
+ * @param object an object that has the named method
+ * @param {String} name name of the method of object
+ * @param ...args arguments to pass to the method; the callback will
+ * be provided by Q and appended to these arguments.
+ * @returns a promise for the value or error
+ */
+Q.nsend = // XXX Based on Mark Miller's proposed "send"
+Q.nmcall = // XXX Based on "Redsandro's" proposal
+Q.ninvoke = function (object, name /*...args*/) {
+ var nodeArgs = array_slice(arguments, 2);
+ var deferred = defer();
+ nodeArgs.push(deferred.makeNodeResolver());
+ Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+ return deferred.promise;
+};
+
+Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
+Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
+Promise.prototype.ninvoke = function (name /*...args*/) {
+ var nodeArgs = array_slice(arguments, 1);
+ var deferred = defer();
+ nodeArgs.push(deferred.makeNodeResolver());
+ this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+ return deferred.promise;
+};
+
+/**
+ * If a function would like to support both Node continuation-passing-style and
+ * promise-returning-style, it can end its internal promise chain with
+ * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
+ * elects to use a nodeback, the result will be sent there. If they do not
+ * pass a nodeback, they will receive the result promise.
+ * @param object a result (or a promise for a result)
+ * @param {Function} nodeback a Node.js-style callback
+ * @returns either the promise or nothing
+ */
+Q.nodeify = nodeify;
+function nodeify(object, nodeback) {
+ return Q(object).nodeify(nodeback);
+}
+
+Promise.prototype.nodeify = function (nodeback) {
+ if (nodeback) {
+ this.then(function (value) {
+ nextTick(function () {
+ nodeback(null, value);
+ });
+ }, function (error) {
+ nextTick(function () {
+ nodeback(error);
+ });
+ });
+ } else {
+ return this;
+ }
+};
+
+// All code before this point will be filtered from stack traces.
+var qEndingLine = captureLine();
+
+return Q;
+
+});
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/queue.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/queue.js b/bin/node_modules/q/queue.js
new file mode 100644
index 0000000..1505fd0
--- /dev/null
+++ b/bin/node_modules/q/queue.js
@@ -0,0 +1,35 @@
+
+var Q = require("./q");
+
+module.exports = Queue;
+function Queue() {
+ var ends = Q.defer();
+ var closed = Q.defer();
+ return {
+ put: function (value) {
+ var next = Q.defer();
+ ends.resolve({
+ head: value,
+ tail: next.promise
+ });
+ ends.resolve = next.resolve;
+ },
+ get: function () {
+ var result = ends.promise.get("head");
+ ends.promise = ends.promise.get("tail");
+ return result.fail(function (error) {
+ closed.resolve(error);
+ throw error;
+ });
+ },
+ closed: closed.promise,
+ close: function (error) {
+ error = error || new Error("Can't get value from closed queue");
+ var end = {head: Q.reject(error)};
+ end.tail = end;
+ ends.resolve(end);
+ return closed.promise;
+ }
+ };
+}
+
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/which/LICENSE
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/LICENSE b/bin/node_modules/which/LICENSE
new file mode 100644
index 0000000..05a4010
--- /dev/null
+++ b/bin/node_modules/which/LICENSE
@@ -0,0 +1,23 @@
+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/which/README.md
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/README.md b/bin/node_modules/which/README.md
new file mode 100644
index 0000000..ff1eb53
--- /dev/null
+++ b/bin/node_modules/which/README.md
@@ -0,0 +1,5 @@
+The "which" util from npm's guts.
+
+Finds the first instance of a specified executable in the PATH
+environment variable. Does not cache the results, so `hash -r` is not
+needed when the PATH changes.
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/which/bin/which
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/bin/which b/bin/node_modules/which/bin/which
new file mode 100755
index 0000000..8432ce2
--- /dev/null
+++ b/bin/node_modules/which/bin/which
@@ -0,0 +1,14 @@
+#!/usr/bin/env node
+var which = require("../")
+if (process.argv.length < 3) {
+ console.error("Usage: which <thing>")
+ process.exit(1)
+}
+
+which(process.argv[2], function (er, thing) {
+ if (er) {
+ console.error(er.message)
+ process.exit(er.errno || 127)
+ }
+ console.log(thing)
+})
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/which/package.json
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/package.json b/bin/node_modules/which/package.json
new file mode 100644
index 0000000..6c5ccb3
--- /dev/null
+++ b/bin/node_modules/which/package.json
@@ -0,0 +1,31 @@
+{
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me"
+ },
+ "name": "which",
+ "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
+ "version": "1.0.5",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/node-which.git"
+ },
+ "main": "which.js",
+ "bin": {
+ "which": "./bin/which"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "dependencies": {},
+ "devDependencies": {},
+ "readme": "The \"which\" util from npm's guts.\n\nFinds the first instance of a specified executable in the PATH\nenvironment variable. Does not cache the results, so `hash -r` is not\nneeded when the PATH changes.\n",
+ "readmeFilename": "README.md",
+ "bugs": {
+ "url": "https://github.com/isaacs/node-which/issues"
+ },
+ "homepage": "https://github.com/isaacs/node-which",
+ "_id": "which@1.0.5",
+ "_from": "which@"
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/which/which.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/which.js b/bin/node_modules/which/which.js
new file mode 100644
index 0000000..db7e8f7
--- /dev/null
+++ b/bin/node_modules/which/which.js
@@ -0,0 +1,104 @@
+module.exports = which
+which.sync = whichSync
+
+var path = require("path")
+ , fs
+ , COLON = process.platform === "win32" ? ";" : ":"
+ , isExe
+
+try {
+ fs = require("graceful-fs")
+} catch (ex) {
+ fs = require("fs")
+}
+
+if (process.platform == "win32") {
+ // On windows, there is no good way to check that a file is executable
+ isExe = function isExe () { return true }
+} else {
+ isExe = function isExe (mod, uid, gid) {
+ //console.error(mod, uid, gid);
+ //console.error("isExe?", (mod & 0111).toString(8))
+ var ret = (mod & 0001)
+ || (mod & 0010) && process.getgid && gid === process.getgid()
+ || (mod & 0100) && process.getuid && uid === process.getuid()
+ //console.error("isExe?", ret)
+ return ret
+ }
+}
+
+
+
+function which (cmd, cb) {
+ if (isAbsolute(cmd)) return cb(null, cmd)
+ var pathEnv = (process.env.PATH || "").split(COLON)
+ , pathExt = [""]
+ if (process.platform === "win32") {
+ pathEnv.push(process.cwd())
+ pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
+ if (cmd.indexOf(".") !== -1) pathExt.unshift("")
+ }
+ //console.error("pathEnv", pathEnv)
+ ;(function F (i, l) {
+ if (i === l) return cb(new Error("not found: "+cmd))
+ var p = path.resolve(pathEnv[i], cmd)
+ ;(function E (ii, ll) {
+ if (ii === ll) return F(i + 1, l)
+ var ext = pathExt[ii]
+ //console.error(p + ext)
+ fs.stat(p + ext, function (er, stat) {
+ if (!er &&
+ stat &&
+ stat.isFile() &&
+ isExe(stat.mode, stat.uid, stat.gid)) {
+ //console.error("yes, exe!", p + ext)
+ return cb(null, p + ext)
+ }
+ return E(ii + 1, ll)
+ })
+ })(0, pathExt.length)
+ })(0, pathEnv.length)
+}
+
+function whichSync (cmd) {
+ if (isAbsolute(cmd)) return cmd
+ var pathEnv = (process.env.PATH || "").split(COLON)
+ , pathExt = [""]
+ if (process.platform === "win32") {
+ pathEnv.push(process.cwd())
+ pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
+ if (cmd.indexOf(".") !== -1) pathExt.unshift("")
+ }
+ for (var i = 0, l = pathEnv.length; i < l; i ++) {
+ var p = path.join(pathEnv[i], cmd)
+ for (var j = 0, ll = pathExt.length; j < ll; j ++) {
+ var cur = p + pathExt[j]
+ var stat
+ try { stat = fs.statSync(cur) } catch (ex) {}
+ if (stat &&
+ stat.isFile() &&
+ isExe(stat.mode, stat.uid, stat.gid)) return cur
+ }
+ }
+ throw new Error("not found: "+cmd)
+}
+
+var isAbsolute = process.platform === "win32" ? absWin : absUnix
+
+function absWin (p) {
+ if (absUnix(p)) return true
+ // pull off the device/UNC bit from a windows path.
+ // from node's lib/path.js
+ var splitDeviceRe =
+ /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
+ , result = splitDeviceRe.exec(p)
+ , device = result[1] || ''
+ , isUnc = device && device.charAt(1) !== ':'
+ , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
+
+ return isAbsolute
+}
+
+function absUnix (p) {
+ return p.charAt(0) === "/" || p === ""
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/replaces
----------------------------------------------------------------------
diff --git a/bin/replaces b/bin/replaces
deleted file mode 100755
index 4aee85a..0000000
--- a/bin/replaces
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/sh
-#
-# 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.
-#
-
-#
-# USAGE
-# ./replaces path from to
-#
-# EXAMPLE
-# ./replaces ./foo.txt FOO BAR
-#
-sed "s/$2/$3/g" "$1" > tmpFile ; mv tmpFile "$1"
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/templates/scripts/cordova/version
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/version b/bin/templates/scripts/cordova/version
index c2dcab0..566a73b 100755
--- a/bin/templates/scripts/cordova/version
+++ b/bin/templates/scripts/cordova/version
@@ -1,29 +1,30 @@
-#!/bin/bash
+#!/usr/bin/env node
-#
-# 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.
-#
+/*
+ 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
-#
-# Returns the VERSION of CordovaLib used.
-# Note: it does not work if the --shared option was used to create the project.
-#
+ http://www.apache.org/licenses/LICENSE-2.0
-VERSION="3.8.0-dev"
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
-echo $VERSION
+/*
+
+ Returns the VERSION of CordovaLib used.
+ Note: it does not work if the --shared option was used to create the project.
+*/
+
+var VERSION = "3.8.0-dev";
+
+console.log(VERSION);
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/templates/scripts/cordova/version.bat
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/version.bat b/bin/templates/scripts/cordova/version.bat
new file mode 100644
index 0000000..84c86b4
--- /dev/null
+++ b/bin/templates/scripts/cordova/version.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0version"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'version' script in 'cordova' folder, aborting...>&2
+ EXIT /B 1
+)
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/update
----------------------------------------------------------------------
diff --git a/bin/update b/bin/update
index 0a97a0e..5ea1974 100755
--- a/bin/update
+++ b/bin/update
@@ -1,79 +1,30 @@
#!/usr/bin/env node
/*
- 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.
+ 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 shell = require('shelljs'),
- path = require('path'),
- fs = require('fs'),
- ROOT = path.join(__dirname, '..');
-
-function setShellFatal(value, func) {
- var oldVal = shell.config.fatal;
- shell.config.fatal = value;
- func();
- shell.config.fatal = oldVal;
-}
-
-function copyJsAndCordovaLib(projectPath) {
- shell.cp('-f', path.join(ROOT, 'CordovaLib', 'cordova.js'), path.join(projectPath, 'www'));
- shell.rm('-rf', path.join(projectPath, 'CordovaLib'));
- shell.cp('-r', path.join(ROOT, 'CordovaLib'), projectPath);
- // Ensure no workspace files got copied over.
- var entries = fs.readdirSync(path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj'));
- entries.forEach(function(p) {
- if (/.*xc.*/.test(p)) {
- shell.rm('-rf', path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj', p));
- }
- });
-}
-
-function copyScripts(projectPath) {
- var srcScriptsDir = path.join(ROOT, 'bin', 'templates', 'scripts', 'cordova');
- var destScriptsDir = path.join(projectPath, 'cordova');
- // Delete old scripts directory.
- shell.rm('-rf', destScriptsDir);
- // Copy in the new ones.
- shell.cp('-r', srcScriptsDir, projectPath);
- shell.cp(path.join(ROOT, 'bin', 'check_reqs'), path.join(destScriptsDir, 'check_reqs'));
- // Make sure they are executable.
- shell.find(destScriptsDir).forEach(function(entry) {
- shell.chmod(755, entry);
- });
-}
-exports.updateProject = function(projectPath) {
- var version = fs.readFileSync(path.join(ROOT, 'CordovaLib', 'VERSION'), 'utf-8').trim();
- setShellFatal(true, function() {
- copyJsAndCordovaLib(projectPath);
- copyScripts(projectPath);
- console.log('iOS project is now at version ' + version);
- });
-};
+var update = require('./lib/update');
-if (require.main === module) {
- (function() {
- var args = process.argv;
- if (args.length < 3 || (args[2] == '--help' || args[2] == '-h')) {
- console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'update')) + ' <path_to_project>');
- process.exit(1);
- } else {
- exports.updateProject(args[2]);
- }
- })();
+var args = process.argv;
+if (args.length < 3 || (args[2] == '--help' || args[2] == '-h')) {
+ console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'update')) + ' <path_to_project>');
+ process.exit(1);
+} else {
+ update.updateProject(args[2]);
}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/update.bat
----------------------------------------------------------------------
diff --git a/bin/update.bat b/bin/update.bat
new file mode 100644
index 0000000..48c451a
--- /dev/null
+++ b/bin/update.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0update"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'update' script in 'bin' folder, aborting...>&2
+ EXIT /B 1
+)
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/update_cordova_subproject
----------------------------------------------------------------------
diff --git a/bin/update_cordova_subproject b/bin/update_cordova_subproject
index 07b257a..88e933e 100755
--- a/bin/update_cordova_subproject
+++ b/bin/update_cordova_subproject
@@ -1,106 +1,31 @@
-#!/usr/bin/python
-# 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.
-"""
-Updates the subproject path of the CordovaLib entry to point to this script's version of Cordova.
-
-Usage: CordovaVersion/bin/update_cordova_project path/to/your/app.xcodeproj [path/to/CordovaLib.xcodeproj]
-"""
-
-import fileinput
-import os
-import re
-import sys
-from posixpath import curdir, sep, pardir, join, abspath, commonprefix
-
-def Usage():
- print __doc__
- sys.exit(1)
-
-def AbsParentPath(path):
- return os.path.abspath(os.path.join(path, os.path.pardir))
-
-def AbsFrameworkPath(argv0):
- script_path = argv0
- # This can happen if the script's dir is in the user's PATH
- if not os.path.exists(script_path):
- raise Exception('Could not locale framework directory.')
- return AbsParentPath(AbsParentPath(script_path))
-
-def AbsProjectPath(relative_path):
- # Do an extra abspath here to strip off trailing / if present.
- project_path = os.path.abspath(relative_path)
- if project_path.endswith('.pbxproj'):
- project_path = AbsParentPath(project_path)
- elif project_path.endswith('.xcodeproj'):
- pass
- else:
- raise Exception('The following is not a valid path to an XCode project: %s' % project_path)
- return project_path
-
-def relpath(path, start=curdir):
- # it would be nice to use os.path.relpath,
- # but that leaves out those with python < v2.6
- if not path:
- raise ValueError("no path specified")
- start_list = abspath(start).split(sep)
- path_list = abspath(path).split(sep)
- # Work out how much of the filepath is shared by start and path.
- i = len(commonprefix([start_list, path_list]))
- rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
- if not rel_list:
- return curdir
- return join(*rel_list)
-
-
-def main(argv):
- if len(argv) < 2 or len(argv) > 3:
- Usage()
-
- project_path = AbsProjectPath(argv[1])
- if len(argv) < 3:
- framework_path = AbsFrameworkPath(argv[0])
- cordova_lib_xcode_path = os.path.join(framework_path, 'CordovaLib', 'CordovaLib.xcodeproj')
- else:
- cordova_lib_xcode_path = AbsProjectPath(argv[2])
-
- parent_project_path = AbsParentPath(project_path)
- subproject_path = relpath(cordova_lib_xcode_path, parent_project_path)
-
- # /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = CordovaLib.xcodeproj; sourceTree = "<group>"; };
- REGEX = re.compile(r'(.+PBXFileReference.+wrapper.pb-project.+)(path = .+?;)(.*)(sourceTree.+;)(.+)')
-
- file_handle = fileinput.input(os.path.join(project_path, 'project.pbxproj'), inplace=1)
- found = False
- for line in file_handle:
- if 'CordovaLib.xcodeproj' in line:
- m = REGEX.match(line)
- if m:
- found = True
- line = m.expand(r'\1path = "%s";\3sourceTree = "<group>";\5\n') % subproject_path
- if 'name =' not in line:
- line = line.replace('path = ', 'name = CordovaLib.xcodeproj; path = ')
- print line,
- file_handle.close()
-
- if not found:
- raise Exception('Sub-project entry not found in project file.')
- print('CordovaLib set to path: %s' % subproject_path)
-
-
-if __name__ == '__main__':
- main(sys.argv)
+#!/usr/bin/env node
+
+/*
+ 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 create = require('./lib/create'),
+ args;
+
+if (process.argv.length < 3) {
+ create.updateSubprojectHelp();
+}
+else {
+ args = process.argv.slice(2);
+ create.update_cordova_subproject(args);
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/update_cordova_subproject.bat
----------------------------------------------------------------------
diff --git a/bin/update_cordova_subproject.bat b/bin/update_cordova_subproject.bat
new file mode 100644
index 0000000..1f1c1c9
--- /dev/null
+++ b/bin/update_cordova_subproject.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0update_cordova_subproject"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'update_cordova_subproject' script in 'bin' folder, aborting...>&2
+ EXIT /B 1
+)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[07/10] ios commit: [CB-8044] updated run script to properly handle
--nobuild flag in all cases
Posted by sh...@apache.org.
[CB-8044] updated run script to properly handle --nobuild flag in all cases
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/b53b305d
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/b53b305d
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/b53b305d
Branch: refs/heads/wkwebview
Commit: b53b305d88ce3b9cf74232c083d962e5b6d778da
Parents: 19e9545
Author: Lorin Beer <lo...@gmail.com>
Authored: Fri Dec 12 13:22:40 2014 -0800
Committer: Lorin Beer <lo...@gmail.com>
Committed: Fri Dec 12 13:22:40 2014 -0800
----------------------------------------------------------------------
bin/templates/scripts/cordova/run | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/b53b305d/bin/templates/scripts/cordova/run
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/run b/bin/templates/scripts/cordova/run
index f66f703..12633bf 100755
--- a/bin/templates/scripts/cordova/run
+++ b/bin/templates/scripts/cordova/run
@@ -115,7 +115,7 @@ if "$USE_DEVICE"; then
USE_SIMULATOR=true
else
# if we got here, we can deploy the app, then exit success
- if [ ! $NO_BUILD ]; then
+ if ! [ "$NO_BUILD" = true ]; then
"$CORDOVA_PATH/build" --device || exit $?
fi
ios-deploy -d -b "$DEVICE_APP_PATH"
@@ -139,7 +139,7 @@ if "$USE_SIMULATOR"; then
fi
# launch using ios-sim
- if [ ! $NO_BUILD ]; then
+ if ! [ "$NO_BUILD" = true ]; then
"$CORDOVA_PATH/build" --emulator || exit $?
fi
ios-sim launch "$SIMULATOR_APP_PATH" --stderr "$CORDOVA_PATH/console.log" --stdout "$CORDOVA_PATH/console.log" --devicetypeid com.apple.CoreSimulator.SimDeviceType.$TARGET --exit
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[05/10] ios commit: [CB-8044] support for --nobuild flag
Posted by sh...@apache.org.
[CB-8044] support for --nobuild flag
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/9ea4c782
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/9ea4c782
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/9ea4c782
Branch: refs/heads/wkwebview
Commit: 9ea4c782c64beec4a9c569f9ca61575bd25a733e
Parents: ea2a946
Author: Lorin Beer <lo...@gmail.com>
Authored: Fri Dec 12 11:38:54 2014 -0800
Committer: Lorin Beer <lo...@gmail.com>
Committed: Fri Dec 12 11:38:54 2014 -0800
----------------------------------------------------------------------
bin/templates/scripts/cordova/run | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/9ea4c782/bin/templates/scripts/cordova/run
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/run b/bin/templates/scripts/cordova/run
index ff60876..12334ac 100755
--- a/bin/templates/scripts/cordova/run
+++ b/bin/templates/scripts/cordova/run
@@ -37,6 +37,9 @@ TARGET="iPhone-6"
USE_DEVICE=true
USE_SIMULATOR=false
+# options
+NO_BUILD=false
+
# separates "key=value", sets an array with 0th index as key, 1st index as value
_parseOption()
{
@@ -71,6 +74,9 @@ _parseArgs()
USE_DEVICE=false
USE_SIMULATOR=true
;;
+ "--nobuild")
+ NO_BUILD=true
+ ;;
esac
done
}
@@ -109,7 +115,9 @@ if "$USE_DEVICE"; then
USE_SIMULATOR=true
else
# if we got here, we can deploy the app, then exit success
- "$CORDOVA_PATH/build" --device || exit $?
+ if [ ! $NO_BUILD ] then
+ "$CORDOVA_PATH/build" --device || exit $?
+ fi
ios-deploy -d -b "$DEVICE_APP_PATH"
exit 0
fi
@@ -131,7 +139,9 @@ if "$USE_SIMULATOR"; then
fi
# launch using ios-sim
- "$CORDOVA_PATH/build" --emulator || exit $?
+ if [ ! $NO_BUILD ] then
+ "$CORDOVA_PATH/build" --emulator || exit $?
+ fi
ios-sim launch "$SIMULATOR_APP_PATH" --stderr "$CORDOVA_PATH/console.log" --stdout "$CORDOVA_PATH/console.log" --devicetypeid com.apple.CoreSimulator.SimDeviceType.$TARGET --exit
fi
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[02/10] ios commit: CB-5706 convert some of the bash scripts to
nodejs (closes #118)
Posted by sh...@apache.org.
CB-5706 convert some of the bash scripts to nodejs (closes #118)
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/dd54d96b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/dd54d96b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/dd54d96b
Branch: refs/heads/wkwebview
Commit: dd54d96bd0eddb7f8967d0d1fcfb90f2635ed22a
Parents: 5769d58
Author: Edna Morales <ed...@gmail.com>
Authored: Mon Nov 3 15:18:05 2014 -0500
Committer: Shazron Abdullah <sh...@apache.org>
Committed: Wed Nov 19 16:26:28 2014 -0800
----------------------------------------------------------------------
bin/apple_ios_version | 47 +-
bin/apple_ios_version.bat | 26 +
bin/apple_osx_version | 47 +-
bin/apple_osx_version.bat | 26 +
bin/apple_xcode_version | 47 +-
bin/apple_xcode_version.bat | 26 +
bin/create | 205 +-
bin/create.bat | 26 +
bin/lib/create.js | 255 +++
bin/lib/update.js | 72 +
bin/lib/versions.js | 101 +
bin/node_modules/q/CONTRIBUTING.md | 40 +
bin/node_modules/q/LICENSE | 18 +
bin/node_modules/q/README.md | 820 ++++++++
.../q/benchmark/compare-with-callbacks.js | 71 +
bin/node_modules/q/benchmark/scenarios.js | 36 +
bin/node_modules/q/package.json | 112 ++
bin/node_modules/q/q.js | 1904 ++++++++++++++++++
bin/node_modules/q/queue.js | 35 +
bin/node_modules/which/LICENSE | 23 +
bin/node_modules/which/README.md | 5 +
bin/node_modules/which/bin/which | 14 +
bin/node_modules/which/package.json | 31 +
bin/node_modules/which/which.js | 104 +
bin/replaces | 28 -
bin/templates/scripts/cordova/version | 51 +-
bin/templates/scripts/cordova/version.bat | 26 +
bin/update | 95 +-
bin/update.bat | 26 +
bin/update_cordova_subproject | 137 +-
bin/update_cordova_subproject.bat | 26 +
31 files changed, 4019 insertions(+), 461 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/apple_ios_version
----------------------------------------------------------------------
diff --git a/bin/apple_ios_version b/bin/apple_ios_version
index 8a5aa7d..d397bb6 100755
--- a/bin/apple_ios_version
+++ b/bin/apple_ios_version
@@ -1,24 +1,27 @@
-#! /bin/sh
+#!/usr/bin/env node
-#
-# 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.
-#
+/*
+ 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
-# outputs the highest level of iOS sdk installed
-iOS_X_VERSIONS=$(xcodebuild -showsdks | sed -e '/./{H;$!d;}' -e 'x;/iOS SDKs/!d;' | grep -o '[0-9]*\.[0-9]* ');
-echo $iOS_X_VERSIONS | tr " " "\n" | sort -g | tail -1;
\ No newline at end of file
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT 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 versions = require('./lib/versions.js');
+
+versions.get_apple_ios_version().done(null, function(err) {
+ console.log(err);
+ process.exit(2);
+});
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/apple_ios_version.bat
----------------------------------------------------------------------
diff --git a/bin/apple_ios_version.bat b/bin/apple_ios_version.bat
new file mode 100644
index 0000000..8219312
--- /dev/null
+++ b/bin/apple_ios_version.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0apple_ios_version"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'apple_ios_version' script in 'bin' folder, aborting...>&2
+ EXIT /B 1
+)
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/apple_osx_version
----------------------------------------------------------------------
diff --git a/bin/apple_osx_version b/bin/apple_osx_version
index 401e9cb..6e697ad 100755
--- a/bin/apple_osx_version
+++ b/bin/apple_osx_version
@@ -1,24 +1,27 @@
-#! /bin/sh
+#!/usr/bin/env node
-#
-# 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.
-#
+/*
+ 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
-# outputs the highest level of OS X sdk installed
-OS_X_VERSIONS=$(xcodebuild -showsdks | sed -e '/./{H;$!d;}' -e 'x;/OS X SDKs/!d;' | grep -o '[0-9]*\.[0-9]* ');
-echo $OS_X_VERSIONS | tr " " "\n" | sort -g | tail -1;
\ No newline at end of file
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT 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 versions = require('./lib/versions.js');
+
+versions.get_apple_osx_version().done(null, function(err) {
+ console.log(err);
+ process.exit(2);
+});
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/apple_osx_version.bat
----------------------------------------------------------------------
diff --git a/bin/apple_osx_version.bat b/bin/apple_osx_version.bat
new file mode 100644
index 0000000..d2acec7
--- /dev/null
+++ b/bin/apple_osx_version.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0apple_osx_version"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'apple_osx_version' script in 'bin' folder, aborting...>&2
+ EXIT /B 1
+)
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/apple_xcode_version
----------------------------------------------------------------------
diff --git a/bin/apple_xcode_version b/bin/apple_xcode_version
index d459b30..5dfe501 100755
--- a/bin/apple_xcode_version
+++ b/bin/apple_xcode_version
@@ -1,24 +1,27 @@
-#! /bin/sh
+#!/usr/bin/env node
-#
-# 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.
-#
+/*
+ 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
-# outputs which version of XCODE is installed
-XCODEBUILD_VERSION=$(xcodebuild -version | head -n 1 | sed -e 's/Xcode //')
-echo $XCODEBUILD_VERSION
\ No newline at end of file
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT 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 versions = require('./lib/versions.js');
+
+versions.get_apple_xcode_version().done(null, function(err) {
+ console.log(err);
+ process.exit(2);
+});
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/apple_xcode_version.bat
----------------------------------------------------------------------
diff --git a/bin/apple_xcode_version.bat b/bin/apple_xcode_version.bat
new file mode 100644
index 0000000..c19f911
--- /dev/null
+++ b/bin/apple_xcode_version.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0apple_xcode_version"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'apple_xcode_version' script in 'bin' folder, aborting...>&2
+ EXIT /B 1
+)
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/create
----------------------------------------------------------------------
diff --git a/bin/create b/bin/create
index b652adf..eeffc10 100755
--- a/bin/create
+++ b/bin/create
@@ -1,165 +1,42 @@
-#! /bin/sh
-
-#
-# 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.
-#
-
-#
-# create a Cordova/iOS project
-#
-# USAGE
-# ./create <path_to_new_project> <package_name> <project_name>
-#
-# EXAMPLE
-# ./create ~/Desktop/radness org.apache.cordova.radness Radness
-#
-set -e
-
-function usage() {
- echo "Usage: $0 [--shared] [--cli] <path_to_new_project> <package_name> <project_name> [<project_template_dir>]"
- echo " --shared (optional): Link directly against the shared copy of the CordovaLib instead of a copy of it."
- echo " --cli (optional): Use the CLI-project template."
- echo " <path_to_new_project>: Path to your new Cordova iOS project"
- echo " <package_name>: Package name, following reverse-domain style convention"
- echo " <project_name>: Project name"
- echo " <project_template_dir>: Path to project template (override)."
- exit 1
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+/*
+ * create a Cordova/iOS project
+ *
+ * USAGE
+ * ./create <path_to_new_project> <package_name> <project_name>
+ *
+ * EXAMPLE
+ * ./create ~/Desktop/radness org.apache.cordova.radness Radness
+ */
+
+var create = require('./lib/create');
+
+if (process.argv.length < 3 || process.argv[2].indexOf('--help') > -1) {
+ create.createHelp();
+}
+else {
+ create.createProject(process.argv).done(null, function(err) {
+ console.error('Failed to create project because of error: ' + err);
+ process.exit(2);
+ });
}
-
-USE_SHARED=0
-USE_CLI=0
-while [ $# -gt 0 ]; do
- case "$1" in
- --shared) USE_SHARED=1 ;;
- --cli) USE_CLI=1 ;;
- -*) ;;
- *)
- if [[ -z "$PROJECT_PATH" ]]; then
- PROJECT_PATH="$1"
- elif [[ -z "$PACKAGE" ]]; then
- PACKAGE="$1"
- elif [[ -z "$PROJECT_NAME" ]]; then
- PROJECT_NAME="$1"
- elif [[ -z "$PROJECT_TEMPLATE_DIR" ]]; then
- PROJECT_TEMPLATE_DIR="$1"
- else
- echo "Too many arguments to $0". >&2
- usage
- fi
- esac
- shift
-done
-
-# check whether it is a proper create command (at least 3 arguments)
-if [[ -z "$PROJECT_NAME" ]]; then
- usage
-fi
-
-# the two lines below are to get the current folder, and resolve symlinks
-SCRIPT="$0"
-# need this for relative symlinks
-while [ -h "$SCRIPT" ] ; do
- SCRIPT=`readlink "$SCRIPT"`
-done
-
-BINDIR=$( cd "$( dirname "$SCRIPT" )" && pwd )
-CORDOVALIB_DIR="$BINDIR/../CordovaLib"
-CDV_VER=$(cat "$CORDOVALIB_DIR/VERSION")
-
-PROJECT_PARENT=$(dirname "$PROJECT_PATH")
-PROJECT_TEMPLATE_DIR=${PROJECT_TEMPLATE_DIR:-"$BINDIR/templates/project"}
-SCRIPT_TEMPLATE_DIR=$BINDIR/templates/scripts
-
-"$BINDIR/check_reqs" || exit $?
-
-# check whether the project path exists and is not empty
-if [ -d "$PROJECT_PATH" ]; then
- if [ "$(ls -1A "$PROJECT_PATH")" ]; then
- echo "\033[31mError: $PROJECT_PATH is not empty. Please specify an empty folder.\033[m"
- exit 1
- fi
-fi
-
-#Ensure the parent directory exists so cp -r will not fail
-if [ ! -d "$PROJECT_PARENT" ]; then
- echo "\033[31mError: $PROJECT_PARENT does not exist. Please specify an existing parent folder.\033[m"
- exit 1
-fi
-
-mkdir -p "$PROJECT_PATH"
-cp -r "$PROJECT_TEMPLATE_DIR/www" "$PROJECT_PATH"/www
-cp "$CORDOVALIB_DIR/cordova.js" "$PROJECT_PATH/www/cordova.js"
-if (($USE_CLI)); then
- cp -r "$PROJECT_TEMPLATE_DIR/__CLI__.xcodeproj" "$PROJECT_PATH/$PROJECT_NAME.xcodeproj"
-else
- cp -r "$PROJECT_TEMPLATE_DIR/__NON-CLI__.xcodeproj" "$PROJECT_PATH/$PROJECT_NAME.xcodeproj"
-fi
-cp -r "$PROJECT_TEMPLATE_DIR/__PROJECT_NAME__" "$PROJECT_PATH/$PROJECT_NAME"
-
-R=$PROJECT_PATH/$PROJECT_NAME
-mv "$R/__PROJECT_NAME__-Info.plist" "$R/$PROJECT_NAME-Info.plist"
-mv "$R/__PROJECT_NAME__-Prefix.pch" "$R/$PROJECT_NAME-Prefix.pch"
-mv "$R/gitignore" "$R/.gitignore"
-
-# replace __PROJECT_NAME__ and --ID-- with ACTIVITY and ID strings, respectively, in:
-#
-# - ./__PROJECT_NAME__.xcodeproj/project.pbxproj
-# - ./__PROJECT_NAME__/Classes/AppDelegate.h
-# - ./__PROJECT_NAME__/Classes/AppDelegate.m
-# - ./__PROJECT_NAME__/Resources/main.m
-# - ./__PROJECT_NAME__/Resources/__PROJECT_NAME__-info.plist
-# - ./__PROJECT_NAME__/Resources/__PROJECT_NAME__-Prefix.plist
-
-PROJECT_NAME_ESC="${PROJECT_NAME//&/\\&}"
-"$BINDIR/replaces" "$R.xcodeproj/project.pbxproj" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/Classes/AppDelegate.h" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/Classes/AppDelegate.m" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/Classes/MainViewController.h" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/Classes/MainViewController.m" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/main.m" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/$PROJECT_NAME-Info.plist" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-"$BINDIR/replaces" "$R/$PROJECT_NAME-Prefix.pch" __PROJECT_NAME__ "$PROJECT_NAME_ESC"
-
-"$BINDIR/replaces" "$R/$PROJECT_NAME-Info.plist" --ID-- $PACKAGE
-
-if [[ $USE_SHARED = 1 ]]; then
- # Make the sub-project reference to Cordova have the correct path.
- "$BINDIR/update_cordova_subproject" "$R.xcodeproj/project.pbxproj" > /dev/null
-else
- # Copy in the CordovaLib directory.
- mkdir -p "$PROJECT_PATH/CordovaLib/CordovaLib.xcodeproj"
- cp "$R/.gitignore" "$PROJECT_PATH/"
- cp -r "$BINDIR/../CordovaLib/Classes" "$PROJECT_PATH/CordovaLib"
- cp "$BINDIR/../CordovaLib/VERSION" "$PROJECT_PATH/CordovaLib"
- cp "$BINDIR/../CordovaLib/cordova.js" "$PROJECT_PATH/CordovaLib"
- cp "$BINDIR/../CordovaLib/CordovaLib_Prefix.pch" "$PROJECT_PATH/CordovaLib"
- cp "$BINDIR/../CordovaLib/CordovaLib.xcodeproj/project.pbxproj" "$PROJECT_PATH/CordovaLib/CordovaLib.xcodeproj"
- # Make the sub-project reference to Cordova have the correct path.
- "$BINDIR/update_cordova_subproject" "$R.xcodeproj/project.pbxproj" "$PROJECT_PATH/CordovaLib/CordovaLib.xcodeproj/project.pbxproj" > /dev/null
-fi
-
-# Finally copy the scripts
-cp -r "$SCRIPT_TEMPLATE_DIR"/* "$PROJECT_PATH/"
-
-# copy the check_reqs script
-cp "$BINDIR/check_reqs" "$PROJECT_PATH"/cordova
-
-# copy the version scripts script
-cp "$BINDIR/apple_ios_version" "$PROJECT_PATH"/cordova
-cp "$BINDIR/apple_osx_version" "$PROJECT_PATH"/cordova
-cp "$BINDIR/apple_xcode_version" "$PROJECT_PATH"/cordova
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/create.bat
----------------------------------------------------------------------
diff --git a/bin/create.bat b/bin/create.bat
new file mode 100644
index 0000000..43172a6
--- /dev/null
+++ b/bin/create.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script="%~dp0create"
+IF EXIST %script% (
+ node %script% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'create' script in 'bin' folder, aborting...>&2
+ EXIT /B 1
+)
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/lib/create.js
----------------------------------------------------------------------
diff --git a/bin/lib/create.js b/bin/lib/create.js
new file mode 100755
index 0000000..8c37c80
--- /dev/null
+++ b/bin/lib/create.js
@@ -0,0 +1,255 @@
+#!/usr/bin/env node
+
+/*
+ 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 shell = require('shelljs'),
+ Q = require ('q'),
+ path = require('path'),
+ fs = require('fs'),
+ root = path.join(__dirname, '..', '..');
+
+function createHelp() {
+ console.log("Usage: $0 [--shared] [--cli] <path_to_new_project> <package_name> <project_name> [<project_template_dir>]");
+ console.log(" --shared (optional): Link directly against the shared copy of the CordovaLib instead of a copy of it.");
+ console.log(" --cli (optional): Use the CLI-project template.");
+ console.log(" <path_to_new_project>: Path to your new Cordova iOS project");
+ console.log(" <package_name>: Package name, following reverse-domain style convention");
+ console.log(" <project_name>: Project name");
+ console.log(" <project_template_dir>: Path to project template (override).");
+}
+
+function updateSubprojectHelp() {
+ console.log('Updates the subproject path of the CordovaLib entry to point to this script\'s version of Cordova.')
+ console.log("Usage: CordovaVersion/bin/update_cordova_project path/to/your/app.xcodeproj [path/to/CordovaLib.xcodeproj]");
+}
+
+function AbsParentPath(_path) {
+ return path.resolve(path.dirname(_path));
+}
+
+function AbsProjectPath(relative_path) {
+ var absolute_path = path.resolve(relative_path);
+ if (/.pbxproj$/.test(absolute_path)) {
+ absolute_path = AbsParentPath(absolute_path);
+ }
+ else if (!(/.xcodeproj$/.test(absolute_path))) {
+ throw new Error('The following is not a valid path to an Xcode project' + absolute_path);
+ }
+ return absolute_path;
+}
+
+function relpath(_path, start) {
+ start = start || process.cwd();
+ return path.relative(path.resolve(start), path.resolve(_path));
+}
+
+/*
+ * Creates a new iOS project with the following options:
+ *
+ * - --shared (optional): Link directly against the shared copy of the CordovaLib instead of a copy of it
+ * - --cli (optional): Use the CLI-project template
+ * - <path_to_new_project>: Path to your new Cordova iOS project
+ * - <package_name>: Package name, following reverse-domain style convention
+ * - <project_name>: Project name
+ * - <project_template_dir>: Path to a project template (override)
+ *
+ */
+
+exports.createProject = function(argv) {
+ var project_path,
+ package_name,
+ project_name,
+ project_template_dir,
+ use_shared = false,
+ use_cli = false;
+
+ //get arguments
+ var args = argv.slice(2);
+
+ //check and set arguments
+ if (args.length < 3)
+ {
+ createHelp();
+ return Q.reject('Too few arguments');
+ }
+
+ for (var i = 0; i < args.length; i++) {
+ if (args[i] === '--shared')
+ use_shared = true;
+ else if (args[i] === '--cli')
+ use_cli = true;
+ else
+ {
+ if (!project_path)
+ project_path = args[i];
+ else if (!package_name)
+ package_name = args[i];
+ else if (!project_name)
+ project_name = args[i];
+ else if (!project_template_dir)
+ project_template_dir = args[i];
+ else
+ {
+ createHelp();
+ return Q.reject('Too many arguments');
+ }
+ }
+ }
+
+ var bin_dir = path.join(root, 'bin'),
+ cordovalib_dir = path.join(root, 'CordovaLib'),
+ cordovalib_ver = fs.readFileSync(path.join(cordovalib_dir, 'VERSION'), 'utf-8').trim();
+ project_parent = path.dirname(project_path),
+ project_template_dir = project_template_dir ? project_template_dir : path.join(bin_dir, 'templates', 'project'),
+ script_template_dir = path.join(bin_dir, 'templates', 'scripts');
+
+ //check that project path doesn't exist
+ if (fs.existsSync(project_path)) {
+ return Q.reject('Project already exists');
+ }
+
+ //check that parent directory does exist so cp -r will not fail
+ if (!fs.existsSync(project_parent)) {
+ return Q.reject(project_parent + ' does not exist. Please specify an existing parent folder');
+ }
+
+ //create the project directory and copy over files
+ shell.mkdir('-p', project_path);
+ shell.cp('-rf', path.join(project_template_dir, 'www'), project_path);
+ shell.cp('-f', path.join(cordovalib_dir, 'cordova.js'), path.join(project_path, 'www', 'cordova.js'));
+ if (use_cli) {
+ shell.cp('-rf', path.join(project_template_dir, '__CLI__.xcodeproj'), project_path);
+ shell.mv(path.join(project_path, '__CLI__.xcodeproj'), path.join(project_path, project_name+'.xcodeproj'));
+ }
+ else {
+ shell.cp('-rf', path.join(project_template_dir, '__NON-CLI__.xcodeproj'), project_path);
+ shell.mv(path.join(project_path, '__NON-CLI__.xcodeproj'), path.join(project_path, project_name+'.xcodeproj'));
+ }
+ shell.cp('-rf', path.join(project_template_dir, '__PROJECT_NAME__'), project_path);
+ shell.mv(path.join(project_path, '__PROJECT_NAME__'), path.join(project_path, project_name));
+
+ var r = path.join(project_path, project_name);
+ shell.mv(path.join(r, '__PROJECT_NAME__-Info.plist'), path.join(r, project_name+'-Info.plist'));
+ shell.mv(path.join(r, '__PROJECT_NAME__-Prefix.pch'), path.join(r, project_name+'-Prefix.pch'));
+ shell.mv(path.join(r, 'gitignore'), path.join(r, '.gitignore'));
+
+ /*replace __PROJECT_NAME__ and --ID-- with ACTIVITY and ID strings, respectively, in:
+ *
+ * - ./__PROJECT_NAME__.xcodeproj/project.pbxproj
+ * - ./__PROJECT_NAME__/Classes/AppDelegate.h
+ * - ./__PROJECT_NAME__/Classes/AppDelegate.m
+ * - ./__PROJECT_NAME__/Resources/main.m
+ * - ./__PROJECT_NAME__/Resources/__PROJECT_NAME__-info.plist
+ * - ./__PROJECT_NAME__/Resources/__PROJECT_NAME__-Prefix.plist
+ */
+ var project_name_esc = project_name.replace(/&/g, '\\&');
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r+'.xcodeproj', 'project.pbxproj'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, 'Classes', 'AppDelegate.h'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, 'Classes', 'AppDelegate.m'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, 'Classes', 'MainViewController.h'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, 'Classes', 'MainViewController.m'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, 'main.m'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, project_name+'-Info.plist'));
+ shell.sed('-i', /__PROJECT_NAME__/g, project_name_esc, path.join(r, project_name+'-Prefix.pch'));
+ shell.sed('-i', /--ID--/g, package_name, path.join(r, project_name+'-Info.plist'));
+
+ //CordovaLib stuff
+ if (use_shared) {
+ update_cordova_subproject([path.join(r+'.xcodeproj', 'project.pbxproj')]);
+ }
+ else {
+ //copy in the CordovaLib directory
+ shell.mkdir('-p', path.join(project_path, 'CordovaLib', 'CordovaLib.xcodeproj'));
+ shell.cp('-f', path.join(r, '.gitignore'), project_path);
+ shell.cp('-rf', path.join(bin_dir, '..', 'CordovaLib', 'Classes'), path.join(project_path, 'CordovaLib'));
+ shell.cp('-f', path.join(bin_dir, '..', 'CordovaLib', 'VERSION'), path.join(project_path, 'CordovaLib'));
+ shell.cp('-f', path.join(bin_dir, '..', 'CordovaLib', 'cordova.js'), path.join(project_path, 'CordovaLib'));
+ shell.cp('-f', path.join(bin_dir, '..', 'CordovaLib', 'CordovaLib_Prefix.pch'), path.join(project_path, 'CordovaLib'));
+ shell.cp('-f', path.join(bin_dir, '..', 'CordovaLib', 'CordovaLib.xcodeproj', 'project.pbxproj'), path.join(project_path, 'CordovaLib', 'CordovaLib.xcodeproj'));
+ update_cordova_subproject([path.join(r+'.xcodeproj', 'project.pbxproj'), path.join(project_path, 'CordovaLib', 'CordovaLib.xcodeproj', 'project.pbxproj')]);
+ }
+
+ //Finally copy the scripts
+ shell.cp('-r', path.join(script_template_dir, '*'), project_path);
+ shell.cp('-r', path.join(bin_dir, 'node_modules'), path.join(project_path, 'cordova'));
+
+ //copy the check_reqs script
+ shell.cp(path.join(bin_dir, 'check_reqs'), path.join(project_path, 'cordova'));
+
+ //copy the version scripts script
+ shell.cp(path.join(bin_dir, 'apple_ios_version'), path.join(project_path, 'cordova'));
+ shell.cp(path.join(bin_dir, 'apple_osx_version'), path.join(project_path, 'cordova'));
+ shell.cp(path.join(bin_dir, 'apple_xcode_version'), path.join(project_path, 'cordova'));
+ shell.cp(path.join(bin_dir, 'lib', 'versions.js'), path.join(project_path, 'cordova', 'lib'));
+
+ //Make scripts executable
+ shell.find(path.join(project_path, 'cordova')).forEach(function(entry) {
+ shell.chmod(755, entry);
+ });
+
+ return Q.resolve();
+}
+
+
+function update_cordova_subproject(argv) {
+ if (argv.length < 1 || argv.length > 2)
+ {
+ updateSubprojectHelp();
+ throw new Error('Usage error for update_cordova_subproject');
+ }
+
+ var projectPath = AbsProjectPath(argv[0]),
+ cordovaLibXcodePath;
+ if (argv.length < 2) {
+ cordovaLibXcodePath = path.join(root, 'CordovaLib', 'CordovaLib.xcodeproj');
+ }
+ else {
+ cordovaLibXcodePath = AbsProjectPath(argv[1]);
+ }
+
+ var parentProjectPath = AbsParentPath(projectPath),
+ subprojectPath = relpath(cordovaLibXcodePath, parentProjectPath),
+ REGEX = /(.+PBXFileReference.+wrapper.pb-project.+)(path = .+?;)(.*)(sourceTree.+;)(.+)/,
+ newLine,
+ lines = shell.grep('CordovaLib.xcodeproj', path.join(projectPath, 'project.pbxproj')),
+ found = false;
+
+ subprojectPath = subprojectPath.replace(/\\/g, '/');
+ lines = lines.split('\n');
+ for (var i = 0; i < lines.length; ++i) {
+ if (lines[i].match(REGEX)) {
+ found = true;
+ newLine = lines[i].replace(/path = .+?;/, 'path = ' + subprojectPath + ';');
+ newLine = newLine.replace(/sourceTree.+?;/, 'sourceTree = \"<group>\";');
+ if (!newLine.match('name')) {
+ newLine = newLine.replace('path = ', 'name = CordovaLib.xcodeproj; path = ');
+ }
+ shell.sed('-i', lines[i], newLine, path.join(projectPath, 'project.pbxproj'));
+ }
+ }
+
+ if (!found) {
+ throw new Error('Subproject: ' + subprojectPath + ' entry not found in project file');
+ }
+}
+
+exports.createHelp = createHelp;
+exports.updateSubprojectHelp = updateSubprojectHelp;
+exports.update_cordova_subproject = update_cordova_subproject;
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/lib/update.js
----------------------------------------------------------------------
diff --git a/bin/lib/update.js b/bin/lib/update.js
new file mode 100755
index 0000000..e023e58
--- /dev/null
+++ b/bin/lib/update.js
@@ -0,0 +1,72 @@
+#!/usr/bin/env node
+
+/*
+ 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 shell = require('shelljs'),
+ path = require('path'),
+ fs = require('fs'),
+ ROOT = path.join(__dirname, '..', '..');
+
+function setShellFatal(value, func) {
+ var oldVal = shell.config.fatal;
+ shell.config.fatal = value;
+ func();
+ shell.config.fatal = oldVal;
+}
+
+function copyJsAndCordovaLib(projectPath) {
+ shell.cp('-f', path.join(ROOT, 'CordovaLib', 'cordova.js'), path.join(projectPath, 'www'));
+ shell.rm('-rf', path.join(projectPath, 'CordovaLib'));
+ shell.cp('-r', path.join(ROOT, 'CordovaLib'), projectPath);
+ // Ensure no workspace files got copied over.
+ var entries = fs.readdirSync(path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj'));
+ entries.forEach(function(p) {
+ if (/.*xc.*/.test(p)) {
+ shell.rm('-rf', path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj', p));
+ }
+ });
+}
+
+function copyScripts(projectPath) {
+ var srcScriptsDir = path.join(ROOT, 'bin', 'templates', 'scripts', 'cordova');
+ var destScriptsDir = path.join(projectPath, 'cordova');
+ // Delete old scripts directory.
+ shell.rm('-rf', destScriptsDir);
+ // Copy in the new ones.
+ shell.cp('-r', srcScriptsDir, projectPath);
+ shell.cp('-r', path.join(ROOT, 'bin', 'node_modules'), destScriptsDir);
+ shell.cp(path.join(ROOT, 'bin', 'check_reqs'), path.join(destScriptsDir, 'check_reqs'));
+ shell.cp(path.join(ROOT, 'bin', 'apple_ios_version'), destScriptsDir);
+ shell.cp(path.join(ROOT, 'bin', 'apple_osx_version'), destScriptsDir);
+ shell.cp(path.join(ROOT, 'bin', 'apple_xcode_version'), destScriptsDir);
+ shell.cp(path.join(ROOT, 'bin', 'lib', 'versions.js'), path.join(destScriptsDir, 'lib'));
+ // Make sure they are executable.
+ shell.find(destScriptsDir).forEach(function(entry) {
+ shell.chmod(755, entry);
+ });
+}
+
+exports.updateProject = function(projectPath) {
+ var version = fs.readFileSync(path.join(ROOT, 'CordovaLib', 'VERSION'), 'utf-8').trim();
+ setShellFatal(true, function() {
+ copyJsAndCordovaLib(projectPath);
+ copyScripts(projectPath);
+ console.log('iOS project is now at version ' + version);
+ });
+};
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/lib/versions.js
----------------------------------------------------------------------
diff --git a/bin/lib/versions.js b/bin/lib/versions.js
new file mode 100755
index 0000000..9a8eaec
--- /dev/null
+++ b/bin/lib/versions.js
@@ -0,0 +1,101 @@
+#!/usr/bin/env node
+
+/*
+ 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 child_process = require('child_process'),
+ Q = require('q');
+
+exports.get_apple_ios_version = function() {
+ var d = Q.defer();
+ child_process.exec('xcodebuild -showsdks', function(error, stdout, stderr) {
+ if (error) {
+ d.reject(stderr);
+ }
+ else {
+ d.resolve(stdout);
+ }
+ });
+
+ return d.promise.then(function(output) {
+ var regex = /[0-9]*\.[0-9]*/,
+ versions = [],
+ regexIOS = /^iOS \d+/;
+ output = output.split('\n');
+ for (var i = 0; i < output.length; i++) {
+ if (output[i].trim().match(regexIOS)) {
+ versions[versions.length] = parseFloat(output[i].match(regex)[0]);
+ }
+ }
+ versions.sort();
+ console.log(versions[0]);
+ return Q();
+ }, function(stderr) {
+ return Q.reject(stderr);
+ });
+}
+
+exports.get_apple_osx_version = function() {
+ var d = Q.defer();
+ child_process.exec('xcodebuild -showsdks', function(error, stdout, stderr) {
+ if (error) {
+ d.reject(stderr);
+ }
+ else {
+ d.resolve(stdout);
+ }
+ });
+
+ return d.promise.then(function(output) {
+ var regex = /[0-9]*\.[0-9]*/,
+ versions = [],
+ regexOSX = /^OS X \d+/;
+ output = output.split('\n');
+ for (var i = 0; i < output.length; i++) {
+ if (output[i].trim().match(regexOSX)) {
+ versions[versions.length] = parseFloat(output[i].match(regex)[0]);
+ }
+ }
+ versions.sort();
+ console.log(versions[0]);
+ return Q();
+ }, function(stderr) {
+ return Q.reject(stderr);
+ });
+}
+
+exports.get_apple_xcode_version = function() {
+ var d = Q.defer();
+ child_process.exec('xcodebuild -version', function(error, stdout, stderr) {
+ if (error) {
+ d.reject(stderr);
+ }
+ else {
+ d.resolve(stdout);
+ }
+ });
+
+ return d.promise.then(function(output) {
+ output = output.split('\n');
+ console.log(output[0].slice(6));
+ return Q();
+ }, function(stderr) {
+ return Q.reject(stderr);
+ });
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/CONTRIBUTING.md
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/CONTRIBUTING.md b/bin/node_modules/q/CONTRIBUTING.md
new file mode 100644
index 0000000..500ab17
--- /dev/null
+++ b/bin/node_modules/q/CONTRIBUTING.md
@@ -0,0 +1,40 @@
+
+For pull requests:
+
+- Be consistent with prevalent style and design decisions.
+- Add a Jasmine spec to `specs/q-spec.js`.
+- Use `npm test` to avoid regressions.
+- Run tests in `q-spec/run.html` in as many supported browsers as you
+ can find the will to deal with.
+- Do not build minified versions; we do this each release.
+- If you would be so kind, add a note to `CHANGES.md` in an
+ appropriate section:
+
+ - `Next Major Version` if it introduces backward incompatibilities
+ to code in the wild using documented features.
+ - `Next Minor Version` if it adds a new feature.
+ - `Next Patch Version` if it fixes a bug.
+
+For releases:
+
+- Run `npm test`.
+- Run tests in `q-spec/run.html` in a representative sample of every
+ browser under the sun.
+- Run `npm run cover` and make sure you're happy with the results.
+- Run `npm run minify` and be sure to commit the resulting `q.min.js`.
+- Note the Gzipped size output by the previous command, and update
+ `README.md` if it has changed to 1 significant digit.
+- Stash any local changes.
+- Update `CHANGES.md` to reflect all changes in the differences
+ between `HEAD` and the previous tagged version. Give credit where
+ credit is due.
+- Update `README.md` to address all new, non-experimental features.
+- Update the API reference on the Wiki to reflect all non-experimental
+ features.
+- Use `npm version major|minor|patch` to update `package.json`,
+ commit, and tag the new version.
+- Use `npm publish` to send up a new release.
+- Send an email to the q-continuum mailing list announcing the new
+ release and the notes from the change log. This helps folks
+ maintaining other package ecosystems.
+
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/LICENSE
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/LICENSE b/bin/node_modules/q/LICENSE
new file mode 100644
index 0000000..8a706b5
--- /dev/null
+++ b/bin/node_modules/q/LICENSE
@@ -0,0 +1,18 @@
+Copyright 2009–2014 Kristopher Michael Kowal. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/README.md
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/README.md b/bin/node_modules/q/README.md
new file mode 100644
index 0000000..bdd4168
--- /dev/null
+++ b/bin/node_modules/q/README.md
@@ -0,0 +1,820 @@
+[](http://travis-ci.org/kriskowal/q)
+
+<a href="http://promises-aplus.github.com/promises-spec">
+ <img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png"
+ align="right" alt="Promises/A+ logo" />
+</a>
+
+*This is Q version 1, from the `v1` branch in Git. This documentation applies to
+the latest of both the version 1 and version 0.9 release trains. These releases
+are stable. There will be no further releases of 0.9 after 0.9.7 which is nearly
+equivalent to version 1.0.0. All further releases of `q@~1.0` will be backward
+compatible. The version 2 release train introduces significant but
+backward-incompatible changes and is experimental at this time.*
+
+If a function cannot return a value or throw an exception without
+blocking, it can return a promise instead. A promise is an object
+that represents the return value or the thrown exception that the
+function may eventually provide. A promise can also be used as a
+proxy for a [remote object][Q-Connection] to overcome latency.
+
+[Q-Connection]: https://github.com/kriskowal/q-connection
+
+On the first pass, promises can mitigate the “[Pyramid of
+Doom][POD]”: the situation where code marches to the right faster
+than it marches forward.
+
+[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/
+
+```javascript
+step1(function (value1) {
+ step2(value1, function(value2) {
+ step3(value2, function(value3) {
+ step4(value3, function(value4) {
+ // Do something with value4
+ });
+ });
+ });
+});
+```
+
+With a promise library, you can flatten the pyramid.
+
+```javascript
+Q.fcall(promisedStep1)
+.then(promisedStep2)
+.then(promisedStep3)
+.then(promisedStep4)
+.then(function (value4) {
+ // Do something with value4
+})
+.catch(function (error) {
+ // Handle any error from all above steps
+})
+.done();
+```
+
+With this approach, you also get implicit error propagation, just like `try`,
+`catch`, and `finally`. An error in `promisedStep1` will flow all the way to
+the `catch` function, where it’s caught and handled. (Here `promisedStepN` is
+a version of `stepN` that returns a promise.)
+
+The callback approach is called an “inversion of control”.
+A function that accepts a callback instead of a return value
+is saying, “Don’t call me, I’ll call you.”. Promises
+[un-invert][IOC] the inversion, cleanly separating the input
+arguments from control flow arguments. This simplifies the
+use and creation of API’s, particularly variadic,
+rest and spread arguments.
+
+[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
+
+
+## Getting Started
+
+The Q module can be loaded as:
+
+- A ``<script>`` tag (creating a ``Q`` global variable): ~2.5 KB minified and
+ gzipped.
+- A Node.js and CommonJS module, available in [npm](https://npmjs.org/) as
+ the [q](https://npmjs.org/package/q) package
+- An AMD module
+- A [component](https://github.com/component/component) as ``microjs/q``
+- Using [bower](http://bower.io/) as ``q``
+- Using [NuGet](http://nuget.org/) as [Q](https://nuget.org/packages/q)
+
+Q can exchange promises with jQuery, Dojo, When.js, WinJS, and more.
+
+## Resources
+
+Our [wiki][] contains a number of useful resources, including:
+
+- A method-by-method [Q API reference][reference].
+- A growing [examples gallery][examples], showing how Q can be used to make
+ everything better. From XHR to database access to accessing the Flickr API,
+ Q is there for you.
+- There are many libraries that produce and consume Q promises for everything
+ from file system/database access or RPC to templating. For a list of some of
+ the more popular ones, see [Libraries][].
+- If you want materials that introduce the promise concept generally, and the
+ below tutorial isn't doing it for you, check out our collection of
+ [presentations, blog posts, and podcasts][resources].
+- A guide for those [coming from jQuery's `$.Deferred`][jquery].
+
+We'd also love to have you join the Q-Continuum [mailing list][].
+
+[wiki]: https://github.com/kriskowal/q/wiki
+[reference]: https://github.com/kriskowal/q/wiki/API-Reference
+[examples]: https://github.com/kriskowal/q/wiki/Examples-Gallery
+[Libraries]: https://github.com/kriskowal/q/wiki/Libraries
+[resources]: https://github.com/kriskowal/q/wiki/General-Promise-Resources
+[jquery]: https://github.com/kriskowal/q/wiki/Coming-from-jQuery
+[mailing list]: https://groups.google.com/forum/#!forum/q-continuum
+
+
+## Tutorial
+
+Promises have a ``then`` method, which you can use to get the eventual
+return value (fulfillment) or thrown exception (rejection).
+
+```javascript
+promiseMeSomething()
+.then(function (value) {
+}, function (reason) {
+});
+```
+
+If ``promiseMeSomething`` returns a promise that gets fulfilled later
+with a return value, the first function (the fulfillment handler) will be
+called with the value. However, if the ``promiseMeSomething`` function
+gets rejected later by a thrown exception, the second function (the
+rejection handler) will be called with the exception.
+
+Note that resolution of a promise is always asynchronous: that is, the
+fulfillment or rejection handler will always be called in the next turn of the
+event loop (i.e. `process.nextTick` in Node). This gives you a nice
+guarantee when mentally tracing the flow of your code, namely that
+``then`` will always return before either handler is executed.
+
+In this tutorial, we begin with how to consume and work with promises. We'll
+talk about how to create them, and thus create functions like
+`promiseMeSomething` that return promises, [below](#the-beginning).
+
+
+### Propagation
+
+The ``then`` method returns a promise, which in this example, I’m
+assigning to ``outputPromise``.
+
+```javascript
+var outputPromise = getInputPromise()
+.then(function (input) {
+}, function (reason) {
+});
+```
+
+The ``outputPromise`` variable becomes a new promise for the return
+value of either handler. Since a function can only either return a
+value or throw an exception, only one handler will ever be called and it
+will be responsible for resolving ``outputPromise``.
+
+- If you return a value in a handler, ``outputPromise`` will get
+ fulfilled.
+
+- If you throw an exception in a handler, ``outputPromise`` will get
+ rejected.
+
+- If you return a **promise** in a handler, ``outputPromise`` will
+ “become” that promise. Being able to become a new promise is useful
+ for managing delays, combining results, or recovering from errors.
+
+If the ``getInputPromise()`` promise gets rejected and you omit the
+rejection handler, the **error** will go to ``outputPromise``:
+
+```javascript
+var outputPromise = getInputPromise()
+.then(function (value) {
+});
+```
+
+If the input promise gets fulfilled and you omit the fulfillment handler, the
+**value** will go to ``outputPromise``:
+
+```javascript
+var outputPromise = getInputPromise()
+.then(null, function (error) {
+});
+```
+
+Q promises provide a ``fail`` shorthand for ``then`` when you are only
+interested in handling the error:
+
+```javascript
+var outputPromise = getInputPromise()
+.fail(function (error) {
+});
+```
+
+If you are writing JavaScript for modern engines only or using
+CoffeeScript, you may use `catch` instead of `fail`.
+
+Promises also have a ``fin`` function that is like a ``finally`` clause.
+The final handler gets called, with no arguments, when the promise
+returned by ``getInputPromise()`` either returns a value or throws an
+error. The value returned or error thrown by ``getInputPromise()``
+passes directly to ``outputPromise`` unless the final handler fails, and
+may be delayed if the final handler returns a promise.
+
+```javascript
+var outputPromise = getInputPromise()
+.fin(function () {
+ // close files, database connections, stop servers, conclude tests
+});
+```
+
+- If the handler returns a value, the value is ignored
+- If the handler throws an error, the error passes to ``outputPromise``
+- If the handler returns a promise, ``outputPromise`` gets postponed. The
+ eventual value or error has the same effect as an immediate return
+ value or thrown error: a value would be ignored, an error would be
+ forwarded.
+
+If you are writing JavaScript for modern engines only or using
+CoffeeScript, you may use `finally` instead of `fin`.
+
+### Chaining
+
+There are two ways to chain promises. You can chain promises either
+inside or outside handlers. The next two examples are equivalent.
+
+```javascript
+return getUsername()
+.then(function (username) {
+ return getUser(username)
+ .then(function (user) {
+ // if we get here without an error,
+ // the value returned here
+ // or the exception thrown here
+ // resolves the promise returned
+ // by the first line
+ })
+});
+```
+
+```javascript
+return getUsername()
+.then(function (username) {
+ return getUser(username);
+})
+.then(function (user) {
+ // if we get here without an error,
+ // the value returned here
+ // or the exception thrown here
+ // resolves the promise returned
+ // by the first line
+});
+```
+
+The only difference is nesting. It’s useful to nest handlers if you
+need to capture multiple input values in your closure.
+
+```javascript
+function authenticate() {
+ return getUsername()
+ .then(function (username) {
+ return getUser(username);
+ })
+ // chained because we will not need the user name in the next event
+ .then(function (user) {
+ return getPassword()
+ // nested because we need both user and password next
+ .then(function (password) {
+ if (user.passwordHash !== hash(password)) {
+ throw new Error("Can't authenticate");
+ }
+ });
+ });
+}
+```
+
+
+### Combination
+
+You can turn an array of promises into a promise for the whole,
+fulfilled array using ``all``.
+
+```javascript
+return Q.all([
+ eventualAdd(2, 2),
+ eventualAdd(10, 20)
+]);
+```
+
+If you have a promise for an array, you can use ``spread`` as a
+replacement for ``then``. The ``spread`` function “spreads” the
+values over the arguments of the fulfillment handler. The rejection handler
+will get called at the first sign of failure. That is, whichever of
+the recived promises fails first gets handled by the rejection handler.
+
+```javascript
+function eventualAdd(a, b) {
+ return Q.spread([a, b], function (a, b) {
+ return a + b;
+ })
+}
+```
+
+But ``spread`` calls ``all`` initially, so you can skip it in chains.
+
+```javascript
+return getUsername()
+.then(function (username) {
+ return [username, getUser(username)];
+})
+.spread(function (username, user) {
+});
+```
+
+The ``all`` function returns a promise for an array of values. When this
+promise is fulfilled, the array contains the fulfillment values of the original
+promises, in the same order as those promises. If one of the given promises
+is rejected, the returned promise is immediately rejected, not waiting for the
+rest of the batch. If you want to wait for all of the promises to either be
+fulfilled or rejected, you can use ``allSettled``.
+
+```javascript
+Q.allSettled(promises)
+.then(function (results) {
+ results.forEach(function (result) {
+ if (result.state === "fulfilled") {
+ var value = result.value;
+ } else {
+ var reason = result.reason;
+ }
+ });
+});
+```
+
+
+### Sequences
+
+If you have a number of promise-producing functions that need
+to be run sequentially, you can of course do so manually:
+
+```javascript
+return foo(initialVal).then(bar).then(baz).then(qux);
+```
+
+However, if you want to run a dynamically constructed sequence of
+functions, you'll want something like this:
+
+```javascript
+var funcs = [foo, bar, baz, qux];
+
+var result = Q(initialVal);
+funcs.forEach(function (f) {
+ result = result.then(f);
+});
+return result;
+```
+
+You can make this slightly more compact using `reduce`:
+
+```javascript
+return funcs.reduce(function (soFar, f) {
+ return soFar.then(f);
+}, Q(initialVal));
+```
+
+Or, you could use th ultra-compact version:
+
+```javascript
+return funcs.reduce(Q.when, Q());
+```
+
+### Handling Errors
+
+One sometimes-unintuive aspect of promises is that if you throw an
+exception in the fulfillment handler, it will not be be caught by the error
+handler.
+
+```javascript
+return foo()
+.then(function (value) {
+ throw new Error("Can't bar.");
+}, function (error) {
+ // We only get here if "foo" fails
+});
+```
+
+To see why this is, consider the parallel between promises and
+``try``/``catch``. We are ``try``-ing to execute ``foo()``: the error
+handler represents a ``catch`` for ``foo()``, while the fulfillment handler
+represents code that happens *after* the ``try``/``catch`` block.
+That code then needs its own ``try``/``catch`` block.
+
+In terms of promises, this means chaining your rejection handler:
+
+```javascript
+return foo()
+.then(function (value) {
+ throw new Error("Can't bar.");
+})
+.fail(function (error) {
+ // We get here with either foo's error or bar's error
+});
+```
+
+### Progress Notification
+
+It's possible for promises to report their progress, e.g. for tasks that take a
+long time like a file upload. Not all promises will implement progress
+notifications, but for those that do, you can consume the progress values using
+a third parameter to ``then``:
+
+```javascript
+return uploadFile()
+.then(function () {
+ // Success uploading the file
+}, function (err) {
+ // There was an error, and we get the reason for error
+}, function (progress) {
+ // We get notified of the upload's progress as it is executed
+});
+```
+
+Like `fail`, Q also provides a shorthand for progress callbacks
+called `progress`:
+
+```javascript
+return uploadFile().progress(function (progress) {
+ // We get notified of the upload's progress
+});
+```
+
+### The End
+
+When you get to the end of a chain of promises, you should either
+return the last promise or end the chain. Since handlers catch
+errors, it’s an unfortunate pattern that the exceptions can go
+unobserved.
+
+So, either return it,
+
+```javascript
+return foo()
+.then(function () {
+ return "bar";
+});
+```
+
+Or, end it.
+
+```javascript
+foo()
+.then(function () {
+ return "bar";
+})
+.done();
+```
+
+Ending a promise chain makes sure that, if an error doesn’t get
+handled before the end, it will get rethrown and reported.
+
+This is a stopgap. We are exploring ways to make unhandled errors
+visible without any explicit handling.
+
+
+### The Beginning
+
+Everything above assumes you get a promise from somewhere else. This
+is the common case. Every once in a while, you will need to create a
+promise from scratch.
+
+#### Using ``Q.fcall``
+
+You can create a promise from a value using ``Q.fcall``. This returns a
+promise for 10.
+
+```javascript
+return Q.fcall(function () {
+ return 10;
+});
+```
+
+You can also use ``fcall`` to get a promise for an exception.
+
+```javascript
+return Q.fcall(function () {
+ throw new Error("Can't do it");
+});
+```
+
+As the name implies, ``fcall`` can call functions, or even promised
+functions. This uses the ``eventualAdd`` function above to add two
+numbers.
+
+```javascript
+return Q.fcall(eventualAdd, 2, 2);
+```
+
+
+#### Using Deferreds
+
+If you have to interface with asynchronous functions that are callback-based
+instead of promise-based, Q provides a few shortcuts (like ``Q.nfcall`` and
+friends). But much of the time, the solution will be to use *deferreds*.
+
+```javascript
+var deferred = Q.defer();
+FS.readFile("foo.txt", "utf-8", function (error, text) {
+ if (error) {
+ deferred.reject(new Error(error));
+ } else {
+ deferred.resolve(text);
+ }
+});
+return deferred.promise;
+```
+
+Note that a deferred can be resolved with a value or a promise. The
+``reject`` function is a shorthand for resolving with a rejected
+promise.
+
+```javascript
+// this:
+deferred.reject(new Error("Can't do it"));
+
+// is shorthand for:
+var rejection = Q.fcall(function () {
+ throw new Error("Can't do it");
+});
+deferred.resolve(rejection);
+```
+
+This is a simplified implementation of ``Q.delay``.
+
+```javascript
+function delay(ms) {
+ var deferred = Q.defer();
+ setTimeout(deferred.resolve, ms);
+ return deferred.promise;
+}
+```
+
+This is a simplified implementation of ``Q.timeout``
+
+```javascript
+function timeout(promise, ms) {
+ var deferred = Q.defer();
+ Q.when(promise, deferred.resolve);
+ delay(ms).then(function () {
+ deferred.reject(new Error("Timed out"));
+ });
+ return deferred.promise;
+}
+```
+
+Finally, you can send a progress notification to the promise with
+``deferred.notify``.
+
+For illustration, this is a wrapper for XML HTTP requests in the browser. Note
+that a more [thorough][XHR] implementation would be in order in practice.
+
+[XHR]: https://github.com/montagejs/mr/blob/71e8df99bb4f0584985accd6f2801ef3015b9763/browser.js#L29-L73
+
+```javascript
+function requestOkText(url) {
+ var request = new XMLHttpRequest();
+ var deferred = Q.defer();
+
+ request.open("GET", url, true);
+ request.onload = onload;
+ request.onerror = onerror;
+ request.onprogress = onprogress;
+ request.send();
+
+ function onload() {
+ if (request.status === 200) {
+ deferred.resolve(request.responseText);
+ } else {
+ deferred.reject(new Error("Status code was " + request.status));
+ }
+ }
+
+ function onerror() {
+ deferred.reject(new Error("Can't XHR " + JSON.stringify(url)));
+ }
+
+ function onprogress(event) {
+ deferred.notify(event.loaded / event.total);
+ }
+
+ return deferred.promise;
+}
+```
+
+Below is an example of how to use this ``requestOkText`` function:
+
+```javascript
+requestOkText("http://localhost:3000")
+.then(function (responseText) {
+ // If the HTTP response returns 200 OK, log the response text.
+ console.log(responseText);
+}, function (error) {
+ // If there's an error or a non-200 status code, log the error.
+ console.error(error);
+}, function (progress) {
+ // Log the progress as it comes in.
+ console.log("Request progress: " + Math.round(progress * 100) + "%");
+});
+```
+
+### The Middle
+
+If you are using a function that may return a promise, but just might
+return a value if it doesn’t need to defer, you can use the “static”
+methods of the Q library.
+
+The ``when`` function is the static equivalent for ``then``.
+
+```javascript
+return Q.when(valueOrPromise, function (value) {
+}, function (error) {
+});
+```
+
+All of the other methods on a promise have static analogs with the
+same name.
+
+The following are equivalent:
+
+```javascript
+return Q.all([a, b]);
+```
+
+```javascript
+return Q.fcall(function () {
+ return [a, b];
+})
+.all();
+```
+
+When working with promises provided by other libraries, you should
+convert it to a Q promise. Not all promise libraries make the same
+guarantees as Q and certainly don’t provide all of the same methods.
+Most libraries only provide a partially functional ``then`` method.
+This thankfully is all we need to turn them into vibrant Q promises.
+
+```javascript
+return Q($.ajax(...))
+.then(function () {
+});
+```
+
+If there is any chance that the promise you receive is not a Q promise
+as provided by your library, you should wrap it using a Q function.
+You can even use ``Q.invoke`` as a shorthand.
+
+```javascript
+return Q.invoke($, 'ajax', ...)
+.then(function () {
+});
+```
+
+
+### Over the Wire
+
+A promise can serve as a proxy for another object, even a remote
+object. There are methods that allow you to optimistically manipulate
+properties or call functions. All of these interactions return
+promises, so they can be chained.
+
+```
+direct manipulation using a promise as a proxy
+-------------------------- -------------------------------
+value.foo promise.get("foo")
+value.foo = value promise.put("foo", value)
+delete value.foo promise.del("foo")
+value.foo(...args) promise.post("foo", [args])
+value.foo(...args) promise.invoke("foo", ...args)
+value(...args) promise.fapply([args])
+value(...args) promise.fcall(...args)
+```
+
+If the promise is a proxy for a remote object, you can shave
+round-trips by using these functions instead of ``then``. To take
+advantage of promises for remote objects, check out [Q-Connection][].
+
+[Q-Connection]: https://github.com/kriskowal/q-connection
+
+Even in the case of non-remote objects, these methods can be used as
+shorthand for particularly-simple fulfillment handlers. For example, you
+can replace
+
+```javascript
+return Q.fcall(function () {
+ return [{ foo: "bar" }, { foo: "baz" }];
+})
+.then(function (value) {
+ return value[0].foo;
+});
+```
+
+with
+
+```javascript
+return Q.fcall(function () {
+ return [{ foo: "bar" }, { foo: "baz" }];
+})
+.get(0)
+.get("foo");
+```
+
+
+### Adapting Node
+
+If you're working with functions that make use of the Node.js callback pattern,
+where callbacks are in the form of `function(err, result)`, Q provides a few
+useful utility functions for converting between them. The most straightforward
+are probably `Q.nfcall` and `Q.nfapply` ("Node function call/apply") for calling
+Node.js-style functions and getting back a promise:
+
+```javascript
+return Q.nfcall(FS.readFile, "foo.txt", "utf-8");
+return Q.nfapply(FS.readFile, ["foo.txt", "utf-8"]);
+```
+
+If you are working with methods, instead of simple functions, you can easily
+run in to the usual problems where passing a method to another function—like
+`Q.nfcall`—"un-binds" the method from its owner. To avoid this, you can either
+use `Function.prototype.bind` or some nice shortcut methods we provide:
+
+```javascript
+return Q.ninvoke(redisClient, "get", "user:1:id");
+return Q.npost(redisClient, "get", ["user:1:id"]);
+```
+
+You can also create reusable wrappers with `Q.denodeify` or `Q.nbind`:
+
+```javascript
+var readFile = Q.denodeify(FS.readFile);
+return readFile("foo.txt", "utf-8");
+
+var redisClientGet = Q.nbind(redisClient.get, redisClient);
+return redisClientGet("user:1:id");
+```
+
+Finally, if you're working with raw deferred objects, there is a
+`makeNodeResolver` method on deferreds that can be handy:
+
+```javascript
+var deferred = Q.defer();
+FS.readFile("foo.txt", "utf-8", deferred.makeNodeResolver());
+return deferred.promise;
+```
+
+### Long Stack Traces
+
+Q comes with optional support for “long stack traces,” wherein the `stack`
+property of `Error` rejection reasons is rewritten to be traced along
+asynchronous jumps instead of stopping at the most recent one. As an example:
+
+```js
+function theDepthsOfMyProgram() {
+ Q.delay(100).done(function explode() {
+ throw new Error("boo!");
+ });
+}
+
+theDepthsOfMyProgram();
+```
+
+usually would give a rather unhelpful stack trace looking something like
+
+```
+Error: boo!
+ at explode (/path/to/test.js:3:11)
+ at _fulfilled (/path/to/test.js:q:54)
+ at resolvedValue.promiseDispatch.done (/path/to/q.js:823:30)
+ at makePromise.promise.promiseDispatch (/path/to/q.js:496:13)
+ at pending (/path/to/q.js:397:39)
+ at process.startup.processNextTick.process._tickCallback (node.js:244:9)
+```
+
+But, if you turn this feature on by setting
+
+```js
+Q.longStackSupport = true;
+```
+
+then the above code gives a nice stack trace to the tune of
+
+```
+Error: boo!
+ at explode (/path/to/test.js:3:11)
+From previous event:
+ at theDepthsOfMyProgram (/path/to/test.js:2:16)
+ at Object.<anonymous> (/path/to/test.js:7:1)
+```
+
+Note how you can see the the function that triggered the async operation in the
+stack trace! This is very helpful for debugging, as otherwise you end up getting
+only the first line, plus a bunch of Q internals, with no sign of where the
+operation started.
+
+This feature does come with somewhat-serious performance and memory overhead,
+however. If you're working with lots of promises, or trying to scale a server
+to many users, you should probably keep it off. But in development, go for it!
+
+## Tests
+
+You can view the results of the Q test suite [in your browser][tests]!
+
+[tests]: https://rawgithub.com/kriskowal/q/v1/spec/q-spec.html
+
+## License
+
+Copyright 2009–2014 Kristopher Michael Kowal
+MIT License (enclosed)
+
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/benchmark/compare-with-callbacks.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/benchmark/compare-with-callbacks.js b/bin/node_modules/q/benchmark/compare-with-callbacks.js
new file mode 100644
index 0000000..97f1298
--- /dev/null
+++ b/bin/node_modules/q/benchmark/compare-with-callbacks.js
@@ -0,0 +1,71 @@
+"use strict";
+
+var Q = require("../q");
+var fs = require("fs");
+
+suite("A single simple async operation", function () {
+ bench("with an immediately-fulfilled promise", function (done) {
+ Q().then(done);
+ });
+
+ bench("with direct setImmediate usage", function (done) {
+ setImmediate(done);
+ });
+
+ bench("with direct setTimeout(…, 0)", function (done) {
+ setTimeout(done, 0);
+ });
+});
+
+suite("A fs.readFile", function () {
+ var denodeified = Q.denodeify(fs.readFile);
+
+ set("iterations", 1000);
+ set("delay", 1000);
+
+ bench("directly, with callbacks", function (done) {
+ fs.readFile(__filename, done);
+ });
+
+ bench("with Q.nfcall", function (done) {
+ Q.nfcall(fs.readFile, __filename).then(done);
+ });
+
+ bench("with a Q.denodeify'ed version", function (done) {
+ denodeified(__filename).then(done);
+ });
+
+ bench("with manual usage of deferred.makeNodeResolver", function (done) {
+ var deferred = Q.defer();
+ fs.readFile(__filename, deferred.makeNodeResolver());
+ deferred.promise.then(done);
+ });
+});
+
+suite("1000 operations in parallel", function () {
+ function makeCounter(desiredCount, ultimateCallback) {
+ var soFar = 0;
+ return function () {
+ if (++soFar === desiredCount) {
+ ultimateCallback();
+ }
+ };
+ }
+ var numberOfOps = 1000;
+
+ bench("with immediately-fulfilled promises", function (done) {
+ var counter = makeCounter(numberOfOps, done);
+
+ for (var i = 0; i < numberOfOps; ++i) {
+ Q().then(counter);
+ }
+ });
+
+ bench("with direct setImmediate usage", function (done) {
+ var counter = makeCounter(numberOfOps, done);
+
+ for (var i = 0; i < numberOfOps; ++i) {
+ setImmediate(counter);
+ }
+ });
+});
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/benchmark/scenarios.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/benchmark/scenarios.js b/bin/node_modules/q/benchmark/scenarios.js
new file mode 100644
index 0000000..7c18564
--- /dev/null
+++ b/bin/node_modules/q/benchmark/scenarios.js
@@ -0,0 +1,36 @@
+"use strict";
+
+var Q = require("../q");
+
+suite("Chaining", function () {
+ var numberToChain = 1000;
+
+ bench("Chaining many already-fulfilled promises together", function (done) {
+ var currentPromise = Q();
+ for (var i = 0; i < numberToChain; ++i) {
+ currentPromise = currentPromise.then(function () {
+ return Q();
+ });
+ }
+
+ currentPromise.then(done);
+ });
+
+ bench("Chaining and then fulfilling the end of the chain", function (done) {
+ var deferred = Q.defer();
+
+ var currentPromise = deferred.promise;
+ for (var i = 0; i < numberToChain; ++i) {
+ (function () {
+ var promiseToReturn = currentPromise;
+ currentPromise = Q().then(function () {
+ return promiseToReturn;
+ });
+ }());
+ }
+
+ currentPromise.then(done);
+
+ deferred.resolve();
+ });
+});
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/dd54d96b/bin/node_modules/q/package.json
----------------------------------------------------------------------
diff --git a/bin/node_modules/q/package.json b/bin/node_modules/q/package.json
new file mode 100644
index 0000000..7b7f3c6
--- /dev/null
+++ b/bin/node_modules/q/package.json
@@ -0,0 +1,112 @@
+{
+ "name": "q",
+ "version": "1.0.1",
+ "description": "A library for promises (CommonJS/Promises/A,B,D)",
+ "homepage": "https://github.com/kriskowal/q",
+ "author": {
+ "name": "Kris Kowal",
+ "email": "kris@cixar.com",
+ "url": "https://github.com/kriskowal"
+ },
+ "keywords": [
+ "q",
+ "promise",
+ "promises",
+ "promises-a",
+ "promises-aplus",
+ "deferred",
+ "future",
+ "async",
+ "flow control",
+ "fluent",
+ "browser",
+ "node"
+ ],
+ "contributors": [
+ {
+ "name": "Kris Kowal",
+ "email": "kris@cixar.com",
+ "url": "https://github.com/kriskowal"
+ },
+ {
+ "name": "Irakli Gozalishvili",
+ "email": "rfobic@gmail.com",
+ "url": "http://jeditoolkit.com"
+ },
+ {
+ "name": "Domenic Denicola",
+ "email": "domenic@domenicdenicola.com",
+ "url": "http://domenicdenicola.com"
+ }
+ ],
+ "bugs": {
+ "url": "http://github.com/kriskowal/q/issues"
+ },
+ "license": {
+ "type": "MIT",
+ "url": "http://github.com/kriskowal/q/raw/master/LICENSE"
+ },
+ "main": "q.js",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/kriskowal/q.git"
+ },
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "jshint": "~2.1.9",
+ "cover": "*",
+ "jasmine-node": "1.11.0",
+ "opener": "*",
+ "promises-aplus-tests": "1.x",
+ "grunt": "~0.4.1",
+ "grunt-cli": "~0.1.9",
+ "grunt-contrib-uglify": "~0.2.2",
+ "matcha": "~0.2.0"
+ },
+ "scripts": {
+ "test": "jasmine-node spec && promises-aplus-tests spec/aplus-adapter",
+ "test-browser": "opener spec/q-spec.html",
+ "benchmark": "matcha",
+ "lint": "jshint q.js",
+ "cover": "cover run node_modules/jasmine-node/bin/jasmine-node spec && cover report html && opener cover_html/index.html",
+ "minify": "grunt",
+ "prepublish": "grunt"
+ },
+ "overlay": {
+ "teleport": {
+ "dependencies": {
+ "system": ">=0.0.4"
+ }
+ }
+ },
+ "directories": {
+ "test": "./spec"
+ },
+ "_id": "q@1.0.1",
+ "dist": {
+ "shasum": "11872aeedee89268110b10a718448ffb10112a14",
+ "tarball": "http://registry.npmjs.org/q/-/q-1.0.1.tgz"
+ },
+ "_from": "q@",
+ "_npmVersion": "1.4.4",
+ "_npmUser": {
+ "name": "kriskowal",
+ "email": "kris.kowal@cixar.com"
+ },
+ "maintainers": [
+ {
+ "name": "kriskowal",
+ "email": "kris.kowal@cixar.com"
+ },
+ {
+ "name": "domenic",
+ "email": "domenic@domenicdenicola.com"
+ }
+ ],
+ "_shasum": "11872aeedee89268110b10a718448ffb10112a14",
+ "_resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz"
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[04/10] ios commit: CB-6637 - Removed -
request:isFragmentIdentifierToRequest: deprecated method in
CDVWebViewDelegate (closes #121)
Posted by sh...@apache.org.
CB-6637 - Removed - request:isFragmentIdentifierToRequest: deprecated method in CDVWebViewDelegate (closes #121)
Signed-off-by: Shazron Abdullah <sh...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/ea2a9467
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/ea2a9467
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/ea2a9467
Branch: refs/heads/wkwebview
Commit: ea2a9467912ea503360c26a867ede4311fe1a3c1
Parents: 9e53aa9
Author: Ivan Karpan <iv...@gmail.com>
Authored: Mon Dec 8 16:59:21 2014 +0200
Committer: Shazron Abdullah <sh...@apache.org>
Committed: Fri Dec 12 11:14:26 2014 -0800
----------------------------------------------------------------------
CordovaLib/Classes/CDVWebViewDelegate.h | 1 -
CordovaLib/Classes/CDVWebViewDelegate.m | 5 -----
2 files changed, 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/ea2a9467/CordovaLib/Classes/CDVWebViewDelegate.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVWebViewDelegate.h b/CordovaLib/Classes/CDVWebViewDelegate.h
index 4b60bab..f6c419f 100644
--- a/CordovaLib/Classes/CDVWebViewDelegate.h
+++ b/CordovaLib/Classes/CDVWebViewDelegate.h
@@ -35,7 +35,6 @@
}
- (id)initWithDelegate:(NSObject <UIWebViewDelegate>*)delegate;
-- (BOOL)request:(NSURLRequest*)newRequest isFragmentIdentifierToRequest:(NSURLRequest*)originalRequest CDV_DEPRECATED(3.5, "Use request:isEqualToRequestAfterStrippingFragments: instead.");
- (BOOL)request:(NSURLRequest*)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest*)originalRequest;
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/ea2a9467/CordovaLib/Classes/CDVWebViewDelegate.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVWebViewDelegate.m b/CordovaLib/Classes/CDVWebViewDelegate.m
index 5a187f4..514827e 100644
--- a/CordovaLib/Classes/CDVWebViewDelegate.m
+++ b/CordovaLib/Classes/CDVWebViewDelegate.m
@@ -114,11 +114,6 @@ static NSString *stripFragment(NSString* url)
return self;
}
-- (BOOL)request:(NSURLRequest*)newRequest isFragmentIdentifierToRequest:(NSURLRequest*)originalRequest
-{
- return [self request:newRequest isEqualToRequestAfterStrippingFragments:originalRequest];
-}
-
- (BOOL)request:(NSURLRequest*)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest*)originalRequest
{
if (originalRequest.URL && newRequest.URL) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[03/10] ios commit: CB-8002 CB-7735 Update cordova.js to include
bridge fix
Posted by sh...@apache.org.
CB-8002 CB-7735 Update cordova.js to include bridge fix
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/9e53aa99
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/9e53aa99
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/9e53aa99
Branch: refs/heads/wkwebview
Commit: 9e53aa9976772ea0a6861d6c451fef019d29fc65
Parents: dd54d96
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Nov 25 13:42:40 2014 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Nov 25 13:42:40 2014 -0500
----------------------------------------------------------------------
CordovaLib/cordova.js | 122 +++++++++++++++++++++++----------------------
1 file changed, 62 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/9e53aa99/CordovaLib/cordova.js
----------------------------------------------------------------------
diff --git a/CordovaLib/cordova.js b/CordovaLib/cordova.js
index 75729c1..9588ca4 100644
--- a/CordovaLib/cordova.js
+++ b/CordovaLib/cordova.js
@@ -1,5 +1,5 @@
// Platform: ios
-// 91157c2e1bf3eb098c7e2ab31404e895ccb0df2a
+// 227d83a122733fdf0300ffe75507a221bcef2b06
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -464,9 +464,14 @@ function each(objects, func, context) {
function clobber(obj, key, value) {
exports.replaceHookForTesting(obj, key);
- obj[key] = value;
+ var needsProperty = false;
+ try {
+ obj[key] = value;
+ } catch (e) {
+ needsProperty = true;
+ }
// Getters can only be overridden by getters.
- if (obj[key] !== value) {
+ if (needsProperty || obj[key] !== value) {
utils.defineGetter(obj, key, function() {
return value;
});
@@ -821,14 +826,13 @@ var cordova = require('cordova'),
// IFRAME_NAV is the fastest.
// IFRAME_HASH could be made to enable synchronous bridge calls if we wanted this feature.
jsToNativeModes = {
- IFRAME_NAV: 0,
- XHR_NO_PAYLOAD: 1,
- XHR_WITH_PAYLOAD: 2,
- XHR_OPTIONAL_PAYLOAD: 3,
- IFRAME_HASH_NO_PAYLOAD: 4,
- // Bundling the payload turns out to be slower. Probably since it has to be URI encoded / decoded.
- IFRAME_HASH_WITH_PAYLOAD: 5,
- WK_WEBVIEW_BINDING: 6
+ IFRAME_NAV: 0, // Default. Uses a new iframe for each poke.
+ XHR_NO_PAYLOAD: 1, // About the same speed as IFRAME_NAV. Performance not about the same as IFRAME_NAV, but more variable.
+ XHR_WITH_PAYLOAD: 2, // Flakey, and not as performant
+ XHR_OPTIONAL_PAYLOAD: 3, // Flakey, and not as performant
+ IFRAME_HASH_NO_PAYLOAD: 4, // Not fully baked. A bit faster than IFRAME_NAV, but risks jank since poke happens synchronously.
+ IFRAME_HASH_WITH_PAYLOAD: 5, // Slower than no payload. Maybe since it has to be URI encoded / decoded.
+ WK_WEBVIEW_BINDING: 6 // Only way that works for WKWebView :)
},
bridgeMode,
execIframe,
@@ -838,26 +842,8 @@ var cordova = require('cordova'),
requestCount = 0,
vcHeaderValue = null,
commandQueue = [], // Contains pending JS->Native messages.
- isInContextOfEvalJs = 0;
-
-function createExecIframe(src, unloadListener) {
- var iframe = document.createElement("iframe");
- iframe.style.display = 'none';
- // Both the unload listener and the src must be set before adding the iframe
- // to the document in order to avoid race conditions. Callbacks from native
- // can happen within the appendChild() call!
- iframe.onunload = unloadListener;
- iframe.src = src;
- document.body.appendChild(iframe);
- return iframe;
-}
-
-function createHashIframe() {
- var ret = createExecIframe('about:blank');
- // Hash changes don't work on about:blank, so switch it to file:///.
- ret.contentWindow.history.replaceState(null, null, 'file:///#');
- return ret;
-}
+ isInContextOfEvalJs = 0,
+ failSafeTimerId = 0;
function shouldBundleCommandJson() {
if (bridgeMode === jsToNativeModes.XHR_WITH_PAYLOAD) {
@@ -990,19 +976,23 @@ function iOSExec() {
// Also, if there is already a command in the queue, then we've already
// poked the native side, so there is no reason to do so again.
if (!isInContextOfEvalJs && commandQueue.length == 1) {
- switch (bridgeMode) {
- case jsToNativeModes.XHR_NO_PAYLOAD:
- case jsToNativeModes.XHR_WITH_PAYLOAD:
- case jsToNativeModes.XHR_OPTIONAL_PAYLOAD:
- pokeNativeViaXhr();
- break;
- default: // iframe-based.
- pokeNativeViaIframe();
- }
+ pokeNative();
}
}
}
+function pokeNative() {
+ switch (bridgeMode) {
+ case jsToNativeModes.XHR_NO_PAYLOAD:
+ case jsToNativeModes.XHR_WITH_PAYLOAD:
+ case jsToNativeModes.XHR_OPTIONAL_PAYLOAD:
+ pokeNativeViaXhr();
+ break;
+ default: // iframe-based.
+ pokeNativeViaIframe();
+ }
+}
+
function pokeNativeViaXhr() {
// This prevents sending an XHR when there is already one being sent.
// This should happen only in rare circumstances (refer to unit tests).
@@ -1026,11 +1016,6 @@ function pokeNativeViaXhr() {
execXhr.send(null);
}
-function onIframeUnload() {
- execIframe = null;
- setTimeout(pokeNativeViaIframe, 0);
-}
-
function pokeNativeViaIframe() {
// CB-5488 - Don't attempt to create iframe before document.body is available.
if (!document.body) {
@@ -1039,10 +1024,12 @@ function pokeNativeViaIframe() {
}
if (bridgeMode === jsToNativeModes.IFRAME_HASH_NO_PAYLOAD || bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
// TODO: This bridge mode doesn't properly support being removed from the DOM (CB-7735)
- execHashIframe = execHashIframe || createHashIframe();
- // Check if they've removed it from the DOM, and put it back if so.
- if (!execHashIframe.contentWindow) {
- execHashIframe = createHashIframe();
+ if (!execHashIframe) {
+ execHashIframe = document.createElement('iframe');
+ execHashIframe.style.display = 'none';
+ document.body.appendChild(execHashIframe);
+ // Hash changes don't work on about:blank, so switch it to file:///.
+ execHashIframe.contentWindow.history.replaceState(null, null, 'file:///#');
}
// The delegate method is called only when the hash changes, so toggle it back and forth.
hashToggle = hashToggle ^ 3;
@@ -1054,13 +1041,25 @@ function pokeNativeViaIframe() {
} else {
// Check if they've removed it from the DOM, and put it back if so.
if (execIframe && execIframe.contentWindow) {
- // Listen for unload, since it can happen (CB-7735) that the iframe gets
- // removed from the DOM before it gets a chance to poke the native side.
- execIframe.contentWindow.onunload = onIframeUnload;
- execIframe.src = 'gap://ready';
+ execIframe.contentWindow.location = 'gap://ready';
} else {
- execIframe = createExecIframe('gap://ready', onIframeUnload);
+ execIframe = document.createElement('iframe');
+ execIframe.style.display = 'none';
+ execIframe.src = 'gap://ready';
+ document.body.appendChild(execIframe);
}
+ // Use a timer to protect against iframe being unloaded during the poke (CB-7735).
+ // This makes the bridge ~ 7% slower, but works around the poke getting lost
+ // when the iframe is removed from the DOM.
+ // An onunload listener could be used in the case where the iframe has just been
+ // created, but since unload events fire only once, it doesn't work in the normal
+ // case of iframe reuse (where unload will have already fired due to the attempted
+ // navigation of the page).
+ failSafeTimerId = setTimeout(function() {
+ if (commandQueue.length) {
+ pokeNative();
+ }
+ }, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
}
}
@@ -1071,7 +1070,9 @@ iOSExec.setJsToNativeBridgeMode = function(mode) {
// can trigger browser bugs.
// https://issues.apache.org/jira/browse/CB-593
if (execIframe) {
- execIframe.parentNode.removeChild(execIframe);
+ if (execIframe.parentNode) {
+ execIframe.parentNode.removeChild(execIframe);
+ }
execIframe = null;
}
bridgeMode = mode;
@@ -1079,8 +1080,9 @@ iOSExec.setJsToNativeBridgeMode = function(mode) {
iOSExec.nativeFetchMessages = function() {
// Stop listing for window detatch once native side confirms poke.
- if (execIframe && execIframe.contentWindow) {
- execIframe.contentWindow.onunload = null;
+ if (failSafeTimerId) {
+ clearTimeout(failSafeTimerId);
+ failSafeTimerId = 0;
}
// Each entry in commandQueue is a JSON string already.
if (!commandQueue.length) {
@@ -1184,7 +1186,7 @@ function replaceNavigator(origNavigator) {
for (var key in origNavigator) {
if (typeof origNavigator[key] == 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
- }
+ }
else {
(function(k) {
utils.defineGetterSetter(newNavigator,key,function() {
@@ -1312,7 +1314,7 @@ function replaceNavigator(origNavigator) {
for (var key in origNavigator) {
if (typeof origNavigator[key] == 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
- }
+ }
else {
(function(k) {
utils.defineGetterSetter(newNavigator,key,function() {
@@ -1367,7 +1369,7 @@ platform.bootstrap && platform.bootstrap();
* Create all cordova objects once native side is ready.
*/
channel.join(function() {
-
+
platform.initialize && platform.initialize();
// Fire event to notify that all objects are created
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[06/10] ios commit: [CB-8044] support for --nobuild flag in run script
Posted by sh...@apache.org.
[CB-8044] support for --nobuild flag in run script
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/19e95454
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/19e95454
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/19e95454
Branch: refs/heads/wkwebview
Commit: 19e9545411bb055ddd12fb3754b08cfad564401d
Parents: 9ea4c78
Author: Lorin Beer <lo...@gmail.com>
Authored: Fri Dec 12 11:50:04 2014 -0800
Committer: Lorin Beer <lo...@gmail.com>
Committed: Fri Dec 12 11:50:04 2014 -0800
----------------------------------------------------------------------
bin/templates/scripts/cordova/run | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/19e95454/bin/templates/scripts/cordova/run
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/run b/bin/templates/scripts/cordova/run
index 12334ac..f66f703 100755
--- a/bin/templates/scripts/cordova/run
+++ b/bin/templates/scripts/cordova/run
@@ -115,7 +115,7 @@ if "$USE_DEVICE"; then
USE_SIMULATOR=true
else
# if we got here, we can deploy the app, then exit success
- if [ ! $NO_BUILD ] then
+ if [ ! $NO_BUILD ]; then
"$CORDOVA_PATH/build" --device || exit $?
fi
ios-deploy -d -b "$DEVICE_APP_PATH"
@@ -139,7 +139,7 @@ if "$USE_SIMULATOR"; then
fi
# launch using ios-sim
- if [ ! $NO_BUILD ] then
+ if [ ! $NO_BUILD ]; then
"$CORDOVA_PATH/build" --emulator || exit $?
fi
ios-sim launch "$SIMULATOR_APP_PATH" --stderr "$CORDOVA_PATH/console.log" --stdout "$CORDOVA_PATH/console.log" --devicetypeid com.apple.CoreSimulator.SimDeviceType.$TARGET --exit
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[10/10] ios commit: Merge branch 'master' into wkwebview
Posted by sh...@apache.org.
Merge branch 'master' into wkwebview
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/e0dc7443
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/e0dc7443
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/e0dc7443
Branch: refs/heads/wkwebview
Commit: e0dc7443be93978f8bead23fc3c968e95cffe4f7
Parents: 1d4ba97 0a2eac7
Author: Shazron Abdullah <sh...@gmail.com>
Authored: Tue Jan 6 16:44:17 2015 -0800
Committer: Shazron Abdullah <sh...@gmail.com>
Committed: Tue Jan 6 16:44:17 2015 -0800
----------------------------------------------------------------------
CordovaLib/Classes/CDVUIWebViewDelegate.h | 1 -
CordovaLib/Classes/CDVUIWebViewDelegate.m | 5 -
CordovaLib/cordova.js | 122 +-
bin/apple_ios_version | 47 +-
bin/apple_ios_version.bat | 26 +
bin/apple_osx_version | 47 +-
bin/apple_osx_version.bat | 26 +
bin/apple_xcode_version | 47 +-
bin/apple_xcode_version.bat | 26 +
bin/create | 205 +-
bin/create.bat | 26 +
bin/lib/create.js | 255 +++
bin/lib/update.js | 72 +
bin/lib/versions.js | 101 +
bin/node_modules/q/CONTRIBUTING.md | 40 +
bin/node_modules/q/LICENSE | 18 +
bin/node_modules/q/README.md | 820 ++++++++
.../q/benchmark/compare-with-callbacks.js | 71 +
bin/node_modules/q/benchmark/scenarios.js | 36 +
bin/node_modules/q/package.json | 112 ++
bin/node_modules/q/q.js | 1904 ++++++++++++++++++
bin/node_modules/q/queue.js | 35 +
bin/node_modules/which/LICENSE | 23 +
bin/node_modules/which/README.md | 5 +
bin/node_modules/which/bin/which | 14 +
bin/node_modules/which/package.json | 31 +
bin/node_modules/which/which.js | 104 +
bin/replaces | 28 -
bin/templates/scripts/cordova/build.xcconfig | 2 +-
bin/templates/scripts/cordova/run | 53 +-
bin/templates/scripts/cordova/version | 51 +-
bin/templates/scripts/cordova/version.bat | 26 +
bin/update | 95 +-
bin/update.bat | 26 +
bin/update_cordova_subproject | 137 +-
bin/update_cordova_subproject.bat | 26 +
tests/spec/create.spec.js | 13 +-
37 files changed, 4145 insertions(+), 531 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/e0dc7443/CordovaLib/Classes/CDVUIWebViewDelegate.h
----------------------------------------------------------------------
diff --cc CordovaLib/Classes/CDVUIWebViewDelegate.h
index 05979ed,0000000..d77f191
mode 100644,000000..100644
--- a/CordovaLib/Classes/CDVUIWebViewDelegate.h
+++ b/CordovaLib/Classes/CDVUIWebViewDelegate.h
@@@ -1,42 -1,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.
+ */
+
+#import <UIKit/UIKit.h>
+#import "CDVAvailability.h"
+
+/**
+ * Distinguishes top-level navigations from sub-frame navigations.
+ * shouldStartLoadWithRequest is called for every request, but didStartLoad
+ * and didFinishLoad is called only for top-level navigations.
+ * Relevant bug: CB-2389
+ */
+@interface CDVUIWebViewDelegate : NSObject <UIWebViewDelegate>{
+ __weak NSObject <UIWebViewDelegate>* _delegate;
+ NSInteger _loadCount;
+ NSInteger _state;
+ NSInteger _curLoadToken;
+ NSInteger _loadStartPollCount;
+}
+
+- (id)initWithDelegate:(NSObject <UIWebViewDelegate>*)delegate;
- - (BOOL)request:(NSURLRequest*)newRequest isFragmentIdentifierToRequest:(NSURLRequest*)originalRequest CDV_DEPRECATED(3.5, "Use request:isEqualToRequestAfterStrippingFragments: instead.");
+
+- (BOOL)request:(NSURLRequest*)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest*)originalRequest;
+
+@end
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/e0dc7443/CordovaLib/Classes/CDVUIWebViewDelegate.m
----------------------------------------------------------------------
diff --cc CordovaLib/Classes/CDVUIWebViewDelegate.m
index d880a4b,0000000..929138f
mode 100644,000000..100644
--- a/CordovaLib/Classes/CDVUIWebViewDelegate.m
+++ b/CordovaLib/Classes/CDVUIWebViewDelegate.m
@@@ -1,416 -1,0 +1,411 @@@
+/*
+ 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.
+ */
+
+//
+// Testing shows:
+//
+// In all cases, webView.request.URL is the previous page's URL (or empty) during the didStartLoad callback.
+// When loading a page with a redirect:
+// 1. shouldStartLoading (requestURL is target page)
+// 2. didStartLoading
+// 3. shouldStartLoading (requestURL is redirect target)
+// 4. didFinishLoad (request.URL is redirect target)
+//
+// Note the lack of a second didStartLoading **
+//
+// When loading a page with iframes:
+// 1. shouldStartLoading (requestURL is main page)
+// 2. didStartLoading
+// 3. shouldStartLoading (requestURL is one of the iframes)
+// 4. didStartLoading
+// 5. didFinishLoad
+// 6. didFinishLoad
+//
+// Note there is no way to distinguish which didFinishLoad maps to which didStartLoad **
+//
+// Loading a page by calling window.history.go(-1):
+// 1. didStartLoading
+// 2. didFinishLoad
+//
+// Note the lack of a shouldStartLoading call **
+// Actually - this is fixed on iOS6. iOS6 has a shouldStart. **
+//
+// Loading a page by calling location.reload()
+// 1. shouldStartLoading
+// 2. didStartLoading
+// 3. didFinishLoad
+//
+// Loading a page with an iframe that fails to load:
+// 1. shouldStart (main page)
+// 2. didStart
+// 3. shouldStart (iframe)
+// 4. didStart
+// 5. didFailWithError
+// 6. didFinish
+//
+// Loading a page with an iframe that fails to load due to an invalid URL:
+// 1. shouldStart (main page)
+// 2. didStart
+// 3. shouldStart (iframe)
+// 5. didFailWithError
+// 6. didFinish
+//
+// This case breaks our logic since there is a missing didStart. To prevent this,
+// we check URLs in shouldStart and return NO if they are invalid.
+//
+// Loading a page with an invalid URL
+// 1. shouldStart (main page)
+// 2. didFailWithError
+//
+// TODO: Record order when page is re-navigated before the first navigation finishes.
+//
+
+#import "CDVUIWebViewDelegate.h"
+
+// #define VerboseLog NSLog
+#define VerboseLog(...) do {} while (0)
+
+typedef enum {
+ STATE_IDLE = 0,
+ STATE_WAITING_FOR_LOAD_START = 1,
+ STATE_WAITING_FOR_LOAD_FINISH = 2,
+ STATE_IOS5_POLLING_FOR_LOAD_START = 3,
+ STATE_IOS5_POLLING_FOR_LOAD_FINISH = 4,
+ STATE_CANCELLED = 5
+} State;
+
+static NSString *stripFragment(NSString* url)
+{
+ NSRange r = [url rangeOfString:@"#"];
+
+ if (r.location == NSNotFound) {
+ return url;
+ }
+ return [url substringToIndex:r.location];
+}
+
+@implementation CDVUIWebViewDelegate
+
+- (id)initWithDelegate:(NSObject <UIWebViewDelegate>*)delegate
+{
+ self = [super init];
+ if (self != nil) {
+ _delegate = delegate;
+ _loadCount = -1;
+ _state = STATE_IDLE;
+ }
+ return self;
+}
+
- - (BOOL)request:(NSURLRequest*)newRequest isFragmentIdentifierToRequest:(NSURLRequest*)originalRequest
- {
- return [self request:newRequest isEqualToRequestAfterStrippingFragments:originalRequest];
- }
-
+- (BOOL)request:(NSURLRequest*)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest*)originalRequest
+{
+ if (originalRequest.URL && newRequest.URL) {
+ NSString* originalRequestUrl = [originalRequest.URL absoluteString];
+ NSString* newRequestUrl = [newRequest.URL absoluteString];
+
+ NSString* baseOriginalRequestUrl = stripFragment(originalRequestUrl);
+ NSString* baseNewRequestUrl = stripFragment(newRequestUrl);
+ return [baseOriginalRequestUrl isEqualToString:baseNewRequestUrl];
+ }
+
+ return NO;
+}
+
+- (BOOL)isPageLoaded:(UIWebView*)webView
+{
+ NSString* readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"];
+
+ return [readyState isEqualToString:@"loaded"] || [readyState isEqualToString:@"complete"];
+}
+
+- (BOOL)isJsLoadTokenSet:(UIWebView*)webView
+{
+ NSString* loadToken = [webView stringByEvaluatingJavaScriptFromString:@"window.__cordovaLoadToken"];
+
+ return [[NSString stringWithFormat:@"%ld", (long)_curLoadToken] isEqualToString:loadToken];
+}
+
+- (void)setLoadToken:(UIWebView*)webView
+{
+ _curLoadToken += 1;
+ [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.__cordovaLoadToken=%ld", (long)_curLoadToken]];
+}
+
+- (NSString*)evalForCurrentURL:(UIWebView*)webView
+{
+ return [webView stringByEvaluatingJavaScriptFromString:@"location.href"];
+}
+
+- (void)pollForPageLoadStart:(UIWebView*)webView
+{
+ if (_state != STATE_IOS5_POLLING_FOR_LOAD_START) {
+ return;
+ }
+ if (![self isJsLoadTokenSet:webView]) {
+ VerboseLog(@"Polled for page load start. result = YES!");
+ _state = STATE_IOS5_POLLING_FOR_LOAD_FINISH;
+ [self setLoadToken:webView];
+ if ([_delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
+ [_delegate webViewDidStartLoad:webView];
+ }
+ [self pollForPageLoadFinish:webView];
+ } else {
+ VerboseLog(@"Polled for page load start. result = NO");
+ // Poll only for 1 second, and then fall back on checking only when delegate methods are called.
+ ++_loadStartPollCount;
+ if (_loadStartPollCount < (1000 * .05)) {
+ [self performSelector:@selector(pollForPageLoadStart:) withObject:webView afterDelay:.05];
+ }
+ }
+}
+
+- (void)pollForPageLoadFinish:(UIWebView*)webView
+{
+ if (_state != STATE_IOS5_POLLING_FOR_LOAD_FINISH) {
+ return;
+ }
+ if ([self isPageLoaded:webView]) {
+ VerboseLog(@"Polled for page load finish. result = YES!");
+ _state = STATE_IDLE;
+ if ([_delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
+ [_delegate webViewDidFinishLoad:webView];
+ }
+ } else {
+ VerboseLog(@"Polled for page load finish. result = NO");
+ [self performSelector:@selector(pollForPageLoadFinish:) withObject:webView afterDelay:.05];
+ }
+}
+
+- (BOOL)shouldLoadRequest:(NSURLRequest*)request
+{
+ NSString* scheme = [[request URL] scheme];
+
+ if ([scheme isEqualToString:@"mailto"] || [scheme isEqualToString:@"tel"]) {
+ return YES;
+ }
+
+ return [NSURLConnection canHandleRequest:request];
+}
+
+- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
+{
+ BOOL shouldLoad = YES;
+
+ if ([_delegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
+ shouldLoad = [_delegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
+ }
+
+ VerboseLog(@"webView shouldLoad=%d (before) state=%d loadCount=%d URL=%@", shouldLoad, _state, _loadCount, request.URL);
+
+ if (shouldLoad) {
+ // When devtools refresh occurs, it blindly uses the same request object. If a history.replaceState() has occured, then
+ // mainDocumentURL != URL even though it's a top-level navigation.
+ BOOL isDevToolsRefresh = (request == webView.request);
+ BOOL isTopLevelNavigation = isDevToolsRefresh || [request.URL isEqual:[request mainDocumentURL]];
+ if (isTopLevelNavigation) {
+ // Ignore hash changes that don't navigate to a different page.
+ // webView.request does actually update when history.replaceState() gets called.
+ if ([self request:request isEqualToRequestAfterStrippingFragments:webView.request]) {
+ NSString* prevURL = [self evalForCurrentURL:webView];
+ if ([prevURL isEqualToString:[request.URL absoluteString]]) {
+ VerboseLog(@"Page reload detected.");
+ } else {
+ VerboseLog(@"Detected hash change shouldLoad");
+ return shouldLoad;
+ }
+ }
+
+ switch (_state) {
+ case STATE_WAITING_FOR_LOAD_FINISH:
+ // Redirect case.
+ // We expect loadCount == 1.
+ if (_loadCount != 1) {
+ NSLog(@"CDVWebViewDelegate: Detected redirect when loadCount=%ld", (long)_loadCount);
+ }
+ break;
+
+ case STATE_IDLE:
+ case STATE_IOS5_POLLING_FOR_LOAD_START:
+ case STATE_CANCELLED:
+ // Page navigation start.
+ _loadCount = 0;
+ _state = STATE_WAITING_FOR_LOAD_START;
+ break;
+
+ default:
+ {
+ _loadCount = 0;
+ _state = STATE_WAITING_FOR_LOAD_START;
+ NSString* description = [NSString stringWithFormat:@"CDVWebViewDelegate: Navigation started when state=%ld", (long)_state];
+ NSLog(@"%@", description);
+ if ([_delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
+ NSDictionary* errorDictionary = @{NSLocalizedDescriptionKey : description};
+ NSError* error = [[NSError alloc] initWithDomain:@"CDVUIWebViewDelegate" code:1 userInfo:errorDictionary];
+ [_delegate webView:webView didFailLoadWithError:error];
+ }
+ }
+ }
+ } else {
+ // Deny invalid URLs so that we don't get the case where we go straight from
+ // webViewShouldLoad -> webViewDidFailLoad (messes up _loadCount).
+ shouldLoad = shouldLoad && [self shouldLoadRequest:request];
+ }
+ VerboseLog(@"webView shouldLoad=%d (after) isTopLevelNavigation=%d state=%d loadCount=%d", shouldLoad, isTopLevelNavigation, _state, _loadCount);
+ }
+ return shouldLoad;
+}
+
+- (void)webViewDidStartLoad:(UIWebView*)webView
+{
+ VerboseLog(@"webView didStartLoad (before). state=%d loadCount=%d", _state, _loadCount);
+ BOOL fireCallback = NO;
+ switch (_state) {
+ case STATE_IDLE:
+ if (IsAtLeastiOSVersion(@"6.0")) {
+ break;
+ }
+ // If history.go(-1) is used pre-iOS6, the shouldStartLoadWithRequest function is not called.
+ // Without shouldLoad, we can't distinguish an iframe from a top-level navigation.
+ // We could try to distinguish using [UIWebView canGoForward], but that's too much complexity,
+ // and would work only on the first time it was used.
+
+ // Our work-around is to set a JS variable and poll until it disappears (from a navigation).
+ _state = STATE_IOS5_POLLING_FOR_LOAD_START;
+ _loadStartPollCount = 0;
+ [self setLoadToken:webView];
+ [self pollForPageLoadStart:webView];
+ break;
+
+ case STATE_CANCELLED:
+ fireCallback = YES;
+ _state = STATE_WAITING_FOR_LOAD_FINISH;
+ _loadCount += 1;
+ break;
+
+ case STATE_WAITING_FOR_LOAD_START:
+ if (_loadCount != 0) {
+ NSLog(@"CDVWebViewDelegate: Unexpected loadCount in didStart. count=%ld", (long)_loadCount);
+ }
+ fireCallback = YES;
+ _state = STATE_WAITING_FOR_LOAD_FINISH;
+ _loadCount = 1;
+ break;
+
+ case STATE_WAITING_FOR_LOAD_FINISH:
+ _loadCount += 1;
+ break;
+
+ case STATE_IOS5_POLLING_FOR_LOAD_START:
+ [self pollForPageLoadStart:webView];
+ break;
+
+ case STATE_IOS5_POLLING_FOR_LOAD_FINISH:
+ [self pollForPageLoadFinish:webView];
+ break;
+
+ default:
+ NSLog(@"CDVWebViewDelegate: Unexpected didStart with state=%ld loadCount=%ld", (long)_state, (long)_loadCount);
+ }
+ VerboseLog(@"webView didStartLoad (after). state=%d loadCount=%d fireCallback=%d", _state, _loadCount, fireCallback);
+ if (fireCallback && [_delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
+ [_delegate webViewDidStartLoad:webView];
+ }
+}
+
+- (void)webViewDidFinishLoad:(UIWebView*)webView
+{
+ VerboseLog(@"webView didFinishLoad (before). state=%d loadCount=%d", _state, _loadCount);
+ BOOL fireCallback = NO;
+ switch (_state) {
+ case STATE_IDLE:
+ break;
+
+ case STATE_WAITING_FOR_LOAD_START:
+ NSLog(@"CDVWebViewDelegate: Unexpected didFinish while waiting for load start.");
+ break;
+
+ case STATE_WAITING_FOR_LOAD_FINISH:
+ if (_loadCount == 1) {
+ fireCallback = YES;
+ _state = STATE_IDLE;
+ }
+ _loadCount -= 1;
+ break;
+
+ case STATE_IOS5_POLLING_FOR_LOAD_START:
+ [self pollForPageLoadStart:webView];
+ break;
+
+ case STATE_IOS5_POLLING_FOR_LOAD_FINISH:
+ [self pollForPageLoadFinish:webView];
+ break;
+ }
+ VerboseLog(@"webView didFinishLoad (after). state=%d loadCount=%d fireCallback=%d", _state, _loadCount, fireCallback);
+ if (fireCallback && [_delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
+ [_delegate webViewDidFinishLoad:webView];
+ }
+}
+
+- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error
+{
+ VerboseLog(@"webView didFailLoad (before). state=%d loadCount=%d", _state, _loadCount);
+ BOOL fireCallback = NO;
+
+ switch (_state) {
+ case STATE_IDLE:
+ break;
+
+ case STATE_WAITING_FOR_LOAD_START:
+ if ([error code] == NSURLErrorCancelled) {
+ _state = STATE_CANCELLED;
+ } else {
+ _state = STATE_IDLE;
+ }
+ fireCallback = YES;
+ break;
+
+ case STATE_WAITING_FOR_LOAD_FINISH:
+ if ([error code] != NSURLErrorCancelled) {
+ if (_loadCount == 1) {
+ _state = STATE_IDLE;
+ fireCallback = YES;
+ }
+ _loadCount = -1;
+ } else {
+ fireCallback = YES;
+ _state = STATE_CANCELLED;
+ _loadCount -= 1;
+ }
+ break;
+
+ case STATE_IOS5_POLLING_FOR_LOAD_START:
+ [self pollForPageLoadStart:webView];
+ break;
+
+ case STATE_IOS5_POLLING_FOR_LOAD_FINISH:
+ [self pollForPageLoadFinish:webView];
+ break;
+ }
+ VerboseLog(@"webView didFailLoad (after). state=%d loadCount=%d, fireCallback=%d", _state, _loadCount, fireCallback);
+ if (fireCallback && [_delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
+ [_delegate webView:webView didFailLoadWithError:error];
+ }
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/e0dc7443/CordovaLib/cordova.js
----------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[08/10] ios commit: CB-8168 `cordova/run --list` support for iOS
(closes #122)
Posted by sh...@apache.org.
CB-8168 `cordova/run --list` support for iOS (closes #122)
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/54420692
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/54420692
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/54420692
Branch: refs/heads/wkwebview
Commit: 54420692ac2d4725e757b93a1771a33d56a4d87d
Parents: b53b305
Author: muratsu <su...@gmail.com>
Authored: Mon Dec 29 15:59:51 2014 -0800
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Sat Jan 3 21:08:43 2015 -0500
----------------------------------------------------------------------
bin/templates/scripts/cordova/run | 39 ++++++++++++++++++++++++++++++++++
tests/spec/create.spec.js | 13 +++++++++++-
2 files changed, 51 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/54420692/bin/templates/scripts/cordova/run
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/run b/bin/templates/scripts/cordova/run
index 12633bf..2cd0811 100755
--- a/bin/templates/scripts/cordova/run
+++ b/bin/templates/scripts/cordova/run
@@ -40,6 +40,11 @@ USE_SIMULATOR=false
# options
NO_BUILD=false
+# display list
+DISPLAY_LIST=false
+DISPLAY_DEVICE=false
+DISPLAY_EMULATOR=false
+
# separates "key=value", sets an array with 0th index as key, 1st index as value
_parseOption()
{
@@ -69,10 +74,15 @@ _parseArgs()
"--device")
USE_DEVICE=true
USE_SIMULATOR=false
+ DISPLAY_DEVICE=true
;;
"--emulator")
USE_DEVICE=false
USE_SIMULATOR=true
+ DISPLAY_EMULATOR=true
+ ;;
+ "--list")
+ DISPLAY_LIST=true
;;
"--nobuild")
NO_BUILD=true
@@ -81,6 +91,18 @@ _parseArgs()
done
}
+_displayDevices()
+{
+ echo "Available iOS Devices:"
+ "$CORDOVA_PATH/lib/list-devices" 2>&1 | sed 's/^/ /'
+}
+
+_displayVirtualDevices()
+{
+ echo "Available iOS Virtual Devices:"
+ "$CORDOVA_PATH/lib/list-emulator-images" 2>&1 | sed 's/^/ /'
+}
+
_parseArgs "$@"
CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd -P)
@@ -93,6 +115,23 @@ DEVICE_APP_PATH="$PROJECT_PATH/build/device/$PROJECT_NAME.app"
source "$CORDOVA_PATH/check_reqs"
+# check if it's a list command
+if "$DISPLAY_LIST"; then
+ if "$DISPLAY_DEVICE" || "$DISPLAY_EMULATOR"; then
+ if "$DISPLAY_EMULATOR"; then
+ _displayVirtualDevices
+ fi
+ if "$DISPLAY_DEVICE"; then
+ _displayDevices
+ fi
+ exit 0
+ else
+ _displayVirtualDevices
+ _displayDevices
+ exit 0
+ fi
+fi
+
# if device build found, run it first
if "$USE_DEVICE"; then
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/54420692/tests/spec/create.spec.js
----------------------------------------------------------------------
diff --git a/tests/spec/create.spec.js b/tests/spec/create.spec.js
index e25440a..48d6073 100644
--- a/tests/spec/create.spec.js
+++ b/tests/spec/create.spec.js
@@ -103,4 +103,15 @@ describe('create', function() {
shell.rm('-rf', tmp);
});
-});
\ No newline at end of file
+});
+
+describe('end-to-end list validation', function(){
+ it('handles list parameter', function() {
+ shell.cp('-f', path.join(cordova_bin, 'check_reqs'), path.join(cordova_bin, 'templates', 'scripts', 'cordova', 'check_reqs'));
+ var command = '"' + path.join(cordova_bin, 'templates', 'scripts', 'cordova', 'run') + '" --list';
+ var output = shell.exec(command, {silent: true}).output;
+ expect(output).toMatch(/Available iOS Virtual Devices/);
+ expect(output).toMatch(/Available iOS Devices/);
+ shell.rm('-f', path.join(cordova_bin, 'templates', 'scripts', 'cordova', 'check_reqs'));
+ });
+});
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[09/10] ios commit: CB-7872 Fix CODE_SIGN_RESOURCE_RULES_PATH being
set wrong in xcconfig (closes #120)
Posted by sh...@apache.org.
CB-7872 Fix CODE_SIGN_RESOURCE_RULES_PATH being set wrong in xcconfig (closes #120)
Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/0a2eac7c
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/0a2eac7c
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/0a2eac7c
Branch: refs/heads/wkwebview
Commit: 0a2eac7c112d0dab054fb8288354c9332c27b6c0
Parents: 5442069
Author: Josef Schweiger <js...@oas.de>
Authored: Fri Dec 5 10:30:30 2014 +0100
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Sat Jan 3 21:11:41 2015 -0500
----------------------------------------------------------------------
bin/templates/scripts/cordova/build.xcconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0a2eac7c/bin/templates/scripts/cordova/build.xcconfig
----------------------------------------------------------------------
diff --git a/bin/templates/scripts/cordova/build.xcconfig b/bin/templates/scripts/cordova/build.xcconfig
index dca8c6c..0b89ad0 100644
--- a/bin/templates/scripts/cordova/build.xcconfig
+++ b/bin/templates/scripts/cordova/build.xcconfig
@@ -29,4 +29,4 @@ CODE_SIGN_IDENTITY = iPhone Developer
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
// (CB-7872) Solution for XCode 6.1 signing errors related to resource envelope format deprecation
-CODE_SIGN_RESOURCE_RULES_PATH = "$(SDKROOT)/ResourceRules.plist"
\ No newline at end of file
+CODE_SIGN_RESOURCE_RULES_PATH = $(SDKROOT)/ResourceRules.plist
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org