Feature/#48 migrate to typescript #151
|
@ -4,6 +4,7 @@ const gulpLoadPlugins = require('gulp-load-plugins')
|
||||||
const terser = require('terser');
|
const terser = require('terser');
|
||||||
const del = require('del');
|
const del = require('del');
|
||||||
const browserify = require('browserify');
|
const browserify = require('browserify');
|
||||||
|
const tsify = require('tsify')
|
||||||
const babelify = require('babelify');
|
const babelify = require('babelify');
|
||||||
const source = require('vinyl-source-stream');
|
const source = require('vinyl-source-stream');
|
||||||
const buffer = require('vinyl-buffer');
|
const buffer = require('vinyl-buffer');
|
||||||
|
@ -124,13 +125,14 @@ gulp.task('scripts', () => {
|
||||||
const streams = [];
|
const streams = [];
|
||||||
|
|
||||||
modules.forEach(module => {
|
modules.forEach(module => {
|
||||||
inputs.push(`${src.scripts}/${module}.js`);
|
inputs.push(`${src.scripts}/${module}.ts`);
|
||||||
streams.push(source(`${module}.js`));
|
streams.push(source(`${module}.js`));
|
||||||
});
|
});
|
||||||
|
|
||||||
const b = browserify(inputs, { debug: isDev });
|
const b = browserify(inputs, { debug: isDev });
|
||||||
|
|
||||||
let outstream = b
|
let outstream = b
|
||||||
|
.plugin(tsify)
|
||||||
.transform('babelify')
|
.transform('babelify')
|
||||||
.plugin(factor, { outputs: streams })
|
.plugin(factor, { outputs: streams })
|
||||||
.bundle()
|
.bundle()
|
||||||
|
@ -206,7 +208,7 @@ Watchers
|
||||||
gulp.task('watch', (done) => {
|
gulp.task('watch', (done) => {
|
||||||
gulp.watch(`${src.styles}/**/*.scss`, gulp.series('clean:build', 'styles', 'dist:copy', 'dist:zip'))
|
gulp.watch(`${src.styles}/**/*.scss`, gulp.series('clean:build', 'styles', 'dist:copy', 'dist:zip'))
|
||||||
|
|
||||||
gulp.watch(`${src.scripts}/**/*.js`, gulp.series('clean:build', 'scripts', 'dist:copy', 'dist:zip'))
|
gulp.watch(`${src.scripts}/**/*.ts`, gulp.series('clean:build', 'scripts', 'dist:copy', 'dist:zip'))
|
||||||
|
|
||||||
gulp.watch(`${src.images}/**/*`, gulp.series('clean:build', 'images', 'dist:copy', 'dist:zip'))
|
gulp.watch(`${src.images}/**/*`, gulp.series('clean:build', 'images', 'dist:copy', 'dist:zip'))
|
||||||
|
|
||||||
|
|
143
package-lock.json
generated
143
package-lock.json
generated
|
@ -1488,12 +1488,37 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"@types/chrome": {
|
||||||
|
"version": "0.0.127",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.127.tgz",
|
||||||
|
"integrity": "sha512-hBB9EApLYKKn2GvklVkTxVP6vZvxsH9okyIRUinNtMzZHIgIKWQk/ESbX+O5g4Bihfy38+aFGn7Kl7Cxou5JUg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/filesystem": "*",
|
||||||
|
"@types/har-format": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/color-name": {
|
"@types/color-name": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/filesystem": {
|
||||||
|
"version": "0.0.29",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz",
|
||||||
|
"integrity": "sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/filewriter": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/filewriter": {
|
||||||
|
"version": "0.0.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz",
|
||||||
|
"integrity": "sha1-wFTor02d11205jq8dviFFocU1LM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/glob": {
|
"@types/glob": {
|
||||||
"version": "7.1.3",
|
"version": "7.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
|
||||||
|
@ -1504,6 +1529,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/har-format": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-IG8AE1m2pWtPqQ7wXhFhy6Q59bwwnLwO36v5Rit2FrbXCIp8Sk8E2PfUCreyrdo17STwFSKDAkitVuVYbpEHvQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/minimatch": {
|
"@types/minimatch": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||||
|
@ -1651,6 +1682,12 @@
|
||||||
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
|
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"any-promise": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||||
|
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"anymatch": {
|
"anymatch": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
|
||||||
|
@ -6736,6 +6773,44 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gulp-typescript": {
|
||||||
|
"version": "6.0.0-alpha.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-6.0.0-alpha.1.tgz",
|
||||||
|
"integrity": "sha512-KoT0TTfjfT7w3JItHkgFH1T/zK4oXWC+a8xxKfniRfVcA0Fa1bKrIhztYelYmb+95RB80OLMBreknYkdwzdi2Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-colors": "^4.1.1",
|
||||||
|
"plugin-error": "^1.0.1",
|
||||||
|
"source-map": "^0.7.3",
|
||||||
|
"through2": "^3.0.1",
|
||||||
|
"vinyl": "^2.2.0",
|
||||||
|
"vinyl-fs": "^3.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-colors": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||||
|
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"through2": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"readable-stream": "2 || 3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"gulp-zip": {
|
"gulp-zip": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.2.tgz",
|
||||||
|
@ -11772,9 +11847,8 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"spacetime": {
|
"spacetime": {
|
||||||
"version": "6.12.2",
|
"version": "github:Serraniel/spacetime#84ae159680732067195b84744e172f4e2497b4ec",
|
||||||
"resolved": "https://registry.npmjs.org/spacetime/-/spacetime-6.12.2.tgz",
|
"from": "github:Serraniel/spacetime#bugfix/#255-typescript-constructor-options-missing"
|
||||||
"integrity": "sha512-w0St4Q9X8KtuZ/JY8+FM8a4hMrAoNNUWQCt9UQQAUzwk8eDW5wrGh4SaNvEg+9cjLF++vixm6SgJyC6F7ALF/A=="
|
|
||||||
},
|
},
|
||||||
"sparkles": {
|
"sparkles": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
@ -12138,6 +12212,12 @@
|
||||||
"get-stdin": "^4.0.1"
|
"get-stdin": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"strip-json-comments": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"strip-outer": {
|
"strip-outer": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
|
||||||
|
@ -12569,6 +12649,51 @@
|
||||||
"glob": "^7.1.2"
|
"glob": "^7.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tsconfig": {
|
||||||
|
"version": "5.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-5.0.3.tgz",
|
||||||
|
"integrity": "sha1-X0J45wGACWeo/Dg/0ZZIh48qbjo=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"any-promise": "^1.3.0",
|
||||||
|
"parse-json": "^2.2.0",
|
||||||
|
"strip-bom": "^2.0.0",
|
||||||
|
"strip-json-comments": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"parse-json": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
|
||||||
|
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"error-ex": "^1.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tsify": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsify/-/tsify-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-Pdo3ZO8CAgbQgNcFRBmfbgsPP+4TsD0itbSF5YgTnxKBXfg6WkQ79e4/bqBaq/7cEYa7vIOM1pHxnux8rJJnzg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"convert-source-map": "^1.1.0",
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"object-assign": "^4.1.0",
|
||||||
|
"semver": "^6.1.0",
|
||||||
|
"through2": "^2.0.0",
|
||||||
|
"tsconfig": "^5.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"tty-browserify": {
|
"tty-browserify": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
|
||||||
|
@ -12602,6 +12727,12 @@
|
||||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"umd": {
|
"umd": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
|
||||||
|
@ -13019,6 +13150,12 @@
|
||||||
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
|
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"web-ext-types": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-ext-types/-/web-ext-types-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-oQZYDU3W8X867h8Jmt3129kRVKklz70db40Y6OzoTTuzOJpF/dB2KULJUf0txVPyUUXuyzV8GmT3nVvRHoG+Ew==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"which": {
|
"which": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
"homepage": "https://github.com/Serraniel/AniwatchPlus#readme",
|
"homepage": "https://github.com/Serraniel/AniwatchPlus#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color": "^3.1.3",
|
"color": "^3.1.3",
|
||||||
"spacetime": "^6.12.2",
|
"spacetime": "github:Serraniel/spacetime#bugfix/#255-typescript-constructor-options-missing",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
"@babel/plugin-proposal-private-methods": "^7.12.1",
|
"@babel/plugin-proposal-private-methods": "^7.12.1",
|
||||||
"@babel/preset-env": "^7.12.11",
|
"@babel/preset-env": "^7.12.11",
|
||||||
"@babel/register": "^7.12.10",
|
"@babel/register": "^7.12.10",
|
||||||
|
"@types/chrome": "0.0.127",
|
||||||
"babelify": "^10.0.0",
|
"babelify": "^10.0.0",
|
||||||
"browserify": "^17.0.0",
|
"browserify": "^17.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
@ -66,12 +67,16 @@
|
||||||
"gulp-size": "^3.0.0",
|
"gulp-size": "^3.0.0",
|
||||||
"gulp-sourcemaps": "^3.0.0",
|
"gulp-sourcemaps": "^3.0.0",
|
||||||
"gulp-terser": "^2.0.0",
|
"gulp-terser": "^2.0.0",
|
||||||
|
"gulp-typescript": "^6.0.0-alpha.1",
|
||||||
"gulp-zip": "^5.0.2",
|
"gulp-zip": "^5.0.2",
|
||||||
"merge-stream": "^2.0.0",
|
"merge-stream": "^2.0.0",
|
||||||
"postcss": "^8.2.1",
|
"postcss": "^8.2.1",
|
||||||
"sass": "^1.30.0",
|
"sass": "^1.30.0",
|
||||||
"terser": "^5.5.1",
|
"terser": "^5.5.1",
|
||||||
|
"tsify": "^5.0.2",
|
||||||
|
"typescript": "^4.1.3",
|
||||||
"vinyl-buffer": "^1.0.1",
|
"vinyl-buffer": "^1.0.1",
|
||||||
"vinyl-source-stream": "^2.0.0"
|
"vinyl-source-stream": "^2.0.0",
|
||||||
|
"web-ext-types": "^3.2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
const { assigned } = require("../utils/helpers")
|
|
||||||
|
|
||||||
class StorageProviderChromium {
|
|
||||||
|
|
||||||
setData(key, value) {
|
|
||||||
let obj = {};
|
|
||||||
obj[key] = value;
|
|
||||||
|
|
||||||
this.getStorage().set(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
getData(key, defaultValue, callback) {
|
|
||||||
this.getStorage().get(key, items => {
|
|
||||||
if (assigned(items) && assigned(items[key])) {
|
|
||||||
callback(items[key]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback(defaultValue);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getStorage() {
|
|
||||||
if (assigned(chrome.storage.sync)) {
|
|
||||||
return chrome.storage.sync;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chrome.storage.local;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class StorageProviderFirefox {
|
|
||||||
|
|
||||||
setData(key, value) {
|
|
||||||
let obj = {};
|
|
||||||
obj[key] = value;
|
|
||||||
|
|
||||||
this.getStorage().set(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
getData(key, defaultValue, callback) {
|
|
||||||
let promise = this.getStorage().get(key);
|
|
||||||
|
|
||||||
promise.then(items => {
|
|
||||||
if (assigned(items) && assigned(items[key])) {
|
|
||||||
callback(items[key]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback(defaultValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getStorage() {
|
|
||||||
if (assigned(browser.storage.sync)) {
|
|
||||||
return browser.storage.sync;
|
|
||||||
}
|
|
||||||
|
|
||||||
return browser.storage.local;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let __storageProvieder;
|
|
||||||
|
|
||||||
function createStorageProvider() {
|
|
||||||
// chrome based browser
|
|
||||||
if (assigned(chrome?.app)) {
|
|
||||||
__storageProvieder = new StorageProviderChromium();
|
|
||||||
}
|
|
||||||
// firefox
|
|
||||||
else {
|
|
||||||
__storageProvieder = new StorageProviderFirefox();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getGlobalStorageProvider() {
|
|
||||||
if (!assigned(__storageProvieder)) {
|
|
||||||
createStorageProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
return __storageProvieder;
|
|
||||||
}
|
|
117
src/javascript/browserApi/storageProvider.ts
Normal file
117
src/javascript/browserApi/storageProvider.ts
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import { assigned } from '../utils/helpers';
|
||||||
|
|
||||||
|
enum BrowserApi {
|
||||||
|
Unknown,
|
||||||
|
Chromium,
|
||||||
|
Firefox,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ConfigurationStorageBooleanCallback = (value: boolean) => void;
|
||||||
|
|
||||||
|
export interface ICustomBrowserStorageProvider {
|
||||||
|
setDataAsBoolean(key: string, value: boolean): void;
|
||||||
|
getDataAsBoolean(key: string, defaultValue: boolean, callback: ConfigurationStorageBooleanCallback): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StorageProviderChromium implements ICustomBrowserStorageProvider {
|
||||||
|
|
||||||
|
setDataAsBoolean(key: string, value: boolean): void {
|
||||||
|
let obj = {};
|
||||||
|
obj[key] = value;
|
||||||
|
|
||||||
|
this.getStorage().set(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDataAsBoolean(key: string, defaultValue: boolean, callback: ConfigurationStorageBooleanCallback): void {
|
||||||
|
this.getStorage().get(key, items => {
|
||||||
|
if (assigned(items) && assigned(items[key])) {
|
||||||
|
callback(items[key]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(defaultValue);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private getStorage(): chrome.storage.StorageArea {
|
||||||
|
if (assigned(chrome.storage.sync)) {
|
||||||
|
return chrome.storage.sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chrome.storage.local;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class StorageProviderFirefox implements ICustomBrowserStorageProvider {
|
||||||
|
|
||||||
|
setDataAsBoolean(key: string, value: boolean): void {
|
||||||
|
let obj = {};
|
||||||
|
obj[key] = value;
|
||||||
|
|
||||||
|
this.getStorage().set(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDataAsBoolean(key: string, defaultValue: boolean, callback: ConfigurationStorageBooleanCallback): void {
|
||||||
|
let promise = this.getStorage().get(key);
|
||||||
|
|
||||||
|
promise.then(items => {
|
||||||
|
if (assigned(items) && assigned(items[key])) {
|
||||||
|
callback(items[key] as boolean);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(defaultValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Serraniel
commented
Review
- [x] Check Todo
This may be used as an alternative and maybe better implementation: This may be used as an alternative and maybe better implementation:
https://stackoverflow.com/a/45985333
|
|||||||
|
private getStorage(): browser.storage.StorageArea {
|
||||||
|
if (assigned(browser.storage.sync)) {
|
||||||
|
return browser.storage.sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
return browser.storage.local;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let __storageProvieder: ICustomBrowserStorageProvider;
|
||||||
|
|
||||||
|
function getBrowserApi(): BrowserApi {
|
||||||
|
if (typeof chrome !== 'undefined') {
|
||||||
|
if (typeof browser !== 'undefined') {
|
||||||
|
return BrowserApi.Firefox;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BrowserApi.Chromium;
|
||||||
|
}
|
||||||
|
else if (typeof browser !== 'undefined') {
|
||||||
|
return BrowserApi.Firefox;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BrowserApi.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStorageProvider() {
|
||||||
|
|
||||||
|
let api = getBrowserApi();
|
||||||
|
|
||||||
|
// chromium
|
||||||
|
if (api === BrowserApi.Chromium) {
|
||||||
|
__storageProvieder = new StorageProviderChromium();
|
||||||
|
}
|
||||||
|
// firefox
|
||||||
|
else if (api === BrowserApi.Firefox) {
|
||||||
|
__storageProvieder = new StorageProviderFirefox();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "Unknown browser API. Cannot create storage provider.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGlobalStorageProvider(): ICustomBrowserStorageProvider {
|
||||||
|
if (!assigned(__storageProvieder)) {
|
||||||
|
createStorageProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
return __storageProvieder;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { getGlobalStorageProvider } from "../browserApi/storageProvider";
|
import { ConfigurationStorageBooleanCallback, getGlobalStorageProvider } from "../browserApi/storageProvider";
|
||||||
import { assigned } from "../utils/helpers";
|
import { assigned } from "../utils/helpers";
|
||||||
|
|
||||||
// website
|
// website
|
||||||
|
@ -17,17 +17,18 @@ export const SETTINGS_playerAutoplayAfterScreenshot = 'playerAutoplayAfterScreen
|
||||||
// w2g
|
// w2g
|
||||||
export const SETTINGS_w2gDisplayCharacterCounter = 'w2gDisplayCharacterCounter';
|
export const SETTINGS_w2gDisplayCharacterCounter = 'w2gDisplayCharacterCounter';
|
||||||
class Configuration {
|
class Configuration {
|
||||||
|
settingsCache: Map<string, boolean>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.settingsCache = new Map();
|
this.settingsCache = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
getProperty(key, callback) {
|
getProperty(key: string, callback: ConfigurationStorageBooleanCallback): void {
|
||||||
if (this.settingsCache.has(key)) {
|
if (this.settingsCache.has(key)) {
|
||||||
callback(this.settingsCache.get(key));
|
callback(this.settingsCache.get(key));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// OOOPS // currently all settings are default true. This isn´t a problem but there should be much better soloutions after migration to typescript....
|
getGlobalStorageProvider().getDataAsBoolean(key, true, value => {
|
||||||
getGlobalStorageProvider().getData(key, true, value => {
|
|
||||||
this.settingsCache.set(key, value);
|
this.settingsCache.set(key, value);
|
||||||
callback(value);
|
callback(value);
|
||||||
});
|
});
|
||||||
|
@ -35,7 +36,7 @@ class Configuration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let __globalConfig;
|
let __globalConfig: Configuration;
|
||||||
|
|
||||||
export function getGlobalConfiguration() {
|
export function getGlobalConfiguration() {
|
||||||
if (!assigned(__globalConfig)) {
|
if (!assigned(__globalConfig)) {
|
||||||
|
@ -43,4 +44,4 @@ export function getGlobalConfiguration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return __globalConfig;
|
return __globalConfig;
|
||||||
}
|
}
|
|
@ -5,26 +5,27 @@ import * as helper from '../utils/helpers';
|
||||||
const SCREENSHOT_TOOLTIP_ID = 'anilyr-screenshots-tooltip';
|
const SCREENSHOT_TOOLTIP_ID = 'anilyr-screenshots-tooltip';
|
||||||
const PLAYER_ID = 'player';
|
const PLAYER_ID = 'player';
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_playerAutoplayAfterScreenshot, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_playerAutoplayAfterScreenshot, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.registerScript(node => {
|
core.registerScript((node: Node) => {
|
||||||
if (helper.isHtmlElement(node) && node.id === SCREENSHOT_TOOLTIP_ID) {
|
let element = node as HTMLElement;
|
||||||
observeScreenshotTooltip(node);
|
if (helper.assigned(element) && element.id === SCREENSHOT_TOOLTIP_ID) {
|
||||||
|
observeScreenshotTooltip(element);
|
||||||
}
|
}
|
||||||
}, "^/anime/[0-9]*/[0-9]*$");
|
}, "^/anime/[0-9]*/[0-9]*$");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function observeScreenshotTooltip(tooltip) {
|
function observeScreenshotTooltip(tooltip: HTMLElement): void {
|
||||||
let observer = new MutationObserver(mutations => {
|
let observer = new MutationObserver(mutations => {
|
||||||
mutations.forEach(mutation => {
|
mutations.forEach(mutation => {
|
||||||
// Switched to invisible
|
// Switched to invisible
|
||||||
if (!mutation.oldValue.includes('display: none') && mutation.target.style.display == 'none') {
|
if (!mutation.oldValue.includes('display: none') && helper.isHtmlElement(mutation.target) && (mutation.target as HTMLElement).style.display == 'none') {
|
||||||
let player = findPlayer();
|
let playerElement = findPlayerElement();
|
||||||
if (helper.assigned(player)) {
|
if (helper.assigned(playerElement)) {
|
||||||
resumePlayer(player);
|
resumePlayer(playerElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -37,17 +38,15 @@ function observeScreenshotTooltip(tooltip) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function findPlayer() {
|
function findPlayerElement(): HTMLVideoElement {
|
||||||
const PLAYER_TAG_NAME = 'VIDEO'; // tagName gives UpperCase
|
|
||||||
|
|
||||||
let playerCandidate = document.getElementById(PLAYER_ID);
|
let playerCandidate = document.getElementById(PLAYER_ID);
|
||||||
if (playerCandidate.tagName === PLAYER_TAG_NAME) {
|
if (playerCandidate instanceof HTMLVideoElement) {
|
||||||
return playerCandidate;
|
return playerCandidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resumePlayer(player) {
|
function resumePlayer(player: HTMLVideoElement) {
|
||||||
player.play();
|
player.play();
|
||||||
}
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
import { getGlobalConfiguration, SETTINGS_requestBeautifyPage } from '../configuration/configuration';
|
import { getGlobalConfiguration, SETTINGS_requestBeautifyPage } from '../configuration/configuration';
|
||||||
import * as core from '../utils/aniwatchCore';
|
import * as core from '../utils/aniwatchCore';
|
||||||
import * as color from '../utils/colors';
|
import * as color from '../utils/colors';
|
||||||
import * as helper from '../utils/helpers';
|
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_requestBeautifyPage, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_requestBeautifyPage, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.registerScript(node => {
|
core.registerScript((node: Node) => {
|
||||||
// run the scripts
|
// run the scripts
|
||||||
if (helper.isHtmlElement(node)) {
|
if (node instanceof HTMLElement) {
|
||||||
changeFollowedStarColor(node);
|
changeFollowedStarColor(node);
|
||||||
changeBorderColorOwnRequests(node);
|
changeBorderColorOwnRequests(node);
|
||||||
removeUnknownUsers(node);
|
removeUnknownUsers(node);
|
||||||
|
@ -18,20 +17,20 @@ export function init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeFollowedStarColor(node) {
|
function changeFollowedStarColor(node: HTMLElement): void {
|
||||||
const starIcon = 'star';
|
const STAR_ICON = 'star';
|
||||||
|
|
||||||
// find stars
|
// find stars
|
||||||
let followedItems = Array.from(node.querySelectorAll('i')).filter(i => i.innerText.trim() === starIcon);
|
let followedItems = Array.from(node.querySelectorAll('i')).filter(i => i.innerText.trim() === STAR_ICON);
|
||||||
|
|
||||||
// change color
|
// change color
|
||||||
followedItems.forEach(item => item.style.color = color.aniBlue);
|
followedItems.forEach(item => item.style.color = color.aniBlue);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeBorderColorOwnRequests(node) {
|
function changeBorderColorOwnRequests(node: HTMLElement): void {
|
||||||
const targetTagName = 'MD-LIST-ITEM'; // tagName is upper case
|
const TARGET_TAG_NAME = 'MD-LIST-ITEM'; // tagName is upper case
|
||||||
|
|
||||||
let updateFunc = item => {
|
let updateFunc = (item: HTMLElement): void => {
|
||||||
let profileLink = item.querySelectorAll('a[href*="/profile/"]:not([href="/profile/false"])');
|
let profileLink = item.querySelectorAll('a[href*="/profile/"]:not([href="/profile/false"])');
|
||||||
|
|
||||||
// highlight left border for own request
|
// highlight left border for own request
|
||||||
|
@ -41,7 +40,7 @@ function changeBorderColorOwnRequests(node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// are we target tag?
|
// are we target tag?
|
||||||
if (node.tagName === targetTagName) {
|
if (node.tagName === TARGET_TAG_NAME) {
|
||||||
updateFunc(node);
|
updateFunc(node);
|
||||||
} else {
|
} else {
|
||||||
// find items -> all
|
// find items -> all
|
||||||
|
@ -49,15 +48,17 @@ function changeBorderColorOwnRequests(node) {
|
||||||
|
|
||||||
// update borders
|
// update borders
|
||||||
requestItems.forEach(item => {
|
requestItems.forEach(item => {
|
||||||
updateFunc(item);
|
if (item instanceof HTMLElement) {
|
||||||
|
updateFunc(item);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeUnknownUsers(node) {
|
function removeUnknownUsers(node: HTMLElement): void {
|
||||||
const targetTagName = 'MD-LIST-ITEM'; // tagName is upper case
|
const TARGET_TAG_NAME = 'MD-LIST-ITEM'; // tagName is upper case
|
||||||
|
|
||||||
let updateFunc = item => {
|
let updateFunc = (item: Element) => {
|
||||||
// find user profile link -> own request
|
// find user profile link -> own request
|
||||||
let profileLink = item.querySelectorAll('a[href*="/profile/"]:not([href="/profile/false"])');
|
let profileLink = item.querySelectorAll('a[href*="/profile/"]:not([href="/profile/false"])');
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ function removeUnknownUsers(node) {
|
||||||
let lowerDiv = upperDiv.parentElement.nextElementSibling;
|
let lowerDiv = upperDiv.parentElement.nextElementSibling;
|
||||||
|
|
||||||
// remember Data
|
// remember Data
|
||||||
let anime = lowerDiv.innerText;
|
let anime = lowerDiv.textContent;
|
||||||
let profileData = upperDiv.innerHTML;
|
let profileData = upperDiv.innerHTML;
|
||||||
|
|
||||||
// add user note if own request
|
// add user note if own request
|
||||||
|
@ -92,7 +93,7 @@ function removeUnknownUsers(node) {
|
||||||
upperDiv.appendChild(bElement);
|
upperDiv.appendChild(bElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.tagName === targetTagName) {
|
if (node.tagName === TARGET_TAG_NAME) {
|
||||||
updateFunc(node);
|
updateFunc(node);
|
||||||
} else {
|
} else {
|
||||||
// find items -> all
|
// find items -> all
|
|
@ -1,61 +0,0 @@
|
||||||
import { getGlobalConfiguration, SETTINGS_websiteHideUnusedTabs, SETTINGS_websiteOptimizeListAppearance } from '../configuration/configuration';
|
|
||||||
import * as core from '../utils/aniwatchCore';
|
|
||||||
import * as helper from '../utils/helpers';
|
|
||||||
|
|
||||||
export function init() {
|
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_websiteHideUnusedTabs, value => {
|
|
||||||
// if disabled, add class to avoid our css optimizations
|
|
||||||
if (!value) {
|
|
||||||
let disableFunc = node => {
|
|
||||||
if (helper.isHtmlElement(node)) {
|
|
||||||
let disableNode = node => {
|
|
||||||
node.classList.add('awp-hide-unused-disabled')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.tagName === 'MD-TAB-ITEM') {
|
|
||||||
disableNode(node);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.querySelectorAll('md-tab-item').forEach(node => disableNode(node));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
core.registerScript(node => {
|
|
||||||
disableFunc(node);
|
|
||||||
}, ".*");
|
|
||||||
|
|
||||||
core.runAfterLoad(() => {
|
|
||||||
disableFunc(document.body);
|
|
||||||
}, ".*");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_websiteOptimizeListAppearance, value => {
|
|
||||||
// if disabled, add class to avoid our css optimizations
|
|
||||||
if (!value) {
|
|
||||||
let disableFunc = node => {
|
|
||||||
if (helper.isHtmlElement(node)) {
|
|
||||||
let disableNode = node => {
|
|
||||||
node.classList.add('awp-list-disabled')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.tagName === 'MD-LIST-ITEM') {
|
|
||||||
disableNode(node);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.querySelectorAll('md-list-item').forEach(node => disableNode(node));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
core.registerScript(node => {
|
|
||||||
disableFunc(node);
|
|
||||||
}, ".*");
|
|
||||||
|
|
||||||
core.runAfterLoad(() => {
|
|
||||||
disableFunc(document.body);
|
|
||||||
}, ".*");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
60
src/javascript/enhancements/cssEnhancements.ts
Normal file
60
src/javascript/enhancements/cssEnhancements.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { getGlobalConfiguration, SETTINGS_websiteHideUnusedTabs, SETTINGS_websiteOptimizeListAppearance } from '../configuration/configuration';
|
||||||
|
import * as core from '../utils/aniwatchCore';
|
||||||
|
|
||||||
|
export function init(): void {
|
||||||
|
getGlobalConfiguration().getProperty(SETTINGS_websiteHideUnusedTabs, value => {
|
||||||
|
// if disabled, add class to avoid our css optimizations
|
||||||
|
if (!value) {
|
||||||
|
let disableFunc = (node: Element) => {
|
||||||
|
let disableNode = (node: Element) => {
|
||||||
|
node.classList.add('awp-hide-unused-disabled')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.tagName === 'MD-TAB-ITEM') {
|
||||||
|
disableNode(node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.querySelectorAll('md-tab-item').forEach(node => disableNode(node));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
core.registerScript((node: Node) => {
|
||||||
|
if (node instanceof Element) {
|
||||||
|
disableFunc(node);
|
||||||
|
}
|
||||||
|
}, ".*");
|
||||||
|
|
||||||
|
core.runAfterLoad(() => {
|
||||||
|
disableFunc(document.body);
|
||||||
|
}, ".*");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getGlobalConfiguration().getProperty(SETTINGS_websiteOptimizeListAppearance, value => {
|
||||||
|
// if disabled, add class to avoid our css optimizations
|
||||||
|
if (!value) {
|
||||||
|
let disableFunc = (node: Element) => {
|
||||||
|
let disableNode = (node: Element) => {
|
||||||
|
node.classList.add('awp-list-disabled')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.tagName === 'MD-LIST-ITEM') {
|
||||||
|
disableNode(node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.querySelectorAll('md-list-item').forEach(node => disableNode(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.registerScript(node => {
|
||||||
|
if (node instanceof Element) {
|
||||||
|
disableFunc(node);
|
||||||
|
}
|
||||||
|
}, ".*");
|
||||||
|
|
||||||
|
core.runAfterLoad(() => {
|
||||||
|
disableFunc(document.body);
|
||||||
|
}, ".*");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ const BADGE_CLASS = 'label';
|
||||||
const DARKCOLOR_CLASS = 'awp-fontColor-dark';
|
const DARKCOLOR_CLASS = 'awp-fontColor-dark';
|
||||||
const __observedBadges = [];
|
const __observedBadges = [];
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_websiteOptimizeFontColors, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_websiteOptimizeFontColors, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.runAfterLoad(() => {
|
core.runAfterLoad(() => {
|
||||||
|
@ -18,30 +18,30 @@ export function init() {
|
||||||
checkRunColorOptimization(document.documentElement);
|
checkRunColorOptimization(document.documentElement);
|
||||||
}, ".*");
|
}, ".*");
|
||||||
|
|
||||||
core.registerScript(node => {
|
core.registerScript((node: Node) => {
|
||||||
checkRunColorOptimization(node);
|
if (node instanceof Element) {
|
||||||
|
checkRunColorOptimization(node);
|
||||||
|
}
|
||||||
}, ".*");
|
}, ".*");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRunColorOptimization(node) {
|
function checkRunColorOptimization(node: Element): void {
|
||||||
// run the scripts
|
// run the scripts
|
||||||
if (helper.isHtmlElement(node)) {
|
if (node.classList.contains(BADGE_CLASS)) {
|
||||||
if (node.classList.contains(BADGE_CLASS)) {
|
tryRegisterObserverForBadge(node);
|
||||||
tryRegisterObserverForBadge(node);
|
optimizeFontColorsBadges(node);
|
||||||
optimizeFontColorsBadges(node);
|
}
|
||||||
}
|
else {
|
||||||
else {
|
node.querySelectorAll(`.${BADGE_CLASS}`).forEach(element => {
|
||||||
node.querySelectorAll(`.${BADGE_CLASS}`).forEach(element => {
|
tryRegisterObserverForBadge(element);
|
||||||
tryRegisterObserverForBadge(element);
|
optimizeFontColorsBadges(element);
|
||||||
optimizeFontColorsBadges(element);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryRegisterObserverForBadge(badge) {
|
function tryRegisterObserverForBadge(badge: Node): void {
|
||||||
// some badges change there color via late loading so we also have to observe the classlist
|
// some badges change there color via late loading so we also have to observe the classlist
|
||||||
// example: Navigating from a list to an anime -> "Currently Airing" late loads the color badge
|
// example: Navigating from a list to an anime -> "Currently Airing" late loads the color badge
|
||||||
// this only happens when navigating from a list, direct loading works
|
// this only happens when navigating from a list, direct loading works
|
||||||
|
@ -52,12 +52,14 @@ function tryRegisterObserverForBadge(badge) {
|
||||||
|
|
||||||
let obsever = new MutationObserver(mutations => {
|
let obsever = new MutationObserver(mutations => {
|
||||||
mutations.forEach(mutation => {
|
mutations.forEach(mutation => {
|
||||||
// prevent recursive calls when our class is added / removed
|
// prevent recursive calls when our class is added / removed
|
||||||
if ((mutation.oldValue?.indexOf(DARKCOLOR_CLASS) ?? -1 ^ mutation.target?.classList?.indexOf(DARKCOLOR_CLASS) ?? -1) === 0) {
|
if (mutation.target instanceof Element) {
|
||||||
return;
|
if ((mutation.oldValue?.indexOf(DARKCOLOR_CLASS) >= 0 ?? false) !== (mutation.target?.classList?.contains(DARKCOLOR_CLASS) ?? false)) {
|
||||||
}
|
return;
|
||||||
else {
|
}
|
||||||
optimizeFontColorsBadges(mutation.target);
|
else {
|
||||||
|
optimizeFontColorsBadges(mutation.target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -71,7 +73,7 @@ function tryRegisterObserverForBadge(badge) {
|
||||||
__observedBadges.push(badge);
|
__observedBadges.push(badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
function optimizeFontColorsBadges(badge) {
|
function optimizeFontColorsBadges(badge: Element): void {
|
||||||
let colorStr = window.getComputedStyle(badge, null).getPropertyValue('background-color');
|
let colorStr = window.getComputedStyle(badge, null).getPropertyValue('background-color');
|
||||||
|
|
||||||
// some elements do not have a computed background color
|
// some elements do not have a computed background color
|
|
@ -2,12 +2,14 @@ import { getGlobalConfiguration, SETTINGS_animeLanguageDisplay } from '../config
|
||||||
import * as core from '../utils/aniwatchCore';
|
import * as core from '../utils/aniwatchCore';
|
||||||
import * as helper from '../utils/helpers';
|
import * as helper from '../utils/helpers';
|
||||||
|
|
||||||
export function init() {
|
const MANIPULATED_ATTR_NAME = 'awpManipulated';
|
||||||
|
|
||||||
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_animeLanguageDisplay, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_animeLanguageDisplay, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.registerScript(node => {
|
core.registerScript((node: Node) => {
|
||||||
// run the scripts
|
// run the scripts
|
||||||
if (helper.isHtmlElement(node)) {
|
if (node instanceof Element) {
|
||||||
updateLanguageDisplay(node)
|
updateLanguageDisplay(node)
|
||||||
}
|
}
|
||||||
}, "^/anime/[0-9]*$");
|
}, "^/anime/[0-9]*$");
|
||||||
|
@ -15,34 +17,35 @@ export function init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLanguageDisplay(node) {
|
function updateLanguageDisplay(node: Element): void {
|
||||||
const listNodeName = 'MD-LIST-ITEM';
|
const LIST_NODE_NAME = 'MD-LIST-ITEM';
|
||||||
const boxNodeName = 'DIV';
|
const BOX_NODE_NAME = 'DIV';
|
||||||
const boxClassName = 'card-margin';
|
const BOX_CLASS_NAME = 'card-margin';
|
||||||
|
|
||||||
if (node.nodeName === listNodeName) {
|
if (node.nodeName === LIST_NODE_NAME) {
|
||||||
updateLanguageDisplayListMode(node);
|
updateLanguageDisplayListMode(node);
|
||||||
}
|
}
|
||||||
else if (node.nodeName === boxNodeName && node.classList.contains(boxClassName)) {
|
else if (node.nodeName === BOX_NODE_NAME && node.classList.contains(BOX_CLASS_NAME)) {
|
||||||
updateLanguageDisplayBoxMode(node);
|
updateLanguageDisplayBoxMode(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLanguageDisplayListMode(node) {
|
function updateLanguageDisplayListMode(node: Element): void {
|
||||||
// last column with flags
|
// last column with flags
|
||||||
let col = node.querySelector('h3.layout-align-end-center');
|
let col = node.querySelector('h3.layout-align-end-center');
|
||||||
if (!helper.assigned(col) || col.awpManipulated) {
|
|
||||||
|
if (!helper.assigned(col) || col.hasAttribute(MANIPULATED_ATTR_NAME)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
doUpdateLanguageDisplay(col, false);
|
doUpdateLanguageDisplay(col, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLanguageDisplayBoxMode(node) {
|
function updateLanguageDisplayBoxMode(node: Element): void {
|
||||||
// last column with flags
|
// last column with flags
|
||||||
let col = node.querySelector('div.layout-align-end-start');
|
let col = node.querySelector('div.layout-align-end-start');
|
||||||
|
|
||||||
if (!helper.assigned(col) || col.awpManipulated) {
|
if (!helper.assigned(col) || col.hasAttribute(MANIPULATED_ATTR_NAME)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,27 +53,27 @@ function updateLanguageDisplayBoxMode(node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
function doUpdateLanguageDisplay(parent: Element, isBoxedModed: boolean): void {
|
||||||
const listLangPrefix = 'ep.lang.';
|
const LIST_LANG_PREFIX = 'ep.lang.';
|
||||||
const boxLangPrefix = 'episodeObject.lang.';
|
const BOX_LANG_PREFIX = 'episodeObject.lang.';
|
||||||
// aniwatch uses different prefixes in list und box mode :/
|
// aniwatch uses different prefixes in list und box mode :/
|
||||||
let realLangPrefix = isBoxedModed ? boxLangPrefix : listLangPrefix;
|
let realLangPrefix = isBoxedModed ? BOX_LANG_PREFIX : LIST_LANG_PREFIX;
|
||||||
|
|
||||||
const dubSuffix = 'dub';
|
const DUB_SUFFIX = 'dub';
|
||||||
const subSuffix = 'sub';
|
const SUB_SUFFIX = 'sub';
|
||||||
|
|
||||||
const dubIcon = 'volume_up';
|
const DUB_ICON = 'volume_up';
|
||||||
const subIcon = 'closed_caption';
|
const SUB_ICON = 'closed_caption';
|
||||||
const zeroWidthSpace = ''; // ​
|
const ZERO_WIDTH_SPACE_CHARACTER = ''; // ​
|
||||||
|
|
||||||
let subs = [];
|
let subs: Array<string> = [];
|
||||||
let dubs = [];
|
let dubs: Array<string> = [];
|
||||||
|
|
||||||
// find subs
|
// find subs
|
||||||
let subCols = parent.querySelectorAll('[ng-hide*="sub"]');
|
let subCols = parent.querySelectorAll('[ng-hide*="sub"]');
|
||||||
subCols.forEach(element => {
|
subCols.forEach((element: Element) => {
|
||||||
let langAttr = element.attributes['ng-hide'].value;
|
let langAttr = element.attributes['ng-hide'].value;
|
||||||
let lang = langAttr.substring(langAttr.indexOf(realLangPrefix) + realLangPrefix.length, langAttr.indexOf(subSuffix));
|
let lang = langAttr.substring(langAttr.indexOf(realLangPrefix) + realLangPrefix.length, langAttr.indexOf(SUB_SUFFIX));
|
||||||
if (element.attributes['aria-hidden'].value == 'false') {
|
if (element.attributes['aria-hidden'].value == 'false') {
|
||||||
subs.push(lang);
|
subs.push(lang);
|
||||||
}
|
}
|
||||||
|
@ -78,9 +81,9 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
|
|
||||||
// find dubs
|
// find dubs
|
||||||
let dubCols = parent.querySelectorAll('[ng-hide*="dub"]');
|
let dubCols = parent.querySelectorAll('[ng-hide*="dub"]');
|
||||||
dubCols.forEach(element => {
|
dubCols.forEach((element: Element) => {
|
||||||
let langAttr = element.attributes['ng-hide'].value;
|
let langAttr = element.attributes['ng-hide'].value;
|
||||||
let lang = langAttr.substring(langAttr.indexOf(realLangPrefix) + realLangPrefix.length, langAttr.indexOf(dubSuffix));
|
let lang = langAttr.substring(langAttr.indexOf(realLangPrefix) + realLangPrefix.length, langAttr.indexOf(DUB_SUFFIX));
|
||||||
if (element.attributes['aria-hidden'].value == 'false') {
|
if (element.attributes['aria-hidden'].value == 'false') {
|
||||||
dubs.push(lang);
|
dubs.push(lang);
|
||||||
}
|
}
|
||||||
|
@ -106,12 +109,12 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
let dubIconDiv = document.createElement('i');
|
let dubIconDiv = document.createElement('i');
|
||||||
if (iconsRequired) {
|
if (iconsRequired) {
|
||||||
dubIconDiv.classList.add('material-icons', 'mr-3');
|
dubIconDiv.classList.add('material-icons', 'mr-3');
|
||||||
dubIconDiv.innerText = dubIcon;
|
dubIconDiv.innerText = DUB_ICON;
|
||||||
}
|
}
|
||||||
// add dummy with 24px for correct presentation
|
// add dummy with 24px for correct presentation
|
||||||
else {
|
else {
|
||||||
dubIconDiv.style.height = '24px';
|
dubIconDiv.style.height = '24px';
|
||||||
dubIconDiv.innerText = zeroWidthSpace;
|
dubIconDiv.innerText = ZERO_WIDTH_SPACE_CHARACTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
dubDiv.appendChild(dubIconDiv);
|
dubDiv.appendChild(dubIconDiv);
|
||||||
|
@ -132,16 +135,16 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
let subIconDiv = document.createElement('i');
|
let subIconDiv = document.createElement('i');
|
||||||
if (iconsRequired) {
|
if (iconsRequired) {
|
||||||
subIconDiv.classList.add('material-icons', 'mr-3');
|
subIconDiv.classList.add('material-icons', 'mr-3');
|
||||||
subIconDiv.innerText = subIcon;
|
subIconDiv.innerText = SUB_ICON;
|
||||||
}
|
}
|
||||||
// add dummy with 24px for correct presentation
|
// add dummy with 24px for correct presentation
|
||||||
else {
|
else {
|
||||||
subIconDiv.style.height = '24px';
|
subIconDiv.style.height = '24px';
|
||||||
subIconDiv.innerText = zeroWidthSpace;
|
subIconDiv.innerText = ZERO_WIDTH_SPACE_CHARACTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
subDiv.appendChild(subIconDiv);
|
subDiv.appendChild(subIconDiv);
|
||||||
subs.forEach(lang => {
|
subs.forEach((lang: string) => {
|
||||||
let langIcon = document.createElement('i');
|
let langIcon = document.createElement('i');
|
||||||
langIcon.classList.add('flag', `flag-${lang}`, 'mg-all-1');
|
langIcon.classList.add('flag', `flag-${lang}`, 'mg-all-1');
|
||||||
subDiv.appendChild(langIcon);
|
subDiv.appendChild(langIcon);
|
||||||
|
@ -154,7 +157,7 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dubs.length > 0) {
|
if (dubs.length > 0) {
|
||||||
dubs.forEach(lang => {
|
dubs.forEach((lang: string) => {
|
||||||
let colDiv = document.createElement('div');
|
let colDiv = document.createElement('div');
|
||||||
colDiv.setAttribute('layout', 'column');
|
colDiv.setAttribute('layout', 'column');
|
||||||
colDiv.classList.add('layout-column');
|
colDiv.classList.add('layout-column');
|
||||||
|
@ -167,12 +170,12 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
let dubIconDiv = document.createElement('i');
|
let dubIconDiv = document.createElement('i');
|
||||||
if (iconsRequired) {
|
if (iconsRequired) {
|
||||||
dubIconDiv.classList.add('material-icons', 'mr-3');
|
dubIconDiv.classList.add('material-icons', 'mr-3');
|
||||||
dubIconDiv.innerText = dubIcon;
|
dubIconDiv.innerText = DUB_ICON;
|
||||||
}
|
}
|
||||||
// add dummy with 24px for correct presentation
|
// add dummy with 24px for correct presentation
|
||||||
else {
|
else {
|
||||||
dubIconDiv.style.height = '24px';
|
dubIconDiv.style.height = '24px';
|
||||||
dubIconDiv.innerText = zeroWidthSpace;
|
dubIconDiv.innerText = ZERO_WIDTH_SPACE_CHARACTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
dubDiv.appendChild(dubIconDiv);
|
dubDiv.appendChild(dubIconDiv);
|
||||||
|
@ -193,12 +196,12 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
let subIconDiv = document.createElement('i');
|
let subIconDiv = document.createElement('i');
|
||||||
if (iconsRequired) {
|
if (iconsRequired) {
|
||||||
subIconDiv.classList.add('material-icons', 'mr-3');
|
subIconDiv.classList.add('material-icons', 'mr-3');
|
||||||
subIconDiv.innerText = subIcon;
|
subIconDiv.innerText = SUB_ICON;
|
||||||
}
|
}
|
||||||
// add dummy with 24px for correct presentation
|
// add dummy with 24px for correct presentation
|
||||||
else {
|
else {
|
||||||
subIconDiv.style.height = '24px';
|
subIconDiv.style.height = '24px';
|
||||||
subIconDiv.innerText = zeroWidthSpace;
|
subIconDiv.innerText = ZERO_WIDTH_SPACE_CHARACTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
subDiv.appendChild(subIconDiv);
|
subDiv.appendChild(subIconDiv);
|
||||||
|
@ -216,13 +219,17 @@ function doUpdateLanguageDisplay(parent, isBoxedModed) {
|
||||||
});
|
});
|
||||||
|
|
||||||
parent.querySelectorAll('.layout-column:not(:last-child)').forEach(div => {
|
parent.querySelectorAll('.layout-column:not(:last-child)').forEach(div => {
|
||||||
div.style.borderRight = '1px solid rgba(155,155,155, 0.2)';
|
if (div instanceof HTMLElement) {
|
||||||
|
div.style.borderRight = '1px solid rgba(155,155,155, 0.2)';
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
parent.querySelectorAll('.layout-column').forEach(div => {
|
parent.querySelectorAll('.layout-column').forEach(div => {
|
||||||
div.style.paddingLeft = '2px';
|
if (div instanceof HTMLElement) {
|
||||||
div.style.paddingRight = '2px';
|
div.style.paddingLeft = '2px';
|
||||||
|
div.style.paddingRight = '2px';
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
parent.awpManipulated = true;
|
parent.setAttribute('awpManipulated', String(true));
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import { getGlobalConfiguration, SETTINGS_websiteShowNotificationsCountInTab } f
|
||||||
import * as core from '../utils/aniwatchCore';
|
import * as core from '../utils/aniwatchCore';
|
||||||
import * as helper from '../utils/helpers';
|
import * as helper from '../utils/helpers';
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_websiteShowNotificationsCountInTab, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_websiteShowNotificationsCountInTab, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.runAfterLoad(() => {
|
core.runAfterLoad(() => {
|
||||||
|
@ -16,17 +16,17 @@ export function init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNotificationCount() {
|
function getNotificationCount(): number {
|
||||||
if (core.isLoggedIn()) {
|
if (core.isLoggedIn()) {
|
||||||
let menuUserText = document.getElementById('materialize-menu-dropdown').innerText.split('\n')[4];
|
let menuUserText = document.getElementById('materialize-menu-dropdown').innerText.split('\n')[4];
|
||||||
let notificationCount = menuUserText.match(/\d+/)?.[0] ?? 0;
|
let notificationCount = parseInt(menuUserText.match(/\d+/)?.[0]) ?? 0;
|
||||||
return notificationCount;
|
return notificationCount;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNotificationsInTitle() {
|
function updateNotificationsInTitle(): void {
|
||||||
let count = getNotificationCount();
|
let count = getNotificationCount();
|
||||||
|
|
||||||
if (helper.assigned(count) && count > 0) {
|
if (helper.assigned(count) && count > 0) {
|
|
@ -5,7 +5,7 @@ import * as helper from '../utils/helpers';
|
||||||
const quickSearchID = 'ea-quickSearch';
|
const quickSearchID = 'ea-quickSearch';
|
||||||
const quickSearchLink = 'ea-quickSearchLink';
|
const quickSearchLink = 'ea-quickSearchLink';
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_websiteDisplayQuickSearch, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_websiteDisplayQuickSearch, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.runAfterLoad(() => {
|
core.runAfterLoad(() => {
|
||||||
|
@ -15,7 +15,7 @@ export function init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSearch() {
|
function initSearch(): void {
|
||||||
let entry = document.createElement('li');
|
let entry = document.createElement('li');
|
||||||
entry.setAttribute('ng-repeat', 'item in navbar');
|
entry.setAttribute('ng-repeat', 'item in navbar');
|
||||||
entry.setAttribute('ng-class', '{\'anime-indicator\': item[\'@attributes\'].title==\'Anime\'}');
|
entry.setAttribute('ng-class', '{\'anime-indicator\': item[\'@attributes\'].title==\'Anime\'}');
|
||||||
|
@ -45,13 +45,13 @@ function initSearch() {
|
||||||
document.addEventListener('keypress', event => handleSearchForShiftF(event));
|
document.addEventListener('keypress', event => handleSearchForShiftF(event));
|
||||||
|
|
||||||
// additionally, the last dropdown ul has a "right: 0px" style, which has to be fixed with auto, otherwhise it will pop up in the wrong position
|
// additionally, the last dropdown ul has a "right: 0px" style, which has to be fixed with auto, otherwhise it will pop up in the wrong position
|
||||||
Array.from(menu.querySelectorAll('ul.dropdown')).slice(-1)[0].style.right = 'auto';
|
(Array.from(menu.querySelectorAll('ul.dropdown')).slice(-1)[0] as HTMLElement).style.right = 'auto';
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleQuickSearch(event) {
|
function handleQuickSearch(event: KeyboardEvent): void {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
let quickSearchElement = document.getElementById(quickSearchID);
|
let quickSearchElement = document.getElementById(quickSearchID) as HTMLInputElement;
|
||||||
let linkElement = document.getElementById(quickSearchLink);
|
let linkElement = document.getElementById(quickSearchLink) as HTMLAnchorElement;
|
||||||
|
|
||||||
let url = new URL(window.location.origin)
|
let url = new URL(window.location.origin)
|
||||||
url.pathname = '/search';
|
url.pathname = '/search';
|
||||||
|
@ -67,10 +67,10 @@ function handleQuickSearch(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSearchForShiftF(event) {
|
function handleSearchForShiftF(event: KeyboardEvent): void {
|
||||||
if (helper.isShiftPressed) {
|
if (helper.isShiftPressed) {
|
||||||
// check if some kind of input is focused already; we then prevent our hotkey
|
// check if some kind of input is focused already; we then prevent our hotkey
|
||||||
if (document.activeElement instanceof HTMLInputElement || document.activeElement instanceof HTMLTextAreaElement || document.activeElement.isContentEditable) {
|
if (document.activeElement instanceof HTMLInputElement || document.activeElement instanceof HTMLTextAreaElement || ((document.activeElement as HTMLElement)?.isContentEditable ?? false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as helper from '../utils/helpers';
|
||||||
const __alteredNodes = [];
|
const __alteredNodes = [];
|
||||||
const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
|
const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_websiteAutoTimeConversion, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_websiteAutoTimeConversion, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
// The regexp pattern matches anything except the airing page.
|
// The regexp pattern matches anything except the airing page.
|
||||||
|
@ -20,18 +20,18 @@ export function init() {
|
||||||
updateTimestamps(document.documentElement);
|
updateTimestamps(document.documentElement);
|
||||||
}, "^/(?!airing).*$");
|
}, "^/(?!airing).*$");
|
||||||
|
|
||||||
core.registerScript(node => {
|
core.registerScript((node: Node) => {
|
||||||
updateTimestamps(node);
|
updateTimestamps(node);
|
||||||
}, "^/(?!airing).*$");
|
}, "^/(?!airing).*$");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSpaceDateTimeFormat(use24Format) {
|
function getSpaceDateTimeFormat(use24Format: boolean): string {
|
||||||
return `${getSpaceDateFormat()} ${getSpaceTimeFormat(use24Format)}`;
|
return `${getSpaceDateFormat()} ${getSpaceTimeFormat(use24Format)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSpaceTimeFormat(use24Format) {
|
function getSpaceTimeFormat(use24Format: boolean): string {
|
||||||
if (use24Format) {
|
if (use24Format) {
|
||||||
return '{time-24}';
|
return '{time-24}';
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,11 @@ function getSpaceTimeFormat(use24Format) {
|
||||||
return '{time}';
|
return '{time}';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSpaceDateFormat() {
|
function getSpaceDateFormat(): string {
|
||||||
return '{date}. {month-short} {year}';
|
return '{date}. {month-short} {year}';
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryUpdateDateTime(node) {
|
function tryUpdateDateTime(node: Node): boolean {
|
||||||
const REG_DATETIME = /(\d{2}(\/|\.)){2}\d{4} *\d?\d:\d{2}( (AM|PM))?/g;
|
const REG_DATETIME = /(\d{2}(\/|\.)){2}\d{4} *\d?\d:\d{2}( (AM|PM))?/g;
|
||||||
const REG_TIME = /\d?\d:\d{2}/;
|
const REG_TIME = /\d?\d:\d{2}/;
|
||||||
const REG_AMPM = /\s(am|pm)/i;
|
const REG_AMPM = /\s(am|pm)/i;
|
||||||
|
@ -81,7 +81,7 @@ function tryUpdateDateTime(node) {
|
||||||
|
|
||||||
let datetime = spacetime(processedStr, 'UTC+1', { dmy: true });
|
let datetime = spacetime(processedStr, 'UTC+1', { dmy: true });
|
||||||
datetime = datetime.goto(spacetime().tz);
|
datetime = datetime.goto(spacetime().tz);
|
||||||
let replaceText = datetime.format(getSpaceDateTimeFormat(use24Format));
|
let replaceText = String(datetime.format(getSpaceDateTimeFormat(use24Format)));
|
||||||
|
|
||||||
node.textContent = node.textContent.replace(hit, replaceText);
|
node.textContent = node.textContent.replace(hit, replaceText);
|
||||||
});
|
});
|
||||||
|
@ -89,7 +89,7 @@ function tryUpdateDateTime(node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryUpdateDate(node) {
|
function tryUpdateDate(node: Node): boolean {
|
||||||
const REG_DATE = /(\d{2}(\/|\.)){2}\d{4}/g;
|
const REG_DATE = /(\d{2}(\/|\.)){2}\d{4}/g;
|
||||||
|
|
||||||
let hits = Array.from(node.textContent.matchAll(REG_DATE), match => match[0]);
|
let hits = Array.from(node.textContent.matchAll(REG_DATE), match => match[0]);
|
||||||
|
@ -101,7 +101,7 @@ function tryUpdateDate(node) {
|
||||||
hits.forEach(hit => {
|
hits.forEach(hit => {
|
||||||
let datetime = spacetime(hit, 'UTC+1', { dmy: true });
|
let datetime = spacetime(hit, 'UTC+1', { dmy: true });
|
||||||
datetime = datetime.goto(spacetime().tz);
|
datetime = datetime.goto(spacetime().tz);
|
||||||
let replaceText = datetime.format(getSpaceDateFormat());
|
let replaceText = String(datetime.format(getSpaceDateFormat()));
|
||||||
|
|
||||||
node.textContent = node.textContent.replace(hit, replaceText);
|
node.textContent = node.textContent.replace(hit, replaceText);
|
||||||
});
|
});
|
||||||
|
@ -109,7 +109,7 @@ function tryUpdateDate(node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryUpdateTime(node) {
|
function tryUpdateTime(node: Node): boolean {
|
||||||
const REG_TIME = /\d?\d:\d{2}( (AM|PM))?/g;
|
const REG_TIME = /\d?\d:\d{2}( (AM|PM))?/g;
|
||||||
const REG_AMPM = /\s(am|pm)/i;
|
const REG_AMPM = /\s(am|pm)/i;
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ function tryUpdateTime(node) {
|
||||||
datetime = datetime.goto('UTC+1');
|
datetime = datetime.goto('UTC+1');
|
||||||
datetime = datetime.time(processedStr);
|
datetime = datetime.time(processedStr);
|
||||||
datetime = datetime.goto(spacetime().tz);
|
datetime = datetime.goto(spacetime().tz);
|
||||||
let replaceText = datetime.format(getSpaceTimeFormat(use24Format));
|
let replaceText = String(datetime.format(getSpaceTimeFormat(use24Format)));
|
||||||
|
|
||||||
node.textContent = node.textContent.replace(hit, replaceText);
|
node.textContent = node.textContent.replace(hit, replaceText);
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ function tryUpdateTime(node) {
|
||||||
|
|
||||||
// if day changed
|
// if day changed
|
||||||
if (dOffset != 0) {
|
if (dOffset != 0) {
|
||||||
let dayNode = node.parentNode.previousElementSibling;
|
let dayNode = (node.parentNode as Element)?.previousElementSibling;
|
||||||
if (helper.assigned(dayNode)) {
|
if (helper.assigned(dayNode)) {
|
||||||
for (let i = 0; i < DAYS.length; i++) {
|
for (let i = 0; i < DAYS.length; i++) {
|
||||||
if (dayNode.textContent.indexOf(DAYS[i]) >= 0) {
|
if (dayNode.textContent.indexOf(DAYS[i]) >= 0) {
|
||||||
|
@ -183,13 +183,17 @@ function tryUpdateTime(node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryUpdateTimeZone(node) {
|
function tryUpdateTimeZone(node: Node): boolean {
|
||||||
const HINT_UTC = 'UTC+1';
|
const HINT_UTC = 'UTC+1';
|
||||||
if (node.textContent === HINT_UTC) {
|
if (node.textContent === HINT_UTC) {
|
||||||
let tzMeta = spacetime().timezone();
|
let tzMeta = spacetime().timezone();
|
||||||
|
|
||||||
node.textContent = `${tzMeta.name} (UTC${tzMeta.current.offset >= 0 ? '+' : ''}${tzMeta.current.offset})`;
|
node.textContent = `${tzMeta.name} (UTC${tzMeta.current.offset >= 0 ? '+' : ''}${tzMeta.current.offset})`;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimestamps(node) {
|
function updateTimestamps(node) {
|
|
@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||||
import { getGlobalConfiguration, SETTINGS_w2gDisplayCharacterCounter } from '../configuration/configuration';
|
import { getGlobalConfiguration, SETTINGS_w2gDisplayCharacterCounter } from '../configuration/configuration';
|
||||||
import { assigned } from '../utils/helpers';
|
import { assigned } from '../utils/helpers';
|
||||||
|
|
||||||
export function init() {
|
export function init(): void {
|
||||||
getGlobalConfiguration().getProperty(SETTINGS_w2gDisplayCharacterCounter, value => {
|
getGlobalConfiguration().getProperty(SETTINGS_w2gDisplayCharacterCounter, value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
core.runAfterLocationChange(() => {
|
core.runAfterLocationChange(() => {
|
||||||
|
@ -13,8 +13,8 @@ export function init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function manipulateChatInput() {
|
function manipulateChatInput(): void {
|
||||||
let textarea = document.querySelector('.chat-input textarea');
|
let textarea = document.querySelector('.chat-input textarea') as HTMLTextAreaElement;
|
||||||
|
|
||||||
// avoid duplicate registration
|
// avoid duplicate registration
|
||||||
if (assigned(textarea.dataset.charCounterId)) {
|
if (assigned(textarea.dataset.charCounterId)) {
|
||||||
|
@ -24,7 +24,7 @@ function manipulateChatInput() {
|
||||||
addCharCounter(textarea);
|
addCharCounter(textarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCharCounter(textarea) {
|
function addCharCounter(textarea: HTMLTextAreaElement): void {
|
||||||
let chatDiv = textarea.parentElement.parentElement; // div with chat input and controls
|
let chatDiv = textarea.parentElement.parentElement; // div with chat input and controls
|
||||||
let controlRow = chatDiv.children[1]; // row with controls
|
let controlRow = chatDiv.children[1]; // row with controls
|
||||||
let btn = controlRow.querySelector('button'); // find send button
|
let btn = controlRow.querySelector('button'); // find send button
|
||||||
|
@ -45,7 +45,7 @@ function addCharCounter(textarea) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCharCounter(textarea, charCounterSpan) {
|
function updateCharCounter(textarea: HTMLTextAreaElement, charCounterSpan: HTMLSpanElement): void {
|
||||||
const SHAKE_CLASS = 'awp-w2g-chatCounter-max';
|
const SHAKE_CLASS = 'awp-w2g-chatCounter-max';
|
||||||
|
|
||||||
let current = textarea.value.length;
|
let current = textarea.value.length;
|
|
@ -5,25 +5,28 @@ const OPTION_SELECTOR = 'input[type="checkbox"';
|
||||||
|
|
||||||
function storeOptions() {
|
function storeOptions() {
|
||||||
document.querySelectorAll(OPTION_SELECTOR).forEach(optionElement => {
|
document.querySelectorAll(OPTION_SELECTOR).forEach(optionElement => {
|
||||||
getGlobalStorageProvider().setData(optionElement.id, optionElement.checked);
|
let optionInputElement = optionElement as HTMLInputElement;
|
||||||
|
getGlobalStorageProvider().setDataAsBoolean(optionInputElement.id, optionInputElement.checked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreOptions() {
|
function restoreOptions() {
|
||||||
document.querySelectorAll(OPTION_SELECTOR).forEach(optionElement => {
|
document.querySelectorAll(OPTION_SELECTOR).forEach(optionElement => {
|
||||||
let defaultValue = optionElement.dataset.defaultValue === 'true' ? true : false;
|
let optionInputElement = optionElement as HTMLInputElement;
|
||||||
|
let defaultValue = optionInputElement.dataset.defaultValue === 'true' ? true : false;
|
||||||
|
|
||||||
getGlobalStorageProvider().getData(optionElement.id, defaultValue, value => {
|
getGlobalStorageProvider().getDataAsBoolean(optionInputElement.id, defaultValue, value => {
|
||||||
optionElement.checked = value;
|
optionInputElement.checked = value;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetOptions() {
|
function resetOptions() {
|
||||||
document.querySelectorAll(OPTION_SELECTOR).forEach(optionElement => {
|
document.querySelectorAll(OPTION_SELECTOR).forEach(optionElement => {
|
||||||
let defaultValue = optionElement.dataset.defaultValue === 'true' ? true : false;
|
let optionInputElement = optionElement as HTMLInputElement;
|
||||||
|
let defaultValue = optionInputElement.dataset.defaultValue === 'true' ? true : false;
|
||||||
|
|
||||||
optionElement.checked = defaultValue;
|
optionInputElement.checked = defaultValue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,24 @@
|
||||||
import * as helper from './helpers';
|
import * as helper from './helpers';
|
||||||
|
|
||||||
/* SCRIPT LOGICS */
|
type ScriptCallback = () => void;
|
||||||
let __scripts = [];
|
type NodeScriptCallback = (node: Node) => void;
|
||||||
let __afterLoadScripts = [];
|
|
||||||
let __afterLocationChangeScripts = [];
|
|
||||||
|
|
||||||
export function initCore() {
|
type ScriptObj = {
|
||||||
|
function: ScriptCallback,
|
||||||
|
pattern: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeScriptObj = {
|
||||||
|
function: NodeScriptCallback,
|
||||||
|
pattern: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SCRIPT LOGICS */
|
||||||
|
let __scripts: Array<NodeScriptObj> = [];
|
||||||
|
let __afterLoadScripts: Array<ScriptObj> = [];
|
||||||
|
let __afterLocationChangeScripts: Array<ScriptObj> = [];
|
||||||
|
|
||||||
|
export function initCore(): void {
|
||||||
let observer = new MutationObserver(mutations => {
|
let observer = new MutationObserver(mutations => {
|
||||||
mutations.forEach(mutation => {
|
mutations.forEach(mutation => {
|
||||||
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
||||||
|
@ -46,11 +59,11 @@ export function initCore() {
|
||||||
helper.onReady(() => awaitPageLoaded());
|
helper.onReady(() => awaitPageLoaded());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerScript(func, pattern = '.*') {
|
export function registerScript(func: NodeScriptCallback, pattern: string = '.*'): void {
|
||||||
__scripts.push({ "function": func, "pattern": pattern });
|
__scripts.push({ function: func, pattern: pattern });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runScripts(node) {
|
export function runScripts(node: Node): void {
|
||||||
__scripts.forEach(script => {
|
__scripts.forEach(script => {
|
||||||
if (window.location.pathname.match(script.pattern)) {
|
if (window.location.pathname.match(script.pattern)) {
|
||||||
script.function(node);
|
script.function(node);
|
||||||
|
@ -58,20 +71,20 @@ export function runScripts(node) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function findPreloader() {
|
function findPreloader(): HTMLElement {
|
||||||
return document.getElementById('preloader');
|
return document.getElementById('preloader');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runAfterLoad(func, pattern = '.*') {
|
export function runAfterLoad(func: ScriptCallback, pattern: string = '.*'): void {
|
||||||
let preloader = findPreloader();
|
let preloader = findPreloader();
|
||||||
if (typeof preloader !== undefined && preloader.style.display !== "none") {
|
if (typeof preloader !== undefined && preloader.style.display !== "none") {
|
||||||
__afterLoadScripts.push({ "function": func, "pattern": pattern });
|
__afterLoadScripts.push({ function: func, pattern: pattern });
|
||||||
} else {
|
} else {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function awaitPageLoaded() {
|
function awaitPageLoaded(): void {
|
||||||
let preLoader = findPreloader();
|
let preLoader = findPreloader();
|
||||||
|
|
||||||
let runScripts = () => {
|
let runScripts = () => {
|
||||||
|
@ -87,9 +100,9 @@ function awaitPageLoaded() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let loop = setInterval(() => {
|
let loop = window.setInterval(() => {
|
||||||
if (preLoader.style.display === "none" && document.readyState === 'complete') {
|
if (preLoader.style.display === "none" && document.readyState === 'complete') {
|
||||||
clearInterval(loop);
|
window.clearInterval(loop);
|
||||||
|
|
||||||
runScripts();
|
runScripts();
|
||||||
}
|
}
|
||||||
|
@ -97,12 +110,12 @@ function awaitPageLoaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PATHNAME LOGIC */
|
/* PATHNAME LOGIC */
|
||||||
export function runAfterLocationChange(func, pattern = '.*') {
|
export function runAfterLocationChange(func: ScriptCallback, pattern: string = '.*'): void {
|
||||||
__afterLocationChangeScripts.push({ "function": func, "pattern": pattern });
|
__afterLocationChangeScripts.push({ function: func, pattern: pattern });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LOGIN LOGIC */
|
/* LOGIN LOGIC */
|
||||||
export function isLoggedIn() {
|
export function isLoggedIn(): boolean {
|
||||||
let menu = document.getElementById('materialize-menu-dropdown');
|
let menu = document.getElementById('materialize-menu-dropdown');
|
||||||
let result = true;
|
let result = true;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
export var isShiftPressed = false;
|
export var isShiftPressed: boolean = false;
|
||||||
export var isCtrlPressed = false;
|
export var isCtrlPressed: boolean = false;
|
||||||
|
|
||||||
export function isHtmlElement(object) {
|
export function isHtmlElement(object: any) {
|
||||||
return object instanceof HTMLElement;
|
return object instanceof HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initHelpers() {
|
export function initHelpers(): void {
|
||||||
document.addEventListener('keydown', event => handleKeyDown(event));
|
document.addEventListener('keydown', event => handleKeyDown(event));
|
||||||
document.addEventListener('keyup', event => handleKeyUp(event));
|
document.addEventListener('keyup', event => handleKeyUp(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onReady(fn) {
|
export function onReady(fn: () => void) {
|
||||||
if (document.readyState != 'loading') {
|
if (document.readyState != 'loading') {
|
||||||
fn();
|
fn();
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,19 +18,19 @@ export function onReady(fn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assigned(obj) {
|
export function assigned(obj: any): boolean {
|
||||||
return !(typeof obj === 'undefined' || obj === null);
|
return !(typeof obj === 'undefined' || obj === null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event: KeyboardEvent) {
|
||||||
handleKeyToggle(event, true);
|
handleKeyToggle(event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyUp(event) {
|
function handleKeyUp(event: KeyboardEvent) {
|
||||||
handleKeyToggle(event, false);
|
handleKeyToggle(event, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyToggle(event, isPressed) {
|
function handleKeyToggle(event: KeyboardEvent, isPressed: boolean) {
|
||||||
if (event.key === 'Shift') {
|
if (event.key === 'Shift') {
|
||||||
isShiftPressed = isPressed;
|
isShiftPressed = isPressed;
|
||||||
} else if (event.key === 'Control') {
|
} else if (event.key === 'Control') {
|
||||||
|
@ -38,7 +38,7 @@ function handleKeyToggle(event, isPressed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findTextNodes(baseNode) {
|
export function findTextNodes(baseNode: Node): Array<Node> {
|
||||||
if (!assigned(baseNode)) {
|
if (!assigned(baseNode)) {
|
||||||
baseNode = document.documentElement;
|
baseNode = document.documentElement;
|
||||||
}
|
}
|
9
tsconfig.json
Normal file
9
tsconfig.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"esModuleInterop": true,
|
||||||
|
// You have to explicitly set @types to get DefinitelyTyped type definitions
|
||||||
|
"typeRoots": ["node_modules/@types", "node_modules/web-ext-types"],
|
||||||
|
// Default would be DOM,ES6,DOM.Iterable,ScriptHost (see https://www.typescriptlang.org/docs/handbook/compiler-options.html). However the ES 2020 is required for string.prototype.matchAll (see https://stackoverflow.com/a/57298833).
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable", "ScriptHost"]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue