diff --git a/Gruntfile.js b/Gruntfile.js index bad8b247..6a7dd70a 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -42,8 +42,10 @@ module.exports = function (grunt) { grunt.registerTask("inline", "Compiles a production build of CyberChef into a single, portable web page.", - runInliner); + ["webpack:webInline", "runInliner", "clean:inlineScripts"]); + + grunt.registerTask("runInliner", runInliner); grunt.registerTask("doc", "docs"); grunt.registerTask("tests", "test"); grunt.registerTask("lint", "eslint"); @@ -107,7 +109,7 @@ module.exports = function (grunt) { let entryModules = {}; fs.readdirSync(path).forEach(file => { - if (file !== "Default.js") + if (file !== "Default.js" && file !== "OpModules.js") entryModules[file.split(".js")[0]] = path + file; }); @@ -121,6 +123,7 @@ module.exports = function (grunt) { test: ["build/test/*"], node: ["build/node/*"], docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"], + inlineScripts: ["build/prod/scripts.js"] }, eslint: { options: { @@ -166,6 +169,43 @@ module.exports = function (grunt) { entry: Object.assign({ main: "./src/web/index.js" }, moduleEntryPoints), + output: { + path: __dirname + "/build/prod" + }, + resolve: { + alias: { + "./config/modules/OpModules.js": "./config/modules/Default.js" + } + }, + plugins: [ + new webpack.DefinePlugin(BUILD_CONSTANTS), + new webpack.optimize.UglifyJsPlugin({ + compress: { + "screw_ie8": true, + "dead_code": true, + "unused": true, + "warnings": false + }, + comments: false, + }), + new HtmlWebpackPlugin({ + filename: "index.html", + template: "./src/web/html/index.html", + chunks: ["main"], + compileTime: compileTime, + version: pkg.version, + minify: { + removeComments: true, + collapseWhitespace: true, + minifyJS: true, + minifyCSS: true + } + }), + ] + }, + webInline: { + target: "web", + entry: "./src/web/index.js", output: { filename: "scripts.js", path: __dirname + "/build/prod" @@ -181,23 +221,9 @@ module.exports = function (grunt) { }, comments: false, }), - new HtmlWebpackPlugin({ // Main version - filename: "index.html", - template: "./src/web/html/index.html", - chunks: ["main"], - compileTime: compileTime, - version: pkg.version, - minify: { - removeComments: true, - collapseWhitespace: true, - minifyJS: true, - minifyCSS: true - } - }), - new HtmlWebpackPlugin({ // Inline version + new HtmlWebpackPlugin({ filename: "cyberchef.htm", template: "./src/web/html/index.html", - chunks: ["main"], compileTime: compileTime, version: pkg.version, inline: true, @@ -243,6 +269,11 @@ module.exports = function (grunt) { entry: Object.assign({ main: "./src/web/index.js" }, moduleEntryPoints), + resolve: { + alias: { + "./config/modules/OpModules.js": "./config/modules/Default.js" + } + }, plugins: [ new webpack.DefinePlugin(BUILD_CONSTANTS), new HtmlWebpackPlugin({ diff --git a/src/core/ChefWorker.js b/src/core/ChefWorker.js index 2f0a79e0..b5a6c4fb 100644 --- a/src/core/ChefWorker.js +++ b/src/core/ChefWorker.js @@ -46,6 +46,11 @@ self.addEventListener("message", function(e) { case "silentBake": silentBake(e.data.data); break; + case "docURL": + // Used to set the URL of the current document so that scripts can be + // imported into an inline worker. + self.docURL = e.data.data; + break; default: break; } @@ -107,7 +112,7 @@ function loadRequiredModules(recipeConfig) { if (!OpModules.hasOwnProperty(module)) { console.log("Loading module " + module); - self.importScripts(module + ".js"); + self.importScripts(self.docURL + "/" + module + ".js"); } }); } diff --git a/src/core/Operation.js b/src/core/Operation.js index d671df1f..4c7bd57e 100755 --- a/src/core/Operation.js +++ b/src/core/Operation.js @@ -1,7 +1,7 @@ import Dish from "./Dish.js"; import Ingredient from "./Ingredient.js"; import OperationConfig from "value-loader?name=conf!./config/OperationConfig.js"; -import OpModules from "./config/modules/Default.js"; +import OpModules from "./config/modules/OpModules.js"; /** diff --git a/src/core/config/modules/OpModules.js b/src/core/config/modules/OpModules.js new file mode 100644 index 00000000..831a0e27 --- /dev/null +++ b/src/core/config/modules/OpModules.js @@ -0,0 +1,37 @@ +/** + * Imports all modules for builds which do not load modules separately. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import OpModules from "./Default.js"; +import CharEncModule from "./CharEnc.js"; +import CipherModule from "./Ciphers.js"; +import CodeModule from "./Code.js"; +import CompressionModule from "./Compression.js"; +import DiffModule from "./Diff.js"; +import EncodingModule from "./Encodings.js"; +import HashingModule from "./Hashing.js"; +import HTTPModule from "./HTTP.js"; +import ImageModule from "./Image.js"; +import JSBNModule from "./JSBN.js"; +import PublicKeyModule from "./PublicKey.js"; + +Object.assign( + OpModules, + CharEncModule, + CipherModule, + CodeModule, + CompressionModule, + DiffModule, + EncodingModule, + HashingModule, + HTTPModule, + ImageModule, + JSBNModule, + PublicKeyModule +); + +export default OpModules; diff --git a/src/web/App.js b/src/web/App.js index e73cbe1b..4c9a819d 100755 --- a/src/web/App.js +++ b/src/web/App.js @@ -1,5 +1,5 @@ import Utils from "../core/Utils.js"; -import ChefWorker from "worker-loader!../core/ChefWorker.js"; +import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js"; import Manager from "./Manager.js"; import HTMLCategory from "./HTMLCategory.js"; import HTMLOperation from "./HTMLOperation.js"; @@ -64,6 +64,13 @@ App.prototype.setup = function() { App.prototype.registerChefWorker = function() { this.chefWorker = new ChefWorker(); this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this)); + + let docURL = document.location.href.split(/[#?]/)[0]; + const index = docURL.lastIndexOf("/"); + if (index > 0) { + docURL = docURL.substring(0, index); + } + this.chefWorker.postMessage({"action": "docURL", "data": docURL}); };