diff --git a/external/builder/fixtures_esprima/umd-expected.js b/external/builder/fixtures_esprima/umd-expected.js new file mode 100644 index 000000000..5d21a466d --- /dev/null +++ b/external/builder/fixtures_esprima/umd-expected.js @@ -0,0 +1,5 @@ +'use strict'; +var aB = require('../a/b.js'); +var cD = require('./d.js'); +var opt; +opt(aB + cD); diff --git a/external/builder/fixtures_esprima/umd.js b/external/builder/fixtures_esprima/umd.js new file mode 100644 index 000000000..605918a14 --- /dev/null +++ b/external/builder/fixtures_esprima/umd.js @@ -0,0 +1,14 @@ +'use strict'; + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define('test', ['exports', 'a/b', 'c/d'], factory); + } else if (typeof exports !== 'undefined') { + factory(exports, require('../a/b.js'), require('./d.js')); + } else { + factory((root.E = {}), root.aB, root.cD); + } +}(this, function (exports, aB, cD, opt) { + +opt(aB + cD); +})); diff --git a/external/builder/preprocessor2.js b/external/builder/preprocessor2.js index 82e15f293..bf22ac64d 100644 --- a/external/builder/preprocessor2.js +++ b/external/builder/preprocessor2.js @@ -201,6 +201,86 @@ function postprocessNode(ctx, node) { block.body.pop(); } break; + case 'Program': + // Checking for a function closure that looks like UMD header. + node.body.some(function (item, index) { + // Is it `(function (root, factory) { ? }(this, function (?) {?}));` ? + if (item.type !== 'ExpressionStatement' || + item.expression.type !== 'CallExpression' || + item.expression.callee.type !== 'FunctionExpression' || + item.expression.callee.params.length !== 2 || + item.expression.arguments.length !== 2 || + item.expression.arguments[0].type !== 'ThisExpression' || + item.expression.arguments[1].type !== 'FunctionExpression') { + return false; + } + var init = item.expression.callee; + // Is init body looks like + // `if (?) { ? } else if (typeof exports !== 'undefined') { ? } ...`? + if (init.body.type !== 'BlockStatement' || + init.body.body.length !== 1 || + init.body.body[0].type !== 'IfStatement') { + return false; + } + var initIf = init.body.body[0]; + if (initIf.alternate.type !== 'IfStatement' || + initIf.alternate.test.type !== 'BinaryExpression' || + initIf.alternate.test.operator !== '!==' || + initIf.alternate.test.left.type !== 'UnaryExpression' || + initIf.alternate.test.left.operator !== 'typeof' || + initIf.alternate.test.left.argument.type !== 'Identifier' || + initIf.alternate.test.left.argument.name !== 'exports' || + initIf.alternate.test.right.type !== 'Literal' || + initIf.alternate.test.right.value !== 'undefined' || + initIf.alternate.consequent.type !== 'BlockStatement') { + return false; + } + var commonJsInit = initIf.alternate.consequent; + // Is commonJsInit `factory(exports, ...)` ? + if (commonJsInit.body.length !== 1 || + commonJsInit.body[0].type !== 'ExpressionStatement' || + commonJsInit.body[0].expression.type !== 'CallExpression' || + commonJsInit.body[0].expression.callee.type !== 'Identifier') { + return false; + } + var commonJsInitArgs = commonJsInit.body[0].expression.arguments; + if (commonJsInitArgs.length === 0 || + commonJsInitArgs[0].type !== 'Identifier' || + commonJsInitArgs[0].name !== 'exports') { + return false; + } + var factory = item.expression.arguments[1]; + // Is factory `function (exports, ....) { ? }` ? + if (factory.params.length === 0 || + factory.params[0].type !== 'Identifier' || + factory.params[0].name !== 'exports' || + factory.body.type !== 'BlockStatement') { + return true; + } + var factoryParams = factory.params; + var factoryBody = factory.body; + + // Remove closure and function and replacing parameters with vars. + node.body.splice(index, 1); + for (var i = 1, ii = factoryParams.length; i < ii; i++) { + var varNode = { + type: 'VariableDeclaration', + 'declarations': [{ + type: 'VariableDeclarator', + id: factoryParams[i], + init: commonJsInitArgs[i] || null, + loc: factoryParams[i].loc + }], + kind: 'var' + }; + node.body.splice(index++, 0, varNode); + } + factoryBody.body.forEach(function (item) { + node.body.splice(index++, 0, item); + }); + return true; + }); + break; } return node; } diff --git a/gulpfile.js b/gulpfile.js index 369e4a057..ab86dacd4 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -90,10 +90,12 @@ function createWebpackConfig(defines, output) { BUNDLE_VERSION: versionInfo.version, BUNDLE_BUILD: versionInfo.commit }); + var licenseHeader = fs.readFileSync('./src/license_header.js').toString(); return { output: output, plugins: [ + new webpack2.BannerPlugin({banner: licenseHeader, raw: true}), new BlockRequirePlugin() ], resolve: { @@ -108,7 +110,7 @@ function createWebpackConfig(defines, output) { loader: path.join(__dirname, 'external/webpack/pdfjsdev-loader.js'), options: { rootPath: __dirname, - saveComments: 'copyright', + saveComments: false, defines: bundleDefines } } diff --git a/src/license_header.js b/src/license_header.js new file mode 100644 index 000000000..c2fb3c8bc --- /dev/null +++ b/src/license_header.js @@ -0,0 +1,14 @@ +/* Copyright 2017 Mozilla Foundation + * + * 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. + */