cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject [2/7] git commit: 3.0
Date Mon, 18 Nov 2013 23:40:42 GMT
3.0


Project: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/commit/b6c3aee7
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/tree/b6c3aee7
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/diff/b6c3aee7

Branch: refs/heads/master
Commit: b6c3aee7eb52f55ea002dc545e2e6db3a23821cb
Parents: 
Author: Maxim Ermilov <maxim.ermilov@canonical.com>
Authored: Thu Nov 7 10:39:06 2013 +0400
Committer: Maxim Ermilov <maxim.ermilov@canonical.com>
Committed: Thu Nov 7 10:39:06 2013 +0400

----------------------------------------------------------------------
 CMakeLists.txt                    | 134 +++++++++++++++
 Cordovaqt/CordovaViewInternal.qml | 145 ++++++++++++++++
 Cordovaqt/cordova_wrapper.js      |  48 ++++++
 Cordovaqt/qmldir                  |   5 +
 LICENSE                           | 202 ++++++++++++++++++++++
 README.md                         |  14 ++
 VERSION                           |   1 +
 bin/build/build                   |  28 ++++
 bin/build/clean                   |  28 ++++
 bin/build/run                     |  29 ++++
 bin/build/version                 |  26 +++
 bin/check_reqs                    |  32 ++++
 bin/create                        |  59 +++++++
 bin/package.json                  |  33 ++++
 main.cpp                          |  97 +++++++++++
 qml/CordovaView.qml.in            |  52 ++++++
 qml/main.qml.in                   |  26 +++
 src/cordova.cpp                   | 141 ++++++++++++++++
 src/cordova.h                     |  69 ++++++++
 src/coreplugins.cpp               |  37 +++++
 src/coreplugins.h                 |  20 +++
 src/cplugin.cpp                   | 151 +++++++++++++++++
 src/cplugin.h                     | 119 +++++++++++++
 src/js/bootstrap.js               | 102 ++++++++++++
 src/js/common/argscheck.js        |  64 +++++++
 src/js/common/builder.js          | 111 +++++++++++++
 src/js/common/channel.js          | 239 +++++++++++++++++++++++++++
 src/js/common/commandProxy.js     |  28 ++++
 src/js/common/modulemapper.js     | 107 ++++++++++++
 src/js/common/pluginloader.js     | 119 +++++++++++++
 src/js/common/symbols.js          |  11 ++
 src/js/common/utils.js            | 168 +++++++++++++++++++
 src/js/cordova.js                 | 251 ++++++++++++++++++++++++++++
 src/js/exec.js                    |  77 +++++++++
 src/js/platform.js                |  35 ++++
 src/js/require.js                 |  91 ++++++++++
 src/qmlplugin.cpp                 |  26 +++
 src/qmlplugin.h                   | 101 +++++++++++
 www/basic.js                      | 294 +++++++++++++++++++++++++++++++++
 www/index.html.in                 |  90 ++++++++++
 www/plugins.xml                   |  44 +++++
 xml/config.xml                    |  46 ++++++
 42 files changed, 3500 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..d1be36e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,134 @@
