diff options
| author | Arpit Chakladar <54011232+arpitchakladar@users.noreply.github.com> | 2023-04-04 14:53:04 +0530 |
|---|---|---|
| committer | Arpit Chakladar <54011232+arpitchakladar@users.noreply.github.com> | 2023-04-04 14:53:04 +0530 |
| commit | 5f23f07d04073c06af530332c2d75b48d6c023a0 (patch) | |
| tree | 2c7359a2b33b95f92f3bba9a9074e6bf9137ac1d | |
| parent | d178caee5c93ad9ed91dbd082b0f0b5a9b0507aa (diff) | |
| download | banglar-bhumi-utils-5f23f07d04073c06af530332c2d75b48d6c023a0.tar.gz banglar-bhumi-utils-5f23f07d04073c06af530332c2d75b48d6c023a0.zip | |
Using different global variables for shared modules.
| -rw-r--r-- | config/webpack.config.js | 54 | ||||
| -rw-r--r-- | config/webpack/loader/dynamic-imports-loader.js | 31 | ||||
| -rw-r--r-- | config/webpack/plugins/create-manifest-webpack-plugin/index.js | 14 | ||||
| -rw-r--r-- | config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json | 9 | ||||
| -rw-r--r-- | config/webpack/plugins/create-rules-webpack-plugin.js | 43 | ||||
| -rw-r--r-- | config/webpack/utils/filename-hash.js (renamed from config/webpack/utils/file-name-hash.js) | 3 | ||||
| -rw-r--r-- | package.json | 6 | ||||
| -rw-r--r-- | src/rules/block-scripts.json | 9 | ||||
| -rw-r--r-- | src/rules/redirect-scripts.json | 12 | ||||
| -rw-r--r-- | src/scripts/optimize.ts | 12 | ||||
| -rw-r--r-- | src/shared/block-url.ts | 1 | ||||
| -rw-r--r-- | src/shared/modify-dom.ts | 55 | ||||
| -rw-r--r-- | src/shared/observe-dom.ts | 10 |
13 files changed, 145 insertions, 114 deletions
diff --git a/config/webpack.config.js b/config/webpack.config.js index 010a51f..22544b9 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -11,11 +11,12 @@ global.production = process.env.NODE_ENV === "production"; global.webpackRequire = modulePath => require(path.resolve(CONFIG_DIR, "webpack", modulePath)); const CreateManifestPlugin = webpackRequire("plugins/create-manifest-webpack-plugin"); +const CreateRulesPlugin = webpackRequire("plugins/create-rules-webpack-plugin"); const InjectScriptPlugin = webpackRequire("plugins/inject-script-webpack-plugin"); const { inlineJavascript } = webpackRequire("utils/inline-javascript"); const { getScriptRuntimeFromType } = webpackRequire("utils/script-runtime"); -const { getFileNameHash } = webpackRequire("utils/file-name-hash"); +const { getFileNameHash } = webpackRequire("utils/filename-hash"); const scripts = webpackRequire("utils/scripts"); @@ -54,11 +55,16 @@ for (const scriptPath in scripts) { for (const sharedModule of sharedModules) { const sharedModuleNameHash = getFileNameHash(sharedModule, "shared"); + const sharedModuleGlobalVariableName = `$${sharedModuleNameHash.substring(sharedModuleNameHash.length - 16)}`; sharedModuleEntries[sharedModule] = { import: path.resolve(SOURCE_DIR, "shared", sharedModule), - filename: `shared/${sharedModuleNameHash}.js` + filename: `shared/${sharedModuleNameHash}.js`, + library: { + name: sharedModuleGlobalVariableName, + type: "var" + } }; - sharedModuleExternals[`@/shared/${sharedModule}`] = `/shared/${sharedModuleNameHash}.js`; + sharedModuleExternals[`@/shared/${sharedModule}`] = sharedModuleGlobalVariableName; } const commonOptions = { @@ -82,26 +88,27 @@ const commonOptions = { }, optimization: { minimize: process.env.NODE_ENV === "production" + }, + output: { + iife: true } }; const ecmaScriptModuleOptions = { experiments: { - outputModule: true, - topLevelAwait: true + outputModule: true } }; -const scriptOptions = { - output: { - iife: true - } +const sharedModuleOptions = { + externals: sharedModuleExternals, + externalsType: "var" }; const uninjectedScriptConfiguration = merge( commonOptions, ecmaScriptModuleOptions, - scriptOptions, + sharedModuleOptions, { entry: uninjectedScriptEntries, plugins: [ @@ -110,24 +117,13 @@ const uninjectedScriptConfiguration = merge( from: path.resolve(ROOT_DIR, "static"), to: "./" }] - }), - new CreateManifestPlugin() - ], - module: { - rules: [ - { - enforce: "post", - test: /\.(js|ts)$/, - loader: "./config/webpack/loader/dynamic-imports-loader" - } - ] - } + }) + ] } ); const injectedAfterScriptConfiguration = merge( commonOptions, - scriptOptions, { entry: injectedAfterScriptEntries, plugins: [ @@ -138,7 +134,6 @@ const injectedAfterScriptConfiguration = merge( const injectedBeforeScriptConfiguration = merge( commonOptions, - scriptOptions, { entry: injectedBeforeScriptEntries, plugins: [ @@ -150,14 +145,13 @@ const injectedBeforeScriptConfiguration = merge( const sharedModulesConfiguration = merge( commonOptions, ecmaScriptModuleOptions, + sharedModuleOptions, { - output: { - library: { - type: "module" - } - }, entry: sharedModuleEntries, - externals: sharedModuleExternals + plugins: [ + new CreateManifestPlugin(), + new CreateRulesPlugin() + ] } ); diff --git a/config/webpack/loader/dynamic-imports-loader.js b/config/webpack/loader/dynamic-imports-loader.js deleted file mode 100644 index 12eb5b7..0000000 --- a/config/webpack/loader/dynamic-imports-loader.js +++ /dev/null @@ -1,31 +0,0 @@ -const { ImportManager } = require("import-manager"); -const { getFileNameHash } = webpackRequire("utils/file-name-hash"); - -const sharedModules = webpackRequire("utils/shared-modules.js"); - -module.exports = source => { - const manager = new ImportManager(source); - let modified = false; - - for (const unit of manager.imports.es6.units) { - const moduleIndex = sharedModules.indexOf(unit.module.name); - - if (moduleIndex >= 0 && unit.type === "es6") { - const importedModuleNames = unit.members.entities - .map(entity => `\t${entity.name}`) - .concat(unit.defaultMembers.entities.map(entity => `\tdefault: ${entity.name}`)) - .join(",\n"); - - const importStatement = `const {\n${importedModuleNames}\n} = await import(/* webpackIgnore: true */ "/shared/${getFileNameHash(sharedModules[moduleIndex], "shared")}.js");\n`; - - unit.methods = { - makeUntraceable() {} - }; - manager.remove(unit); - manager.insertStatement(importStatement, "bottom", "dynamic"); - modified = true; - } - } - - return modified ? manager.code.toString() + "\nexport {};" : source; -}; diff --git a/config/webpack/plugins/create-manifest-webpack-plugin/index.js b/config/webpack/plugins/create-manifest-webpack-plugin/index.js index 785d604..a2040da 100644 --- a/config/webpack/plugins/create-manifest-webpack-plugin/index.js +++ b/config/webpack/plugins/create-manifest-webpack-plugin/index.js @@ -2,7 +2,7 @@ const { sources } = require("webpack"); const path = require("path"); const { getScriptRuntimeFromType } = webpackRequire("utils/script-runtime"); -const { getFileNameHash } = webpackRequire("utils/file-name-hash"); +const { getFileNameHash } = webpackRequire("utils/filename-hash"); const scripts = webpackRequire("utils/scripts"); const sharedModules = webpackRequire("utils/shared-modules"); const manifest = webpackRequire("plugins/create-manifest-webpack-plugin/manifest-template.json"); @@ -35,6 +35,14 @@ class CreateManifestPlugin { } } + for (const sharedModule of sharedModules) { + manifest.content_scripts.push({ + matches: [`*://banglarbhumi.gov.in/BanglarBhumi/*`], + js: [`shared/${getFileNameHash(sharedModule, "shared")}.js`], + run_at: "document_start" + }); + } + const resources = []; for (const assetName in assets) { @@ -43,10 +51,6 @@ class CreateManifestPlugin { } } - for (const sharedModule of sharedModules) { - resources.push(`shared/${getFileNameHash(sharedModule, "shared")}.js`); - } - if (resources.length > 0) { manifest.web_accessible_resources = [ { diff --git a/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json b/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json index 0c59ef2..d1d29f4 100644 --- a/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json +++ b/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json @@ -1,9 +1,16 @@ { "manifest_version": 3, "name": "Banglar Bhumi Utils", - "permissions": ["scripting"], + "permissions": ["scripting", "declarativeNetRequest"], "description": "A chrome extension to improve functionality of the banglarbhumi.gov.in website.", "icons": { "512": "icon512.png" + }, + "declarative_net_request" : { + "rule_resources" : [{ + "id": "rules", + "enabled": true, + "path": "rules.json" + }] } } diff --git a/config/webpack/plugins/create-rules-webpack-plugin.js b/config/webpack/plugins/create-rules-webpack-plugin.js new file mode 100644 index 0000000..4a02e2f --- /dev/null +++ b/config/webpack/plugins/create-rules-webpack-plugin.js @@ -0,0 +1,43 @@ +const path = require("path"); +const fs = require("fs"); +const { sources } = require("webpack"); + +class CreateRulesPlugin { + apply(compiler) { + compiler.hooks.compilation.tap("CreateRulesPlugin", compilation => { + compilation.hooks.processAssets.tap( + { + name: "CreateRulesPlugin", + stage: compiler.webpack.Compilation.PROCESS_ASSETS_ADDITIONAL, + additionalAssets: true + }, + assets => { + const ruleFileNames = fs.readdirSync(path.resolve(SOURCE_DIR, "rules")); + const rules = []; + let ruleId = 1; + + for (const ruleFileName of ruleFileNames) { + const rule = require(path.resolve(SOURCE_DIR, "rules", ruleFileName)); + + if (rule instanceof Array) { + for (const rule of rule) { + rule.id = ruleId++; + rules.push(rule); + } + } else { + rule.id = ruleId++; + rules.push(rule); + } + } + + compilation.emitAsset( + "rules.json", + new sources.RawSource(JSON.stringify(rules, undefined, process.env.NODE_ENV === "production" ? undefined : "\t")) + ); + } + ); + }); + } +} + +module.exports = CreateRulesPlugin; diff --git a/config/webpack/utils/file-name-hash.js b/config/webpack/utils/filename-hash.js index 889e9a4..bd66647 100644 --- a/config/webpack/utils/file-name-hash.js +++ b/config/webpack/utils/filename-hash.js @@ -1,10 +1,9 @@ const crypto = require("crypto"); module.exports.getFileNameHash = (fileName, prefix) => { - const finalFileName = `${prefix}-${fileName}`; const hash = crypto .createHash("md5") - .update(finalFileName) + .update(`${prefix}-${fileName}`) .digest("hex"); return production ? hash : `${fileName}-${hash.substring(16)}`; diff --git a/package.json b/package.json index 3506709..e49a2dd 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "author": "Arpit Chakladar", "license": "MIT", "scripts": { - "watch": "NODE_ENV=development webpack watch --config config/webpack.config.js", - "build": "NODE_ENV=production webpack build --config config/webpack.config.js", - "build:dev": "NODE_ENV=development webpack build --config config/webpack.config.js" + "watch": "rm -rf dist && NODE_ENV=development webpack watch --config config/webpack.config.js", + "build": "rm -rf dist && NODE_ENV=production webpack build --config config/webpack.config.js", + "build:dev": "rm -rf dist && NODE_ENV=development webpack build --config config/webpack.config.js" }, "devDependencies": { "@types/chrome": "^0.0.213", diff --git a/src/rules/block-scripts.json b/src/rules/block-scripts.json new file mode 100644 index 0000000..0e7606b --- /dev/null +++ b/src/rules/block-scripts.json @@ -0,0 +1,9 @@ +{ + "priority": 1, + "action": { + "type": "block" + }, + "condition": { + "regexFilter": "^https:\/\/banglarbhumi.gov.in\/BanglarBhumi\/js\/(jquery-1.12.4|jquery.nivo.slider|bootstrap-dropdownhover).js$" + } +} diff --git a/src/rules/redirect-scripts.json b/src/rules/redirect-scripts.json new file mode 100644 index 0000000..b54a7ed --- /dev/null +++ b/src/rules/redirect-scripts.json @@ -0,0 +1,12 @@ +{ + "priority": 1, + "action": { + "type": "redirect", + "redirect": { + "url": "https://code.jquery.com/jquery-1.12.4.min.js" + } + }, + "condition": { + "urlFilter": "https://banglarbhumi.gov.in/BanglarBhumi/js/jquery-1.12.4.min.js" + } +} diff --git a/src/scripts/optimize.ts b/src/scripts/optimize.ts index 55492b6..336a6ca 100644 --- a/src/scripts/optimize.ts +++ b/src/scripts/optimize.ts @@ -2,22 +2,10 @@ import { modifyDOM } from "@/shared/modify-dom"; modifyDOM([ [ - "head > script:nth-child(34)", - { - src: null - } - ], - [ "head > script:nth-child(36)", { src: null, innerHTML: "$.prototype.nivoSlider = () => {};" } - ], - [ - "head > script:nth-child(43)", - { - src: null - } ] ]); diff --git a/src/shared/block-url.ts b/src/shared/block-url.ts new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/shared/block-url.ts @@ -0,0 +1 @@ + diff --git a/src/shared/modify-dom.ts b/src/shared/modify-dom.ts index 337c879..21dfab0 100644 --- a/src/shared/modify-dom.ts +++ b/src/shared/modify-dom.ts @@ -4,44 +4,47 @@ type DOMReplacements = { innerHTML?: string; [key: string]: string | undefined | null; }; - type DOMModificaitonRule = readonly [string, DOMReplacements]; +type DOMModificationRules = (DOMModificaitonRule | null)[]; -export const modifyDOM = (modificationRules: (DOMModificaitonRule | null)[]) => { - let count = 0; +let domModificationRules: DOMModificationRules = []; +let domModificationFinishedCount = 0; - observeDOM(() => { - for (let i = 0; i < modificationRules.length; i++) { - if (modificationRules[i]) { - const element = document.querySelector(modificationRules[i]![0]) as HTMLElement | null; +observeDOM(() => { + for (let i = 0; i < domModificationRules.length; i++) { + if (domModificationRules[i]) { + const element = document.querySelector(domModificationRules[i]![0]) as HTMLElement | null; - if (element) { - const attributes = modificationRules[i]![1]; + if (element) { + const attributes = domModificationRules[i]![1]; - if (attributes.innerHTML) { - element.innerHTML = attributes.innerHTML as string; - } + if (attributes.innerHTML) { + element.innerHTML = attributes.innerHTML as string; + } - delete attributes.innerHTML; + delete attributes.innerHTML; - for (const attribute in attributes) { - if (attributes[attribute] === null) { - element.removeAttribute(attribute); - } else { - element.setAttribute(attribute, attributes[attribute] as string); - } + for (const attribute in attributes) { + if (attributes[attribute] === null) { + element.removeAttribute(attribute); + } else { + element.setAttribute(attribute, attributes[attribute] as string); } + } - modificationRules[i] = null; - count++; + domModificationRules[i] = null; + domModificationFinishedCount++; - if (count >= modificationRules.length) { - return true; - } + if (domModificationFinishedCount >= domModificationRules.length) { + return true; } } } + } + + return false; +}); - return false; - }); +export const modifyDOM = (modificationRules: DOMModificationRules) => { + domModificationRules = domModificationRules.concat(modificationRules); }; diff --git a/src/shared/observe-dom.ts b/src/shared/observe-dom.ts index dc2cb45..37bcfcd 100644 --- a/src/shared/observe-dom.ts +++ b/src/shared/observe-dom.ts @@ -1,15 +1,17 @@ type ObserveDOMCallback = () => boolean; let callbacks: (ObserveDOMCallback | null)[] = []; -let count = 0; +let callbacksCalledCount = 0; const observer = new MutationObserver(() => { - for (const callback of callbacks) { + for (let i = 0; i < callbacks.length; i++) { + const callback = callbacks[i]; if (callback && callback()) { - count++; + callbacksCalledCount++; + callbacks[i] = null; } - if (count >= callbacks.length) { + if (callbacksCalledCount >= callbacks.length) { observer.disconnect(); break; |
