| /* |
| * |
| * 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. |
| * |
| */ |
| |
| /* |
| * This probably should live in plugman/cli world |
| * Transoforms old require calls to new node-style require calls |
| * the whole thing is fucking bullshit and needs to disappear ASAP |
| */ |
| |
| var fs = require('fs'); |
| var path = require('path'); |
| var util = require('util'); |
| var through = require('through'); |
| var UglifyJS = require('uglify-js'); |
| var os = require('os'); |
| var root = fs.realpathSync(path.join(__dirname, '..', '..')); |
| |
| var requireTr = { |
| |
| init: function(platform) { |
| this.platform = platform; |
| this.modules[platform] = []; |
| }, |
| |
| transform: function(file, platObj) { |
| this.platform = platObj.platform; |
| var data = ''; |
| |
| function write(buf) { |
| data += buf; |
| } |
| |
| function end() { |
| var platform = platObj.platform; |
| // SOME BS pre-transforms |
| if(data.match(/clobbers\('cordova\/plugin\/android\/app/)) { |
| // Checking for '\' from the windows path |
| root = root.replace(/\\/g, '/'); |
| |
| if(file.match(/android\/platform.js$/) || file.match(/android\\platform.js$/)) { |
| data = data.replace(/modulemapper\.clobbers.*\n/, |
| util.format('navigator.app = require("%s/src/legacy-exec/android/plugin/android/app")', root)); |
| } else if (file.match(/amazon-fireos\/platform.js$/) || file.match(/amazon-fireos\\platform.js$/)) { |
| data = data.replace(/modulemapper\.clobbers.*\n/, |
| util.format('navigator.app = require("%s/src/legacy-exec/amazon-fireos/plugin/android/app")', root)); |
| } |
| } |
| |
| if(data.match(/clobbers\('cordova\/exec\/proxy/)) { |
| // Checking for '\' from the windows path |
| root = root.replace(/\\/g, '/'); |
| |
| data = data.replace(/modulemapper\.clobbers.*\n/, |
| util.format('cordova.commandProxy = require("%s/src/common/exec/proxy");', root)); |
| } |
| |
| if(file.match(/FileReader.js$/)) { |
| data = data.replace(/getOriginalSymbol\(this/, |
| 'getOriginalSymbol(window'); |
| } |
| |
| this.queue(_updateRequires(data, platform)); |
| this.queue(null); |
| } |
| |
| return through(write, end); |
| }, |
| hasModule: function(module, platform) { |
| if(this.modules[platform] === undefined) { |
| this.modules[platform] = []; |
| } |
| var platformModules = this.modules[platform]; |
| |
| for(var i = 0, j = platformModules.length ; i < j ; i++) { |
| if(platformModules[i].symbol === module) { |
| return true; |
| } |
| } |
| return false; |
| }, |
| getModules: function(platform) { |
| return this.modules[platform]; |
| }, |
| addModule: function(module, platform) { |
| if(!module || !module.symbol || !module.path) { |
| throw new Error("Can't add module without a symbol and a path"); |
| } |
| this.modules[platform].push(module); |
| }, |
| modules:{}, |
| platform: null |
| } |
| |
| /* |
| * visits AST and modifies all the require('cordova/*') and require('org.apache.cordova.*') |
| */ |
| function _updateRequires(code, platform) { |
| var ast = UglifyJS.parse(code); |
| |
| var before = new UglifyJS.TreeTransformer(function(node, descend) { |
| |
| // check all function calls |
| if(node instanceof UglifyJS.AST_Call) { |
| // check if function call is a require('module') call |
| if(node.expression.name === "require" && node.args.length === 1) { |
| |
| // Uglify is not able to recognize Windows style paths using '\' instead of '/' |
| // So replacing all of the '/' back to Windows '\' |
| if (node.args[0].value !== undefined && node.args[0].value.indexOf(root) !== -1 && process.platform === 'win32') { |
| node.args[0].value = node.args[0].value.replace(/\//g, '\\'); |
| } |
| |
| var module = node.args[0].value; |
| // make sure require only has one argument and that it starts with cordova (old style require.js) |
| if(module !== undefined && |
| module.indexOf("cordova") === 0) { |
| |
| var scriptpath; |
| var cordovajssrc = path.join(process.cwd(), "platforms", platform, "platform_www", "cordova-js-src") |
| |
| |
| // require('cordova') -> cordova.js |
| if(module === "cordova") { |
| scriptPath = node.args[0].value = path.join(root, "src", "cordova_b"); |
| // require('cordova/init') -> common/init |
| } else if(module.match(/cordova\/init/)) { |
| scriptPath = node.args[0].value = module.replace(/cordova\/init/, |
| path.join(root, "src", "common", "init_b")); |
| // android and amazon-fireos have some special require's |
| } else if(module.match(/cordova\/(android|amazon-fireos)\/(.+)/)) { |
| if(fs.existsSync(cordovajssrc)) { |
| //cordova cli project with cordova-js-src in platform |
| scriptPath = node.args[0].value = module.replace(/cordova\/(android|amazon-fireos)\/(.+)/, path.join(cordovajssrc, "android", "$2")); |
| } else { |
| //non cli or no cordova-js-src directory |
| scriptPath = node.args[0].value = module.replace(/cordova\/(android|amazon-fireos)\/(.+)/, path.join(root, "src", "legacy-exec", "$1", "android", "$2")); |
| } |
| // require('cordova/exec') and require('cordova/platform') -> platform's exec/platform |
| } else if(module.match(/cordova\/(platform|exec)$/)) { |
| if(fs.existsSync(cordovajssrc)) { |
| //cordova cli project with cordova-js-src in platform |
| scriptPath = node.args[0].value = module.replace(/cordova\/(platform|exec)/, path.join(cordovajssrc, "$1")); |
| } else { |
| //non cli or no cordova-js-src directory |
| scriptPath = node.args[0].value = module.replace(/cordova\/(platform|exec)/, path.join(root, "src", "legacy-exec", platform, "$1")); |
| } |
| |
| // require('cordova/anything') should be under common/ |
| } else if(module.match(/cordova\/(.+)/)) { |
| scriptPath = node.args[0].value = module.replace(/cordova\/(.+)/, |
| path.join(root, "src", "common", "$1")); |
| } |
| if(requireTr.hasModule(module, platform) === false) { |
| requireTr.addModule({symbol: module, path: scriptPath}, platform); |
| } |
| } |
| else if(module !== undefined && ( module.indexOf("org.apache.cordova") !== -1 || |
| module.indexOf("./") === 0 || module.indexOf("../") === 0 ) ) { |
| var modules = requireTr.getModules(platform); |
| |
| if(module.indexOf("../") === 0){ |
| module = module.replace('../', ''); |
| } |
| if(module.indexOf("./") === 0 ) { |
| module = module.replace('./', ''); |
| } |
| |
| for(var i = 0, j = modules.length ; i < j ; i++) { |
| var regx = new RegExp ("\\."+ module + "$"); |
| if(module === modules[i].symbol || modules[i].symbol.search(regx) != -1) { |
| node.args[0].value = modules[i].path; |
| break; |
| } |
| } |
| } |
| descend(node, this); |
| return node; |
| } |
| } |
| }); |
| |
| ast.transform(before, null); |
| |
| var stream = UglifyJS.OutputStream({beautify:true}); |
| |
| ast.print(stream); |
| |
| return stream.toString(); |
| } |
| |
| |
| module.exports = requireTr; |