+cmake_minimum_required(VERSION 2.8.8)
+
+project(cordova-ubuntu)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}")
+
+file (STRINGS "VERSION" tmp)
+STRING(REGEX MATCH "^[0-9]+\\.[0-9]+" VERSION ${tmp})
+STRING(REGEX MATCH "^[0-9]+" MAJOR_VERSION ${tmp})
+STRING(REGEX MATCH "[0-9]+$" MINOR_VERSION ${VERSION})
+
+configure_file (
+  "${PROJECT_SOURCE_DIR}/qml/main.qml.in"
+  "${PROJECT_BINARY_DIR}/main.qml"
+)
+configure_file (
+  "${PROJECT_SOURCE_DIR}/qml/CordovaView.qml.in"
+  "${PROJECT_BINARY_DIR}/CordovaView.qml"
+)
+
+SET(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -DCORDOVA_UBUNTU_VERSION=\\\"${VERSION}\\\" -DCORDOVA_UBUNTU_MAJOR_VERSION=${MAJOR_VERSION} -DCORDOVA_UBUNTU_MINOR_VERSION=${MINOR_VERSION} -I ${PROJECT_SOURCE_DIR}/src")
+
+set(js_src
+  src/js/require.js
+  src/js/cordova.js
+  src/js/common/argscheck.js
+  src/js/common/builder.js
+  src/js/common/channel.js
+  src/js/common/commandProxy.js
+  src/js/common/modulemapper.js
+  src/js/common/pluginloader.js
+  src/js/common/symbols.js
+  src/js/common/utils.js
+  src/js/exec.js
+
+  src/js/platform.js
+  src/js/bootstrap.js
+)
+
+add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/www/cordova.js
+  COMMAND echo \"\(function\(\){\" > ${PROJECT_BINARY_DIR}/www/cordova.js
+  COMMAND cat ${js_src} >> ${PROJECT_BINARY_DIR}/www/cordova.js
+  COMMAND echo \"}\)\(\)\;\" >> ${PROJECT_BINARY_DIR}/www/cordova.js
+  DEPENDS ${js_src} ${PROJECT_BINARY_DIR}/www/index.html
+  SOURCE ${js_src}
+  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+)
+add_custom_target(concatenate_js DEPENDS ${PROJECT_BINARY_DIR}/www/cordova.js)
+
+add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/qml
+  COMMAND mkdir -p ${PROJECT_BINARY_DIR}/qml
+  COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/main.qml ${PROJECT_BINARY_DIR}/qml
+  DEPENDS ${PROJECT_BINARY_DIR}/main.qml
+)
+
+file(GLOB tmp Cordovaqt/*)
+add_custom_command(
+  OUTPUT ${PROJECT_BINARY_DIR}/CordovaUbuntu.${VERSION}
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Cordovaqt ${PROJECT_BINARY_DIR}/CordovaUbuntu.${VERSION}
+  COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/libcordovaubuntuplugin.so ${PROJECT_BINARY_DIR}/CordovaUbuntu.${VERSION}
+  COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/CordovaView.qml ${PROJECT_BINARY_DIR}/CordovaUbuntu.${VERSION}
+  DEPENDS ${tmp} cordovaubuntuplugin ${PROJECT_BINARY_DIR}/CordovaView.qml
+)
+file(GLOB tmp xml/*)
+add_custom_command(
+  OUTPUT ${PROJECT_BINARY_DIR}/xml
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/xml ${PROJECT_BINARY_DIR}/xml
+  DEPENDS ${tmp} ${PROJECT_SOURCE_DIR}/xml
+)
+file(GLOB tmp www/*)
+add_custom_command(
+  OUTPUT ${PROJECT_BINARY_DIR}/www/index.html
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/www ${PROJECT_BINARY_DIR}/www
+  COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/libcoreplugins.so ${PROJECT_BINARY_DIR}/www
+  COMMAND sed "s/\@VERSION\@/${VERSION}/" "${PROJECT_SOURCE_DIR}/www/index.html.in" > "${PROJECT_BINARY_DIR}/www/index.html"
+  DEPENDS ${tmp} ${PROJECT_SOURCE_DIR}/www/index.html.in coreplugins
+)
+add_custom_target(copy_wwwqmlxml DEPENDS ${PROJECT_BINARY_DIR}/www/index.html ${PROJECT_BINARY_DIR}/CordovaUbuntu.${VERSION} ${PROJECT_BINARY_DIR}/xml ${PROJECT_BINARY_DIR}/qml)
+
+find_package(Qt5Widgets)
+find_package(Qt5Core)
+
+add_executable(cordova-ubuntu
+  main.cpp
+)
+qt5_use_modules(cordova-ubuntu Widgets Quick)
+add_dependencies(cordova-ubuntu concatenate_js copy_wwwqmlxml)
+
+ADD_LIBRARY(cordovaubuntuplugin SHARED
+  src/cplugin.cpp
+  src/cordova.cpp
+  src/qmlplugin.cpp
+
+  src/cordova.h
+  src/cplugin.h
+  src/qmlplugin.h
+)
+qt5_use_modules(cordovaubuntuplugin Widgets Quick)
+
+
+#TODO use subprojects
+file(GLOB_RECURSE PLUGIN_SOURCES src/plugins/*.cpp)
+file(GLOB_RECURSE PLUGIN_HEADERS src/plugins/*.h)
+
+ADD_LIBRARY(coreplugins SHARED
+  src/coreplugins.cpp
+
+  ${PLUGIN_SOURCES}
+  ${PLUGIN_HEADERS}
+)
+qt5_use_modules(coreplugins Widgets Location Sensors Feedback SystemInfo Contacts Multimedia Quick MultimediaWidgets)
+
+find_library(XCB_LIB xcb)
+target_link_libraries(cordova-ubuntu ${XCB_LIB} cordovaubuntuplugin)
+target_link_libraries(coreplugins cordovaubuntuplugin)
+
+# Qt5's cmake does not export QT_IMPORTS_DIR, lets query qmake on our own for now
+get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
+function(QUERY_QMAKE VAR RESULT)
+ exec_program(${QMAKE_EXECUTABLE} ARGS "-query ${VAR}" RETURN_VALUE return_code OUTPUT_VARIABLE output )
+ if(NOT return_code)
+ file(TO_CMAKE_PATH "${output}" output)
+ set(${RESULT} ${output} PARENT_SCOPE)
+ endif(NOT return_code)
+endfunction(QUERY_QMAKE)
+query_qmake(QT_INSTALL_QML QT_IMPORTS_DIR)
+
+install (TARGETS cordova-ubuntu DESTINATION ${CMAKE_INSTALL_PREFIX})
+install (TARGETS coreplugins DESTINATION ${CMAKE_INSTALL_PREFIX}/www)
+install (FILES ${PROJECT_BINARY_DIR}/www/cordova.js DESTINATION ${CMAKE_INSTALL_PREFIX}/www/)
+install (DIRECTORY ${PROJECT_BINARY_DIR}/qml DESTINATION ${CMAKE_INSTALL_PREFIX})
+install (DIRECTORY ${PROJECT_BINARY_DIR}/CordovaUbuntu.${VERSION} DESTINATION ${CMAKE_INSTALL_PREFIX})

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/Cordovaqt/CordovaViewInternal.qml
----------------------------------------------------------------------
diff --git a/Cordovaqt/CordovaViewInternal.qml b/Cordovaqt/CordovaViewInternal.qml
new file mode 100644
index 0000000..f69833d
--- /dev/null
+++ b/Cordovaqt/CordovaViewInternal.qml
@@ -0,0 +1,145 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 QtQuick 2.0
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+import "cordova_wrapper.js" as CordovaWrapper
+import Ubuntu.Components 0.1
+import Ubuntu.Components.Popups 0.1
+
+Item {
+    anchors.fill: parent
+    state: "main"
+    id: root
+    signal completed
+    property string wwwDir
+    property string splashscreenPath
+    function exec(plugin, func, args) {
+        CordovaWrapper.execMethod(plugin, func, args);
+    }
+
+    Rectangle {
+        id: webViewContainer
+        anchors.fill: parent
+        WebView {
+            id: webView
+            anchors.fill: parent
+            objectName: "webView"
+
+            property string scheme: "file"
+            experimental.preferences.navigatorQtObjectEnabled: true
+            experimental.preferences.localStorageEnabled: true
+            experimental.preferences.offlineWebApplicationCacheEnabled: true
+            experimental.preferences.universalAccessFromFileURLsAllowed: true
+            experimental.preferences.webGLEnabled: true
+            experimental.databaseQuotaDialog: Item {
+                Timer {
+                    interval: 1
+                    running: true
+                    onTriggered: {
+                        model.accept(model.expectedUsage)
+                    }
+                }
+            }
+            // port in QTWEBKIT_INSPECTOR_SERVER enviroment variable
+            experimental.preferences.developerExtrasEnabled: true
+
+            function evalInPageUnsafe(expr) {
+                experimental.evaluateJavaScript('(function() { ' + expr + ' })();');
+            }
+
+            experimental.onMessageReceived: {
+                if (message.data.length > 1000) {
+                    console.debug("WebView received Message: " + message.data.substr(0, 900) + "...");
+                } else {
+                    console.debug("WebView received Message: " + message.data);
+                }
+
+                CordovaWrapper.messageHandler(message)
+            }
+
+            Component.onCompleted: {
+                webView.url = cordova.mainUrl
+            }
+
+            onTitleChanged: {
+                cordova.setTitle(webView.title)
+            }
+
+            onLoadingChanged: {
+                if (loadRequest.status) {
+                    root.completed()
+                    cordova.loadFinished(true)
+                }
+                //TODO: check here for errors
+            }
+
+            Connections {
+                target: cordova
+                onJavaScriptExecNeeded: {
+                    webView.experimental.evaluateJavaScript(js);
+                }
+                onQmlExecNeeded: {
+                    console.log("2345");
+                    eval(src);
+                }
+                onPluginWantsToBeAdded: {
+                    CordovaWrapper.addPlugin(pluginName, pluginObject)
+                }
+            }
+        }
+    }
+
+    Image {
+        id: splashscreen
+        anchors.fill: parent
+        source: splashscreenPath
+        visible: false
+        smooth: true
+        fillMode: Image.PreserveAspectFit
+    }
+
+    states: [
+        State {
+            name: "main"
+            PropertyChanges {
+                target: webViewContainer
+                visible: true
+            }
+            PropertyChanges {
+                target: splashscreen
+                visible: false
+            }
+        },
+        State {
+            name: "splashscreen"
+            PropertyChanges {
+                target: webViewContainer
+                visible: false
+            }
+            PropertyChanges {
+                target: splashscreen
+                visible: true
+            }
+        }
+    ]
+    transitions: Transition {
+        RotationAnimation { duration: 500; direction: RotationAnimation.Shortest }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/Cordovaqt/cordova_wrapper.js
----------------------------------------------------------------------
diff --git a/Cordovaqt/cordova_wrapper.js b/Cordovaqt/cordova_wrapper.js
new file mode 100644
index 0000000..e8d7193
--- /dev/null
+++ b/Cordovaqt/cordova_wrapper.js
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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 pluginObjects = {}
+
+
+function addPlugin(pluginName, pluginObject) {
+    pluginObjects[pluginName] = pluginObject
+}
+
+function messageHandler(message) {
+    var received = JSON.parse(message.data);
+    if (typeof received === 'undefined')
+        return false;
+    if (typeof received.messageType === 'undefined')
+        return false;
+    if (received.messageType === "callPluginFunction") {
+        if (typeof received.plugin === 'undefined' || typeof received.func == 'undefined')
+            return false;
+        execMethod(received.plugin, received.func, received.params);
+    }
+    return true;
+}
+
+function execMethod(pluginName, functionName, params) {
+    if (typeof pluginObjects[pluginName][functionName] != "function")
+        return false;
+    pluginObjects[pluginName][functionName].apply(this, params);
+    return true;
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/Cordovaqt/qmldir
----------------------------------------------------------------------
diff --git a/Cordovaqt/qmldir b/Cordovaqt/qmldir
new file mode 100644
index 0000000..f1a4d22
--- /dev/null
+++ b/Cordovaqt/qmldir
@@ -0,0 +1,5 @@
+module CordovaUbuntu
+plugin cordovaubuntuplugin
+CordovaView 3.0 CordovaView.qml
+CordovaViewInternal 3.0 CordovaViewInternal.qml
+

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fe5da93
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+Cordova/Ubuntu
+==========
+
+Cordova/Ubuntu is the Ubuntu port of the Apache Cordova project.
+
+Requirements
+------------
+
+- Ubuntu SDK
+
+License
+-------
+
+Licensed under the APACHE-2.0 license. See LICENSE file for details.

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/VERSION
----------------------------------------------------------------------
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..4a36342
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+3.0.0

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/build/build
----------------------------------------------------------------------
diff --git a/bin/build/build b/bin/build/build
new file mode 100755
index 0000000..55fab99
--- /dev/null
+++ b/bin/build/build
@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 path = require('path');
+var platform = require('./lib/ubuntu');
+
+var root = path.resolve();
+var www = path.join(root, 'www');
+
+platform.build(root, www);

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/build/clean
----------------------------------------------------------------------
diff --git a/bin/build/clean b/bin/build/clean
new file mode 100755
index 0000000..4f1f27a
--- /dev/null
+++ b/bin/build/clean
@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 path = require('path');
+var args = process.argv;
+var ROOT = path.join(__dirname, '..');
+var shell = require('shelljs');
+var fs    = require('fs');
+var et    = require('elementtree');
+
+throw new Error('unimplemented');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/build/run
----------------------------------------------------------------------
diff --git a/bin/build/run b/bin/build/run
new file mode 100755
index 0000000..76b1a1a
--- /dev/null
+++ b/bin/build/run
@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 path = require('path');
+var platform = require('./lib/ubuntu');
+
+var root = path.resolve();
+var www = path.join(root, 'www');
+
+platform.build(root, www);
+platform.run(root, www);
+

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/build/version
----------------------------------------------------------------------
diff --git a/bin/build/version b/bin/build/version
new file mode 100755
index 0000000..56e4c35
--- /dev/null
+++ b/bin/build/version
@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 path = require('path');
+var args = process.argv;
+var ROOT = path.join(__dirname, '..');
+var shell = require('shelljs');
+var fs    = require('fs');
+var et    = require('elementtree');

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/check_reqs
----------------------------------------------------------------------
diff --git a/bin/check_reqs b/bin/check_reqs
new file mode 100755
index 0000000..dd84963
--- /dev/null
+++ b/bin/check_reqs
@@ -0,0 +1,32 @@
+#! /bin/sh
+
+#
+# Copyright 2013 Canonical Ltd.
+#
+# 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.
+#
+
+
+#### CHECK FOR UBUNTU-SDK
+set PACKAGE_LIST="cmake debhelper libx11-dev libicu-dev pkg-config qtbase5-dev qtchooser qtdeclarative5-dev qtfeedback5-dev qtlocation5-dev qtmultimedia5-dev qtpim5-dev qtsensors5-dev qtsystems5-dev"
+dpkg-query -Wf'$${db:Status-abbrev}' ${PACKAGE_LIST} 2>/dev/null | grep -q '^i'
+if [ $? != 0 ]; then
+	echo "missing dependency ${PACKAGE_LIST}"
+	exit 1
+fi
+

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/create
----------------------------------------------------------------------
diff --git a/bin/create b/bin/create
new file mode 100755
index 0000000..a5fbf45
--- /dev/null
+++ b/bin/create
@@ -0,0 +1,59 @@
+#!/usr/bin/env node
+
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 path = require('path');
+var args = process.argv;
+var ROOT = path.join(__dirname, '..');
+var shell = require('shelljs');
+var fs    = require('fs');
+var et    = require('elementtree');
+
+function help() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'bin', 'create')) + ' <path_to_new_project> <package_name> <project_name>');
+    console.log('    <path_to_new_project>: Path to your new Cordova Ubuntu project');
+    console.log('    <package_name>: Package name');
+    console.log('    <project_name>: Project name');
+    process.exit(0);
+}
+
+function create(project_path, package_name, project_name, project_template_dir) {
+    // Check if project already exists
+    if(fs.existsSync(project_path)) {
+        console.error('Project already exists! Delete and recreate');
+        process.exit(2);
+    }
+    shell.mkdir(project_path);
+    shell.cp('-r', path.join(ROOT, '*'), path.join(project_path, 'build'));
+    shell.cp('-r', path.join(ROOT, 'bin/build/*'), path.join(project_path, 'cordova'));
+    shell.cp('-r', path.join(ROOT, 'xml/config.xml'), project_path);
+    // TODO:TAREGET API
+
+    shell.cd(project_path);
+//    console.log(project_path + "|" + project_name + "|" + project_template_dir + "|" + ROOT);
+//throw new Error();
+}
+
+if(args.length < 3 || (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+                       args[2] == 'help' || args[2] == '-help' || args[2] == '/help')) {
+    help();
+} else {
+    create(args[2], args[3], args[4], args[5]);
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/bin/package.json
----------------------------------------------------------------------
diff --git a/bin/package.json b/bin/package.json
new file mode 100644
index 0000000..28d2045
--- /dev/null
+++ b/bin/package.json
@@ -0,0 +1,33 @@
+{
+    "name": "cordova-ubuntu",
+    "description": "Cordova tooling for the Ubuntu platform.",
+    "version": "0.0.0",
+    "homepage": "https://launchpad.net/cordova-ubuntu/",
+    "repository": {
+        "type": "bzr",
+        "url": "lp:cordova-ubuntu"
+    },
+    "keywords": [
+        "cli",
+        "cordova",
+        "ubuntu",
+        "tooling"
+    ],
+    "engineStrict": "true",
+    "engines": {
+        "node": ">=0.10.0"
+    },
+    "dependencies": {
+        "shelljs" : "0.1.4"
+    },
+    "devDependencies": {
+    },
+    "optionalDependencies": {
+    },
+    "author": {
+        "name": "Maxim Ermilov",
+        "email": "maxim.ermilov@canonical.com"
+    },
+    "contributors": [
+    ]
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/main.cpp
----------------------------------------------------------------------
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..9502f5e
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,97 @@
+/*
+ *  Copyright 2013 Canonical Ltd.
+ *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <QtCore>
+#include <QApplication>
+#include <QQuickView>
+#include <QQuickItem>
+#include <QQmlContext>
+#include <QQmlEngine>
+
+#ifdef Q_OS_LINUX
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
+#endif
+
+static void customMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg) {
+    switch (type) {
+    case QtDebugMsg:
+        if (qgetenv("DEBUG").size()) {
+            fprintf(stderr, "Debug: %s\n", msg.toStdString().c_str());
+        }
+        break;
+    case QtWarningMsg:
+        fprintf(stderr, "Warning: %s\n", msg.toStdString().c_str());
+        break;
+    case QtCriticalMsg:
+        fprintf(stderr, "Critical: %s\n", msg.toStdString().c_str());
+        break;
+    case QtFatalMsg:
+        fprintf(stderr, "Fatal: %s\n", msg.toStdString().c_str());
+        abort();
+    }
+}
+
+int main(int argc, char *argv[]) {
+    qInstallMessageHandler(customMessageOutput);
+    QScopedPointer<QApplication> app(new QApplication(argc, argv));
+
+    //TODO: switch to options parser
+    // temprory hack to filter --desktop_file_hint
+    QStringList args = app->arguments().filter(QRegularExpression("^[^-]"));
+
+    std::string wm_class;
+    QDir wwwDir;
+    qDebug() << args << args[args.size() - 1];
+    if (QDir(args[args.size() - 1]).exists()) {
+        QDir app_dir(args[args.size() - 1]);
+        QDir parent(app_dir);
+        parent.cdUp();
+        wm_class = parent.dirName().toStdString();
+        wwwDir = app_dir;
+    } else {
+        wwwDir = QDir(QApplication::applicationDirPath());
+        wwwDir.cd("www");
+    }
+
+    QScopedPointer<QQuickView> view(new QQuickView());;
+
+    std::string execDir = "/usr/bin";
+    QDir workingDir;
+    if (QApplication::applicationDirPath().toStdString().substr(0, execDir.size()) == execDir) {
+        workingDir = QString("/usr/share/cordova-ubuntu-") + CORDOVA_UBUNTU_VERSION;
+    } else {
+        workingDir = QApplication::applicationDirPath();
+    }
+
+    view->rootContext()->setContextProperty("www", wwwDir.absolutePath());
+    view->setSource(QUrl(QString("%1/qml/main.qml").arg(workingDir.absolutePath())));
+
+#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86)
+    if (wm_class.size()) {
+        xcb_connection_t *c = xcb_connect(NULL,NULL);
+        xcb_change_property(c, XCB_PROP_MODE_REPLACE, view->winId(), XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, wm_class.size(), wm_class.c_str());
+        xcb_flush(c);
+        xcb_disconnect(c);
+    }
+#endif
+
+    view->setResizeMode(QQuickView::SizeRootObjectToView);
+    view->show();
+
+    return app->exec();
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/qml/CordovaView.qml.in
----------------------------------------------------------------------
diff --git a/qml/CordovaView.qml.in b/qml/CordovaView.qml.in
new file mode 100644
index 0000000..31ca432
--- /dev/null
+++ b/qml/CordovaView.qml.in
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 QtQuick 2.0
+import CordovaUbuntu @VERSION@
+
+Item {
+    id: root
+    property string wwwDir
+
+    Cordova {
+        id: cordova
+        wwwDir: root.wwwDir
+    }
+    Image {
+        id: splashscreen
+        anchors.fill: parent
+    }
+    Loader {
+        id: loader
+        asynchronous: true
+        visible: false
+        anchors.fill: parent
+        onLoaded: {
+            cordova.parent = loader.item
+            loader.item.completed.connect(function(){
+                loader.item.visible = true
+                loader.visible = true
+                splashscreen.visible = false
+            });
+        }
+    }
+    Component.onCompleted: {
+        splashscreen.source = cordova.getSplashscreenPath(cordova, root.wwwDir)
+        loader.source = "CordovaViewInternal.qml"
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/qml/main.qml.in
----------------------------------------------------------------------
diff --git a/qml/main.qml.in b/qml/main.qml.in
new file mode 100644
index 0000000..3302e3f
--- /dev/null
+++ b/qml/main.qml.in
@@ -0,0 +1,26 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 QtQuick 2.0
+import CordovaUbuntu @VERSION@
+
+CordovaView {
+    width: 560
+    height: 896
+    wwwDir: www
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/cordova.cpp
----------------------------------------------------------------------
diff --git a/src/cordova.cpp b/src/cordova.cpp
new file mode 100644
index 0000000..1a66d0f
--- /dev/null
+++ b/src/cordova.cpp
@@ -0,0 +1,141 @@
+/*
+ *  Copyright 2013 Canonical Ltd.
+ *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "cordova.h"
+
+#include <QtGui>
+
+#include <QApplication>
+#include <QQuickView>
+#include <QQuickItem>
+#include <QQmlContext>
+
+Cordova::Cordova(QDir wwwDir, QQuickItem *item, QObject *parent): QObject(parent), m_item(item), m_www(wwwDir) {
+    qDebug() << "Using" << m_www.absolutePath() << "as working dir";
+    m_mainUrl = QUrl::fromUserInput(m_www.absoluteFilePath("index.html")).toString();
+}
+
+QString Cordova::get_app_dir() {
+    return m_www.absolutePath();
+}
+
+struct Splash {
+    double rating;
+    QString path;
+};
+
+QString Cordova::getSplashscreenPath() {
+    double ratio = (double)m_item->width() / m_item->height();
+
+    QDir dir(get_app_dir());
+    if (!dir.cd("splashscreen"))
+        return "";
+
+    QList<Splash> images;
+    for (QFileInfo info: dir.entryInfoList()) {
+        QImage image(info.absoluteFilePath());
+        if (image.isNull())
+            continue;
+        Splash t;
+        t.path = info.absoluteFilePath();
+        t.rating = std::abs((image.width() / (double)m_item->width()) * ((image.width() / image.height()) / ratio) - 1);
+        images.push_back(t);
+    }
+    std::min_element(images.begin(), images.end(), [](Splash &f, Splash &s) {
+        return f.rating < s.rating;
+    });
+    if (!images.empty())
+      return images.first().path;
+    return "";
+}
+
+void Cordova::initPlugins() {
+    QList<QDir> searchPath = {QDir("/usr/lib/cordova-ubuntu-" CORDOVA_UBUNTU_VERSION), get_app_dir()};
+
+    m_plugins.clear();
+    for (QDir pluginsDir: searchPath) {
+        for (const QString &fileName: pluginsDir.entryList(QDir::Files)) {
+            QString path = pluginsDir.absoluteFilePath(fileName);
+            qDebug() << "Testing " << path;
+
+            if (!QLibrary::isLibrary(path))
+                continue;
+
+            CordovaGetPluginInstances loader = (CordovaGetPluginInstances) QLibrary::resolve(path, "cordovaGetPluginInstances");
+            if (!loader) {
+                qCritical() << "Missing cordovaGetPluginInstances symbol in" << path;
+                continue;
+            }
+
+            auto plugins = (*loader)(this);
+
+            for (QSharedPointer<CPlugin> plugin: plugins) {
+              qCritical() << plugin->fullName();
+                emit pluginWantsToBeAdded(plugin->fullName(), plugin.data(), plugin->shortName());
+            }
+            m_plugins += plugins;
+        }
+    }
+}
+
+void Cordova::loadFinished(bool ok) {
+    Q_UNUSED(ok)
+
+    initPlugins();
+}
+
+void Cordova::execQML(const QString &src) {
+    emit qmlExecNeeded(src);
+}
+
+void Cordova::execJS(const QString &js) {
+    emit javaScriptExecNeeded(js);
+}
+
+QString Cordova::mainUrl() const {
+    return m_mainUrl;
+}
+
+QObject *Cordova::topLevelEventsReceiver() {
+    return dynamic_cast<QQuickView*>(m_item->window());
+}
+
+QQuickItem *Cordova::rootObject() {
+    return m_item->parentItem();
+}
+
+void Cordova::setTitle(const QString &title) {
+    dynamic_cast<QQuickView*>(m_item->window())->setTitle(title);
+}
+
+void Cordova::pushViewState(const QString &state) {
+    if (m_states.empty()) {
+        rootObject()->setState(state);
+    }
+    m_states.push_front(state);
+}
+
+void Cordova::popViewState(const QString &state) {
+    if (!m_states.removeOne(state))
+        qDebug() << "WARNING: incorrect view states order";
+
+    if (m_states.empty()) {
+        rootObject()->setState("main");
+    } else {
+        rootObject()->setState(m_states.front());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/cordova.h
----------------------------------------------------------------------
diff --git a/src/cordova.h b/src/cordova.h
new file mode 100644
index 0000000..9b67ad6
--- /dev/null
+++ b/src/cordova.h
@@ -0,0 +1,69 @@
+/*
+ *  Copyright 2013 Canonical Ltd.
+ *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef CORDOVA_H_DJJKASDM44
+#define CORDOVA_H_DJJKASDM44
+
+#include <QtCore>
+#include <cassert>
+
+#include "cplugin.h"
+
+class QQuickView;
+class QQuickItem;
+
+class Cordova: public QObject {
+    Q_OBJECT
+    Q_PROPERTY(QString mainUrl READ mainUrl CONSTANT)
+
+public:
+    explicit Cordova(QDir wwwDir, QQuickItem *item, QObject *parent = nullptr);
+
+    QString mainUrl() const;
+    QObject *topLevelEventsReceiver();
+    QQuickItem *rootObject();
+    QString get_app_dir();
+
+    void pushViewState(const QString &state);
+    void popViewState(const QString &state);
+    QString getSplashscreenPath();
+signals:
+    void javaScriptExecNeeded(const QString &js);
+    void qmlExecNeeded(const QString &src);
+    void pluginWantsToBeAdded(const QString &pluginName, QObject *pluginObject, const QString &pluginShortName);
+
+public slots:
+    void loadFinished(bool ok);
+    void execJS(const QString &js);
+    void setTitle(const QString &title);
+    void execQML(const QString &src);
+
+private:
+    int m_alertCallback;
+
+    void initPlugins();
+
+    QQuickItem *m_item;
+    QList<QSharedPointer<CPlugin>> m_plugins;
+
+    QDir m_www;
+    QString m_mainUrl;
+    QList<QString> m_states;
+    Q_DISABLE_COPY(Cordova)
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/coreplugins.cpp
----------------------------------------------------------------------
diff --git a/src/coreplugins.cpp b/src/coreplugins.cpp
new file mode 100644
index 0000000..fc1a115
--- /dev/null
+++ b/src/coreplugins.cpp
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+#include <QtCore>
+#include "cplugin.h"
+#include "coreplugins.h"
+INSERT_HEADER_HERE
+
+#define INIT_PLUGIN(class) \
+    res.prepend(QSharedPointer<class>(new class(cordova))); \
+
+extern "C" {
+
+Q_DECL_EXPORT QList<QSharedPointer<CPlugin>> cordovaGetPluginInstances(Cordova *cordova) {
+    QList<QSharedPointer<CPlugin>> res;
+
+    INSERT_PLUGIN_HERE
+
+    return res;
+}
+
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/coreplugins.h
----------------------------------------------------------------------
diff --git a/src/coreplugins.h b/src/coreplugins.h
new file mode 100644
index 0000000..228d5b3
--- /dev/null
+++ b/src/coreplugins.h
@@ -0,0 +1,20 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+#define INSERT_HEADER_HERE
+#define INSERT_PLUGIN_HERE

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/cplugin.cpp
----------------------------------------------------------------------
diff --git a/src/cplugin.cpp b/src/cplugin.cpp
new file mode 100644
index 0000000..b03164a
--- /dev/null
+++ b/src/cplugin.cpp
@@ -0,0 +1,151 @@
+/*
+ *  Copyright 2013 Canonical Ltd.
+ *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "cplugin.h"
+#include "cordova.h"
+
+CPlugin::CPlugin(Cordova *cordova): QObject(0), m_cordova(cordova) {
+}
+
+void CPlugin::callback(int p_callbackId, const QString &p_jsParameters) {
+    QString javascript;
+    if (p_jsParameters.length() > 0) {
+        javascript = QString("cordova.callback(%1, %2);").arg(p_callbackId).arg(p_jsParameters);
+    }
+    else {
+        javascript = QString("cordova.callback(%1);").arg(p_callbackId);
+    }
+
+    if (javascript.size() > 1000) {
+        QString t = javascript;
+        t.resize(1000);
+        qDebug() << "Running: " << t;
+    } else {
+        qDebug() << "Running: " << javascript;
+    }
+    m_cordova->execJS(javascript);
+}
+
+void CPlugin::callbackWithoutRemove(int p_callbackId, const QString &p_jsParameters) {
+    QString javascript;
+
+    if (p_jsParameters.length() > 0) {
+        javascript = QString("cordova.callbackWithoutRemove(%1, %2);").arg(p_callbackId).arg(p_jsParameters);
+    }
+    else {
+        javascript = QString("cordova.callbackWithoutRemove(%1);").arg(p_callbackId);
+    }
+
+    if (javascript.size() > 1000) {
+        QString t = javascript;
+        t.resize(1000);
+        qDebug() << "Running: " << t;
+    } else {
+        qDebug() << "Running: " << javascript;
+    }
+    m_cordova->execJS(javascript);
+}
+
+static QString escapeCharacters(QString str) {
+    QString res;
+    str = str.replace('\\', QString("\\\\")).replace('"', "\\\"").replace('\'', "\\\'").replace('\n', "\\n");
+    res.reserve(str.size() * 2);
+    for (QString::const_iterator it = str.begin(); it != str.end(); ++it) {
+        QChar ch = *it;
+        ushort code = ch.unicode();
+        if (code < 0x80 && code >= 0x20) {
+            res += ch;
+        } else {
+            res += "\\u";
+            res += QString::number(code, 16).rightJustified(4, '0').toUpper();
+        }
+    }
+    return res;
+}
+
+namespace CordovaInternal {
+    QString format(const QString &t) {
+        return QString("\"%1\"").arg(escapeCharacters(t));
+    }
+
+    QString format(bool t) {
+        if (t)
+            return QString("true");
+        return "false";
+    }
+
+    QString format(const QByteArray &t) {
+        return format(QString(t));
+    }
+
+    QString format(const char* const t) {
+        return format(QString(t));
+    }
+
+    QString format(const double &t) {
+        if (std::isnan(t))
+            return "Number.NaN";
+        return QString::number(t);
+    }
+
+    QString format(const float &t) {
+        return format(static_cast<double>(t));
+    }
+
+    QString format(const QVariant &t) {
+        switch (t.userType()) {
+        case QVariant::LongLong:
+        case QVariant::ULongLong:
+        case QVariant::Int:
+        case QVariant::UInt:
+            return format(t.toLongLong());
+            break;
+        case QVariant::String:
+            return format(t.toString());
+            break;
+        case QVariant::Double:
+            return format(t.toDouble());
+            break;
+        case QMetaType::Float:
+            return format(t.toFloat());
+        case QMetaType::Bool:
+            return format(t.toBool());
+        case QMetaType::QVariantMap:
+            return format(t.toMap(), true);
+        default:
+            throw std::exception();
+        }
+    }
+
+    QString format(const QVariantMap &t, bool clean) {
+      // QString(QJsonDocument(QJsonObject::fromVariantMap(t)).toJson()) is not good enough
+      // e.g. QVariant(qlonglong, 1374944677139) ) -> 1.37494e+12
+
+      auto map = t.toStdMap();
+      QString res;
+      for (const std::pair<QString, QVariant> &p: map) {
+          if (res.size())
+              res += ", ";
+          res += QString("%1: %2").arg(format(p.first)).arg(format(p.second));
+      }
+      if (clean)
+          res = QString("{%1}").arg(res);
+      else
+          res = QString("JSON.parse('{%1}')").arg(res);
+      return res;
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/cplugin.h
----------------------------------------------------------------------
diff --git a/src/cplugin.h b/src/cplugin.h
new file mode 100644
index 0000000..92d62bc
--- /dev/null
+++ b/src/cplugin.h
@@ -0,0 +1,119 @@
+/*
+ *  Copyright 2013 Canonical Ltd.
+ *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef CPLUGIN_H
+#define CPLUGIN_H
+
+#include <QtCore>
+
+namespace CordovaInternal {
+    template<size_t J>
+    struct Assign {
+        template<typename Result, typename Src>
+        static void x(Result& t, const Src& tup) {
+            std::get<J - 1>(t) = std::get<J>(tup);
+            Assign<J - 1>::x(t, tup);
+        }
+    };
+
+    template<>
+    struct Assign<1> {
+        template<typename Result, typename Src>
+        static void x(Result& t, const Src& tup) {
+            std::get<0>(t) = std::get<1>(tup);
+        }
+    };
+
+    template<typename Head, typename... Tail>
+    std::tuple<Tail...> tail(std::tuple<Head, Tail...> &tuple) {
+        std::tuple<Tail...> t;
+        Assign<std::tuple_size<std::tuple<Tail...>>::value>::x(t, tuple);
+        return t;
+    }
+    template<typename Head>
+    std::tuple<> tail(std::tuple<Head> &) {
+	return std::tuple<>();
+    }
+    template<typename Head = QString>
+	std::tuple<> tail(std::tuple<> &) {
+	return std::tuple<>();
+    }
+
+    template<typename T>
+        QString format(const T &t) {
+        return QString("%1").arg(t);
+    }
+    QString format(const QString &t);
+    QString format(const QByteArray &t);
+    QString format(const char* const t);
+    QString format(const double &t);
+    QString format(const float &t);
+    QString format(const QVariant &t);
+    QString format(const QVariantMap &t, bool clean = false);
+    QString format(bool t);
+
+    template<class Head = QString>
+    QString tuple2str(std::tuple<> &) {
+      return QString();
+    }
+    template<class... Args>
+    QString tuple2str(std::tuple<Args...> &tuple) {
+      auto t = tail(tuple);
+      QString rest = tuple2str(t);
+      QString head(format(std::get<0>(tuple)));
+      if (rest.size() == 0)
+	return head;
+      return QString("%1, %2").arg(head).arg(rest);
+    }
+    template<typename Head>
+    QString tuple2str(std::tuple<Head> &tuple) {
+      return format(std::get<0>(tuple));
+    }
+};
+
+class Cordova;
+
+class CPlugin: public QObject {
+    Q_OBJECT
+public:
+    explicit CPlugin(Cordova *cordova);
+
+    void callbackWithoutRemove(int p_callbackId, const QString &p_jsParameters);
+    void callback(int p_callbackId, const QString &p_jsParameters);
+
+    template<typename... Arguments>
+    void cb(int callbackId, Arguments... args) {
+      auto tuple = std::make_tuple(args...);
+      callback(callbackId, CordovaInternal::tuple2str(tuple));
+    }
+    template<typename... Arguments>
+    void cb(int callbackId) {
+      callback(callbackId, "");
+    }
+
+    virtual const QString fullName() = 0;
+    virtual const QString shortName() = 0;
+protected:
+    Cordova *m_cordova;
+private:
+    CPlugin(const CPlugin&) = delete;
+    CPlugin& operator=(const CPlugin&) = delete;
+};
+
+typedef QList<QSharedPointer<CPlugin>> (*CordovaGetPluginInstances)(Cordova *cordova);
+
+#endif

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/js/bootstrap.js
----------------------------------------------------------------------
diff --git a/src/js/bootstrap.js b/src/js/bootstrap.js
new file mode 100644
index 0000000..460c9de
--- /dev/null
+++ b/src/js/bootstrap.js
@@ -0,0 +1,102 @@
+/*
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+window.cordova = require('cordova');
+
+(function (context) {
+    if (context._cordovaJsLoaded) {
+        throw new Error('cordova.js included multiple times.');
+    }
+    context._cordovaJsLoaded = true;
+
+    var channel = require('cordova/channel');
+    var pluginloader = require('cordova/pluginloader');
+
+    var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
+
+    function logUnfiredChannels(arr) {
+        for (var i = 0; i < arr.length; ++i) {
+            if (arr[i].state != 2) {
+                console.log('Channel not fired: ' + arr[i].type);
+            }
+        }
+    }
+
+    window.setTimeout(function() {
+        if (channel.onDeviceReady.state != 2) {
+            console.log('deviceready has not fired after 5 seconds.');
+            logUnfiredChannels(platformInitChannelsArray);
+            logUnfiredChannels(channel.deviceReadyChannelsArray);
+        }
+    }, 5000);
+
+    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
+    // We replace it so that properties that can't be clobbered can instead be overridden.
+    function replaceNavigator(origNavigator) {
+        var CordovaNavigator = function() {};
+        CordovaNavigator.prototype = origNavigator;
+        var newNavigator = new CordovaNavigator();
+        // This work-around really only applies to new APIs that are newer than Function.bind.
+        // Without it, APIs such as getGamepads() break.
+        if (CordovaNavigator.bind) {
+            for (var key in origNavigator) {
+                if (typeof origNavigator[key] == 'function') {
+                    newNavigator[key] = origNavigator[key].bind(origNavigator);
+                }
+            }
+        }
+        return newNavigator;
+    }
+    if (context.navigator) {
+        context.navigator = replaceNavigator(context.navigator);
+    }
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+    /**
+     * Create all cordova objects once native side is ready.
+     */
+    channel.join(function() {
+        // Call the platform-specific initialization
+        require('cordova/platform').initialize();
+
+        // Fire event to notify that all objects are created
+        channel.onCordovaReady.fire();
+
+        // Fire onDeviceReady event once page has fully loaded, all
+        // constructors have run and cordova info has been received from native
+        // side.
+        // This join call is deliberately made after platform.initialize() in
+        // order that plugins may manipulate channel.deviceReadyChannelsArray
+        // if necessary.
+        channel.join(function() {
+            require('cordova').fireDocumentEvent('deviceready');
+        }, channel.deviceReadyChannelsArray);
+
+    }, platformInitChannelsArray);
+
+    // Don't attempt to load when running unit tests.
+    if (typeof XMLHttpRequest != 'undefined') {
+        pluginloader.load();
+    }
+}(window));
+require('cordova/channel').onNativeReady.fire();

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/js/common/argscheck.js
----------------------------------------------------------------------
diff --git a/src/js/common/argscheck.js b/src/js/common/argscheck.js
new file mode 100644
index 0000000..310a456
--- /dev/null
+++ b/src/js/common/argscheck.js
@@ -0,0 +1,64 @@
+define("cordova/argscheck", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+    'A': 'Array',
+    'D': 'Date',
+    'N': 'Number',
+    'S': 'String',
+    'F': 'Function',
+    'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+  return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+    if (!moduleExports.enableChecks) {
+        return;
+    }
+    var errMsg = null;
+    var typeName;
+    for (var i = 0; i < spec.length; ++i) {
+        var c = spec.charAt(i),
+            cUpper = c.toUpperCase(),
+            arg = args[i];
+        // Asterix means allow anything.
+        if (c == '*') {
+            continue;
+        }
+        typeName = utils.typeName(arg);
+        if ((arg === null || arg === undefined) && c == cUpper) {
+            continue;
+        }
+        if (typeName != typeMap[cUpper]) {
+            errMsg = 'Expected ' + typeMap[cUpper];
+            break;
+        }
+    }
+    if (errMsg) {
+        errMsg += ', but got ' + typeName + '.';
+        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+        // Don't log when running unit tests.
+        if (typeof jasmine == 'undefined') {
+            console.error(errMsg);
+        }
+        throw TypeError(errMsg);
+    }
+}
+
+function getValue(value, defaultValue) {
+    return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+
+});

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/js/common/builder.js
----------------------------------------------------------------------
diff --git a/src/js/common/builder.js b/src/js/common/builder.js
new file mode 100644
index 0000000..14eddb0
--- /dev/null
+++ b/src/js/common/builder.js
@@ -0,0 +1,111 @@
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function clobber(obj, key, value) {
+    exports.replaceHookForTesting(obj, key);
+    obj[key] = value;
+    // Getters can only be overridden by getters.
+    if (obj[key] !== value) {
+        utils.defineGetter(obj, key, function() {
+            return value;
+        });
+    }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+    if (message) {
+        utils.defineGetter(obj, key, function() {
+            console.log(message);
+            delete obj[key];
+            clobber(obj, key, value);
+            return value;
+        });
+    } else {
+        clobber(obj, key, value);
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+          var result = obj.path ? require(obj.path) : {};
+
+          if (clobber) {
+              // Clobber if it doesn't exist.
+              if (typeof parent[key] === 'undefined') {
+                  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+              } else if (typeof obj.path !== 'undefined') {
+                  // If merging, merge properties onto parent, otherwise, clobber.
+                  if (merge) {
+                      recursiveMerge(parent[key], result);
+                  } else {
+                      assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                  }
+              }
+              result = parent[key];
+          } else {
+            // Overwrite if not currently defined.
+            if (typeof parent[key] == 'undefined') {
+              assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+            } else {
+              // Set result to what already exists, so we can build children into it if they exist.
+              result = parent[key];
+            }
+          }
+
+          if (obj.children) {
+            include(result, obj.children, clobber, merge);
+          }
+        } catch(e) {
+          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (target.prototype && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                clobber(target.prototype, prop, src[prop]);
+            } else {
+                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+                    recursiveMerge(target[prop], src[prop]);
+                } else {
+                    clobber(target, prop, src[prop]);
+                }
+            }
+        }
+    }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+    include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+    include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+    include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
+
+});

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/js/common/channel.js
----------------------------------------------------------------------
diff --git a/src/js/common/channel.js b/src/js/common/channel.js
new file mode 100644
index 0000000..1567634
--- /dev/null
+++ b/src/js/common/channel.js
@@ -0,0 +1,239 @@
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady*              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
+ * onDeviceReady*              User event fired to indicate that Cordova is ready
+ * onResume                    User event fired to indicate a start/resume lifecycle event
+ * onPause                     User event fired to indicate a pause lifecycle event
+ * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ */
+var Channel = function(type, sticky) {
+    this.type = type;
+    // Map of guid -> function.
+    this.handlers = {};
+    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+    this.state = sticky ? 1 : 0;
+    // Used in sticky mode to remember args passed to fire().
+    this.fireArgs = null;
+    // Used by onHasSubscribersChange to know if there are any listeners.
+    this.numHandlers = 0;
+    // Function that is called when the first listener is subscribed, or when
+    // the last listener is unsubscribed.
+    this.onHasSubscribersChange = null;
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired. All channels must be sticky channels.
+         */
+        join: function(h, c) {
+            var len = c.length,
+                i = len,
+                f = function() {
+                    if (!(--i)) h();
+                };
+            for (var j=0; j<len; j++) {
+                if (c[j].state === 0) {
+                    throw Error('Can only use join with sticky channels.');
+                }
+                c[j].subscribe(f);
+            }
+            if (!len) h();
+        },
+        create: function(type) {
+            return channel[type] = new Channel(type, false);
+        },
+        createSticky: function(type) {
+            return channel[type] = new Channel(type, true);
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = channel[feature] || this.createSticky(feature);
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+    if (this.state == 2) {
+        f.apply(c || this, this.fireArgs);
+        return;
+    }
+
+    var func = f,
+        guid = f.observer_guid;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    if (!guid) {
+        // first time any channel has seen this subscriber
+        guid = '' + nextGuid++;
+    }
+    func.observer_guid = guid;
+    f.observer_guid = guid;
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[guid]) {
+        this.handlers[guid] = func;
+        this.numHandlers++;
+        if (this.numHandlers == 1) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+    // need a function to unsubscribe
+    forceFunction(f);
+
+    var guid = f.observer_guid,
+        handler = this.handlers[guid];
+    if (handler) {
+        delete this.handlers[guid];
+        this.numHandlers--;
+        if (this.numHandlers === 0) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    var fail = false,
+        fireArgs = Array.prototype.slice.call(arguments);
+    // Apply stickiness.
+    if (this.state == 1) {
+        this.state = 2;
+        this.fireArgs = fireArgs;
+    }
+    if (this.numHandlers) {
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
+        for (var item in this.handlers) {
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            toCall[i].apply(this, fireArgs);
+        }
+        if (this.state == 2 && this.numHandlers) {
+            this.numHandlers = 0;
+            this.handlers = {};
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/js/common/commandProxy.js
----------------------------------------------------------------------
diff --git a/src/js/common/commandProxy.js b/src/js/common/commandProxy.js
new file mode 100644
index 0000000..e45dc5d
--- /dev/null
+++ b/src/js/common/commandProxy.js
@@ -0,0 +1,28 @@
+define("cordova/commandProxy", function(require, exports, module) {
+
+
+// internal map of proxy function
+var CommandProxyMap = {};
+
+module.exports = {
+
+    // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
+    add:function(id,proxyObj) {
+        console.log("adding proxy for " + id);
+        CommandProxyMap[id] = proxyObj;
+        return proxyObj;
+    },
+
+    // cordova.commandProxy.remove("Accelerometer");
+    remove:function(id) {
+        var proxy = CommandProxyMap[id];
+        delete CommandProxyMap[id];
+        CommandProxyMap[id] = null;
+        return proxy;
+    },
+
+    get:function(service,action) {
+        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
+    }
+};
+});

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/b6c3aee7/src/js/common/modulemapper.js
----------------------------------------------------------------------
diff --git a/src/js/common/modulemapper.js b/src/js/common/modulemapper.js
new file mode 100644
index 0000000..16c8edd
--- /dev/null
+++ b/src/js/common/modulemapper.js
@@ -0,0 +1,107 @@
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+    moduleMap = define.moduleMap,
+    symbolList,
+    deprecationMap;
+
+exports.reset = function() {
+    symbolList = [];
+    deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+    if (!(moduleName in moduleMap)) {
+        throw new Error('Module ' + moduleName + ' does not exist.');
+    }
+    symbolList.push(strategy, moduleName, symbolPath);
+    if (opt_deprecationMessage) {
+        deprecationMap[symbolPath] = opt_deprecationMessage;
+    }
+}
+
+// Note: Android 2.3 does have Function.bind().
+exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.runs = function(moduleName) {
+    addEntry('r', moduleName, null);
+};
+
+function prepareNamespace(symbolPath, context) {
+    if (!symbolPath) {
+        return context;
+    }
+    var parts = symbolPath.split('.');
+    var cur = context;
+    for (var i = 0, part; part = parts[i]; ++i) {
+        cur = cur[part] = cur[part] || {};
+    }
+    return cur;
+}
+
+exports.mapModules = function(context) {
+    var origSymbols = {};
+    context.CDV_origSymbols = origSymbols;
+    for (var i = 0, len = symbolList.length; i < len; i += 3) {
+        var strategy = symbolList[i];
+        var moduleName = symbolList[i + 1];
+        var module = require(moduleName);
+        // <runs/>
+        if (strategy == 'r') {
+            continue;
+        }
+        var symbolPath = symbolList[i + 2];
+        var lastDot = symbolPath.lastIndexOf('.');
+        var namespace = symbolPath.substr(0, lastDot);
+        var lastName = symbolPath.substr(lastDot + 1);
+
+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
+        var parentObj = prepareNamespace(namespace, context);
+        var target = parentObj[lastName];
+
+        if (strategy == 'm' && target) {
+            builder.recursiveMerge(target, module);
+        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+            if (!(symbolPath in origSymbols)) {
+                origSymbols[symbolPath] = target;
+            }
+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
+        }
+    }
+};
+
+exports.getOriginalSymbol = function(context, symbolPath) {
+    var origSymbols = context.CDV_origSymbols;
+    if (origSymbols && (symbolPath in origSymbols)) {
+        return origSymbols[symbolPath];
+    }
+    var parts = symbolPath.split('.');
+    var obj = context;
+    for (var i = 0; i < parts.length; ++i) {
+        obj = obj && obj[parts[i]];
+    }
+    return obj;
+};
+
+exports.loadMatchingModules = function(matchingRegExp) {
+    for (var k in moduleMap) {
+        if (matchingRegExp.exec(k)) {
+            require(k);
+        }
+    }
+};
+
+exports.reset();
+
+
+});


Mime
View raw message