Skip to content

Instantly share code, notes, and snippets.

@axemclion
Last active August 18, 2018 05:14
Show Gist options
  • Save axemclion/cb19bd30a6f7a944b47f to your computer and use it in GitHub Desktop.
Save axemclion/cb19bd30a6f7a944b47f to your computer and use it in GitHub Desktop.

Revisions

  1. axemclion revised this gist Aug 17, 2015. 1 changed file with 28 additions and 2 deletions.
    30 changes: 28 additions & 2 deletions browser-sync.js
    Original file line number Diff line number Diff line change
    @@ -26,6 +26,7 @@ module.exports = function(context) {

    // Installs browser-sync and other packages locally
    function installDependencies() {
    return Q();
    debug('Starting npm');
    return Q.ninvoke(npm, 'load').then(function() {
    debug('Installing dependencies');
    @@ -88,7 +89,16 @@ module.exports = function(context) {
    directory: true
    },
    files: location,
    open: false
    open: false,
    snippetOptions: {
    rule: {
    match: /<\/body>/i,
    fn: function(snippet, match) {
    return '<script>window.__karma__=true</script>' + snippet + monkeyPatch() + match;
    }
    }
    },
    minify: false
    }, function(err, bs) {
    var server = bs.options.getIn(['urls', 'external']);
    resolve(Url.resolve(server, 'platforms'));
    @@ -106,4 +116,20 @@ module.exports = function(context) {
    });
    };

    // Ensure that you add ws: 'unsafe-inline' to the CSP in index.html

    function monkeyPatch() {
    var script = function() {
    (function patch() {
    if (typeof window.__bs === 'undefined') {
    window.setTimeout(patch, 500);
    } else {
    var oldCanSync = window.__bs.prototype.canSync;
    window.__bs.prototype.canSync = function(data, optPath) {
    data.url = window.location.pathname.substr(0, window.location.pathname.indexOf('/www')) + data.url.substr(data.url.indexOf('/www'))
    return oldCanSync.apply(this, [data, optPath]);
    };
    }
    }());
    };
    return '<script>(' + script.toString() + '());</script>';
    }
  2. axemclion revised this gist Aug 15, 2015. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion browser-sync.js
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,6 @@ module.exports = function(context) {

    // Installs browser-sync and other packages locally
    function installDependencies() {
    return Q();
    debug('Starting npm');
    return Q.ninvoke(npm, 'load').then(function() {
    debug('Installing dependencies');
  3. axemclion revised this gist Aug 15, 2015. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions browser-sync.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,9 @@
    // Browser-Sync support for Cordova projects
    // To use this, add the following snippet as a after_run hook using something like
    // <hook type="after_prepare" src="hooks/browser-sync.js" />
    // Also add ws: 'unsafe-inline' to the CSP in index.html
    // The do Cordova run, and changing anything in www/ will live-reload the cordova app on emulator/device

    module.exports = function(context) {
    if (context.opts.options[0] === '--browser-sync-mode') {
    // Prepare was called by this script, so don't run the script again
  4. axemclion revised this gist Aug 15, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion browser-sync.js
    Original file line number Diff line number Diff line change
    @@ -93,7 +93,7 @@ module.exports = function(context) {

    // Main workfow
    return installDependencies().then(function() {
    return browserSyncServer(path.join(context.opts.projectRoot, 'www'));
    return browserSyncServer(path.join(context.opts.projectRoot, 'www/'));
    }).then(function(server) {
    // TODO - Change host based on platform
    changeHost(server + '/android/assets/www/index.html', 'android/res');
  5. axemclion revised this gist Aug 15, 2015. 1 changed file with 18 additions and 12 deletions.
    30 changes: 18 additions & 12 deletions browser-sync.js
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,14 @@
    var path = require('path');
    var fs = require('fs');
    var Url = require('url');
    module.exports = function(context) {
    if (context.opts.options[0] === '--browser-sync-mode') {
    // Prepare was called by this script, so don't run the script again
    return;
    }
    var path = require('path');
    var fs = require('fs');
    var Url = require('url');

    var debug = console.log.bind(console);
    var debug = console.log.bind(console);

    module.exports = function(context) {
    var npm = context.requireCordovaModule('npm');
    var Q = context.requireCordovaModule('q');
    var glob = context.requireCordovaModule('glob')
    @@ -45,7 +49,6 @@ module.exports = function(context) {
    // Also add allow nav in case of
    var allowNavTag = et.SubElement(configXml.find('.'), 'allow-navigation');
    allowNavTag.set('href', '*');

    fs.writeFileSync(filename, configXml.write({
    indent: 4
    }), "utf-8");
    @@ -60,13 +63,17 @@ module.exports = function(context) {
    */
    function browserSyncServer(location) {
    debug('Starting browser-sync server');
    var bs = require('browser-sync');
    location = location + '**/*.*'
    return Q.promise(function(resolve, reject, notify) {
    bs.watch('**/*.*', function(event, files) {
    console.log('HERERE', event, files);
    var bs = require('browser-sync').create();
    bs.watch(location, function(event, files) {
    if (event !== 'change') {
    return;
    }
    // TODO Prepare only the platform that was run
    context.cordova.prepare({
    options: ['--browser-sync-mode'] // to indicate who is calling prepare
    });
    bs.reload(files);
    });

    @@ -75,9 +82,8 @@ module.exports = function(context) {
    baseDir: context.opts.projectRoot,
    directory: true
    },
    files: location + '**/*.*',
    open: false,
    logLevel: 'debug'
    files: location,
    open: false
    }, function(err, bs) {
    var server = bs.options.getIn(['urls', 'external']);
    resolve(Url.resolve(server, 'platforms'));
  6. axemclion created this gist Aug 15, 2015.
    98 changes: 98 additions & 0 deletions browser-sync.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,98 @@
    var path = require('path');
    var fs = require('fs');
    var Url = require('url');

    var debug = console.log.bind(console);

    module.exports = function(context) {
    var npm = context.requireCordovaModule('npm');
    var Q = context.requireCordovaModule('q');
    var glob = context.requireCordovaModule('glob')
    var et = context.requireCordovaModule('elementtree');

    function parseXml(filename) {
    return new et.ElementTree(et.XML(fs.readFileSync(filename, "utf-8").replace(/^\uFEFF/, "")));
    }

    // Installs browser-sync and other packages locally
    function installDependencies() {
    return Q();
    debug('Starting npm');
    return Q.ninvoke(npm, 'load').then(function() {
    debug('Installing dependencies');
    return Q.ninvoke(npm.commands, 'install', ['browser-sync']);
    });
    }

    /**
    * Cordova is usually served from index.html on the device. This function serves changes that to be served from a server instead
    * @param configLocation - The place where platform specific config.xml is located, relative to platforms folder
    * @param hostedPage - Location from where the www/index.html file should be served, relative to platforms folder
    **/
    function changeHost(hostedPage, configLocation) {
    var cwd = path.join(context.opts.projectRoot, 'platforms', configLocation);
    debug('Searching for config files at', cwd);
    return configs = glob.sync('**/config.xml', {
    cwd: cwd
    }).map(function(filename) {
    var filename = path.join(cwd, filename);
    debug('Changing ', filename);
    configXml = parseXml(filename);
    var contentTag = configXml.find('content[@src]');
    if (contentTag) {
    contentTag.attrib.src = hostedPage;
    }
    // Also add allow nav in case of
    var allowNavTag = et.SubElement(configXml.find('.'), 'allow-navigation');
    allowNavTag.set('href', '*');

    fs.writeFileSync(filename, configXml.write({
    indent: 4
    }), "utf-8");
    return filename;
    });
    }

    /**
    * Starts the browser sync server, and when files are changed, does the reload
    * @param location - where to watch
    * @returns location where files are served from
    */
    function browserSyncServer(location) {
    debug('Starting browser-sync server');
    var bs = require('browser-sync');
    return Q.promise(function(resolve, reject, notify) {
    bs.watch('**/*.*', function(event, files) {
    console.log('HERERE', event, files);
    if (event !== 'change') {
    return;
    }
    bs.reload(files);
    });

    bs.init({
    server: {
    baseDir: context.opts.projectRoot,
    directory: true
    },
    files: location + '**/*.*',
    open: false,
    logLevel: 'debug'
    }, function(err, bs) {
    var server = bs.options.getIn(['urls', 'external']);
    resolve(Url.resolve(server, 'platforms'));
    });
    });
    }

    // Main workfow
    return installDependencies().then(function() {
    return browserSyncServer(path.join(context.opts.projectRoot, 'www'));
    }).then(function(server) {
    // TODO - Change host based on platform
    changeHost(server + '/android/assets/www/index.html', 'android/res');
    changeHost(server + '/ios/www/index.html', 'ios');
    });
    };

    // Ensure that you add ws: 'unsafe-inline' to the CSP in index.html