Guest User

Untitled

a guest
Jun 21st, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. // Browser-Sync support for Cordova projects
  2. // To use this, add the following snippet as a after_run hook using something like
  3. // <hook type="after_prepare" src="hooks/browser-sync.js" />
  4. // Add under default-src ws: 'unsafe-inline' to the CSP in index.html
  5. // Add under script-src * (you can whitelist the host for livereload, but this is a shortcut).
  6. // Don't forget to remove them in prod!
  7. // Then run: cordova run -- --live-reload
  8. // Changing anything in www/ will live-reload the cordova app on emulator/device
  9.  
  10. module.exports = function(context) {
  11.  
  12. if (typeof context.opts.options["--browser-sync-mode"] !== 'undefined') {
  13. // Prepare was called by this script, so don't run the script again
  14. return;
  15. }
  16.  
  17. if (context.opts.options.argv.indexOf('--live-reload') === -1) {
  18. // --live-reload switch was not provided
  19. return;
  20. }
  21.  
  22. var path = require('path');
  23. var fs = require('fs');
  24. var Url = require('url');
  25.  
  26. var debug = console.log.bind(console);
  27.  
  28. var npm = context.requireCordovaModule('npm');
  29. var Q = context.requireCordovaModule('q');
  30. var glob = context.requireCordovaModule('glob')
  31. var et = context.requireCordovaModule('elementtree');
  32.  
  33. function parseXml(filename) {
  34. return new et.ElementTree(et.XML(fs.readFileSync(filename, "utf-8").replace(/^\uFEFF/, "")));
  35. }
  36.  
  37. // Installs browser-sync and other packages locally
  38. function installDependencies() {
  39. return Q();
  40. debug('Starting npm');
  41. return Q.ninvoke(npm, 'load').then(function() {
  42. debug('Installing dependencies');
  43. return Q.ninvoke(npm.commands, 'install', ['browser-sync']);
  44. });
  45. }
  46.  
  47. /**
  48. * Cordova is usually served from index.html on the device. This function serves changes that to be served from a server instead
  49. * @param configLocation - The place where platform specific config.xml is located, relative to platforms folder
  50. * @param hostedPage - Location from where the www/index.html file should be served, relative to platforms folder
  51. **/
  52. function changeHost(hostedPage, configLocation) {
  53. var cwd = path.join(context.opts.projectRoot, 'platforms', configLocation);
  54. debug('Searching for config files at', cwd);
  55. return configs = glob.sync('**/config.xml', {
  56. cwd: cwd
  57. }).map(function(filename) {
  58. debug(`Found config.xml: ${filename}`);
  59. var filename = path.join(cwd, filename);
  60. debug('Changing ', filename);
  61. configXml = parseXml(filename);
  62. var contentTag = configXml.find('content[@src]');
  63. if (contentTag) {
  64. contentTag.attrib.src = hostedPage;
  65. }
  66. // Also add allow nav in case of
  67. var allowNavTag = et.SubElement(configXml.find('.'), 'allow-navigation');
  68. allowNavTag.set('href', '*');
  69. fs.writeFileSync(filename, configXml.write({
  70. indent: 4
  71. }), "utf-8");
  72. return filename;
  73. });
  74. }
  75.  
  76. /**
  77. * Starts the browser sync server, and when files are changed, does the reload
  78. * @param location - where to watch
  79. * @returns location where files are served from
  80. */
  81. function browserSyncServer(location) {
  82. debug('Starting browser-sync server');
  83. location = location + '**/*.*'
  84. return Q.promise(function(resolve, reject, notify) {
  85. var bs = require('browser-sync').create();
  86. bs.watch(location, function(event, files) {
  87. if (event !== 'change') {
  88. return;
  89. }
  90. // TODO Prepare only the platform that was run
  91. context.cordova.prepare({
  92. options: { "--browser-sync-mode": true } // to indicate who is calling prepare
  93. });
  94. bs.reload(files);
  95. });
  96.  
  97. bs.init({
  98. server: {
  99. baseDir: context.opts.projectRoot,
  100. directory: true
  101. },
  102. files: location,
  103. open: false,
  104. snippetOptions: {
  105. rule: {
  106. match: /<\/body>/i,
  107. fn: function(snippet, match) {
  108. return '<script>window.__karma__=true</script>' + snippet + match;
  109. }
  110. }
  111. },
  112. minify: false
  113. }, function(err, bs) {
  114. var server = bs.options.getIn(['urls', 'external']);
  115. resolve(Url.resolve(server, 'platforms'));
  116. });
  117. });
  118. }
  119.  
  120. // Main workfow
  121. return installDependencies().then(function() {
  122. const projectRoot = path.join(context.opts.projectRoot, 'www/');
  123. return browserSyncServer(projectRoot);
  124. }).then(function(server) {
  125. // TODO - Change host based on platform
  126. changeHost(server + '/android/assets/www/index.html', 'android/res/xml');
  127. changeHost(server + '/ios/www/index.html', 'ios');
  128. });
  129. };
Add Comment
Please, Sign In to add comment