diff --git a/.babelrc b/.babelrc
new file mode 100644
index 00000000..12e02c0e
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ ["env", {
+ "targets": {
+ "chrome": 40,
+ "firefox": 35,
+ "edge": 14
+ },
+ "modules": false
+ }]
+ ]
+}
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..4277ae0f
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+src/core/lib/**
diff --git a/src/js/.eslintrc.json b/.eslintrc.json
similarity index 70%
rename from src/js/.eslintrc.json
rename to .eslintrc.json
index 7ea169f3..8632d2e6 100755
--- a/src/js/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,15 +1,15 @@
{
"parserOptions": {
- "ecmaVersion": 6,
+ "ecmaVersion": 8,
"ecmaFeatures": {
"impliedStrict": true
- }
+ },
+ "sourceType": "module"
},
"env": {
"browser": true,
- "jquery": true,
"es6": true,
- "node": false
+ "node": true
},
"extends": "eslint:recommended",
"rules": {
@@ -28,7 +28,11 @@
// modify rules from base configurations
"no-unused-vars": ["error", {
"args": "none",
- "vars": "local"
+ "vars": "local",
+ // Allow vars that start with a capital letter to be unused.
+ // This is mainly for exported module names which are useful to indicate
+ // the name of the module and may be used to refer to itself in future.
+ "varsIgnorePattern": "^[A-Z]"
}],
"no-empty": ["error", {
"allowEmptyCatch": true
@@ -80,39 +84,15 @@
}],
"no-whitespace-before-property": "error",
"operator-linebreak": ["error", "after"],
- "space-in-parens": "error"
+ "space-in-parens": "error",
+ "no-var": "error"
},
"globals": {
- /* core/* */
- "Chef": false,
- "Dish": false,
- "Recipe": false,
- "Ingredient": false,
- "Operation": false,
- "Utils": false,
-
- /* config/* */
- "Categories": false,
- "OperationConfig": false,
-
- /* views/html/* */
- "HTMLApp": false,
- "HTMLCategory": false,
- "HTMLOperation": false,
- "HTMLIngredient": false,
- "Manager": false,
- "ControlsWaiter": false,
- "HighlighterWaiter": false,
- "InputWaiter": false,
- "OperationsWaiter": false,
- "OptionsWaiter": false,
- "OutputWaiter": false,
- "RecipeWaiter": false,
- "SeasonalWaiter": false,
- "WindowWaiter": false,
+ "$": false,
+ "jQuery": false,
+ "moment": false,
- /* tests */
- "TestRegister": false,
- "TestRunner": false
+ "COMPILE_TIME": false,
+ "COMPILE_MSG": false
}
}
diff --git a/.gitignore b/.gitignore
index 5697a2cc..deafd4da 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
node_modules
npm-debug.log
-build/*
+travis.log
+build
docs/*
!docs/*.conf.json
!docs/*.ico
diff --git a/.npmignore b/.npmignore
new file mode 100755
index 00000000..6f32ec06
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,8 @@
+node_modules
+npm-debug.log
+travis.log
+build/*
+!build/node
+docs
+.vscode
+.github
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..5f039562
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,42 @@
+language: node_js
+node_js:
+ - node
+install: npm install
+before_script:
+ - npm install -g grunt
+script:
+ - grunt lint
+ - grunt test
+ - grunt docs
+ - grunt node
+ - grunt prod --msg="$COMPILE_MSG"
+before_deploy:
+ - grunt copy:ghPages
+deploy:
+ - provider: pages
+ skip_cleanup: true
+ github_token: $GITHUB_TOKEN
+ local_dir: build/prod/
+ target_branch: gh-pages
+ on:
+ repo: gchq/CyberChef
+ branch: master
+ - provider: releases
+ skip_cleaup: true
+ api_key:
+ secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
+ file:
+ - build/prod/cyberchef.htm
+ - build/node/CyberChef.js
+ on:
+ repo: gchq/CyberChef
+ tags: true
+ - provider: npm
+ skip_cleanup: true
+ email: "n1474335@gmail.com"
+ api_key:
+ secure: "Z3FK6bm4RfQEIRXZ1lBNzQkVIoHpivThr9U+XBHmsBgIfdrK/XUnzs/slugo+NIz8nPiGmMx4gxyJonBCLHDGb1ysky2aEWTl26c0teaF4DeQEjWC1ZaGzv8MV1/GkUamnr1qouXjyUhyEAp33rd8ccN9Rq3QNYB/qLDcA9/FCme7JCW6sCd4zWO0LGEYMJEMc2FzAUkqhqsI05hegGhSDgKXRn5PmLARek4yHD+Hx7pstaTeQIy0WoGJjdzoB3iJIMmo/hWZGzZafktUOh223c5qzx4zMpDRNmMngBUw6R94nKd4KvplYRgB87Y3L/aiVU4CF+axwLmK8RPaC1wbJnlHf06zxHPdiFmsY/zKPpNel+nOnxzRrF5l2KMU4TU6gug3s9Jnzp9T5UMfhp0jW3YkxHGeuOPOeE1i0lTUWUGWrPHLQquAhLfkr2zxaU4ETk/y85hq9W4LAy0ENEDVXX2jP7FnI4Z1fdpmljpmVNJR+outPg6t+Coqgvil7v7XpMtDm8lKQanVYuxwmkb/ncOWFRWuM2j5zIEg3CHnFDcJ9bYrfKRg0b0tb/2BWD14pQnV76goVwzJQYVzdPc8TKIYJw2BZ1Nh9c0iruQVebe/6l1FX9fDCkz8VMmltni61/LxZrf8y0NT1YaU1raeNY2dH5UWvEa9p72FPMI6Eg="
+ on:
+ tags: true
+ branch: master
+
diff --git a/Gruntfile.js b/Gruntfile.js
index c9f97fb9..c3b0e49f 100755
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,38 +1,40 @@
-/* eslint-env node */
+const webpack = require("webpack");
+const ExtractTextPlugin = require("extract-text-webpack-plugin");
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+const Inliner = require("web-resource-inliner");
-module.exports = function(grunt) {
+module.exports = function (grunt) {
grunt.file.defaultEncoding = "utf8";
grunt.file.preserveBOM = false;
// Tasks
grunt.registerTask("dev",
"A persistent task which creates a development build whenever source files are modified.",
- ["clean:dev", "concat:css", "concat:js", "copy:htmlDev", "copy:staticDev", "chmod:build", "watch"]);
+ ["clean:dev", "webpack:webDev"]);
+
+ grunt.registerTask("node",
+ "Compiles CyberChef into a single NodeJS module.",
+ ["clean:node", "webpack:node", "chmod:build"]);
grunt.registerTask("test",
"A task which runs all the tests in test/tests.",
- ["clean:test", "concat:jsTest", "copy:htmlTest", "chmod:build", "execute:test"]);
-
- grunt.registerTask("prod",
- "Creates a production-ready build. Use the --msg flag to add a compile message.",
- ["eslint", "exec:stats", "clean", "jsdoc", "concat", "copy:htmlDev", "copy:htmlProd", "copy:htmlInline",
- "copy:staticDev", "copy:staticProd", "cssmin", "uglify:prod", "inline", "htmlmin", "chmod", "test"]);
+ ["clean:test", "webpack:tests", "execute:test"]);
grunt.registerTask("docs",
"Compiles documentation in the /docs directory.",
["clean:docs", "jsdoc", "chmod:docs"]);
- grunt.registerTask("stats",
- "Provides statistics about the code base such as how many lines there are as well as details of file sizes before and after compression.",
- ["concat:js", "uglify:prod", "exec:stats", "exec:repoSize", "exec:displayStats"]);
-
- grunt.registerTask("release",
- "Prepares and deploys a production version of CyberChef to the gh-pages branch.",
- ["copy:ghPages", "exec:deployGhPages"]);
+ grunt.registerTask("prod",
+ "Creates a production-ready build. Use the --msg flag to add a compile message.",
+ ["eslint", "clean:prod", "webpack:webProd", "inline", "chmod"]);
grunt.registerTask("default",
- "Lints the code base and shows stats",
- ["eslint", "exec:stats", "exec:displayStats"]);
+ "Lints the code base",
+ ["eslint", "exec:repoSize"]);
+
+ grunt.registerTask("inline",
+ "Compiles a production build of CyberChef into a single, portable web page.",
+ runInliner);
grunt.registerTask("doc", "docs");
grunt.registerTask("tests", "test");
@@ -41,179 +43,83 @@ module.exports = function(grunt) {
// Load tasks provided by each plugin
grunt.loadNpmTasks("grunt-eslint");
+ grunt.loadNpmTasks("grunt-webpack");
grunt.loadNpmTasks("grunt-jsdoc");
grunt.loadNpmTasks("grunt-contrib-clean");
- grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-copy");
- grunt.loadNpmTasks("grunt-contrib-uglify");
- grunt.loadNpmTasks("grunt-contrib-cssmin");
- grunt.loadNpmTasks("grunt-contrib-htmlmin");
- grunt.loadNpmTasks("grunt-inline-alt");
grunt.loadNpmTasks("grunt-chmod");
grunt.loadNpmTasks("grunt-exec");
grunt.loadNpmTasks("grunt-execute");
- grunt.loadNpmTasks("grunt-contrib-watch");
+ grunt.loadNpmTasks("grunt-accessibility");
- // JS includes
- var jsIncludes = [
- // Third party framework libraries
- "src/js/lib/jquery-2.1.1.js",
- "src/js/lib/bootstrap-3.3.6.js",
- "src/js/lib/split.js",
- "src/js/lib/bootstrap-switch.js",
- "src/js/lib/yahoo.js",
- "src/js/lib/snowfall.jquery.js",
-
- // Third party operation libraries
- "src/js/lib/cryptojs/core.js",
- "src/js/lib/cryptojs/x64-core.js",
- "src/js/lib/cryptojs/enc-base64.js",
- "src/js/lib/cryptojs/enc-utf16.js",
- "src/js/lib/cryptojs/md5.js",
- "src/js/lib/cryptojs/evpkdf.js",
- "src/js/lib/cryptojs/cipher-core.js",
- "src/js/lib/cryptojs/mode-cfb.js",
- "src/js/lib/cryptojs/mode-ctr-gladman.js",
- "src/js/lib/cryptojs/mode-ctr.js",
- "src/js/lib/cryptojs/mode-ecb.js",
- "src/js/lib/cryptojs/mode-ofb.js",
- "src/js/lib/cryptojs/format-hex.js",
- "src/js/lib/cryptojs/lib-typedarrays.js",
- "src/js/lib/cryptojs/pad-ansix923.js",
- "src/js/lib/cryptojs/pad-iso10126.js",
- "src/js/lib/cryptojs/pad-iso97971.js",
- "src/js/lib/cryptojs/pad-nopadding.js",
- "src/js/lib/cryptojs/pad-zeropadding.js",
- "src/js/lib/cryptojs/aes.js",
- "src/js/lib/cryptojs/hmac.js",
- "src/js/lib/cryptojs/rabbit-legacy.js",
- "src/js/lib/cryptojs/rabbit.js",
- "src/js/lib/cryptojs/ripemd160.js",
- "src/js/lib/cryptojs/sha1.js",
- "src/js/lib/cryptojs/sha256.js",
- "src/js/lib/cryptojs/sha224.js",
- "src/js/lib/cryptojs/sha512.js",
- "src/js/lib/cryptojs/sha384.js",
- "src/js/lib/cryptojs/sha3.js",
- "src/js/lib/cryptojs/tripledes.js",
- "src/js/lib/cryptojs/rc4.js",
- "src/js/lib/cryptojs/pbkdf2.js",
- "src/js/lib/cryptoapi/crypto-api.js",
- "src/js/lib/cryptoapi/hasher.md2.js",
- "src/js/lib/cryptoapi/hasher.md4.js",
- "src/js/lib/cryptoapi/hasher.sha0.js",
- "src/js/lib/jsbn/jsbn.js",
- "src/js/lib/jsbn/jsbn2.js",
- "src/js/lib/jsbn/base64.js",
- "src/js/lib/jsbn/ec.js",
- "src/js/lib/jsbn/prng4.js",
- "src/js/lib/jsbn/rng.js",
- "src/js/lib/jsbn/rsa.js",
- "src/js/lib/jsbn/sec.js",
- "src/js/lib/jsrasign/asn1-1.0.js",
- "src/js/lib/jsrasign/asn1hex-1.1.js",
- "src/js/lib/jsrasign/asn1x509-1.0.js",
- "src/js/lib/jsrasign/base64x-1.1.js",
- "src/js/lib/jsrasign/crypto-1.1.js",
- "src/js/lib/jsrasign/dsa-modified-1.0.js",
- "src/js/lib/jsrasign/ecdsa-modified-1.0.js",
- "src/js/lib/jsrasign/ecparam-1.0.js",
- "src/js/lib/jsrasign/keyutil-1.0.js",
- "src/js/lib/jsrasign/x509-1.1.js",
- "src/js/lib/blowfish.dojo.js",
- "src/js/lib/rawdeflate.js",
- "src/js/lib/rawinflate.js",
- "src/js/lib/zip.js",
- "src/js/lib/unzip.js",
- "src/js/lib/zlib_and_gzip.js",
- "src/js/lib/bzip2.js",
- "src/js/lib/punycode.js",
- "src/js/lib/uas_parser.js",
- "src/js/lib/esprima.js",
- "src/js/lib/escodegen.browser.js",
- "src/js/lib/esmangle.min.js",
- "src/js/lib/diff.js",
- "src/js/lib/moment.js",
- "src/js/lib/moment-timezone.js",
- "src/js/lib/prettify.js",
- "src/js/lib/vkbeautify.js",
- "src/js/lib/Sortable.js",
- "src/js/lib/bootstrap-colorpicker.js",
- "src/js/lib/es6-promise.auto.js",
- "src/js/lib/xpath.js",
-
- // Custom libraries
- "src/js/lib/canvascomponents.js",
-
- // Utility functions
- "src/js/core/Utils.js",
-
- // Operation objects
- "src/js/operations/*.js",
-
- // Core framework objects
- "src/js/core/*.js",
- "src/js/config/Categories.js",
- "src/js/config/OperationConfig.js",
-
- // HTML view objects
- "src/js/views/html/*.js",
- "!src/js/views/html/main.js",
-
- ];
-
- var jsAppFiles = jsIncludes.concat([
- // Start the main app!
- "src/js/views/html/main.js",
- ]);
-
- var jsTestFiles = jsIncludes.concat([
- "test/TestRegister.js",
- "test/tests/**/*.js",
- "test/TestRunner.js",
- ]);
-
- var banner = '/**\n\
- * CyberChef - The Cyber Swiss Army Knife\n\
- *\n\
- * @copyright Crown Copyright 2016\n\
- * @license Apache-2.0\n\
- *\n\
- * Copyright 2016 Crown Copyright\n\
- *\n\
- * Licensed under the Apache License, Version 2.0 (the "License");\n\
- * you may not use this file except in compliance with the License.\n\
- * You may obtain a copy of the License at\n\
- *\n\
- * http://www.apache.org/licenses/LICENSE-2.0\n\
- *\n\
- * Unless required by applicable law or agreed to in writing, software\n\
- * distributed under the License is distributed on an "AS IS" BASIS,\n\
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\
- * See the License for the specific language governing permissions and\n\
- * limitations under the License.\n\
- */\n';
-
- var templateOptions = {
- data: {
- compileTime: grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC",
- compileMsg: grunt.option("compile-msg") || grunt.option("msg") || "",
- codebaseStats: grunt.file.read("src/static/stats.txt").split("\n").join("
")
- }
- };
-
// Project configuration
+ const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
+ banner = "/**\n" +
+ "* CyberChef - The Cyber Swiss Army Knife\n" +
+ "*\n" +
+ "* @copyright Crown Copyright 2016\n" +
+ "* @license Apache-2.0\n" +
+ "*\n" +
+ "* Copyright 2016 Crown Copyright\n" +
+ "*\n" +
+ '* Licensed under the Apache License, Version 2.0 (the "License");\n' +
+ "* you may not use this file except in compliance with the License.\n" +
+ "* You may obtain a copy of the License at\n" +
+ "*\n" +
+ "* http://www.apache.org/licenses/LICENSE-2.0\n" +
+ "*\n" +
+ "* Unless required by applicable law or agreed to in writing, software\n" +
+ '* distributed under the License is distributed on an "AS IS" BASIS,\n' +
+ "* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
+ "* See the License for the specific language governing permissions and\n" +
+ "* limitations under the License.\n" +
+ "*/\n",
+ pkg = grunt.file.readJSON("package.json");
+
+ /**
+ * Compiles a production build of CyberChef into a single, portable web page.
+ */
+ function runInliner() {
+ const done = this.async();
+ Inliner.html({
+ relativeTo: "build/prod/",
+ fileContent: grunt.file.read("build/prod/cyberchef.htm"),
+ images: true,
+ svgs: true,
+ scripts: true,
+ links: true,
+ strict: true
+ }, function(error, result) {
+ if (error) {
+ if (error instanceof Error) {
+ done(error);
+ } else {
+ done(new Error(error));
+ }
+ } else {
+ grunt.file.write("build/prod/cyberchef.htm", result);
+ done(true);
+ }
+ });
+ }
+
grunt.initConfig({
+ clean: {
+ dev: ["build/dev/*"],
+ prod: ["build/prod/*"],
+ test: ["build/test/*"],
+ node: ["build/node/*"],
+ docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
+ },
eslint: {
options: {
- configFile: "src/js/.eslintrc.json"
+ configFile: "./.eslintrc.json"
},
- gruntfile: ["Gruntfile.js"],
- core: ["src/js/core/**/*.js"],
- config: ["src/js/config/**/*.js"],
- views: ["src/js/views/**/*.js"],
- operations: ["src/js/operations/**/*.js"],
+ configs: ["Gruntfile.js"],
+ core: ["src/core/**/*.js", "!src/core/lib/**/*"],
+ web: ["src/web/**/*.js"],
+ node: ["src/node/**/*.js"],
tests: ["test/**/*.js"],
},
jsdoc: {
@@ -226,210 +132,203 @@ module.exports = function(grunt) {
},
all: {
src: [
- "src/js/**/*.js",
- "!src/js/lib/**/*",
+ "src/**/*.js",
+ "!src/core/lib/**/*",
],
}
},
- clean: {
- dev: ["build/dev/*"],
- prod: ["build/prod/*"],
- test: ["build/test/*"],
- docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
- },
- concat: {
+ accessibility: {
options: {
- process: templateOptions
+ accessibilityLevel: "WCAG2A",
+ verbose: false,
+ ignore: [
+ "WCAG2A.Principle1.Guideline1_3.1_3_1.H42.2"
+ ]
},
- css: {
- options: {
- banner: banner.replace(/\/\*\*/g, "/*!"),
- process: function(content, srcpath) {
- // Change special comments from /** to /*! to comply with cssmin
- content = content.replace(/^\/\*\* /g, "/*! ");
- return grunt.template.process(content);
+ test: {
+ src: ["build/**/*.html"]
+ }
+ },
+ webpack: {
+ options: {
+ plugins: [
+ new webpack.ProvidePlugin({
+ $: "jquery",
+ jQuery: "jquery",
+ moment: "moment-timezone"
+ }),
+ new webpack.BannerPlugin({
+ banner: banner,
+ raw: true,
+ entryOnly: true
+ }),
+ new webpack.DefinePlugin({
+ COMPILE_TIME: JSON.stringify(compileTime),
+ COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || "")
+ }),
+ new ExtractTextPlugin("styles.css"),
+ ],
+ resolve: {
+ alias: {
+ jquery: "jquery/src/jquery"
}
},
- src: [
- "src/css/lib/**/*.css",
- "src/css/structure/**/*.css",
- //"src/css/themes/classic.css"
- "src/css/themes/orange.css"
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ loader: "babel-loader?compact=false"
+ },
+ {
+ test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ use: [
+ { loader: "css-loader?minimize" },
+ { loader: "postcss-loader" },
+ ]
+ })
+ },
+ {
+ test: /\.less$/,
+ use: ExtractTextPlugin.extract({
+ use: [
+ { loader: "css-loader?minimize" },
+ { loader: "postcss-loader" },
+ { loader: "less-loader" }
+ ]
+ })
+ },
+ {
+ test: /\.(ico|eot|ttf|woff|woff2)$/,
+ loader: "url-loader",
+ options: {
+ limit: 10000
+ }
+ },
+ { // First party images are saved as files to be cached
+ test: /\.(png|jpg|gif|svg)$/,
+ exclude: /node_modules/,
+ loader: "file-loader",
+ options: {
+ name: "images/[name].[ext]"
+ }
+ },
+ { // Third party images are inlined
+ test: /\.(png|jpg|gif|svg)$/,
+ exclude: /web\/static/,
+ loader: "url-loader",
+ options: {
+ limit: 10000
+ }
+ },
+ ]
+ },
+ stats: {
+ children: false,
+ warningsFilter: /source-map/
+ }
+ },
+ webDev: {
+ target: "web",
+ entry: "./src/web/index.js",
+ output: {
+ filename: "scripts.js",
+ path: __dirname + "/build/dev"
+ },
+ plugins: [
+ new HtmlWebpackPlugin({
+ filename: "index.html",
+ template: "./src/web/html/index.html",
+ compileTime: compileTime,
+ version: pkg.version,
+ })
],
- dest: "build/dev/styles.css"
+ watch: true
},
- js: {
- options: {
- banner: '"use strict";\n'
+ webProd: {
+ target: "web",
+ entry: "./src/web/index.js",
+ output: {
+ filename: "scripts.js",
+ path: __dirname + "/build/prod"
},
- src: jsAppFiles,
- dest: "build/dev/scripts.js"
+ plugins: [
+ new webpack.optimize.UglifyJsPlugin({
+ compress: {
+ "screw_ie8": true,
+ "dead_code": true,
+ "unused": true,
+ "warnings": false
+ },
+ comments: false,
+ }),
+ new HtmlWebpackPlugin({ // Main version
+ filename: "index.html",
+ template: "./src/web/html/index.html",
+ compileTime: compileTime,
+ version: pkg.version,
+ minify: {
+ removeComments: true,
+ collapseWhitespace: true,
+ minifyJS: true,
+ minifyCSS: true
+ }
+ }),
+ new HtmlWebpackPlugin({ // Inline version
+ filename: "cyberchef.htm",
+ template: "./src/web/html/index.html",
+ compileTime: compileTime,
+ version: pkg.version,
+ inline: true,
+ minify: {
+ removeComments: true,
+ collapseWhitespace: true,
+ minifyJS: true,
+ minifyCSS: true
+ }
+ }),
+ ]
},
- jsTest: {
- options: {
- banner: '"use strict";\n'
- },
- src: jsTestFiles,
- dest: "build/test/tests.js"
+ tests: {
+ target: "node",
+ entry: "./test/index.js",
+ output: {
+ filename: "index.js",
+ path: __dirname + "/build/test"
+ }
+ },
+ node: {
+ target: "node",
+ entry: "./src/node/index.js",
+ output: {
+ filename: "CyberChef.js",
+ path: __dirname + "/build/node",
+ library: "CyberChef",
+ libraryTarget: "commonjs2"
+ }
}
},
copy: {
- htmlDev: {
- options: {
- process: function(content, srcpath) {
- return grunt.template.process(content, templateOptions);
- }
- },
- src: "src/html/index.html",
- dest: "build/dev/index.html"
- },
- htmlTest: {
- src: "test/test.html",
- dest: "build/test/index.html"
- },
- htmlProd: {
- options: {
- process: function(content, srcpath) {
- return grunt.template.process(content, templateOptions);
- }
- },
- src: "src/html/index.html",
- dest: "build/prod/index.html"
- },
- htmlInline: {
- options: {
- process: function(content, srcpath) {
- // TODO: Do all this in Jade
- content = content.replace(
- 'Download CyberChef
',
- 'Compile time: ' + grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC");
- return grunt.template.process(content, templateOptions);
- }
- },
- src: "src/html/index.html",
- dest: "build/prod/cyberchef.htm"
- },
- staticDev: {
- files: [
- {
- expand: true,
- cwd: "src/static/",
- src: [
- "**/*",
- "**/.*",
- "!stats.txt",
- "!ga.html"
- ],
- dest: "build/dev/"
- }
- ]
- },
- staticProd: {
- files: [
- {
- expand: true,
- cwd: "src/static/",
- src: [
- "**/*",
- "**/.*",
- "!stats.txt",
- "!ga.html"
- ],
- dest: "build/prod/"
- }
- ]
- },
ghPages: {
options: {
- process: function(content, srcpath) {
+ process: function (content) {
// Add Google Analytics code to index.html
content = content.replace("