diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7baeda87..8738d2fc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -16,7 +16,7 @@ pool: steps: - task: NodeTool@0 inputs: - versionSpec: '10.x' + versionSpec: '24.x' displayName: 'Install Node.js' - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3 diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..4a42b74b --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,55 @@ +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { + ignores: [ + "build/**", + "target/**", + "node_modules/**", + "src/**/*.d.ts", + // Copies sourced from WebClipper_Internal via the copyInternal gulp + // task (basename + "_internal"). Lint those in their own repo. + "src/scripts/**/*_internal.ts", + "src/scripts/**/*_internal.tsx", + "src/scripts/definitions/custom/aria-web-telemetry-*.d_internal.ts" + ] + }, + { + files: ["src/**/*.ts", "src/**/*.tsx"], + languageOptions: { + parser: tseslint.parser, + ecmaVersion: 2022, + sourceType: "module", + parserOptions: { + project: "./tsconfig.json", + tsconfigRootDir: import.meta.dirname + } + }, + plugins: { + "@typescript-eslint": tseslint.plugin + }, + rules: { + "spaced-comment": ["error", "always"], + "curly": "error", + "eol-last": "error", + "indent": ["error", "tab", { "SwitchCase": 1 }], + "no-multiple-empty-lines": ["error", { "max": 1 }], + "no-console": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-shadow": "error", + "dot-notation": "error", + "no-fallthrough": "error", + "no-trailing-spaces": "error", + "no-unreachable": "error", + "@typescript-eslint/no-unused-expressions": ["error", { "allowTernary": true, "allowShortCircuit": true }], + "no-var": "error", + "brace-style": ["error", "1tbs", { "allowSingleLine": true }], + "quotes": ["error", "double", { "avoidEscape": true }], + "radix": "error", + "semi": ["error", "always"], + "default-case": "error", + "eqeqeq": "error", + "@typescript-eslint/prefer-optional-chain": "error" + } + } +); diff --git a/gulpfile.js b/gulpfile.js index c7c35d75..8f4075e1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,32 +1,20 @@ -/// +/// "use strict"; -var require; -var argv = require("yargs").argv; -var browserify = require("browserify"); +var fs = require("fs"); +var argv = require("yargs/yargs")(process.argv.slice(2)).argv; var concat = require("gulp-concat"); -var del = require("del"); -var fileExists = require("file-exists"); -var forever = require("forever"); -var globby = require("globby"); +var del = require("del").deleteAsync; +var esbuild = require("esbuild"); var gulp = require("gulp"); var less = require("gulp-less"); -var merge = require("merge-stream"); var mergeJSON = require("gulp-merge-json"); -var minifyCSS = require("gulp-cssnano"); -var msx = require("gulp-msx"); -var open = require("gulp-open"); -var plumber = require("gulp-plumber"); -var qunit = require("node-qunit-phantomjs"); +var cssnano = require("cssnano"); +var postcss = require("gulp-postcss"); var rename = require("gulp-rename"); -var rtlcss = require("gulp-rtlcss"); -var runSequence = require("run-sequence"); -var shell = require("gulp-shell"); -var source = require("vinyl-source-stream"); -var ts = require("gulp-typescript"); -var tslint = require("gulp-tslint"); +var spawn = require("child_process").spawn; var uglify = require("gulp-uglify"); -var zip = require("gulp-zip"); +var zip = require("gulp-zip").default; var PATHS = { SRC: { @@ -35,13 +23,11 @@ var PATHS = { }, BUILDROOT: "build/", BUNDLEROOT: "build/bundles/", - LIBROOT: "lib/", TARGET: { ROOT: "target/", CHROME: "target/chrome/", EDGE_ROOT: "target/edge/OneNoteWebClipper/edgeextension/", - EDGE_EXTENSION: "target/edge/OneNoteWebClipper/edgeextension/manifest/extension/", - TESTS: "target/tests/" + EDGE_EXTENSION: "target/edge/OneNoteWebClipper/edgeextension/manifest/extension/" }, NODE_MODULES: "node_modules/", INTERNAL: { @@ -53,54 +39,41 @@ var PATHS = { } }; -var RTL_SUFFIX = "-rtl"; - var ARIA_LIB_VERSION = "2.8.2"; -// Used for debugging glob declarations -function printGlobResults(glob) { - globby.sync(glob).map(function(filePath) { - console.log(filePath); - }); +function fileExists(path) { + try { return fs.statSync(path).isFile(); } catch (e) { return false; } } //////////////////////////////////////// // CLEAN //////////////////////////////////////// -gulp.task("clean", ["cleanInternal"], function(callback) { +gulp.task("cleanInternal", function () { + return del([ + PATHS.SRC.ROOT + "scripts/**/*_internal.*", + PATHS.BUILDROOT + "scripts/**/*_internal.*", + PATHS.BUILDROOT + "bundles/**/*_internal.*" + ]); +}); + +gulp.task("clean", gulp.series("cleanInternal", function cleanRoots() { return del([ PATHS.BUILDROOT, PATHS.BUNDLEROOT, PATHS.TARGET.ROOT - ], callback); -}); + ]); +})); //////////////////////////////////////// // COMPILE CSS //////////////////////////////////////// gulp.task("compileLess", function() { - var clipperCss = gulp.src(PATHS.SRC.ROOT + "styles/clipper.less") + return gulp.src(PATHS.SRC.ROOT + "styles/renderer.less") .pipe(less()) .pipe(gulp.dest(PATHS.BUILDROOT + "css")); - var rendererCss = gulp.src(PATHS.SRC.ROOT + "styles/renderer.less") - .pipe(less()) - .pipe(gulp.dest(PATHS.BUILDROOT + "css")); - return merge(clipperCss, rendererCss); }); -gulp.task("compileRtlCss", function() { - return gulp.src(PATHS.BUILDROOT + "css/clipper.css") - .pipe(rtlcss()) - .pipe(rename({ suffix: RTL_SUFFIX })) - .pipe(gulp.dest(PATHS.BUILDROOT + "css")); -}); - -gulp.task("compileCss", function(callback) { - runSequence( - "compileLess", - "compileRtlCss", - callback); -}); +gulp.task("compileCss", gulp.series("compileLess")); //////////////////////////////////////// // COMPILE @@ -121,7 +94,7 @@ gulp.task("mergeSettings", function() { mergeOrder.push(PATHS.SRC.SETTINGS + "production.json"); if (!argv.nointernal) { mergeOrder.push(PATHS.INTERNAL.SRC.SETTINGS + "production.json"); - }; + } } else if (argv.dogfood) { mergeOrder.push(PATHS.SRC.SETTINGS + "dogfood.json"); if (!argv.nointernal) { @@ -129,19 +102,14 @@ gulp.task("mergeSettings", function() { } } - return gulp.src(mergeOrder) - .pipe(mergeJSON("settings.json")) + // allowEmpty restores gulp 4's behavior of silently tolerating missing + // production.json / dogfood.json overrides (only the internal repo + // ships those by default). + return gulp.src(mergeOrder, { allowEmpty: true }) + .pipe(mergeJSON({ fileName: "settings.json" })) .pipe(gulp.dest(PATHS.BUILDROOT)); }); -gulp.task("cleanInternal", function () { - return del([ - PATHS.SRC.ROOT + "scripts/**/*_internal.*", - PATHS.BUILDROOT + "scripts/**/*_internal.*", - PATHS.BUILDROOT + "bundles/**/*_internal.*" - ]); -}); - gulp.task("copyInternal", function () { if (fileExists(PATHS.INTERNAL.SRC.SCRIPTS + "logging/logManager.ts") && !argv.nointernal) { return gulp.src(PATHS.INTERNAL.SRC.SCRIPTS + "**/*.+(ts|tsx|d.ts)") @@ -153,155 +121,106 @@ gulp.task("copyInternal", function () { return file.base.replace(/webclipper_internal/i, "webclipper"); })); } + // gulp 4+ requires every task to signal completion — return a resolved promise on no-op. + return Promise.resolve(); }); -gulp.task("preCompileInternal", function (callback) { - runSequence( - "cleanInternal", - "copyInternal", - callback); -}); - -gulp.task("compileTypeScript", ["copyStrings", "mergeSettings", "preCompileInternal"], function () { - var tsProject = ts.createProject("./tsconfig.json", { - typescript: require('typescript'), - noEmitOnError: true - }) +gulp.task("preCompileInternal", gulp.series("cleanInternal", "copyInternal")); - return gulp.src([PATHS.SRC.ROOT + "**/*.+(ts|tsx)"]) - .pipe(tsProject()) - .pipe(gulp.dest(PATHS.BUILDROOT)); -}); - -gulp.task("mithrilify", function() { - return gulp.src(PATHS.BUILDROOT + "**/*.jsx") - .pipe(msx()) - .pipe(gulp.dest(PATHS.BUILDROOT)); -}); +gulp.task("compileTypeScript", gulp.series("copyStrings", "mergeSettings", "preCompileInternal", function compileTypeScriptInner(done) { + var tscBin = require.resolve("typescript/bin/tsc"); + var tsc = spawn(process.execPath, [tscBin, "-p", "tsconfig.json"], { stdio: "inherit" }); + tsc.on("close", function (code) { + done(code === 0 ? null : new Error("tsc exited with code " + code)); + }); +})); -gulp.task("compile", function(callback) { - runSequence( - "compileTypeScript", - "mithrilify", - callback); -}); +gulp.task("compile", gulp.series("compileTypeScript")); //////////////////////////////////////// -// TSLINT +// LINT (eslint) //////////////////////////////////////// -//The actual task to run -gulp.task("tslint", function() { - var tsFiles = [ - PATHS.SRC.ROOT + "**/*.ts", - PATHS.SRC.ROOT + "**/*.tsx", - "!" + PATHS.SRC.ROOT + "**/*.d.ts", - "!" + PATHS.SRC.ROOT + "scripts/definitions/custom/aria-web-telemetry-*.d_internal.ts" - ]; - - return gulp.src(tsFiles) - .pipe(plumber()) - .pipe(tslint({ - formatter: "verbose" - })) - .pipe(tslint.report({ - emitError: false, - summarizeFailureOutput: true - })) +gulp.task("lint", function (done) { + // require.resolve("eslint") is blocked by eslint's "exports" field; resolve + // via package.json (always exported) and walk to the bin entry instead. + var path = require("path"); + var eslintPkgDir = path.dirname(require.resolve("eslint/package.json")); + var eslintBin = path.join(eslintPkgDir, "bin", "eslint.js"); + var eslint = spawn(process.execPath, [eslintBin, "--no-error-on-unmatched-pattern", "src/**/*.ts", "src/**/*.tsx"], { stdio: "inherit" }); + eslint.on("close", function (code) { + done(code === 0 ? null : new Error("eslint exited with code " + code)); + }); }); +// Preserve the legacy task name for any external callers / pipeline references. +gulp.task("tslint", gulp.series("lint")); + //////////////////////////////////////// // BUNDLE //////////////////////////////////////// -function generateBrowserifyTasks(folderPath, files) { - var tasks = []; - for (var i = 0; i < files.length; i++) { - tasks.push(browserify(folderPath + files[i]) - .bundle() - .pipe(source(files[i])) - .pipe(gulp.dest(PATHS.BUNDLEROOT))); +function bundleEntry(folderPath, file, options) { + options = options || {}; + var buildOptions = { + entryPoints: [folderPath + file], + outfile: PATHS.BUNDLEROOT + file, + bundle: true, + platform: "browser", + format: "iife", + target: "es2022", + logLevel: "warning" + }; + if (options.globalName) { + buildOptions.globalName = options.globalName; } - return tasks; + return esbuild.build(buildOptions); } gulp.task("bundleAppendIsInstalledMarker", function () { - var extensionRoot = PATHS.BUILDROOT + "scripts/extensions/"; - var files = ["appendIsInstalledMarker.js"]; - var tasks = generateBrowserifyTasks(extensionRoot, files); - return merge(tasks); + return bundleEntry(PATHS.BUILDROOT + "scripts/extensions/", "appendIsInstalledMarker.js"); }); gulp.task("bundleOffscreen", function () { - var extensionRoot = PATHS.BUILDROOT + "scripts/extensions/"; - var files = ["offscreen.js"]; - var tasks = generateBrowserifyTasks(extensionRoot, files); - return merge(tasks); + return bundleEntry(PATHS.BUILDROOT + "scripts/extensions/", "offscreen.js"); }); gulp.task("bundleRegionOverlay", function () { - var extensionRoot = PATHS.BUILDROOT + "scripts/extensions/"; - var files = ["regionOverlay.js"]; - var tasks = generateBrowserifyTasks(extensionRoot, files); - return merge(tasks); + return bundleEntry(PATHS.BUILDROOT + "scripts/extensions/", "regionOverlay.js"); }); gulp.task("bundleContentCaptureInject", function () { - var extensionRoot = PATHS.BUILDROOT + "scripts/extensions/"; - var files = ["contentCaptureInject.js"]; - var tasks = generateBrowserifyTasks(extensionRoot, files); - return merge(tasks); + return bundleEntry(PATHS.BUILDROOT + "scripts/extensions/", "contentCaptureInject.js"); }); gulp.task("bundleRenderer", function () { - var scriptsRoot = PATHS.BUILDROOT + "scripts/"; - var files = ["renderer.js"]; - var tasks = generateBrowserifyTasks(scriptsRoot, files); - return merge(tasks); + return bundleEntry(PATHS.BUILDROOT + "scripts/", "renderer.js"); }); gulp.task("bundleLogManager", function () { - var defaultLogManager = browserify(PATHS.BUILDROOT + "scripts/logging/logManager.js", { standalone: "LogManager" }) - .bundle() - .pipe(source("logManager.js")) - .pipe(gulp.dest(PATHS.BUNDLEROOT)); - + var tasks = [bundleEntry(PATHS.BUILDROOT + "scripts/logging/", "logManager.js", { globalName: "LogManager" })]; if (fileExists(PATHS.BUILDROOT + "scripts/logging/logManager_internal.js") && !argv.nointernal) { - var internalLogManager = browserify(PATHS.BUILDROOT + "scripts/logging/logManager_internal.js", { standalone: "LogManager" }) - .bundle() - .pipe(source("logManager_internal.js")) - .pipe(gulp.dest(PATHS.BUNDLEROOT)); - - return merge(defaultLogManager, internalLogManager); + tasks.push(bundleEntry(PATHS.BUILDROOT + "scripts/logging/", "logManager_internal.js", { globalName: "LogManager" })); } - - return defaultLogManager; + return Promise.all(tasks); }); -gulp.task("bundleChrome", function() { - var extensionRoot = PATHS.BUILDROOT + "scripts/extensions/chrome/"; - var files = ["chromeExtension.js"]; - var tasks = generateBrowserifyTasks(extensionRoot, files); - return merge(tasks); +gulp.task("bundleChrome", function () { + return bundleEntry(PATHS.BUILDROOT + "scripts/extensions/chrome/", "chromeExtension.js"); }); gulp.task("bundleEdge", function () { - var extensionRoot = PATHS.BUILDROOT + "scripts/extensions/edge/"; - var files = ["edgeExtension.js"]; - var tasks = generateBrowserifyTasks(extensionRoot, files); - return merge(tasks); + return bundleEntry(PATHS.BUILDROOT + "scripts/extensions/edge/", "edgeExtension.js"); }); -gulp.task("bundle", function(callback) { - runSequence( - "bundleAppendIsInstalledMarker", - "bundleOffscreen", - "bundleRegionOverlay", - "bundleContentCaptureInject", - "bundleRenderer", - "bundleLogManager", - "bundleChrome", - "bundleEdge", - callback); -}); +gulp.task("bundle", gulp.series( + "bundleAppendIsInstalledMarker", + "bundleOffscreen", + "bundleRegionOverlay", + "bundleContentCaptureInject", + "bundleRenderer", + "bundleLogManager", + "bundleChrome", + "bundleEdge" +)); //////////////////////////////////////// // EXPORT - HELPER FUNCTIONS @@ -314,97 +233,58 @@ function lowerCasePathName() { }); } -function exportPickerFiles(targetDir) { - var pickerImages = gulp.src(PATHS.NODE_MODULES + "onenotepicker/target/images/*", - { base: PATHS.NODE_MODULES + "onenotepicker/target/" }) - .pipe(gulp.dest(targetDir)); - - var pickerCss = gulp.src(PATHS.NODE_MODULES + "onenotepicker/target/css/*") - .pipe(gulp.dest(targetDir)); - - var pickerRtlCss = gulp.src(PATHS.NODE_MODULES + "onenotepicker/target/css/*") - .pipe(rtlcss()) - .pipe(rename({ suffix: RTL_SUFFIX })) - .pipe(gulp.dest(targetDir)); - - return merge(pickerImages, pickerCss, pickerRtlCss); -} - var targetDirHasExportedCommonJs = {}; targetDirHasExportedCommonJs[PATHS.TARGET.CHROME] = false; targetDirHasExportedCommonJs[PATHS.TARGET.EDGE_EXTENSION] = false; function exportCommonJS(targetDir) { - if (!targetDirHasExportedCommonJs[targetDir]) { - // logManager.js is bundled standalone (browserify { standalone: - // "LogManager" }) so the global LogManager is available to other - // bundles (extensionWorkerBase calls LogManager.createExtLogger, - // authenticationHelper calls LogManager.reInitLoggerForDataBoundary - // Change). The internal variant is used when the WebClipper_Internal - // sibling project is present and --nointernal is not passed; it - // bundles the Aria/MSIT telemetry shim. Otherwise the public stub - // logManager.js ships. - var logManagerExportTask; - if (fileExists(PATHS.BUNDLEROOT + "logManager_internal.js") && !argv.nointernal) { - var ariaFileName = "aria-web-telemetry-"; - var unminifiedAriaLibraryFileName = ariaFileName + ARIA_LIB_VERSION + ".js"; - var minifiedAriaLibraryFileName = ariaFileName + ARIA_LIB_VERSION + ".min.js"; - var ariaLibToInclude = argv.nominify ? unminifiedAriaLibraryFileName : minifiedAriaLibraryFileName; - logManagerExportTask = gulp.src([ - PATHS.INTERNAL.LIBROOT + ariaLibToInclude, - PATHS.BUNDLEROOT + "logManager_internal.js" - ]).pipe(concat("logManager.js")).pipe(gulp.dest(targetDir)); - } else { - logManagerExportTask = gulp.src(PATHS.BUNDLEROOT + "logManager.js").pipe(gulp.dest(targetDir)); - } - - var injectLibPaths = [ - PATHS.NODE_MODULES + "oneNoteApi/target/oneNoteApi.min.js" - ]; - var injectLibsTask = gulp.src(assertModuleExists(injectLibPaths)).pipe(gulp.dest(targetDir)); - - targetDirHasExportedCommonJs[targetDir] = true; - - return merge(logManagerExportTask, injectLibsTask); + if (targetDirHasExportedCommonJs[targetDir]) { + return Promise.resolve(); } + targetDirHasExportedCommonJs[targetDir] = true; + + // logManager.js is bundled standalone (browserify { standalone: "LogManager" }) + // so the global LogManager is available to other bundles. The internal + // variant is used when WebClipper_Internal is present; it bundles the + // Aria/MSIT telemetry shim. Otherwise the public stub logManager.js ships. + var logManagerExportTask; + if (fileExists(PATHS.BUNDLEROOT + "logManager_internal.js") && !argv.nointernal) { + var ariaFileName = "aria-web-telemetry-"; + var unminifiedAriaLibraryFileName = ariaFileName + ARIA_LIB_VERSION + ".js"; + var minifiedAriaLibraryFileName = ariaFileName + ARIA_LIB_VERSION + ".min.js"; + var ariaLibToInclude = argv.nominify ? unminifiedAriaLibraryFileName : minifiedAriaLibraryFileName; + logManagerExportTask = gulp.src([ + PATHS.INTERNAL.LIBROOT + ariaLibToInclude, + PATHS.BUNDLEROOT + "logManager_internal.js" + ]).pipe(concat("logManager.js")).pipe(gulp.dest(targetDir)); + } else { + logManagerExportTask = gulp.src(PATHS.BUNDLEROOT + "logManager.js").pipe(gulp.dest(targetDir)); + } + + return streamToPromise(logManagerExportTask); } function exportCommonCSS(targetDir) { - return gulp.src([ - PATHS.BUILDROOT + "css/*.css" - ]).pipe(gulp.dest(targetDir)); + return streamToPromise(gulp.src([PATHS.BUILDROOT + "css/*.css"]).pipe(gulp.dest(targetDir))); } function exportCommonSrcFiles(targetDir) { - var pickerTask = exportPickerFiles(targetDir); - - var imagesTask = gulp.src(PATHS.SRC.ROOT + "images/**/*", { base: PATHS.SRC.ROOT }) - .pipe(lowerCasePathName()) - .pipe(gulp.dest(targetDir)); - - var clipperTask = gulp.src([ - PATHS.SRC.ROOT + "unsupportedBrowser.html", - PATHS.SRC.ROOT + "renderer.html" - ]).pipe(gulp.dest(targetDir)); - - return merge(pickerTask, imagesTask, clipperTask); + return streamsToPromise( + gulp.src(PATHS.SRC.ROOT + "images/**/*", { base: PATHS.SRC.ROOT, encoding: false }) + .pipe(lowerCasePathName()) + .pipe(gulp.dest(targetDir)), + gulp.src([PATHS.SRC.ROOT + "renderer.html"]).pipe(gulp.dest(targetDir)) + ); } function exportCommonLibFiles(targetDir) { var libFiles = [ - PATHS.NODE_MODULES + "json3/lib/json3.min.js", - PATHS.NODE_MODULES + "es5-shim/es5-shim.min.js", - PATHS.NODE_MODULES + "mithril/mithril.min.js", - PATHS.NODE_MODULES + "onenoteapi/target/oneNoteApi.min.js", - PATHS.NODE_MODULES + "onenotepicker/target/oneNotePicker.min.js", - PATHS.NODE_MODULES + "pdfjs-dist/build/pdf.combined.js", - PATHS.NODE_MODULES + "rangy/lib/rangy-core.js", - PATHS.NODE_MODULES + "urijs/src/URI.min.js", - PATHS.NODE_MODULES + "velocity-animate/velocity.min.js", - PATHS.LIBROOT + "sanitize-html.js" + PATHS.NODE_MODULES + "pdfjs-dist/legacy/build/pdf.mjs", + PATHS.NODE_MODULES + "pdfjs-dist/legacy/build/pdf.worker.mjs" ]; - var exportTask = gulp.src(assertModuleExists(libFiles)) - .pipe(gulp.dest(targetDir)); + var exportTask = gulp.src(assertModuleExists(libFiles)).pipe(gulp.dest(targetDir)); + + var pdfLoaderTask = gulp.src(PATHS.SRC.ROOT + "pdfLoader.mjs").pipe(gulp.dest(targetDir)); // The provided TextHighlighter.min.js file has a jQuery dependency so we have to use a sub-file var minifyAndExportTask = gulp.src(PATHS.SRC.ROOT + "scripts/highlighting/textHighlighter.js") @@ -413,180 +293,113 @@ function exportCommonLibFiles(targetDir) { })) .pipe(gulp.dest(targetDir)); - return merge(exportTask, minifyAndExportTask); + return streamsToPromise(exportTask, pdfLoaderTask, minifyAndExportTask); } function exportCommonWebExtensionFiles(targetDir) { - var iconsTask = gulp.src(PATHS.SRC.ROOT + "icons/*", { base: PATHS.SRC.ROOT }) - .pipe(gulp.dest(targetDir)); - - var localesTask = gulp.src(PATHS.SRC.ROOT + "_locales/**/*", { base: PATHS.SRC.ROOT }) - .pipe(lowerCasePathName()) - .pipe(gulp.dest(targetDir)); - - return merge(iconsTask, localesTask); + return streamsToPromise( + gulp.src(PATHS.SRC.ROOT + "icons/*", { base: PATHS.SRC.ROOT, encoding: false }) + .pipe(gulp.dest(targetDir)), + gulp.src(PATHS.SRC.ROOT + "_locales/**/*", { base: PATHS.SRC.ROOT }) + .pipe(lowerCasePathName()) + .pipe(gulp.dest(targetDir)) + ); } function exportChromeJS() { var targetDir = PATHS.TARGET.CHROME; - var commonTask = exportCommonJS(targetDir); - - var appendIsInstalledMarkerTask = gulp.src([ - PATHS.BUNDLEROOT + "appendIsInstalledMarker.js" - ]).pipe(concat("appendIsInstalledMarker.js")).pipe(gulp.dest(targetDir)); - - var offscreenTask = gulp.src([ - PATHS.BUNDLEROOT + "offscreen.js" - ]).pipe(concat("offscreen.js")).pipe(gulp.dest(targetDir)); - - var regionOverlayTask = gulp.src([ - PATHS.BUNDLEROOT + "regionOverlay.js" - ]).pipe(concat("regionOverlay.js")).pipe(gulp.dest(targetDir)); - - var contentCaptureInjectTask = gulp.src([ - PATHS.BUNDLEROOT + "contentCaptureInject.js" - ]).pipe(concat("contentCaptureInject.js")).pipe(gulp.dest(targetDir)); - - var rendererTask = gulp.src([ - PATHS.BUNDLEROOT + "renderer.js" - ]).pipe(concat("renderer.js")).pipe(gulp.dest(targetDir)); + var bundles = ["appendIsInstalledMarker.js", "offscreen.js", "regionOverlay.js", "contentCaptureInject.js", "renderer.js"]; + var bundleStreams = bundles.map(function(name) { + return gulp.src([PATHS.BUNDLEROOT + name]).pipe(concat(name)).pipe(gulp.dest(targetDir)); + }); var chromeExtensionTask = gulp.src([ targetDir + "logManager.js", - targetDir + "oneNoteApi.min.js", PATHS.BUNDLEROOT + "chromeExtension.js" ]).pipe(concat("chromeExtension.js")).pipe(gulp.dest(targetDir)); - if (commonTask) { - return merge(commonTask, appendIsInstalledMarkerTask, offscreenTask, regionOverlayTask, contentCaptureInjectTask, rendererTask, chromeExtensionTask); - } - return merge(chromeExtensionTask, appendIsInstalledMarkerTask, offscreenTask, regionOverlayTask, contentCaptureInjectTask, rendererTask); + return exportCommonJS(targetDir).then(function() { + return streamsToPromise.apply(null, bundleStreams.concat([chromeExtensionTask])); + }); } function exportChromeCSS() { - var targetDir = PATHS.TARGET.CHROME; - return exportCommonCSS(targetDir); + return exportCommonCSS(PATHS.TARGET.CHROME); } function exportChromeSrcFiles() { var targetDir = PATHS.TARGET.CHROME; - - var srcCommonTask = exportCommonSrcFiles(targetDir); - var commonWebExtensionFiles = exportCommonWebExtensionFiles(targetDir); - - var chromeTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/chrome/manifest.json" - ]).pipe(gulp.dest(targetDir)); - - var offscreenTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/offscreen.html" - ]).pipe(gulp.dest(targetDir)); - - return merge(srcCommonTask, commonWebExtensionFiles, chromeTask, offscreenTask); + return Promise.all([ + exportCommonSrcFiles(targetDir), + exportCommonWebExtensionFiles(targetDir), + streamToPromise(gulp.src([PATHS.SRC.ROOT + "scripts/extensions/chrome/manifest.json"]).pipe(gulp.dest(targetDir))), + streamToPromise(gulp.src([PATHS.SRC.ROOT + "scripts/extensions/offscreen.html"]).pipe(gulp.dest(targetDir))) + ]); } function exportChromeLibFiles() { - var targetDir = PATHS.TARGET.CHROME; - return exportCommonLibFiles(targetDir); + return exportCommonLibFiles(PATHS.TARGET.CHROME); } function exportEdgeJS() { var targetDir = PATHS.TARGET.EDGE_EXTENSION; - var commonTask = exportCommonJS(targetDir); - - var appendIsInstalledMarkerTask = gulp.src([ - PATHS.BUNDLEROOT + "appendIsInstalledMarker.js" - ]).pipe(concat("appendIsInstalledMarker.js")).pipe(gulp.dest(targetDir)); - - var offscreenTask = gulp.src([ - PATHS.BUNDLEROOT + "offscreen.js" - ]).pipe(concat("offscreen.js")).pipe(gulp.dest(targetDir)); - - var regionOverlayTask = gulp.src([ - PATHS.BUNDLEROOT + "regionOverlay.js" - ]).pipe(concat("regionOverlay.js")).pipe(gulp.dest(targetDir)); - - var contentCaptureInjectTask = gulp.src([ - PATHS.BUNDLEROOT + "contentCaptureInject.js" - ]).pipe(concat("contentCaptureInject.js")).pipe(gulp.dest(targetDir)); - - var rendererTask = gulp.src([ - PATHS.BUNDLEROOT + "renderer.js" - ]).pipe(concat("renderer.js")).pipe(gulp.dest(targetDir)); + var bundles = ["appendIsInstalledMarker.js", "offscreen.js", "regionOverlay.js", "contentCaptureInject.js", "renderer.js"]; + var bundleStreams = bundles.map(function(name) { + return gulp.src([PATHS.BUNDLEROOT + name]).pipe(concat(name)).pipe(gulp.dest(targetDir)); + }); var edgeExtensionTask = gulp.src([ targetDir + "logManager.js", - targetDir + "oneNoteApi.min.js", PATHS.BUNDLEROOT + "edgeExtension.js" ]).pipe(concat("edgeExtension.js")).pipe(gulp.dest(targetDir)); - if (commonTask) { - return merge(commonTask, appendIsInstalledMarkerTask, offscreenTask, regionOverlayTask, contentCaptureInjectTask, rendererTask, edgeExtensionTask); - } - return merge(edgeExtensionTask, appendIsInstalledMarkerTask, offscreenTask, regionOverlayTask, contentCaptureInjectTask, rendererTask); + return exportCommonJS(targetDir).then(function() { + return streamsToPromise.apply(null, bundleStreams.concat([edgeExtensionTask])); + }); } function exportEdgeCSS() { - var targetDir = PATHS.TARGET.EDGE_EXTENSION; - return exportCommonCSS(targetDir); + return exportCommonCSS(PATHS.TARGET.EDGE_EXTENSION); } function exportEdgeSrcFiles() { var targetDir = PATHS.TARGET.EDGE_EXTENSION; - - var srcCommonTask = exportCommonSrcFiles(targetDir); - var commonWebExtensionFiles = exportCommonWebExtensionFiles(targetDir); - - var edgeTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/edge/edgeExtension.html", - PATHS.SRC.ROOT + "scripts/extensions/edge/manifest.json" - ]).pipe(gulp.dest(targetDir)); - - var offscreenTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/offscreen.html" - ]).pipe(gulp.dest(targetDir)); - - return merge(srcCommonTask, commonWebExtensionFiles, edgeTask, offscreenTask); + return Promise.all([ + exportCommonSrcFiles(targetDir), + exportCommonWebExtensionFiles(targetDir), + streamToPromise(gulp.src([ + PATHS.SRC.ROOT + "scripts/extensions/edge/edgeExtension.html", + PATHS.SRC.ROOT + "scripts/extensions/edge/manifest.json" + ]).pipe(gulp.dest(targetDir))), + streamToPromise(gulp.src([PATHS.SRC.ROOT + "scripts/extensions/offscreen.html"]).pipe(gulp.dest(targetDir))) + ]); } function exportEdgePackageFiles() { - var edgeAssetsTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/edge/package/assets/*" - ]).pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT + "manifest/assets")); - - var edgeResourcesTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/edge/package/resources/**" - ]).pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT + "manifest/resources")); - - var edgeManifestTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/edge/package/appxmanifest.xml", - PATHS.SRC.ROOT + "scripts/extensions/edge/package/priconfig.xml" - ]).pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT + "manifest")); - - var edgePriconfigTask = gulp.src([ - PATHS.SRC.ROOT + "scripts/extensions/edge/package/generationInfo.json" - ]).pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT)); - - return merge(edgeAssetsTask, edgeManifestTask, edgePriconfigTask, edgeResourcesTask); + return streamsToPromise( + gulp.src([PATHS.SRC.ROOT + "scripts/extensions/edge/package/assets/*"], { encoding: false }) + .pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT + "manifest/assets")), + gulp.src([PATHS.SRC.ROOT + "scripts/extensions/edge/package/resources/**"], { encoding: false }) + .pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT + "manifest/resources")), + gulp.src([ + PATHS.SRC.ROOT + "scripts/extensions/edge/package/appxmanifest.xml", + PATHS.SRC.ROOT + "scripts/extensions/edge/package/priconfig.xml" + ]).pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT + "manifest")), + gulp.src([PATHS.SRC.ROOT + "scripts/extensions/edge/package/generationInfo.json"]) + .pipe(gulp.dest(PATHS.TARGET.EDGE_ROOT)) + ); } function exportEdgeLibFiles() { - var targetDir = PATHS.TARGET.EDGE_EXTENSION; - return exportCommonLibFiles(targetDir); + return exportCommonLibFiles(PATHS.TARGET.EDGE_EXTENSION); } // Checks if a file path or list of file paths exists. Throws an error if one or more files don't exist, // and returns itself otherwise. function assertModuleExists(filePath) { - var paths = []; - if (typeof filePath === "string") { - paths.push(filePath); - } else { - // Assume this is a list of paths - paths = filePath; - } + var paths = typeof filePath === "string" ? [filePath] : filePath; for (var i = 0; i < paths.length; i++) { if (!fileExists(paths[i])) { @@ -600,86 +413,66 @@ function assertModuleExists(filePath) { //////////////////////////////////////// // EXPORT - TASKS //////////////////////////////////////// +function streamToPromise(stream) { + return new Promise(function (resolve, reject) { + stream.on("close", resolve); + stream.on("end", resolve); + stream.on("finish", resolve); + stream.on("error", reject); + }); +} + +function streamsToPromise() { + var args = Array.prototype.slice.call(arguments); + return Promise.all(args.map(streamToPromise)); +} + gulp.task("exportAllCommonJS", function () { - var exportCommonJsTasks = []; + var promises = []; for (var dir in targetDirHasExportedCommonJs) { if (targetDirHasExportedCommonJs.hasOwnProperty(dir)) { - exportCommonJsTasks.push(exportCommonJS(dir)); + promises.push(exportCommonJS(dir)); } } - - return merge(exportCommonJsTasks); + return Promise.all(promises); }); -gulp.task("exportChrome", function() { - var jsTask = exportChromeJS(); - var cssTask = exportChromeCSS(); - var srcTask = exportChromeSrcFiles(); - var libTask = exportChromeLibFiles(); +gulp.task("exportChromeJS", function() { return exportChromeJS(); }); +gulp.task("exportChromeCSS", function() { return exportChromeCSS(); }); +gulp.task("exportChromeSrcFiles", function() { return exportChromeSrcFiles(); }); +gulp.task("exportChromeLibFiles", function() { return exportChromeLibFiles(); }); +gulp.task("exportChrome", gulp.series("exportChromeJS", "exportChromeCSS", "exportChromeSrcFiles", "exportChromeLibFiles")); - return merge(jsTask, cssTask, srcTask, libTask); -}); +gulp.task("exportEdgeJS", function() { return exportEdgeJS(); }); +gulp.task("exportEdgeCSS", function() { return exportEdgeCSS(); }); +gulp.task("exportEdgeSrcFiles", function() { return exportEdgeSrcFiles(); }); +gulp.task("exportEdgePackageFiles", function() { return exportEdgePackageFiles(); }); +gulp.task("exportEdgeLibFiles", function() { return exportEdgeLibFiles(); }); +gulp.task("exportEdge", gulp.series("exportEdgeJS", "exportEdgeCSS", "exportEdgeSrcFiles", "exportEdgePackageFiles", "exportEdgeLibFiles")); -gulp.task("exportEdge", function() { - var jsTask = exportEdgeJS(); - var cssTask = exportEdgeCSS(); - var srcTask = exportEdgeSrcFiles(); - var packageTask = exportEdgePackageFiles(); - var libTask = exportEdgeLibFiles(); +gulp.task("exportJS", gulp.series("exportChromeJS", "exportEdgeJS")); +gulp.task("exportCSS", gulp.series("exportChromeCSS", "exportEdgeCSS")); +gulp.task("exportSrcFiles", gulp.series("exportChromeSrcFiles", "exportEdgeSrcFiles")); - return merge(jsTask, cssTask, srcTask, packageTask, libTask); -}); - -gulp.task("exportJS", function() { - var chromeTask = exportChromeJS(); - var edgeTask = exportEdgeJS(); - - return merge(chromeTask, edgeTask); -}); - -gulp.task("exportCSS", function() { - var chromeTask = exportChromeCSS(); - var edgeTask = exportEdgeCSS(); - - return merge(chromeTask, edgeTask); -}); - -gulp.task("exportSrcFiles", function() { - var chromeTask = exportChromeSrcFiles(); - var edgeTask = exportEdgeSrcFiles(); - - return merge(chromeTask, edgeTask); -}); - -gulp.task("export", function(callback) { - runSequence( - "exportAllCommonJS", - "exportChrome", - "exportEdge", - callback); -}); +gulp.task("export", gulp.series("exportAllCommonJS", "exportChrome", "exportEdge")); //////////////////////////////////////// // PACKAGING TASKS //////////////////////////////////////// gulp.task("packageChrome", function() { - return gulp.src([PATHS.TARGET.CHROME + "/**/*", "!" + PATHS.TARGET.CHROME + "/OneNoteWebClipper.zip"]). - pipe(zip("OneNoteWebClipper.zip")). - pipe(gulp.dest(PATHS.TARGET.CHROME)); + return gulp.src([PATHS.TARGET.CHROME + "/**/*", "!" + PATHS.TARGET.CHROME + "/OneNoteWebClipper.zip"], { encoding: false }) + .pipe(zip("OneNoteWebClipper.zip")) + .pipe(gulp.dest(PATHS.TARGET.CHROME)); }); -gulp.task("package", function (callback) { - runSequence( - "packageChrome", - callback); -}); +gulp.task("package", gulp.series("packageChrome")); //////////////////////////////////////// // PRODUCTION-ONLY TASKS //////////////////////////////////////// gulp.task("minifyCss", function() { return gulp.src(PATHS.BUILDROOT + "css/**/*.css") - .pipe(minifyCSS()) + .pipe(postcss([cssnano()])) .pipe(gulp.dest(PATHS.BUILDROOT + "css")); }); @@ -689,102 +482,60 @@ gulp.task("minifyJs", function() { .pipe(gulp.dest(PATHS.BUNDLEROOT)); }); -gulp.task("minify", function(callback) { - runSequence( - "minifyCss", - "minifyJs", - callback); -}); +gulp.task("minify", gulp.series("minifyCss", "minifyJs")); //////////////////////////////////////// // WATCH TASKS //////////////////////////////////////// +gulp.task("watchTSAction", gulp.series("compile", "bundle", "exportJS", "tslint")); + gulp.task("watchTS", function() { - gulp.watch([ + return gulp.watch([ PATHS.SRC.ROOT + "strings.json", PATHS.SRC.ROOT + "settings.json", PATHS.SRC.ROOT + "**/*.+(ts|tsx)", PATHS.SRC.ROOT + "!**/*.d.ts" - ], ["watchTSAction"]); + ], gulp.series("watchTSAction")); }); -gulp.task("watchTSAction", function(callback) { - runSequence( - "compile", - "bundle", - "exportJS", - "tslint", - callback); -}); +gulp.task("watchLessAction", gulp.series("compileCss", "exportCSS")); gulp.task("watchLess", function() { - gulp.watch(PATHS.SRC.ROOT + "styles/*.less", - ["watchLessAction"] - ); + return gulp.watch(PATHS.SRC.ROOT + "styles/*.less", gulp.series("watchLessAction")); }); -gulp.task("watchLessAction", function(callback) { - runSequence( - "compileCss", - "exportCSS", - callback); -}); +gulp.task("watchSrcAction", gulp.series("exportSrcFiles")); gulp.task("watchSrcFiles", function() { - gulp.watch([ - PATHS.SRC.ROOT + "_locales/*", - PATHS.SRC.ROOT + "icons/*", - PATHS.SRC.ROOT + "images/*", - PATHS.SRC.ROOT + "unsupportedBrowser.html", - PATHS.SRC.ROOT + "renderer.html", - PATHS.SRC.ROOT + "scripts/extensions/chrome/manifest.json", - PATHS.SRC.ROOT + "scripts/extensions/offscreen.html", - PATHS.SRC.ROOT + "scripts/extensions/edge/edgeExtension.html", - PATHS.SRC.ROOT + "scripts/extensions/edge/manifest.json" - ], ["watchSrcAction"] - ); -}); - -gulp.task("watchSrcAction", function(callback) { - runSequence( - "exportSrcFiles", - callback); + return gulp.watch([ + PATHS.SRC.ROOT + "_locales/*", + PATHS.SRC.ROOT + "icons/*", + PATHS.SRC.ROOT + "images/*", + PATHS.SRC.ROOT + "renderer.html", + PATHS.SRC.ROOT + "scripts/extensions/chrome/manifest.json", + PATHS.SRC.ROOT + "scripts/extensions/offscreen.html", + PATHS.SRC.ROOT + "scripts/extensions/edge/edgeExtension.html", + PATHS.SRC.ROOT + "scripts/extensions/edge/manifest.json" + ], gulp.series("watchSrcAction")); }); //////////////////////////////////////// // SHORTCUT TASKS //////////////////////////////////////// -gulp.task("buildOnly", function(callback) { +gulp.task("buildOnly", function buildOnlyDispatch(done) { var tasks = ["compileCss", "compile", "bundle"]; if (argv.production && !argv.nominify) { tasks.push("minify"); } - tasks.push("export", "package", callback); + tasks.push("export", "package"); - runSequence.apply(null, tasks); + gulp.series.apply(gulp, tasks)(done); }); -gulp.task("watch", function(callback) { - runSequence( - "buildOnly", - "watchTS", - "watchLess", - "watchSrcFiles", - callback); -}); +gulp.task("watch", gulp.series("buildOnly", "watchTS", "watchLess", "watchSrcFiles")); -gulp.task("build", function(callback) { - runSequence( - "buildOnly", - "tslint", - callback); -}); +gulp.task("build", gulp.series("buildOnly", "tslint")); -gulp.task("full", function(callback) { - runSequence( - "clean", - "build", - callback); -}); +gulp.task("full", gulp.series("clean", "build")); -gulp.task("default", ["build"]); \ No newline at end of file +gulp.task("default", gulp.series("build")); diff --git a/lib/sanitize-html.js b/lib/sanitize-html.js deleted file mode 100644 index ffe13f79..00000000 --- a/lib/sanitize-html.js +++ /dev/null @@ -1,8205 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sanitizeHtml = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0) { - globRegex.push(quoteRegexp(name).replace(/\\\*/g, '.*')); - } else { - allowedAttributesMap[tag].push(name); - } - }); - allowedAttributesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$'); - }); - } - var allowedClassesMap = {}; - each(options.allowedClasses, function(classes, tag) { - // Implicitly allows the class attribute - if(allowedAttributesMap) { - if (!has(allowedAttributesMap, tag)) { - allowedAttributesMap[tag] = []; - } - allowedAttributesMap[tag].push('class'); - } - - allowedClassesMap[tag] = classes; - }); - - var transformTagsMap = {}; - var transformTagsAll; - each(options.transformTags, function(transform, tag) { - var transFun; - if (typeof transform === 'function') { - transFun = transform; - } else if (typeof transform === "string") { - transFun = sanitizeHtml.simpleTransform(transform); - } - if (tag === '*') { - transformTagsAll = transFun; - } else { - transformTagsMap[tag] = transFun; - } - }); - - var depth = 0; - var stack = []; - var skipMap = {}; - var transformMap = {}; - var skipText = false; - var skipTextDepth = 0; - - var parser = new htmlparser.Parser({ - onopentag: function(name, attribs) { - if (skipText) { - skipTextDepth++; - return; - } - var frame = new Frame(name, attribs); - stack.push(frame); - - var skip = false; - var hasText = frame.text ? true : false; - var transformedTag; - if (has(transformTagsMap, name)) { - transformedTag = transformTagsMap[name](name, attribs); - - frame.attribs = attribs = transformedTag.attribs; - - if (transformedTag.text !== undefined) { - frame.innerText = transformedTag.text; - } - - if (name !== transformedTag.tagName) { - frame.name = name = transformedTag.tagName; - transformMap[depth] = transformedTag.tagName; - } - } - if (transformTagsAll) { - transformedTag = transformTagsAll(name, attribs); - - frame.attribs = attribs = transformedTag.attribs; - if (name !== transformedTag.tagName) { - frame.name = name = transformedTag.tagName; - transformMap[depth] = transformedTag.tagName; - } - } - - if (options.allowedTags && options.allowedTags.indexOf(name) === -1) { - skip = true; - if (nonTextTagsArray.indexOf(name) !== -1) { - skipText = true; - skipTextDepth = 1; - } - skipMap[depth] = true; - } - depth++; - if (skip) { - // We want the contents but not this tag - return; - } - result += '<' + name; - if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) { - each(attribs, function(value, a) { - if (!allowedAttributesMap || - (has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1 ) || - (allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1 ) || - (has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a)) || - (allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a))) { - if ((a === 'href') || (a === 'src')) { - if (naughtyHref(name, value)) { - delete frame.attribs[a]; - return; - } - } - if (a === 'class') { - value = filterClasses(value, allowedClassesMap[name]); - if (!value.length) { - delete frame.attribs[a]; - return; - } - } - result += ' ' + a; - if (value.length) { - result += '="' + escapeHtml(value) + '"'; - } - } else { - delete frame.attribs[a]; - } - }); - } - if (options.selfClosing.indexOf(name) !== -1) { - result += " />"; - } else { - result += ">"; - if (frame.innerText && !hasText && !options.textFilter) { - result += frame.innerText; - } - } - }, - ontext: function(text) { - if (skipText) { - return; - } - var lastFrame = stack[stack.length-1]; - var tag; - - if (lastFrame) { - tag = lastFrame.tag; - // If inner text was set by transform function then let's use it - text = lastFrame.innerText !== undefined ? lastFrame.innerText : text; - } - - if ((tag === 'script') || (tag === 'style')) { - // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing - // script tags is, by definition, game over for XSS protection, so if that's - // your concern, don't allow them. The same is essentially true for style tags - // which have their own collection of XSS vectors. - result += text; - } else { - var escaped = escapeHtml(text); - if (options.textFilter) { - result += options.textFilter(escaped); - } else { - result += escaped; - } - } - if (stack.length) { - var frame = stack[stack.length - 1]; - frame.text += text; - } - }, - onclosetag: function(name) { - - if (skipText) { - skipTextDepth--; - if (!skipTextDepth) { - skipText = false; - } else { - return; - } - } - - var frame = stack.pop(); - if (!frame) { - // Do not crash on bad markup - return; - } - skipText = false; - depth--; - if (skipMap[depth]) { - delete skipMap[depth]; - frame.updateParentNodeText(); - return; - } - - if (transformMap[depth]) { - name = transformMap[depth]; - delete transformMap[depth]; - } - - if (options.exclusiveFilter && options.exclusiveFilter(frame)) { - result = result.substr(0, frame.tagPosition); - return; - } - - frame.updateParentNodeText(); - - if (options.selfClosing.indexOf(name) !== -1) { - // Already output /> - return; - } - - result += ""; - } - }, options.parser); - parser.write(html); - parser.end(); - - return result; - - function escapeHtml(s) { - if (typeof(s) !== 'string') { - s = s + ''; - } - return s.replace(/\&/g, '&').replace(//g, '>').replace(/\"/g, '"'); - } - - function naughtyHref(name, href) { - // Browsers ignore character codes of 32 (space) and below in a surprising - // number of situations. Start reading here: - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_tab - href = href.replace(/[\x00-\x20]+/g, ''); - // Clobber any comments in URLs, which the browser might - // interpret inside an XML data island, allowing - // a javascript: URL to be snuck through - href = href.replace(/<\!\-\-.*?\-\-\>/g, ''); - // Case insensitive so we don't get faked out by JAVASCRIPT #1 - var matches = href.match(/^([a-zA-Z]+)\:/); - if (!matches) { - // No scheme = no way to inject js (right?) - return false; - } - var scheme = matches[1].toLowerCase(); - - if (has(options.allowedSchemesByTag, name)) { - return options.allowedSchemesByTag[name].indexOf(scheme) === -1; - } - - return !options.allowedSchemes || options.allowedSchemes.indexOf(scheme) === -1; - } - - function filterClasses(classes, allowed) { - if (!allowed) { - // The class attribute is allowed without filtering on this tag - return classes; - } - classes = classes.split(/\s+/); - return classes.filter(function(clss) { - return allowed.indexOf(clss) !== -1; - }).join(' '); - } -} - -// Defaults are accessible to you so that you can use them as a starting point -// programmatically if you wish - -var htmlParserDefaults = { - decodeEntities: true -}; -sanitizeHtml.defaults = { - allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', - 'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div', - 'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre' ], - allowedAttributes: { - a: [ 'href', 'name', 'target' ], - // We don't currently allow img itself by default, but this - // would make sense if we did - img: [ 'src' ] - }, - // Lots of these won't come up by default because we don't allow them - selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ], - // URL schemes we permit - allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ], - allowedSchemesByTag: {} -}; - -sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) { - merge = (merge === undefined) ? true : merge; - newAttribs = newAttribs || {}; - - return function(tagName, attribs) { - var attrib; - if (merge) { - for (attrib in newAttribs) { - attribs[attrib] = newAttribs[attrib]; - } - } else { - attribs = newAttribs; - } - - return { - tagName: newTagName, - attribs: attribs - }; - }; -}; - -},{"htmlparser2":36,"regexp-quote":54,"xtend":58}],2:[function(require,module,exports){ -'use strict' - -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -function init () { - var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i - } - - revLookup['-'.charCodeAt(0)] = 62 - revLookup['_'.charCodeAt(0)] = 63 -} - -init() - -function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - var len = b64.length - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(len * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len - - var L = 0 - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' - } - - parts.push(output) - - return parts.join('') -} - -},{}],3:[function(require,module,exports){ - -},{}],4:[function(require,module,exports){ -(function (global){ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"buffer":5}],5:[function(require,module,exports){ -(function (global){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ - -'use strict' - -var base64 = require('base64-js') -var ieee754 = require('ieee754') -var isArray = require('isarray') - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. - - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() - -/* - * Export kMaxLength after typed array support is determined. - */ -exports.kMaxLength = kMaxLength() - -function typedArraySupport () { - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 && // typed array instances can be augmented - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false - } -} - -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} - -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length) - } - that.length = length - } - - return that -} - -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ - -function Buffer (arg, encodingOrOffset, length) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) - } - - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) - } - return from(this, arg, encodingOrOffset, length) -} - -Buffer.poolSize = 8192 // not used by this implementation - -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype - return arr -} - -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } - - return fromObject(that, value) -} - -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) -} - -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array - if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true - }) - } -} - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} - -function alloc (that, size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(that, size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -} - -function allocUnsafe (that, size) { - assertSize(size) - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0 - } - } - return that -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -} - -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - var length = byteLength(string, encoding) | 0 - that = createBuffer(that, length) - - var actual = that.write(string, encoding) - - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - that = that.slice(0, actual) - } - - return that -} - -function fromArrayLike (that, array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - that = createBuffer(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that -} - -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength // this throws if `array` is not a valid ArrayBuffer - - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') - } - - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array) - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset) - } else { - array = new Uint8Array(array, byteOffset, length) - } - - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array) - } - return that -} - -function fromObject (that, obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - that = createBuffer(that, len) - - if (that.length === 0) { - return that - } - - obj.copy(that, 0, 0, len) - return that - } - - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } - - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } - - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} - -function checked (length) { - // Note: cannot use `length < kMaxLength()` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} - -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} - -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) -} - -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } - - if (a === b) return 0 - - var x = a.length - var y = b.length - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} - -Buffer.concat = function concat (list, length) { - if (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string - } - - var len = string.length - if (len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 - - if (end <= start) { - return '' - } - - if (!encoding) encoding = 'utf8' - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } -} - -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -Buffer.prototype._isBuffer = true - -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} - -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} - -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} - -Buffer.prototype.swap64 = function swap64 () { - var len = this.length - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7) - swap(this, i + 1, i + 6) - swap(this, i + 2, i + 5) - swap(this, i + 3, i + 4) - } - return this -} - -Buffer.prototype.toString = function toString () { - var length = this.length | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} - -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } - - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) - - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 - - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (isNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1) - } - - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset - if (byteOffset >= buffer.length) { - if (dir) return -1 - else byteOffset = buffer.length - 1 - } else if (byteOffset < 0) { - if (dir) byteOffset = 0 - else return -1 - } - - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding) - } - - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF // Search for a byte value [0-255] - if (Buffer.TYPED_ARRAY_SUPPORT && - typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) - } - - throw new TypeError('val must be string, number or Buffer') -} - -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } - - return -1 -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} - -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} - -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} - -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} - -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} - -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0 - if (isFinite(length)) { - length = length | 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } - - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } - - if (!encoding) encoding = 'utf8' - - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) - - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - - case 'ascii': - return asciiWrite(this, string, offset, length) - - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) - - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} - -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 - - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint - - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } - - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } - - res.push(codePoint) - i += bytesPerSequence - } - - return decodeCodePointsArray(res) -} - -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 - -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } - - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} - -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) - } - return ret -} - -function latin1Slice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length - - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len - - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) - } - return res -} - -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end - - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } - - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len - } - - if (end < start) end = start - - var newBuf - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end) - newBuf.__proto__ = Buffer.prototype - } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start] - } - } - - return newBuf -} - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - - return val -} - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } - - return val -} - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} - -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} - -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} - -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start - - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } - - var len = end - start - var i - - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ) - } - - return len -} - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if (code < 256) { - val = code - } - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255 - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()) - var len = bytes.length - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } - - return this -} - -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g - -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } - - // valid lead - leadSurrogate = codePoint - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } - - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break - - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} - -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":2,"ieee754":37,"isarray":40}],6:[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = Buffer.isBuffer; - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) -},{"../../is-buffer/index.js":39}],7:[function(require,module,exports){ -/* - Module dependencies -*/ -var ElementType = require('domelementtype'); -var entities = require('entities'); - -/* - Boolean Attributes -*/ -var booleanAttributes = { - __proto__: null, - allowfullscreen: true, - async: true, - autofocus: true, - autoplay: true, - checked: true, - controls: true, - default: true, - defer: true, - disabled: true, - hidden: true, - ismap: true, - loop: true, - multiple: true, - muted: true, - open: true, - readonly: true, - required: true, - reversed: true, - scoped: true, - seamless: true, - selected: true, - typemustmatch: true -}; - -var unencodedElements = { - __proto__: null, - style: true, - script: true, - xmp: true, - iframe: true, - noembed: true, - noframes: true, - plaintext: true, - noscript: true -}; - -/* - Format attributes -*/ -function formatAttrs(attributes, opts) { - if (!attributes) return; - - var output = '', - value; - - // Loop through the attributes - for (var key in attributes) { - value = attributes[key]; - if (output) { - output += ' '; - } - - if (!value && booleanAttributes[key]) { - output += key; - } else { - output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"'; - } - } - - return output; -} - -/* - Self-enclosing tags (stolen from node-htmlparser) -*/ -var singleTag = { - __proto__: null, - area: true, - base: true, - basefont: true, - br: true, - col: true, - command: true, - embed: true, - frame: true, - hr: true, - img: true, - input: true, - isindex: true, - keygen: true, - link: true, - meta: true, - param: true, - source: true, - track: true, - wbr: true, -}; - - -var render = module.exports = function(dom, opts) { - if (!Array.isArray(dom) && !dom.cheerio) dom = [dom]; - opts = opts || {}; - - var output = ''; - - for(var i = 0; i < dom.length; i++){ - var elem = dom[i]; - - if (elem.type === 'root') - output += render(elem.children, opts); - else if (ElementType.isTag(elem)) - output += renderTag(elem, opts); - else if (elem.type === ElementType.Directive) - output += renderDirective(elem); - else if (elem.type === ElementType.Comment) - output += renderComment(elem); - else if (elem.type === ElementType.CDATA) - output += renderCdata(elem); - else - output += renderText(elem, opts); - } - - return output; -}; - -function renderTag(elem, opts) { - // Handle SVG - if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true}; - - var tag = '<' + elem.name, - attribs = formatAttrs(elem.attribs, opts); - - if (attribs) { - tag += ' ' + attribs; - } - - if ( - opts.xmlMode - && (!elem.children || elem.children.length === 0) - ) { - tag += '/>'; - } else { - tag += '>'; - if (elem.children) { - tag += render(elem.children, opts); - } - - if (!singleTag[elem.name] || opts.xmlMode) { - tag += ''; - } - } - - return tag; -} - -function renderDirective(elem) { - return '<' + elem.data + '>'; -} - -function renderText(elem, opts) { - var data = elem.data || ''; - - // if entities weren't decoded, no need to encode them back - if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) { - data = entities.encodeXML(data); - } - - return data; -} - -function renderCdata(elem) { - return ''; -} - -function renderComment(elem) { - return ''; -} - -},{"domelementtype":8,"entities":20}],8:[function(require,module,exports){ -//Types of elements found in the DOM -module.exports = { - Text: "text", //Text - Directive: "directive", // - Comment: "comment", // - Script: "script", // + diff --git a/src/scripts/browserUtils.ts b/src/scripts/browserUtils.ts deleted file mode 100644 index e1b12e55..00000000 --- a/src/scripts/browserUtils.ts +++ /dev/null @@ -1,68 +0,0 @@ -export module BrowserUtils { - export function appendHiddenIframeToDocument(url: string) { - let iframe = document.createElement("iframe"); - iframe.hidden = true; - iframe.style.display = "none"; - iframe.src = url; - document.body.appendChild(iframe); - } - - /** - * Checks if the browser is unsupported by the Web Clipper, i.e., IE 9 and below. - * - * @return true if the the browser is supported by the Web Clipper; false otherwise - */ - export function browserNotSupported(): boolean { - // Does not exist on IE8 and below - if (!window.addEventListener) { - return true; - } - - // IE9 - if (navigator.appVersion.indexOf("MSIE 9") >= 0) { - return true; - } - - return false; - } - - /** - * Assuming the caller is from IE, returns the browser version - */ - export function ieVersion(): string { - let ua = window.navigator.userAgent; - - let msieIndex = ua.indexOf("MSIE "); - if (msieIndex >= 0) { - // IE 10 or older - return "IE" + ua.substring(msieIndex + 5, ua.indexOf(".", msieIndex)); - } - - if (ua.indexOf("Trident/") >= 0) { - // IE 11 - let rvIndex = ua.indexOf("rv:"); - return "IE" + ua.substring(rvIndex + 3, ua.indexOf(".", rvIndex)); - } - - if (ua.indexOf("Edge/") >= 0) { - // Edge (IE 12+) => return version number - return "Edge"; - } - - return undefined; - } - - export function openPopupWindow(url: string, popupWidth = 1000, popupHeight = 700): Window { - let leftPosition: number = (screen.width) ? (screen.width - popupWidth) / 2 : 0; - let topPosition: number = (screen.height) ? (screen.height - popupHeight) / 2 : 0; - - let settings: string = - "height=" + popupHeight + - ",width=" + popupWidth + - ",top=" + topPosition + - ",left=" + leftPosition + - ",scrollbars=yes,resizable=yes,location=no,menubar=no,status=yes,titlebar=no,toolbar=no"; - - return window.open(url, "_blank", settings); - } -} diff --git a/src/scripts/clipperUI/frontEndGlobals.ts b/src/scripts/clipperUI/frontEndGlobals.ts deleted file mode 100644 index ddcebcfe..00000000 --- a/src/scripts/clipperUI/frontEndGlobals.ts +++ /dev/null @@ -1,83 +0,0 @@ -import {SmartValue} from "../communicator/smartValue"; -import {Communicator} from "../communicator/communicator"; -import {Logger} from "../logging/logger"; - -import {RemoteStorage} from "../storage/remoteStorage"; -import { StorageAsync } from "../storage/storageAsync"; - -export class Clipper { - private static injectCommunicator: Communicator; - private static extensionCommunicator: Communicator; - - private static storage: StorageAsync; - - public static logger: Logger; - public static sessionId: SmartValue = new SmartValue(); - - public static getUserSessionId(): string { - return Clipper.sessionId.get(); - } - - public static getUserSessionIdWhenDefined(): Promise { - return new Promise((resolve) => { - let sessionId = Clipper.sessionId.get(); - if (sessionId) { - resolve(sessionId); - } else { - Clipper.sessionId.subscribe((definedSessionId: string) => { - resolve(definedSessionId); - }, { times: 1, callOnSubscribe: false }); - } - }); - } - - public static getInjectCommunicator(): Communicator { - return Clipper.injectCommunicator; - } - - public static setInjectCommunicator(injectCommunicator: Communicator) { - Clipper.injectCommunicator = injectCommunicator; - } - - public static getExtensionCommunicator(): Communicator { - return Clipper.extensionCommunicator; - } - - public static setExtensionCommunicator(extensionCommunicator: Communicator) { - Clipper.extensionCommunicator = extensionCommunicator; - Clipper.setUpRemoteStorage(extensionCommunicator); - } - - public static getCachedValue(key: string): string { - if (!Clipper.storage) { - throw new Error("The remote storage needs to be set up with the extension communicator first"); - } - return Clipper.storage.getCachedValue(key); - } - - public static getStoredValue(key: string, callback: (value: string) => void, cacheValue?: boolean): void { - if (!Clipper.storage) { - throw new Error("The remote storage needs to be set up with the extension communicator first"); - } - Clipper.storage.getValue(key, callback, cacheValue); - } - - public static preCacheStoredValues(storageKeys: string[]): void { - if (!Clipper.storage) { - throw new Error("The remote storage needs to be set up with the extension communicator first"); - } - - Clipper.storage.getValues(storageKeys, () => {}, true); - } - - public static storeValue(key: string, value: string, callback?: (value: string) => void): void { - if (!Clipper.storage) { - throw new Error("The remote storage needs to be set up with the extension communicator first"); - } - Clipper.storage.setValue(key, value, callback); - } - - private static setUpRemoteStorage(extensionCommunicator: Communicator) { - Clipper.storage = new RemoteStorage(Clipper.getExtensionCommunicator()); - } -} diff --git a/src/scripts/clipperUI/tooltipProps.ts b/src/scripts/clipperUI/tooltipProps.ts deleted file mode 100644 index d663080b..00000000 --- a/src/scripts/clipperUI/tooltipProps.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {ChangeLog} from "../versioning/changeLog"; - -export module TooltipProps { - export interface WhatsNew { - updates: ChangeLog.Update[]; - } -} diff --git a/src/scripts/clipperUI/tooltipType.ts b/src/scripts/clipperUI/tooltipType.ts deleted file mode 100644 index cabc8f3e..00000000 --- a/src/scripts/clipperUI/tooltipType.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {InvokeSource} from "../extensions/invokeSource"; - -export enum TooltipType { - ChangeLog, - Pdf, - Product, - Recipe, - Video, - WhatsNew -} - -export module TooltipTypeUtils { - export function toInvokeSource(tooltipType: TooltipType): InvokeSource { - switch (tooltipType) { - case TooltipType.Pdf: - return InvokeSource.PdfTooltip; - case TooltipType.Product: - return InvokeSource.ProductTooltip; - case TooltipType.Recipe: - return InvokeSource.RecipeTooltip; - case TooltipType.Video: - return InvokeSource.VideoTooltip; - case TooltipType.WhatsNew: - return InvokeSource.WhatsNewTooltip; - default: - throw Error("Invalid TooltipType passed in TooltipType.toInvokeSource"); - } - } -} diff --git a/src/scripts/communicator/communicator.ts b/src/scripts/communicator/communicator.ts index eec117c8..0c570d70 100644 --- a/src/scripts/communicator/communicator.ts +++ b/src/scripts/communicator/communicator.ts @@ -17,9 +17,9 @@ export interface RemoteFunctionOptions { * Communication interface for handling message passing between two scripts (separate windows, extensions, etc...) */ export class Communicator { - public static initializationKey: string = "INITIALIZATION-K3Y"; - public static acknowledgeKey: string = "ACKNOWLEDGE-K3Y"; - public static registrationKey: string = "REGISTER-FUNCTION-K3Y"; + public static initializationKey = "INITIALIZATION-K3Y"; + public static acknowledgeKey = "ACKNOWLEDGE-K3Y"; + public static registrationKey = "REGISTER-FUNCTION-K3Y"; public static setValuePrefix = "SETVALUE-"; private static callbackPostfix = "-CALLBACK"; @@ -38,7 +38,7 @@ export class Communicator { // We do not want to override the callback if we call a remote function more than once, so each // time we register a callback, we need to add this and increment it accordingly. - private callbackIdPostfix: number = 0; + private callbackIdPostfix = 0; constructor(messageHandler: MessageHandler, channel: string) { this.functionMap = {}; @@ -164,7 +164,7 @@ export class Communicator { let func = this.functionMap[dataPackage.functionKey]; if (func) { let promiseResult = func(dataPackage.data) as Promise; - if (promiseResult && promiseResult.then && dataPackage.callbackKey) { + if (promiseResult?.then && dataPackage.callbackKey) { promiseResult.then((result) => { this.callRemoteFunction(dataPackage.callbackKey, { param: result }); }, (error) => { @@ -197,7 +197,7 @@ export class Communicator { let paramData = options ? options.param : undefined; let callbackKey: string = undefined; - if (options && options.callback) { + if (options?.callback) { callbackKey = name + Communicator.callbackPostfix + "-" + this.callbackIdPostfix++; this.registerFunction(callbackKey, options.callback); } diff --git a/src/scripts/communicator/offscreenCommunicator.ts b/src/scripts/communicator/offscreenCommunicator.ts index 62d61ba7..6f92863f 100644 --- a/src/scripts/communicator/offscreenCommunicator.ts +++ b/src/scripts/communicator/offscreenCommunicator.ts @@ -24,6 +24,7 @@ async function handleResponse(message): Promise { case OffscreenMessageTypes.getPathnameResponse: return message.data; default: + // eslint-disable-next-line no-console -- diagnostic for unknown offscreen response type console.warn(`Unexpected message type received: '${message.type}'.`); return; } diff --git a/src/scripts/communicator/offscreenMessageTypes.ts b/src/scripts/communicator/offscreenMessageTypes.ts index d95eba82..6e7a764b 100644 --- a/src/scripts/communicator/offscreenMessageTypes.ts +++ b/src/scripts/communicator/offscreenMessageTypes.ts @@ -1,12 +1,12 @@ export module OffscreenMessageTypes { - export var getFromLocalStorage = "get-from-local-storage"; - export var setToLocalStorage = "set-to-local-storage"; - export var removeFromLocalStorage = "remove-from-local-storage"; - export var getHostname = "get-hostname"; - export var getPathname = "get-pathname"; - export var getFromLocalStorageResponse = "local-storage-value-received"; - export var setToLocalStorageResponse = "local-storage-value-set"; - export var removeFromLocalStorageResponse = "local-storage-value-removed"; - export var getHostnameResponse = "hostname-received"; - export var getPathnameResponse = "pathname-received"; + export let getFromLocalStorage = "get-from-local-storage"; + export let setToLocalStorage = "set-to-local-storage"; + export let removeFromLocalStorage = "remove-from-local-storage"; + export let getHostname = "get-hostname"; + export let getPathname = "get-pathname"; + export let getFromLocalStorageResponse = "local-storage-value-received"; + export let setToLocalStorageResponse = "local-storage-value-set"; + export let removeFromLocalStorageResponse = "local-storage-value-removed"; + export let getHostnameResponse = "hostname-received"; + export let getPathnameResponse = "pathname-received"; } diff --git a/src/scripts/communicator/smartValue.ts b/src/scripts/communicator/smartValue.ts index f6ea49a9..d436e2ec 100644 --- a/src/scripts/communicator/smartValue.ts +++ b/src/scripts/communicator/smartValue.ts @@ -70,7 +70,7 @@ export class SmartValue { this.subscriptions[i].times--; this.subscriptions[i].func(this.t); - let noMoreExecutions = this.subscriptions[i] && this.subscriptions[i].times === 0; + let noMoreExecutions = this.subscriptions[i]?.times === 0; if (noMoreExecutions) { this.subscriptions.splice(i, 1); } diff --git a/src/scripts/constants.ts b/src/scripts/constants.ts index 331ba0ba..fd989290 100644 --- a/src/scripts/constants.ts +++ b/src/scripts/constants.ts @@ -1,471 +1,382 @@ export module Constants { export module Classes { // animators - export var heightAnimator = "height-animator"; - export var panelAnimator = "panel-animator"; - export var clearfix = "clearfix"; + export let heightAnimator = "height-animator"; + export let panelAnimator = "panel-animator"; + export let clearfix = "clearfix"; // changeLogPanel - export var change = "change"; - export var changes = "changes"; - export var changeBody = "change-body"; - export var changeDescription = "change-description"; - export var changeImage = "change-image"; - export var changeTitle = "change-title"; + export let change = "change"; + export let changes = "changes"; + export let changeBody = "change-body"; + export let changeDescription = "change-description"; + export let changeImage = "change-image"; + export let changeTitle = "change-title"; // checkbox - export var checkboxCheck = "checkboxCheck"; + export let checkboxCheck = "checkboxCheck"; // textArea input control - export var textAreaInput = "textAreaInput"; - export var textAreaInputMirror = "textAreaInputMirror"; + export let textAreaInput = "textAreaInput"; + export let textAreaInputMirror = "textAreaInputMirror"; // popover - export var popover = "popover"; - export var popoverArrow = "popover-arrow"; + export let popover = "popover"; + export let popoverArrow = "popover-arrow"; // previewViewer - export var deleteHighlightButton = "delete-highlight"; - export var highlightable = "highlightable"; - export var highlighted = "highlighted"; - export var regionSelection = "region-selection"; - export var regionSelectionImage = "region-selection-image"; - export var regionSelectionRemoveButton = "region-selection-remove-button"; + export let deleteHighlightButton = "delete-highlight"; + export let highlightable = "highlightable"; + export let highlighted = "highlighted"; + export let regionSelection = "region-selection"; + export let regionSelectionImage = "region-selection-image"; + export let regionSelectionRemoveButton = "region-selection-remove-button"; // pdfPreviewViewer - export var attachmentOverlay = "attachment-overlay"; - export var centeredInCanvas = "centered-in-canvas"; - export var overlay = "overlay"; - export var overlayHidden = "overlay-hidden"; - export var overlayNumber = "overlay-number"; - export var pdfPreviewImage = "pdf-preview-image"; - export var pdfPreviewImageCanvas = "pdf-preview-image-canvas"; - export var unselected = "unselected"; - - export var localPdfPanelTitle = "local-pdf-panel-title"; - export var localPdfPanelSubtitle = "local-pdf-panel-subtitle"; + export let attachmentOverlay = "attachment-overlay"; + export let centeredInCanvas = "centered-in-canvas"; + export let overlay = "overlay"; + export let overlayHidden = "overlay-hidden"; + export let overlayNumber = "overlay-number"; + export let pdfPreviewImage = "pdf-preview-image"; + export let pdfPreviewImageCanvas = "pdf-preview-image-canvas"; + export let unselected = "unselected"; + + export let localPdfPanelTitle = "local-pdf-panel-title"; + export let localPdfPanelSubtitle = "local-pdf-panel-subtitle"; // radioButton - export var radioIndicatorFill = "radio-indicator-fill"; + export let radioIndicatorFill = "radio-indicator-fill"; // spriteAnimation - export var spinner = "spinner"; + export let spinner = "spinner"; - // Accessibility - export var srOnly = "sr-only"; + // Accessibility + export let srOnly = "sr-only"; // tooltip - export var tooltip = "tooltip"; + export let tooltip = "tooltip"; // rotatingMessageSpriteAnimation - export var centeredInPreview = "centered-in-preview"; + export let centeredInPreview = "centered-in-preview"; } export module Cookies { - export var clipperInfo = "ClipperInfo"; + export let clipperInfo = "ClipperInfo"; } export module Extension { export module NotificationIds { - export var conflictingExtension = "conflictingExtension"; + export let conflictingExtension = "conflictingExtension"; } } export module Ids { // annotationInput - export var annotationContainer = "annotationContainer"; - export var annotationField = "annotationField"; - export var annotationFieldMirror = "annotationFieldMirror"; - export var annotationPlaceholder = "annotationPlaceholder"; + export let annotationContainer = "annotationContainer"; + export let annotationField = "annotationField"; + export let annotationFieldMirror = "annotationFieldMirror"; + export let annotationPlaceholder = "annotationPlaceholder"; // bookmarkPreview - export var bookmarkThumbnail = "bookmarkThumbnail"; - export var bookmarkPreviewContentContainer = "bookmarkPreviewContentContainer"; - export var bookmarkPreviewInnerContainer = "bookmarkPreviewInnerContainer"; + export let bookmarkThumbnail = "bookmarkThumbnail"; + export let bookmarkPreviewContentContainer = "bookmarkPreviewContentContainer"; + export let bookmarkPreviewInnerContainer = "bookmarkPreviewInnerContainer"; // clippingPanel - export var clipperApiProgressContainer = "clipperApiProgressContainer"; + export let clipperApiProgressContainer = "clipperApiProgressContainer"; // clippingPanel - export var clipProgressDelayedMessage = "clipProgressDelayedMessage"; - export var clipProgressIndicatorMessage = "clipProgressIndicatorMessage"; + export let clipProgressDelayedMessage = "clipProgressDelayedMessage"; + export let clipProgressIndicatorMessage = "clipProgressIndicatorMessage"; // dialogPanel - export var dialogBackButton = "dialogBackButton"; - export var dialogButtonContainer = "dialogButtonContainer"; - export var dialogDebugMessageContainer = "dialogDebugMessageContainer"; - export var dialogMessageContainer = "dialogMessageContainer"; - export var dialogContentContainer = "dialogContentContainer"; - export var dialogMessage = "dialogMessage"; - export var dialogSignOutButton = "dialogSignoutButton"; - export var dialogTryAgainButton = "dialogTryAgainButton"; + export let dialogBackButton = "dialogBackButton"; + export let dialogButtonContainer = "dialogButtonContainer"; + export let dialogDebugMessageContainer = "dialogDebugMessageContainer"; + export let dialogMessageContainer = "dialogMessageContainer"; + export let dialogContentContainer = "dialogContentContainer"; + export let dialogMessage = "dialogMessage"; + export let dialogSignOutButton = "dialogSignoutButton"; + export let dialogTryAgainButton = "dialogTryAgainButton"; // editorPreviewComponentBase - export var highlightablePreviewBody = "highlightablePreviewBody"; + export let highlightablePreviewBody = "highlightablePreviewBody"; // failurePanel - export var apiErrorMessage = "apiErrorMessage"; - export var backToHomeButton = "backToHomeButton"; - export var clipperFailureContainer = "clipperFailureContainer"; - export var refreshPageButton = "refreshPageButton"; - export var tryAgainButton = "tryAgainButton"; + export let apiErrorMessage = "apiErrorMessage"; + export let backToHomeButton = "backToHomeButton"; + export let clipperFailureContainer = "clipperFailureContainer"; + export let refreshPageButton = "refreshPageButton"; + export let tryAgainButton = "tryAgainButton"; // footer - export var clipperFooterContainer = "clipperFooterContainer"; - export var currentUserControl = "currentUserControl"; - export var currentUserDetails = "currentUserDetails"; - export var currentUserEmail = "currentUserEmail"; - export var currentUserId = "currentUserId"; - export var currentUserName = "currentUserName"; - export var feedbackButton = "feedbackButton"; - export var feedbackImage = "feedbackImage"; - export var signOutButton = "signOutButton"; - export var userDropdownArrow = "userDropdownArrow"; - export var userSettingsContainer = "userSettingsContainer"; - export var feedbackLabel = "feedbackLabel"; - export var footerButtonsContainer = "footerButtonsContainer"; + export let clipperFooterContainer = "clipperFooterContainer"; + export let currentUserControl = "currentUserControl"; + export let currentUserDetails = "currentUserDetails"; + export let currentUserEmail = "currentUserEmail"; + export let currentUserId = "currentUserId"; + export let currentUserName = "currentUserName"; + export let feedbackButton = "feedbackButton"; + export let feedbackImage = "feedbackImage"; + export let signOutButton = "signOutButton"; + export let userDropdownArrow = "userDropdownArrow"; + export let userSettingsContainer = "userSettingsContainer"; + export let feedbackLabel = "feedbackLabel"; + export let footerButtonsContainer = "footerButtonsContainer"; // loadingPanel - export var clipperLoadingContainer = "clipperLoadingContainer"; + export let clipperLoadingContainer = "clipperLoadingContainer"; // mainController - export var closeButton = "closeButton"; - export var closeButtonContainer = "closeButtonContainer"; - export var mainController = "mainController"; + export let closeButton = "closeButton"; + export let closeButtonContainer = "closeButtonContainer"; + export let mainController = "mainController"; // OneNotePicker - export var saveToLocationContainer = "saveToLocationContainer"; + export let saveToLocationContainer = "saveToLocationContainer"; // modeButton - export var regionButton = "regionButton"; - export var fullPageButton = "fullPageButton"; - export var bookmarkButton = "bookmarkButton"; - export var augmentationButton = "augmentationButton"; - export var pdfButton = "pdfButton"; - export var selectionButton = "selectionButton"; + export let regionButton = "regionButton"; + export let fullPageButton = "fullPageButton"; + export let bookmarkButton = "bookmarkButton"; + export let augmentationButton = "augmentationButton"; + export let pdfButton = "pdfButton"; + export let selectionButton = "selectionButton"; // optionsPanel - export var clipButton = "clipButton"; - export var clipButtonContainer = "clipButtonContainer"; - export var optionLabel = "optionLabel"; + export let clipButton = "clipButton"; + export let clipButtonContainer = "clipButtonContainer"; + export let optionLabel = "optionLabel"; // previewViewerPdfHeader - export var radioAllPagesLabel = "radioAllPagesLabel"; - export var radioPageRangeLabel = "radioPageRangeLabel"; - export var rangeInput = "rangeInput"; + export let radioAllPagesLabel = "radioAllPagesLabel"; + export let radioPageRangeLabel = "radioPageRangeLabel"; + export let rangeInput = "rangeInput"; // previewViewer - export var previewBody = "previewBody"; - export var previewContentContainer = "previewContentContainer"; - export var previewHeader = "previewHeader"; - export var previewHeaderContainer = "previewHeaderContainer"; - export var previewHeaderInput = "previewHeaderInput"; - export var previewHeaderInputMirror = "previewHeaderInputMirror"; - export var previewTitleContainer = "previewTitleContainer"; - export var previewSubtitleContainer = "previewSubtitleContainer"; - export var previewInnerContainer = "previewInnerContainer"; - export var previewAriaLiveDiv = "previewAriaLiveDiv"; - export var previewOptionsContainer = "previewOptionsContainer"; - export var previewInnerWrapper = "previewInnerWrapper"; - export var previewOuterContainer = "previewOuterContainer"; - export var previewUrlContainer = "previewUrlContainer"; - export var previewNotesContainer = "previewNotesContainer"; + export let previewBody = "previewBody"; + export let previewContentContainer = "previewContentContainer"; + export let previewHeader = "previewHeader"; + export let previewHeaderContainer = "previewHeaderContainer"; + export let previewHeaderInput = "previewHeaderInput"; + export let previewHeaderInputMirror = "previewHeaderInputMirror"; + export let previewTitleContainer = "previewTitleContainer"; + export let previewSubtitleContainer = "previewSubtitleContainer"; + export let previewInnerContainer = "previewInnerContainer"; + export let previewAriaLiveDiv = "previewAriaLiveDiv"; + export let previewOptionsContainer = "previewOptionsContainer"; + export let previewInnerWrapper = "previewInnerWrapper"; + export let previewOuterContainer = "previewOuterContainer"; + export let previewUrlContainer = "previewUrlContainer"; + export let previewNotesContainer = "previewNotesContainer"; // previewViewerFullPageHeader - export var fullPageControl = "fullPageControl"; - export var fullPageHeaderTitle = "fullPageHeaderTitle"; + export let fullPageControl = "fullPageControl"; + export let fullPageHeaderTitle = "fullPageHeaderTitle"; // previewViewerPdfHeader - export var localPdfFileTitle = "localPdfFileTitle"; - export var pdfControl = "pdfControl"; - export var pdfHeaderTitle = "pdfHeaderTitle"; - export var pageRangeControl = "pageRangeControl"; + export let localPdfFileTitle = "localPdfFileTitle"; + export let pdfControl = "pdfControl"; + export let pdfHeaderTitle = "pdfHeaderTitle"; + export let pageRangeControl = "pageRangeControl"; // pdfClipOptions - export var checkboxToDistributePages = "checkboxToDistributePages"; - export var pdfIsTooLargeToAttachIndicator = "pdfIsTooLargeToAttachIndicator"; - export var checkboxToAttachPdf = "checkboxToAttachPdf"; - export var moreClipOptions = "moreClipOptions"; + export let checkboxToDistributePages = "checkboxToDistributePages"; + export let pdfIsTooLargeToAttachIndicator = "pdfIsTooLargeToAttachIndicator"; + export let checkboxToAttachPdf = "checkboxToAttachPdf"; + export let moreClipOptions = "moreClipOptions"; // previewViewerRegionHeader - export var addAnotherRegionButton = "addAnotherRegionButton"; - export var addRegionControl = "addRegionControl"; + export let addAnotherRegionButton = "addAnotherRegionButton"; + export let addRegionControl = "addRegionControl"; // previewViewerRegionTitleOnlyHeader - export var regionControl = "regionControl"; - export var regionHeaderTitle = "regionHeaderTitle"; + export let regionControl = "regionControl"; + export let regionHeaderTitle = "regionHeaderTitle"; // previewViewerAugmentationHeader - export var decrementFontSize = "decrementFontSize"; - export var fontSizeControl = "fontSizeControl"; - export var highlightButton = "highlightButton"; - export var highlightControl = "highlightControl"; - export var incrementFontSize = "incrementFontSize"; - export var serifControl = "serifControl"; - export var sansSerif = "sansSerif"; - export var serif = "serif"; + export let decrementFontSize = "decrementFontSize"; + export let fontSizeControl = "fontSizeControl"; + export let highlightButton = "highlightButton"; + export let highlightControl = "highlightControl"; + export let incrementFontSize = "incrementFontSize"; + export let serifControl = "serifControl"; + export let sansSerif = "sansSerif"; + export let serif = "serif"; // previewViewerBookmarkHeader - export var bookmarkControl = "bookmarkControl"; - export var bookmarkHeaderTitle = "bookmarkHeaderTitle"; + export let bookmarkControl = "bookmarkControl"; + export let bookmarkHeaderTitle = "bookmarkHeaderTitle"; // ratingsPrompt - export var ratingsButtonFeedbackNo = "ratingsButtonFeedbackNo"; - export var ratingsButtonFeedbackYes = "ratingsButtonFeedbackYes"; - export var ratingsButtonInitNo = "ratingsButtonInitNo"; - export var ratingsButtonInitYes = "ratingsButtonInitYes"; - export var ratingsButtonRateNo = "ratingsButtonRateNo"; - export var ratingsButtonRateYes = "ratingsButtonRateYes"; - export var ratingsPromptContainer = "ratingsPromptContainer"; + export let ratingsButtonFeedbackNo = "ratingsButtonFeedbackNo"; + export let ratingsButtonFeedbackYes = "ratingsButtonFeedbackYes"; + export let ratingsButtonInitNo = "ratingsButtonInitNo"; + export let ratingsButtonInitYes = "ratingsButtonInitYes"; + export let ratingsButtonRateNo = "ratingsButtonRateNo"; + export let ratingsButtonRateYes = "ratingsButtonRateYes"; + export let ratingsPromptContainer = "ratingsPromptContainer"; // regionSelectingPanel - export var regionInstructionsContainer = "regionInstructionsContainer"; - export var regionClipCancelButton = "regionClipCancelButton"; + export let regionInstructionsContainer = "regionInstructionsContainer"; + export let regionClipCancelButton = "regionClipCancelButton"; // regionSelector - export var innerFrame = "innerFrame"; - export var outerFrame = "outerFrame"; - export var regionSelectorContainer = "regionSelectorContainer"; + export let innerFrame = "innerFrame"; + export let outerFrame = "outerFrame"; + export let regionSelectorContainer = "regionSelectorContainer"; // rotatingMessageSpriteAnimation - export var spinnerText = "spinnerText"; + export let spinnerText = "spinnerText"; // sectionPicker - export var locationPickerContainer = "locationPickerContainer"; - export var sectionLocationContainer = "sectionLocationContainer"; + export let locationPickerContainer = "locationPickerContainer"; + export let sectionLocationContainer = "sectionLocationContainer"; // signInPanel - export var signInButtonMsa = "signInButtonMsa"; - export var signInButtonOrgId = "signInButtonOrgId"; - export var signInContainer = "signInContainer"; - export var signInErrorCookieInformation = "signInErrorCookieInformation"; - export var signInErrorDebugInformation = "signInErrorDebugInformation"; - export var signInErrorDebugInformationDescription = "signInErrorDebugInformationDescription"; - export var signInErrorDebugInformationContainer = "signInErrorDebugInformationContainer"; - export var signInErrorDebugInformationList = "signInErrorDebugInformationList"; - export var signInErrorDescription = "signInErrorDescription"; - export var signInErrorDescriptionContainer = "signInErrorDescriptionContainer"; - export var signInErrorMoreInformation = "signInErrorMoreInformation"; - export var signInLogo = "signInLogo"; - export var signInMessageLabelContainer = "signInMessageLabelContainer"; - export var signInText = "signInText"; - export var signInToggleErrorDropdownArrow = "signInToggleErrorDropdownArrow"; - export var signInToggleErrorInformationText = "signInToggleErrorInformationText"; + export let signInButtonMsa = "signInButtonMsa"; + export let signInButtonOrgId = "signInButtonOrgId"; + export let signInContainer = "signInContainer"; + export let signInErrorCookieInformation = "signInErrorCookieInformation"; + export let signInErrorDebugInformation = "signInErrorDebugInformation"; + export let signInErrorDebugInformationDescription = "signInErrorDebugInformationDescription"; + export let signInErrorDebugInformationContainer = "signInErrorDebugInformationContainer"; + export let signInErrorDebugInformationList = "signInErrorDebugInformationList"; + export let signInErrorDescription = "signInErrorDescription"; + export let signInErrorDescriptionContainer = "signInErrorDescriptionContainer"; + export let signInErrorMoreInformation = "signInErrorMoreInformation"; + export let signInLogo = "signInLogo"; + export let signInMessageLabelContainer = "signInMessageLabelContainer"; + export let signInText = "signInText"; + export let signInToggleErrorDropdownArrow = "signInToggleErrorDropdownArrow"; + export let signInToggleErrorInformationText = "signInToggleErrorInformationText"; // successPanel - export var clipperSuccessContainer = "clipperSuccessContainer"; - export var launchOneNoteButton = "launchOneNoteButton"; + export let clipperSuccessContainer = "clipperSuccessContainer"; + export let launchOneNoteButton = "launchOneNoteButton"; // tooltipRenderer - export var pageNavAnimatedTooltip = "pageNavAnimatedTooltip"; + export let pageNavAnimatedTooltip = "pageNavAnimatedTooltip"; // unsupportedBrowser - export var unsupportedBrowserContainer = "unsupportedBrowserContainer"; - export var unsupportedBrowserPanel = "unsupportedBrowserPanel"; + export let unsupportedBrowserContainer = "unsupportedBrowserContainer"; + export let unsupportedBrowserPanel = "unsupportedBrowserPanel"; // whatsNewPanel - export var changeLogSubPanel = "changeLogSubPanel"; - export var checkOutWhatsNewButton = "checkOutWhatsNewButton"; - export var proceedToWebClipperButton = "proceedToWebClipperButton"; - export var whatsNewTitleSubPanel = "whatsNewTitleSubPanel"; + export let changeLogSubPanel = "changeLogSubPanel"; + export let checkOutWhatsNewButton = "checkOutWhatsNewButton"; + export let proceedToWebClipperButton = "proceedToWebClipperButton"; + export let whatsNewTitleSubPanel = "whatsNewTitleSubPanel"; - export var clipperRootScript = "oneNoteCaptureRootScript"; - export var clipperUiFrame = "oneNoteWebClipper"; - export var clipperPageNavFrame = "oneNoteWebClipperPageNav"; - export var clipperExtFrame = "oneNoteWebClipperExtension"; + export let clipperRootScript = "oneNoteCaptureRootScript"; + export let clipperUiFrame = "oneNoteWebClipper"; + export let clipperPageNavFrame = "oneNoteWebClipperPageNav"; + export let clipperExtFrame = "oneNoteWebClipperExtension"; // tooltips - export var brandingContainer = "brandingContainer"; + export let brandingContainer = "brandingContainer"; } export module HeaderValues { - export var accept = "Accept"; - export var appIdKey = "MS-Int-AppId"; - export var correlationId = "X-CorrelationId"; - export var noAuthKey = "X-NoAuth"; - export var userSessionIdKey = "X-UserSessionId"; - } - - export module CommunicationChannels { - // Debug Logging - export var debugLoggingInjectedAndExtension = "DEBUGLOGGINGINJECTED_AND_EXTENSION"; - - // Web Clipper - export var extensionAndUi = "EXTENSION_AND_UI"; - export var injectedAndUi = "INJECTED_AND_UI"; - export var injectedAndExtension = "INJECTED_AND_EXTENSION"; - - // What's New - export var extensionAndPageNavUi = "EXTENSION_AND_PAGENAVUI"; - export var pageNavInjectedAndPageNavUi = "PAGENAVINJECTED_AND_PAGENAVUI"; - export var pageNavInjectedAndExtension = "PAGENAVINJECTED_AND_EXTENSION"; + export let accept = "Accept"; + export let appIdKey = "MS-Int-AppId"; + export let correlationId = "X-CorrelationId"; + export let noAuthKey = "X-NoAuth"; + export let userSessionIdKey = "X-UserSessionId"; } export module FunctionKeys { - export var clipperStrings = "CLIPPER_STRINGS"; - export var clipperStringsFrontLoaded = "CLIPPER_STRINGS_FRONT_LOADED"; - export var closePageNavTooltip = "CLOSE_PAGE_NAV_TOOLTIP"; - export var createHiddenIFrame = "CREATE_HIDDEN_IFRAME"; - export var ensureFreshUserBeforeClip = "ENSURE_FRESH_USER_BEFORE_CLIP"; - export var escHandler = "ESC_HANDLER"; - export var getInitialUser = "GET_INITIAL_USER"; - export var getPageNavTooltipProps = "GET_PAGE_NAV_TOOLTIP_PROPS"; - export var getStorageValue = "GET_STORAGE_VALUE"; - export var getMultipleStorageValues = "GET_MULTIPLE_STORAGE_VALUES"; - export var getTooltipToRenderInPageNav = "GET_TOOLTIP_TO_RENDER_IN_PAGE_NAV"; - export var hideUi = "HIDE_UI"; - export var showUi = "SHOW_UI"; - export var showSignInPanel = "SHOW_SIGN_IN_PANEL"; - export var startRegionCapture = "START_REGION_CAPTURE"; - export var regionCaptureComplete = "REGION_CAPTURE_COMPLETE"; - export var regionCaptureCancelled = "REGION_CAPTURE_CANCELLED"; - export var invokeClipper = "INVOKE_CLIPPER"; - export var invokeClipperFromPageNav = "INVOKE_CLIPPER_FROM_PAGE_NAV"; - export var invokeDebugLogging = "INVOKE_DEBUG_LOGGING"; - export var invokePageNav = "INVOKE_PAGE_NAV"; - export var extensionNotAllowedToAccessLocalFiles = "EXTENSION_NOT_ALLOWED_TO_ACCESS_LOCAL_FILES"; - export var noOpTracker = "NO_OP_TRACKER"; - export var onSpaNavigate = "ON_SPA_NAVIGATE"; - export var refreshPage = "REFRESH_PAGE"; - export var showRefreshClipperMessage = "SHOW_REFRESH_CLIPPER_MESSAGE"; - export var setInjectOptions = "SET_INJECT_OPTIONS"; - export var setInvokeOptions = "SET_INVOKE_OPTIONS"; - export var setStorageValue = "SET_STORAGE_VALUE"; - export var signInUser = "SIGN_IN_USER"; - export var signOutUser = "SIGN_OUT_USER"; - export var tabToLowestIndexedElement = "TAB_TO_LOWEST_INDEXED_ELEMENT"; - export var takeTabScreenshot = "TAKE_TAB_SCREENSHOT"; - export var takeFullPageScreenshot = "TAKE_FULL_PAGE_SCREENSHOT"; - export var cancelFullPageScreenshot = "CANCEL_FULL_PAGE_SCREENSHOT"; - export var telemetry = "TELEMETRY"; - export var toggleClipper = "TOGGLE_CLIPPER"; - export var unloadHandler = "UNLOAD_HANDLER"; - export var updateFrameHeight = "UPDATE_FRAME_HEIGHT"; - export var updatePageInfoIfUrlChanged = "UPDATE_PAGE_INFO_IF_URL_CHANGED"; - export var keepAlive = "KEEP_ALIVE"; - export var clearKeepAlive = "CLEAR_KEEP_ALIVE"; + // Only entry still referenced — by the kept-orphan + // communicatorLoggerPure.ts, which calls callRemoteFunction with this + // channel name. Live V3 telemetry uses Aria fetch() directly. + export let telemetry = "TELEMETRY"; } export module KeyCodes { // event.which is deprecated -.- - export var tab = 9; - export var enter = 13; - export var esc = 27; - export var c = 67; - export var down = 40; - export var up = 38; - export var left = 37; - export var right = 39; - export var space = 32; - export var home = 36; - export var end = 35; + export let tab = 9; + export let enter = 13; + export let esc = 27; + export let c = 67; + export let down = 40; + export let up = 38; + export let left = 37; + export let right = 39; + export let space = 32; + export let home = 36; + export let end = 35; } export module StringKeyCodes { - export var c = "KeyC"; - } - - export module SmartValueKeys { - export var clientInfo = "CLIENT_INFO"; - export var isFullScreen = "IS_FULL_SCREEN"; - export var pageInfo = "PAGE_INFO"; - export var sessionId = "SESSION_ID"; - export var user = "USER"; + export let c = "KeyC"; } export module Styles { - export var sectionPickerContainerHeight = 280; - export var clipperUiWidth = 322; - export var customCursorSize = 20; - export var clipperUiTopRightOffset = 20; - export var clipperUiDropShadowBuffer = 7; - export var clipperUiInnerPadding = 30; + export let sectionPickerContainerHeight = 280; + export let clipperUiWidth = 322; + export let customCursorSize = 20; + export let clipperUiTopRightOffset = 20; + export let clipperUiDropShadowBuffer = 7; + export let clipperUiInnerPadding = 30; export module Colors { - export var oneNoteHighlightColor = "#fefe56"; + export let oneNoteHighlightColor = "#fefe56"; } } export module Urls { - export var serviceDomain = "https://www.onenote.com"; + export let serviceDomain = "https://www.onenote.com"; - export var changelogUrl = serviceDomain + "/whatsnext/webclipper"; - export var localizedStringsUrlBase = serviceDomain + "/strings?ids=WebClipper."; + export let localizedStringsUrlBase = serviceDomain + "/strings?ids=WebClipper."; - export var clipperInstallPageUrl = "https://support.microsoft.com/en-us/office/getting-started-with-the-onenote-web-clipper-5696609d-c5ae-4591-b3af-1f897cb6eda6"; - export var clipperFeedbackUrl = "https://feedbackportal.microsoft.com/feedback/post/c06dcc30-2e1c-ec11-b6e7-0022481f8472"; - export var msaDomain = "https://login.live.com"; - export var orgIdDomain = "https://login.microsoftonline.com"; - export var userDataBoundaryDomain = "https://odc.officeapps.live.com/odc/v2.1/federationprovider"; + export let clipperInstallPageUrl = "https://support.microsoft.com/en-us/office/getting-started-with-the-onenote-web-clipper-5696609d-c5ae-4591-b3af-1f897cb6eda6"; + export let clipperFeedbackUrl = "https://feedbackportal.microsoft.com/feedback/post/c06dcc30-2e1c-ec11-b6e7-0022481f8472"; + export let msaDomain = "https://login.live.com"; + export let orgIdDomain = "https://login.microsoftonline.com"; + export let userDataBoundaryDomain = "https://odc.officeapps.live.com/odc/v2.1/federationprovider"; export module Authentication { - export var authRedirectUrl = serviceDomain + "/webclipper/auth"; - export var signInUrl = serviceDomain + "/webclipper/signin"; - export var signOutUrl = serviceDomain + "/webclipper/signout"; - export var userInformationUrl = serviceDomain + "/webclipper/userinfo"; + export let authRedirectUrl = serviceDomain + "/webclipper/auth"; + export let signInUrl = serviceDomain + "/webclipper/signin"; + export let signOutUrl = serviceDomain + "/webclipper/signout"; + export let userInformationUrl = serviceDomain + "/webclipper/userinfo"; } export module QueryParams { - export var authType = "authType"; - export var category = "category"; - export var changelogLocale = "omkt"; - export var channel = "channel"; - export var clientType = "clientType"; - export var clipperId = "clipperId"; - export var clipperVersion = "clipperVersion"; - export var correlationId = "correlationId"; - export var error = "error"; - export var errorDescription = "error_?description"; - export var event = "event"; - export var eventName = "eventName"; - export var failureId = "failureId"; - export var failureInfo = "failureInfo"; - export var failureType = "failureType"; - export var inlineInstall = "inlineInstall"; - export var label = "label"; - export var noOpType = "noOpType"; - export var stackTrace = "stackTrace"; - export var timeoutInMs = "timeoutInMs"; - export var url = "url"; - export var userSessionId = "userSessionId"; - export var wdFromClipper = "wdfromclipper"; // This naming convention is standard in OneNote Online - export var domain = "domain"; + export let authType = "authType"; + export let clipperId = "clipperId"; + export let error = "error"; + export let errorDescription = "error_?description"; + export let userSessionId = "userSessionId"; + export let domain = "domain"; } } - export module LogCategories { - export var oneNoteClipperUsage = "OneNoteClipperUsage"; - } - export module Settings { - export var fontSizeStep = 2; - export var maxClipSuccessForRatingsPrompt = 12; - export var maximumJSTimeValue = 1000 * 60 * 60 * 24 * 100000000; // 100M days in milliseconds, http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1 - export var maximumFontSize = 72; - export var maximumNumberOfTimesToShowTooltips = 3; - export var maximumMimeSizeLimit = 24900000; - export var minClipSuccessForRatingsPrompt = 4; - export var minimumFontSize = 8; - export var minTimeBetweenBadRatings = 1000 * 60 * 60 * 24 * 7 * 10; // 10 weeks - export var noOpTrackerTimeoutDuration = 20 * 1000; // 20 seconds - export var numRetriesPerPatchRequest = 3; - export var pdfCheckCreatePageInterval = 2000; // 2 seconds - export var pdfClippingMessageDelay = 5000; // 5 seconds - export var pdfExtraPageLoadEachSide = 1; - export var pdfInitialPageLoadCount = 3; - export var timeBetweenDifferentTooltips = 1000 * 60 * 60 * 24 * 7 * 1; // 1 week - export var timeBetweenSameTooltip = 1000 * 60 * 60 * 24 * 7 * 3; // 3 weeks - export var timeBetweenTooltips = 1000 * 60 * 60 * 24 * 7 * 3; // 21 days - export var timeUntilPdfPageNumbersFadeOutAfterScroll = 1000; // 1 second + export let fontSizeStep = 2; + export let maxClipSuccessForRatingsPrompt = 12; + export let maximumJSTimeValue = 1000 * 60 * 60 * 24 * 100000000; // 100M days in milliseconds, http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1 + export let maximumFontSize = 72; + export let maximumMimeSizeLimit = 24900000; + export let minClipSuccessForRatingsPrompt = 4; + export let minimumFontSize = 8; + export let minTimeBetweenBadRatings = 1000 * 60 * 60 * 24 * 7 * 10; // 10 weeks + export let numRetriesPerPatchRequest = 3; + export let pdfCheckCreatePageInterval = 2000; // 2 seconds + export let pdfClippingMessageDelay = 5000; // 5 seconds + export let pdfExtraPageLoadEachSide = 1; + export let pdfInitialPageLoadCount = 3; + export let timeUntilPdfPageNumbersFadeOutAfterScroll = 1000; // 1 second } export module CustomHtmlAttributes { - export var setNameForArrowKeyNav = "setnameforarrowkeynav"; + export let setNameForArrowKeyNav = "setnameforarrowkeynav"; } export module AriaSet { - export var modeButtonSet = "ariaModeButtonSet"; - export var pdfPageSelection = "pdfPageSelection"; - export var serifGroupSet = "serifGroupSet"; + export let modeButtonSet = "ariaModeButtonSet"; + export let pdfPageSelection = "pdfPageSelection"; + export let serifGroupSet = "serifGroupSet"; } } diff --git a/src/scripts/domParsers/domUtils.ts b/src/scripts/domParsers/domUtils.ts deleted file mode 100644 index 21492645..00000000 --- a/src/scripts/domParsers/domUtils.ts +++ /dev/null @@ -1,1178 +0,0 @@ -// 9/28/2016 - We need to go back and update sanitize-html to the latest .d.ts once -// they rename `sanitize` to `sanitizeHtml`, which is the name of the actually exported function -declare let sanitizeHtml; - -// This private has technically been deprecated, but is present in all major browsers as of 2/12/14 and offers -// the best perf for the UTF byte manipulation we need for truncation and byte size estimation. -// DO NOT USE IT WITHOUT CHECKING IF IT EXISTS -- in case browser vendors actually remove them -// ReSharper disable once InconsistentNaming -declare function unescape(s: string): string; - -import {Constants} from "../constants"; -import {ObjectUtils} from "../objectUtils"; -import {SupportedVideoDomains, VideoUtils} from "./videoUtils"; - -import {VideoExtractorFactory} from "./videoExtractorFactory"; - -export interface EmbeddedVideoIFrameSrcs { - srcAttribute: string; - dataOriginalSrcAttribute: string; -} - -/** - * Dom specific Helper utility methods - */ -export class DomUtils { - public static tags = { - a: "a", - b: "b", - applet: "applet", - article: "article", - audio: "audio", - base: "base", - body: "body", - br: "br", - button: "button", - canvas: "canvas", - center: "center", - cite: "cite", - code: "code", - del: "del", - div: "div", - em: "em", - embed: "embed", - figure: "figure", - font: "font", - h1: "h1", - h2: "h2", - h3: "h3", - h4: "h4", - h5: "h5", - h6: "h6", - head: "head", - header: "header", - hr: "hr", - html: "html", - i: "i", - iframe: "iframe", - img: "img", - input: "input", - li: "li", - link: "link", - main: "main", - map: "map", - menu: "menu", - menuitem: "menuitem", - meta: "meta", - meter: "meter", - noscript: "noscript", - object: "object", - ol: "ol", - p: "p", - pre: "pre", - progress: "progress", - script: "script", - span: "span", - source: "source", - strike: "strike", - strong: "strong", - style: "style", - sub: "sub", - sup: "sup", - svg: "svg", - table: "table", - td: "td", - title: "title", - tr: "tr", - u: "u", - ul: "ul", - video: "video" - }; - - // See the OneNote Dev Center API Reference for a list of supported attributes and tags - // https://dev.onenote.com/docs#/introduction/html-tag-support-for-pages - protected static attributesAllowedByOnml: { [index: string]: string[] } = { - "a": ["href", "name", "target"], - "img": ["src"], - "*": ["src", "background-color", "color", "font-family", "font-size", "data*", "alt", "height", "width", "style", "id", "type"] - }; - - protected static tableTags = [ - DomUtils.tags.table, - DomUtils.tags.td, - DomUtils.tags.tr - ]; - - protected static markupTags = [ - DomUtils.tags.b, - DomUtils.tags.em, - DomUtils.tags.strong, - DomUtils.tags.i, - DomUtils.tags.u, - DomUtils.tags.strike, - DomUtils.tags.del, - DomUtils.tags.sup, - DomUtils.tags.sub, - DomUtils.tags.cite, - DomUtils.tags.font, - DomUtils.tags.pre, - DomUtils.tags.code - ]; - - protected static htmlTags = [ - DomUtils.tags.html, - DomUtils.tags.head, - DomUtils.tags.title, - DomUtils.tags.meta, - DomUtils.tags.body, - DomUtils.tags.div, - DomUtils.tags.span, - DomUtils.tags.article, - DomUtils.tags.figure, - DomUtils.tags.header, - DomUtils.tags.main, - DomUtils.tags.center, - DomUtils.tags.iframe, - DomUtils.tags.a, - DomUtils.tags.p, - DomUtils.tags.br, - DomUtils.tags.h1, - DomUtils.tags.h2, - DomUtils.tags.h3, - DomUtils.tags.h4, - DomUtils.tags.h5, - DomUtils.tags.h6, - DomUtils.tags.ul, - DomUtils.tags.ol, - DomUtils.tags.li, - DomUtils.tags.img, - DomUtils.tags.object, - DomUtils.tags.video - ]; - - // TODO: write a module test to make sure these tagsNotSupportedInOnml and the tags above have no intersection - protected static tagsNotSupportedInOnml = [ - DomUtils.tags.applet, - DomUtils.tags.audio, - DomUtils.tags.button, - DomUtils.tags.canvas, - DomUtils.tags.embed, - DomUtils.tags.hr, - DomUtils.tags.input, - DomUtils.tags.link, - DomUtils.tags.map, - DomUtils.tags.menu, - DomUtils.tags.menuitem, - DomUtils.tags.meter, - DomUtils.tags.noscript, - DomUtils.tags.progress, - DomUtils.tags.script, - DomUtils.tags.source, - DomUtils.tags.style, - DomUtils.tags.svg, - DomUtils.tags.video - ]; - - /** - * Given an HTML Document in string form, return an HTML Document in string form - * with the attributes and the content between the HTML tags scrubbed, while preserving - * document structure - */ - public static cleanHtml(contentInHtml: string): string { - let allAttributes: string[] = []; - for (let key in DomUtils.attributesAllowedByOnml) { - if (DomUtils.attributesAllowedByOnml.hasOwnProperty(key)) { - allAttributes = allAttributes.concat(DomUtils.attributesAllowedByOnml[key]); - } - } - - let tags = DomUtils.htmlTags.concat(DomUtils.markupTags).concat(DomUtils.tableTags); - let sanitizedHtml = sanitizeHtml(contentInHtml, { - allowedTags: tags, - allowedAttributes: DomUtils.attributesAllowedByOnml, - allowedSchemes: sanitizeHtml.defaults.allowedSchemes.concat(["data"]), - allowedClasses: { - "*": ["MainArticleContainer"] - } - }); - - return sanitizedHtml; - } - - /** - * Many extensions inject their own stylings into the page, and generally that isn't a problem. But, - * occasionally the styling includes a specific font, which can be very, very large. This method - * removes any base64 encoded binaries defined in any