Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add scripts/plugin_loader.js, which runs after bootstrap.

This code does an XHR for cordova_plugins.json. If it finds the file, it
will load the plugins specified in it. If the response is empty or the
XHR fails, it does nothing.

This creates a new onPluginsReady event that fires either when the
plugins are all loaded or there are no plugins to load. The bootstrap is
waiting on this now, as well as onDOMContentLoaded and onNativeReady.
  • Loading branch information...
commit f97bd694da3364664776d79c5bbf5e914e8e4f5a 1 parent bbb9d79
@shepheb shepheb authored
View
10 build/packager.js
@@ -111,6 +111,16 @@ packager.bundle = function(platform, debug, commitId ) {
writeScript(output, scripts[bootstrapPlatform], debug)
}
+ // Include the plugin loading code.
+ if (platform !== 'test') {
+ // NB: This should probably run last of all, and definitely after the bootstrap.
+ if (!scripts['plugin_loader']) {
+ throw new Error("didn't find a script for 'plugin_loader'");
+ }
+
+ writeScript(output, scripts['plugin_loader'], debug);
+ }
+
// write trailer
output.push('\n})();')
View
1  lib/common/channel.js
@@ -243,7 +243,6 @@ channel.createSticky('onCordovaInfoReady');
channel.createSticky('onCordovaConnectionReady');
// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-// This is used in conjunction with the automatic plugin JS loading CLI prototype.
channel.createSticky('onPluginsReady');
// Event to indicate that Cordova is ready
View
11 lib/scripts/bootstrap.js
@@ -53,15 +53,6 @@
/**
* Create all cordova objects once page has fully loaded and native side is ready.
*/
- var joinEvents = [ channel.onDOMContentLoaded, channel.onNativeReady ];
-
- // If this property is set to something truthy, join on onPluginsReady too.
- // This property is set by the automatic JS installation prototype in cordova-cli,
- // and will be removed when the prototype either becomes mainline or is dropped.
- if (window.__onPluginsLoadedHack) {
- joinEvents.push(channel.onPluginsReady);
- }
-
channel.join(function() {
var builder = require('cordova/builder'),
platform = require('cordova/platform');
@@ -82,6 +73,6 @@
require('cordova').fireDocumentEvent('deviceready');
}, channel.deviceReadyChannelsArray);
- }, joinEvents);
+ }, [ channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady ]);
}(window));
View
118 lib/scripts/plugin_loader.js
@@ -0,0 +1,118 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+(function (context) {
+ // To be populated with the handler by handlePluginsObject.
+ var onScriptLoadingComplete;
+
+ var scriptCounter = 0;
+ function scriptLoadedCallback() {
+ scriptCounter--;
+ if (scriptCounter === 0) {
+ onScriptLoadingComplete && onScriptLoadingComplete();
+ }
+ }
+
+ // Helper function to inject a <script> tag.
+ function injectScript(path) {
+ scriptCounter++;
+ var script = document.createElement("script");
+ script.onload = scriptLoadedCallback;
+ script.src = path;
+ document.head.appendChild(script);
+ }
+
+ // Called when:
+ // * There are plugins defined and all plugins are finished loading.
+ // * There are no plugins to load.
+ function finishPluginLoading() {
+ context.cordova.require('cordova/channel').onPluginsReady.fire();
+ }
+
+ // Handler for the cordova_plugins.json content.
+ // See plugman's plugin_loader.js for the details of this object.
+ // This function is only called if the really is a plugins array that isn't empty.
+ // Otherwise the XHR response handler will just call finishPluginLoading().
+ function handlePluginsObject(modules) {
+ // First create the callback for when all plugins are loaded.
+ var mapper = context.cordova.require('cordova/modulemapper');
+ onScriptLoadingComplete = function() {
+ // Loop through all the plugins and then through their clobbers and merges.
+ for (var i = 0; i < modules.length; i++) {
+ var module = modules[i];
+ if (!module) continue;
+
+ if (module.clobbers && module.clobbers.length) {
+ for (var j = 0; j < module.clobbers.length; j++) {
+ mapper.clobbers(module.id, module.clobbers[j]);
+ }
+ }
+
+ if (module.merges && module.merges.length) {
+ for (var k = 0; k < module.merges.length; k++) {
+ mapper.merges(module.id, module.merges[k]);
+ }
+ }
+
+ // Finally, if runs is truthy we want to simply require() the module.
+ // This can be skipped if it had any merges or clobbers, though,
+ // since the mapper will already have required the module.
+ if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+ context.cordova.require(module.id);
+ }
+ }
+
+ finishPluginLoading();
+ };
+
+ // Now inject the scripts.
+ for (var i = 0; i < modules.length; i++) {
+ injectScript(modules[i].file);
+ }
+ }
+
+ // Try to XHR the cordova_plugins.json file asynchronously.
+ var xhr = new context.XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (this.readyState != 4) { // not DONE
+ return;
+ }
+
+ // If the response is a JSON string which composes an array, call handlePluginsObject.
+ // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
+ if (this.status == 200) {
+ var obj = JSON.parse(this.responseText);
+ if (obj && obj instanceof Array && obj.length > 0) {
+ handlePluginsObject(obj);
+ } else {
+ finishPluginLoading();
+ }
+ } else {
+ finishPluginLoading();
+ }
+ };
+ xhr.open('GET', 'cordova_plugins.json', true); // Async
+ xhr.send();
+}(window));
+
Please sign in to comment.
Something went wrong with that request. Please try again.