DOM mutator cleanup
This commit is contained in:
parent
00ab298d62
commit
c7b8b53f9a
|
@ -39,7 +39,7 @@
|
|||
import core from '../core';
|
||||
import { EventBus, EventBusEvent } from './event-bus';
|
||||
import {domain} from '../../bbcode/core';
|
||||
import {ImagePreviewMutator} from './image-preview-mutator';
|
||||
import {ImageDomMutator} from './image-dom-mutator';
|
||||
|
||||
import { ExternalImagePreviewHelper, LocalImagePreviewHelper } from './helper';
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
|||
runJs = true;
|
||||
debug = false;
|
||||
|
||||
jsMutator = new ImagePreviewMutator(this.debug);
|
||||
jsMutator = new ImageDomMutator(this.debug);
|
||||
|
||||
externalPreviewStyle: Record<string, any> = {};
|
||||
localPreviewStyle: Record<string, any> = {};
|
||||
|
@ -101,6 +101,9 @@
|
|||
onMounted(): void {
|
||||
console.warn('Mounted ImagePreview');
|
||||
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.jsMutator.init();
|
||||
|
||||
EventBus.$on(
|
||||
'imagepreview-dismiss',
|
||||
(eventData: EventBusEvent) => {
|
||||
|
@ -572,7 +575,7 @@
|
|||
this.runJs = true;
|
||||
this.debug = false;
|
||||
|
||||
this.jsMutator = new ImagePreviewMutator(this.debug);
|
||||
this.jsMutator = new ImageDomMutator(this.debug);
|
||||
|
||||
this.cancelExitTimer();
|
||||
this.cancelTimer();
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
// window.onload = () => console.log('window.onload');
|
||||
// window.onloadstart = () => console.log('window.onloadstart');
|
||||
// window.onloadend = () => console.log('window.onloadend');
|
||||
// window.addEventListener('DOMContentLoaded', () => (console.log('window.DOMContentLoaded')));
|
||||
// setTimeout(() => (console.log('Timeout')), 0); ---- Note that clear() below will break this
|
||||
/***
|
||||
* This script is injected on every web page ImagePreview loads
|
||||
*/
|
||||
|
||||
const previewInitiationTime = Date.now();
|
||||
|
||||
window.onload = () => console.log('window.onload', `${(Date.now() - previewInitiationTime)/1000}s`);
|
||||
window.onloadstart = () => console.log('window.onloadstart', `${(Date.now() - previewInitiationTime)/1000}s`);
|
||||
window.onloadend = () => console.log('window.onloadend', `${(Date.now() - previewInitiationTime)/1000}s`);
|
||||
window.addEventListener('DOMContentLoaded', () => (console.log('window.DOMContentLoaded', `${(Date.now() - previewInitiationTime)/1000}s`)));
|
||||
setTimeout(() => (console.log('Timeout', `${(Date.now() - previewInitiationTime)/1000}s`)), 0); // ---- Note that clear() below could break this
|
||||
|
||||
|
||||
(() => {
|
||||
try {
|
||||
if (window.location.href.match(/^https?:\/\/(www.)?pornhub.com/)) {
|
||||
// Inject JQuery
|
||||
const el = document.createElement('script');
|
||||
el.type='text/javascript';
|
||||
el.text="console.log('JQuery Injection'); window.$ = window.jQuery = require('jquery');";
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
This script is MUTATED and EXECUTED after DOM has loaded
|
||||
It is wrapped into a `(() => {})();` to prevent it from polluting its surroundings.
|
||||
|
||||
Avoid using array functions, such as `arr.forEach`, as some websites override them with incompatible functions
|
||||
|
||||
Do not remove the `SETTINGS_START` and `SETTINGS_END` markers below,
|
||||
they are used for dynamically injecting settings from Electron.
|
||||
*/
|
||||
|
||||
const sizePairs = [
|
||||
['naturalWidth', 'naturalHeight'],
|
||||
['videoWidth', 'videoHeight'],
|
||||
['width', 'height'],
|
||||
];
|
||||
|
||||
|
||||
class FListImagePreviewDomMutator {
|
||||
constructor(settings) {
|
||||
/* ## SETTINGS_START ## */
|
||||
this.settings = settings || {
|
||||
selectors: ['video', 'img'],
|
||||
debug: true,
|
||||
skipElementRemove: false,
|
||||
safeTags: [],
|
||||
injectStyle: false
|
||||
};
|
||||
/* ## SETTINGS_END ## */
|
||||
|
||||
this.startTime = Date.now();
|
||||
|
||||
this.selectors = this.settings.selectors;
|
||||
this.skipElementRemove = this.settings.skipElementRemove;
|
||||
this.safeTags = this.settings.safeTags;
|
||||
|
||||
this.body = document.querySelector('body');
|
||||
this.html = document.querySelector('html');
|
||||
|
||||
this.ipcRenderer = (typeof require !== 'undefined')
|
||||
? require('electron').ipcRenderer
|
||||
: { sendToHost: (...args) => (this.debug('ipc.sendToHost', ...args)) };
|
||||
|
||||
this.preprocess();
|
||||
|
||||
this.img = this.detectImage(this.selectors, this.body);
|
||||
this.wrapper = this.createWrapperElement();
|
||||
this.style = this.createStyleElement();
|
||||
}
|
||||
|
||||
|
||||
preprocess() {
|
||||
for (const el of document.querySelectorAll('header, .header, nav, .nav, .navbar, .navigation')) {
|
||||
try {
|
||||
el.remove();
|
||||
} catch (err) {
|
||||
this.error('preprocess', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
detectImage(selectors, body) {
|
||||
let selected = [];
|
||||
|
||||
for (const selector of selectors) {
|
||||
const selectedElements = (Array.from(document.querySelectorAll(selector)).filter((i) => ((i.width !== 1) && (i.height !== 1))));
|
||||
selected = selected.concat(selectedElements);
|
||||
}
|
||||
|
||||
this.debug('detectImage.selected', selectors, selected);
|
||||
|
||||
const img = selected.filter(el => (el !== body)).shift();
|
||||
|
||||
this.debug('detectImage.found', img);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
run() {
|
||||
if (!this.img) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateImgSize(this.img, 'pre');
|
||||
|
||||
this.attachImgToWrapper(this.img, this.wrapper);
|
||||
this.attachWrapperToBody(this.wrapper, this.body);
|
||||
this.attachStyleToWrapper(this.style, this.wrapper);
|
||||
|
||||
this.forceElementStyling(this.html, this.body, this.wrapper, this.img);
|
||||
|
||||
this.resolveVideoSrc(this.img);
|
||||
|
||||
this.setEventListener('DOMContentLoaded', this.img);
|
||||
this.setEventListener('load', this.img);
|
||||
this.setEventListener('loadstart', this.img);
|
||||
|
||||
this.attemptPlay(this.img, true);
|
||||
|
||||
this.updateImgSizeTimer(this.img);
|
||||
|
||||
this.cleanDom(this.body);
|
||||
}
|
||||
|
||||
|
||||
cleanDom(body) {
|
||||
if (this.skipElementRemove) {
|
||||
return;
|
||||
}
|
||||
|
||||
const removeList = [];
|
||||
const safeIds = ['flistWrapper', 'flistError', 'flistHider'];
|
||||
const safeTags = this.safeTags;
|
||||
|
||||
for (const el of body.childNodes) {
|
||||
try {
|
||||
if (
|
||||
(safeIds.indexOf(el.id) < 0)
|
||||
&& ((!el.tagName) || (safeTags.indexOf(el.tagName.toLowerCase())) < 0)
|
||||
) {
|
||||
removeList.push(el);
|
||||
}
|
||||
} catch (err) {
|
||||
this.error('cleanDom find nodes', err);
|
||||
}
|
||||
}
|
||||
|
||||
for (const el of removeList) {
|
||||
try {
|
||||
el.remove();
|
||||
} catch (err) {
|
||||
this.error('cleanDom remove element', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateImgSizeTimer(img) {
|
||||
const result = this.updateImgSize(img, 'timer');
|
||||
|
||||
if (!result) {
|
||||
setTimeout(() => this.updateImgSizeTimer(img), 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resolveVideoSrc(img) {
|
||||
if ((img.src) || (!img.tagName) || ((img.tagName) && (img.tagName.toUpperCase() !== 'VIDEO'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug('resolveVideoSrc', 'Needs a content URL', img);
|
||||
|
||||
const contentUrls = document.querySelectorAll('meta[itemprop="contentURL"]');
|
||||
|
||||
if ((contentUrls) && (contentUrls.length > 0)) {
|
||||
this.debug('Found content URLs', contentUrls);
|
||||
|
||||
const cu = contentUrls[0];
|
||||
|
||||
if ((cu.attributes) && (cu.attributes.content) && (cu.attributes.content.value)) {
|
||||
this.debug('Content URL', cu.attributes.content.value);
|
||||
|
||||
img.src = cu.attributes.content.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setEventListener(eventName, img) {
|
||||
document.addEventListener(eventName, (event) => {
|
||||
this.debug('event', eventName, event);
|
||||
|
||||
this.updateImgSize(img, `event.${eventName}`);
|
||||
this.attemptPlay(img, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
attemptPlay(img, lessStrict) {
|
||||
try {
|
||||
if (
|
||||
(img.play)
|
||||
&& (
|
||||
(lessStrict)
|
||||
|| ((!lessStrict) && (!img.paused) && (!img.ended) && (!(img.currentTime > 0)))
|
||||
)
|
||||
)
|
||||
{
|
||||
img.muted = true;
|
||||
img.loop = true;
|
||||
img.play();
|
||||
}
|
||||
} catch (err) {
|
||||
this.error('attemptPlay', err, img, lessStrict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
forceElementStyling(html, body, wrapper, img) {
|
||||
try {
|
||||
body.class = '';
|
||||
img.class = '';
|
||||
wrapper.class = '';
|
||||
html.class = '';
|
||||
|
||||
body.removeAttribute('class');
|
||||
img.removeAttribute('class');
|
||||
wrapper.removeAttribute('class');
|
||||
html.removeAttribute('class');
|
||||
|
||||
img.removeAttribute('width');
|
||||
img.removeAttribute('height');
|
||||
} catch (err) {
|
||||
this.error('forceElementStyling remove class', err);
|
||||
}
|
||||
|
||||
html.style = this.getWrapperStyleOverrides();
|
||||
body.style = this.getWrapperStyleOverrides();
|
||||
img.style = this.getImageStyleOverrides();
|
||||
}
|
||||
|
||||
|
||||
attachWrapperToBody(wrapper, body) {
|
||||
body.append(wrapper);
|
||||
}
|
||||
|
||||
|
||||
attachStyleToWrapper(style, wrapper) {
|
||||
try {
|
||||
wrapper.append(style);
|
||||
} catch (err) {
|
||||
this.error('attach style', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
attachImgToWrapper(img, wrapper) {
|
||||
try {
|
||||
img.remove();
|
||||
} catch(err) {
|
||||
this.error('attachImgToWrapper', 'remove()', err);
|
||||
|
||||
try {
|
||||
img.parentNode.removeChild(img);
|
||||
} catch(err2) {
|
||||
console.error('attachImgToWrapper', 'removeChild()', err2);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.append(img);
|
||||
}
|
||||
|
||||
|
||||
createWrapperElement() {
|
||||
const el = document.createElement('div');
|
||||
el.id = 'flistWrapper';
|
||||
|
||||
el.style = this.getWrapperStyleOverrides()
|
||||
+ 'z-index: 100000 !important;'
|
||||
+ 'background-color: black !important;'
|
||||
+ 'background-size: contain !important;'
|
||||
+ 'background-repeat: no-repeat !important;'
|
||||
+ 'background-position: top left !important;';
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
|
||||
createStyleElement() {
|
||||
if (!!this.settings.skipInjectStyle) {
|
||||
return document.createElement('i');
|
||||
}
|
||||
|
||||
const el = document.createElement('style');
|
||||
|
||||
el.textContent = `
|
||||
#flistWrapper img, #flistWrapper video {
|
||||
${this.getImageStyleOverrides()}
|
||||
}
|
||||
`;
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
|
||||
resolveImgSize(img) {
|
||||
const solved = {};
|
||||
|
||||
for (let ri = 0; ri < sizePairs.length; ri++) {
|
||||
const val = sizePairs[ri];
|
||||
|
||||
if ((img[val[0]]) && (img[val[1]])) {
|
||||
solved.width = img[val[0]];
|
||||
solved.height = img[val[1]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return solved;
|
||||
}
|
||||
|
||||
|
||||
updateImgSize(img, stage) {
|
||||
const imSize = this.resolveImgSize(img);
|
||||
|
||||
if ((imSize.width) && (imSize.height)) {
|
||||
this.debug('IPC webview.img', imSize, stage);
|
||||
|
||||
this.ipcRenderer.sendToHost('webview.img', imSize.width, imSize.height, stage);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
getBasicStyleOverrides() {
|
||||
return 'border: 0 !important;'
|
||||
+ 'padding: 0 !important;'
|
||||
+ 'margin: 0 !important;'
|
||||
+ 'width: 100% !important;'
|
||||
+ 'height: 100% !important;'
|
||||
+ 'opacity: 1 !important;'
|
||||
+ 'min-width: initial !important;'
|
||||
+ 'min-height: initial !important;'
|
||||
+ 'max-width: initial !important;'
|
||||
+ 'max-height: initial !important;'
|
||||
+ 'display: block !important;'
|
||||
+ 'visibility: visible !important;';
|
||||
}
|
||||
|
||||
|
||||
getWrapperStyleOverrides() {
|
||||
return this.getBasicStyleOverrides()
|
||||
+ 'overflow: hidden !important;'
|
||||
+ 'top: 0 !important;'
|
||||
+ 'left: 0 !important;'
|
||||
+ 'position: absolute !important;';
|
||||
}
|
||||
|
||||
|
||||
getImageStyleOverrides() {
|
||||
return this.getBasicStyleOverrides()
|
||||
+ 'object-position: top left !important;'
|
||||
+ 'object-fit: contain !important;';
|
||||
}
|
||||
|
||||
|
||||
debug(...args) {
|
||||
if (this.settings.debug) {
|
||||
console.log('DOM Mutator:', ...args, `${(Date.now() - this.startTime)/1000}s`);
|
||||
}
|
||||
}
|
||||
|
||||
error(...args) {
|
||||
console.error('DOM Mutator:', ...args, `${(Date.now() - this.startTime)/1000}s`);
|
||||
}
|
||||
}
|
||||
|
||||
/* ## EXECUTION_START ## */
|
||||
const flistImagePreviewMutator = new FListImagePreviewDomMutator();
|
||||
flistImagePreviewMutator.run();
|
||||
/* ## EXECUTION_END ## */
|
|
@ -3,10 +3,15 @@
|
|||
import * as _ from 'lodash';
|
||||
import * as urlHelper from 'url';
|
||||
|
||||
|
||||
import { domain as extractDomain } from '../../bbcode/core';
|
||||
|
||||
export interface PreviewMutator {
|
||||
// tslint:disable-next-line:ban-ts-ignore
|
||||
// @ts-ignore
|
||||
// tslint:disable-next-line:no-submodule-imports ban-ts-ignore match-default-export-name
|
||||
import processorScript from '!!raw-loader!./assets/browser.processor.raw.js';
|
||||
|
||||
|
||||
export interface DomMutator {
|
||||
match: string | RegExp;
|
||||
injectJs: string;
|
||||
eventName: string;
|
||||
|
@ -14,32 +19,31 @@ export interface PreviewMutator {
|
|||
urlMutator?(url: string): string;
|
||||
}
|
||||
|
||||
export interface ImagePreviewMutatorCollection {
|
||||
[key: string]: PreviewMutator;
|
||||
}
|
||||
|
||||
|
||||
// tslint:disable-next-line:max-line-length
|
||||
const imgurOuterStyle = 'z-index: 1000000; position: absolute; bottom: 0.75rem; right: 0.75rem; background: rgba(0, 128, 0, 0.8); border: 2px solid rgba(144, 238, 144, 0.5); width: 3rem; height: 3rem; font-size: 15pt; font-weight: normal; color: white; border-radius: 3rem; margin: 0; font-family: Helvetica,Arial,sans-serif; box-shadow: 2px 2px 2px rgba(0,0,0,0.5)';
|
||||
// tslint:disable-next-line:max-line-length
|
||||
const imgurInnerStyle = 'position: absolute; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%); text-shadow: 1px 1px 2px rgba(0,0,0,0.4);';
|
||||
|
||||
export interface DomMutatorScripts {
|
||||
processor: string;
|
||||
}
|
||||
|
||||
export class ImagePreviewMutator {
|
||||
|
||||
export class ImageDomMutator {
|
||||
// tslint:disable: prefer-function-over-method
|
||||
private hostMutators: ImagePreviewMutatorCollection = {};
|
||||
private regexMutators: PreviewMutator[] = [];
|
||||
private hostMutators: Record<string, DomMutator> = {};
|
||||
private regexMutators: DomMutator[] = [];
|
||||
private debug: boolean;
|
||||
private scripts: DomMutatorScripts = { processor: '' };
|
||||
|
||||
constructor(debug: boolean) {
|
||||
this.init();
|
||||
|
||||
// this.debug = debug;
|
||||
this.debug = debug || true;
|
||||
}
|
||||
|
||||
setDebug(debug: boolean): void {
|
||||
this.debug = debug;
|
||||
this.debug = debug || true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +69,7 @@ export class ImagePreviewMutator {
|
|||
return this.wrapJs(mutator.injectJs) + this.getReShowMutator();
|
||||
}
|
||||
|
||||
matchMutator(url: string): PreviewMutator | undefined {
|
||||
matchMutator(url: string): DomMutator | undefined {
|
||||
const urlDomain = extractDomain(url);
|
||||
|
||||
if (!urlDomain)
|
||||
|
@ -76,7 +80,7 @@ export class ImagePreviewMutator {
|
|||
|
||||
return _.find(
|
||||
this.regexMutators,
|
||||
(m: PreviewMutator) => {
|
||||
(m: DomMutator) => {
|
||||
const match = m.match;
|
||||
|
||||
return (match instanceof RegExp) ? (urlDomain.match(match) !== null) : (match === urlDomain);
|
||||
|
@ -115,7 +119,17 @@ export class ImagePreviewMutator {
|
|||
};
|
||||
}
|
||||
|
||||
protected init(): void {
|
||||
|
||||
protected async loadScripts(): Promise<void> {
|
||||
this.scripts = {
|
||||
processor: processorScript
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
async init(): Promise<void> {
|
||||
await this.loadScripts();
|
||||
|
||||
this.add('default', this.getBaseJsMutatorScript(['#video, video', '#image, img']));
|
||||
this.add('e621.net', this.getBaseJsMutatorScript(['video', '#image']));
|
||||
this.add('e-hentai.org', this.getBaseJsMutatorScript(['video', '#img']));
|
||||
|
@ -139,6 +153,7 @@ export class ImagePreviewMutator {
|
|||
this.add('tenor.com', this.getBaseJsMutatorScript(['#view video', '#view img']));
|
||||
this.add('hypnohub.net', this.getBaseJsMutatorScript(['video', '#image', 'img']));
|
||||
this.add('derpibooru.org', this.getBaseJsMutatorScript(['video', '#image-display', 'img']));
|
||||
this.add('sexbot.gallery', this.getBaseJsMutatorScript(['video.hero', 'video']));
|
||||
|
||||
this.add(
|
||||
'pornhub.com',
|
||||
|
@ -208,223 +223,23 @@ export class ImagePreviewMutator {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
getBaseJsMutatorScript(elSelector: string[], skipElementRemove: boolean = false, safeTags: string[] = []): string {
|
||||
return `
|
||||
const ipcRenderer = (typeof require !== 'undefined')
|
||||
? require('electron').ipcRenderer
|
||||
: { sendToHost: (...args) => (console.log('ipc.sendToHost', ...args)) };
|
||||
const js = this.scripts.processor; // ./assets/browser.processor.raw.js
|
||||
|
||||
const body = document.querySelector('body');
|
||||
const html = document.querySelector('html');
|
||||
const selectors = ${JSON.stringify(elSelector)};
|
||||
const settings = {
|
||||
skipElementRemove,
|
||||
safeTags,
|
||||
selectors: elSelector,
|
||||
debug: this.debug
|
||||
};
|
||||
|
||||
for (const el of document.querySelectorAll('header, .header')) {
|
||||
try {
|
||||
el.remove();
|
||||
} catch (err) {
|
||||
console.error('Header removal error', err);
|
||||
}
|
||||
}
|
||||
const settingsJson = JSON.stringify(settings, null, 0);
|
||||
|
||||
// writing this out because sometimes .map and .reduce are overridden
|
||||
let selected = [];
|
||||
|
||||
for (selector of selectors) {
|
||||
const selectedElements = (Array.from(document.querySelectorAll(selector)).filter((i) => ((i.width !== 1) && (i.height !== 1))));
|
||||
selected = selected.concat(selectedElements);
|
||||
}
|
||||
|
||||
${this.debug ? `console.log('Selector', '${elSelector.toString()}'); console.log('Selected', selected);` : ''}
|
||||
|
||||
const img = selected.filter(el => (el !== body)).shift();
|
||||
|
||||
${this.debug ? `console.log('Img', img);` : ''}
|
||||
|
||||
if (!img) { return; }
|
||||
|
||||
const sizePairs = [
|
||||
['naturalWidth', 'naturalHeight'],
|
||||
['videoWidth', 'videoHeight'],
|
||||
['width', 'height'],
|
||||
];
|
||||
|
||||
const resolveImgSize = function() {
|
||||
const solved = {};
|
||||
|
||||
for (let ri = 0; ri < sizePairs.length; ri++) {
|
||||
const val = sizePairs[ri];
|
||||
|
||||
if ((img[val[0]]) && (img[val[1]])) {
|
||||
solved.width = img[val[0]];
|
||||
solved.height = img[val[1]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return solved;
|
||||
}
|
||||
|
||||
|
||||
const preImSize = resolveImgSize();
|
||||
ipcRenderer.sendToHost('webview.img', preImSize.width, preImSize.height, 'preImSize');
|
||||
|
||||
const el = document.createElement('div');
|
||||
el.id = 'flistWrapper';
|
||||
|
||||
el.style = 'width: 100% !important; height: 100% !important; position: absolute !important;'
|
||||
+ 'top: 0 !important; left: 0 !important; z-index: 100000 !important;'
|
||||
+ 'background-color: black !important; background-size: contain !important;'
|
||||
+ 'background-repeat: no-repeat !important; background-position: top left !important;'
|
||||
+ 'opacity: 1 !important; padding: 0 !important; border: 0 !important; margin: 0 !important;'
|
||||
+ 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;';
|
||||
|
||||
try {
|
||||
img.remove();
|
||||
} catch(err) {
|
||||
console.error('Failed remove()', err);
|
||||
|
||||
try {
|
||||
img.parentNode.removeChild(img);
|
||||
} catch(err2) {
|
||||
console.error('Failed removeChild()', err2);
|
||||
}
|
||||
}
|
||||
|
||||
el.append(img);
|
||||
body.append(el);
|
||||
body.class = '';
|
||||
|
||||
body.style = 'border: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important;'
|
||||
+ 'width: 100% !important; height: 100% !important; opacity: 1 !important;'
|
||||
+ 'top: 0 !important; left: 0 !important; position: absolute !important;'
|
||||
+ 'min-width: initial !important; min-height: initial !important; max-width: initial !important; max-height: initial !important;'
|
||||
+ 'display: block !important; visibility: visible !important';
|
||||
|
||||
img.style = 'object-position: top left !important; object-fit: contain !important;'
|
||||
+ 'width: 100% !important; height: 100% !important; opacity: 1 !important;'
|
||||
+ 'margin: 0 !important; border: 0 !important; padding: 0 !important;'
|
||||
+ 'min-width: initial !important; min-height: initial !important; max-width: initial !important; max-height: initial !important;'
|
||||
+ 'display: block !important; visibility: visible !important;';
|
||||
|
||||
img.removeAttribute('width');
|
||||
img.removeAttribute('height');
|
||||
|
||||
img.class = '';
|
||||
el.class = '';
|
||||
html.class = '';
|
||||
|
||||
html.style = 'border: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important;'
|
||||
+ 'width: 100% !important; height: 100% !important; opacity: 1 !important;'
|
||||
+ 'top: 0 !important; left: 0 !important; position: absolute !important;'
|
||||
+ 'min-width: initial !important; min-height: initial !important; max-width: initial !important; max-height: initial !important;'
|
||||
+ 'display: block !important; visibility: visible !important';
|
||||
|
||||
const extraStyle = document.createElement('style');
|
||||
|
||||
extraStyle.textContent = \`
|
||||
#flistWrapper img, #flistWrapper video {
|
||||
object-position: top left !important;
|
||||
object-fit: contain !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
opacity: 1 !important;
|
||||
margin: 0 !important;
|
||||
border: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-width: initial !important;
|
||||
min-height: initial !important;
|
||||
max-width: initial !important;
|
||||
max-height: initial !important;
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
\`;
|
||||
|
||||
el.append(extraStyle);
|
||||
|
||||
${this.debug ? "console.log('Wrapper', el);" : ''}
|
||||
|
||||
if ((!img.src) && (img.tagName) && (img.tagName.toUpperCase() === 'VIDEO')) {
|
||||
${this.debug ? "console.log('Nedds a content URL', img);" : ''}
|
||||
|
||||
const contentUrls = document.querySelectorAll('meta[itemprop="contentURL"]');
|
||||
|
||||
if ((contentUrls) && (contentUrls.length > 0)) {
|
||||
${this.debug ? "console.log('Found content URLs', contentUrls);" : ''}
|
||||
|
||||
const cu = contentUrls[0];
|
||||
|
||||
if ((cu.attributes) && (cu.attributes.content) && (cu.attributes.content.value)) {
|
||||
${this.debug ? "console.log('Content URL', cu.attributes.content.value);" : ''}
|
||||
|
||||
img.src = cu.attributes.content.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
${this.debug ? "console.log('on DOMContentLoaded');" : ''}
|
||||
|
||||
const imSize = resolveImgSize();
|
||||
ipcRenderer.sendToHost('webview.img', imSize.width, imSize.height, 'dom-content-loaded');
|
||||
|
||||
if (
|
||||
(img.play)
|
||||
&& ((!img.paused) && (!img.ended) && (!(img.currentTime > 0)))
|
||||
)
|
||||
{ img.muted = true; img.loop = true; img.play(); }
|
||||
});
|
||||
|
||||
document.addEventListener('load', (event) => {
|
||||
${this.debug ? "console.log('on load');" : ''}
|
||||
|
||||
const imSize = resolveImgSize();
|
||||
ipcRenderer.sendToHost('webview.img', imSize.width, imSize.height, 'load');
|
||||
|
||||
if (
|
||||
(img.play)
|
||||
&& ((!img.paused) && (!img.ended) && (!(img.currentTime > 0)))
|
||||
)
|
||||
{ img.muted = true; img.loop = true; img.play(); }
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
if (img.play) { img.muted = true; img.loop = true; img.play(); }
|
||||
} catch (err) {
|
||||
console.error('Failed img.play()', err);
|
||||
}
|
||||
|
||||
|
||||
const updateSize = () => {
|
||||
const imSize = resolveImgSize();
|
||||
|
||||
if ((imSize.width) && (imSize.height)) {
|
||||
ipcRenderer.sendToHost('webview.img', imSize.width, imSize.height, 'updateSize');
|
||||
} else {
|
||||
setTimeout(() => updateSize(), 200);
|
||||
}
|
||||
}
|
||||
|
||||
updateSize();
|
||||
|
||||
|
||||
let removeList = [];
|
||||
const safeIds = ['flistWrapper', 'flistError', 'flistHider'];
|
||||
const safeTags = [${_.map(safeTags, (t) => `'${t.toLowerCase()}'`).join(',')}];
|
||||
|
||||
body.childNodes.forEach((el) => (
|
||||
(
|
||||
(safeIds.indexOf(el.id) < 0)
|
||||
&& ((!el.tagName) || (safeTags.indexOf(el.tagName.toLowerCase())) < 0)
|
||||
) ? removeList.push(el) : true)
|
||||
);
|
||||
|
||||
${skipElementRemove ? '' : 'removeList.forEach((el) => el.remove());'}
|
||||
removeList = [];
|
||||
`;
|
||||
return js.replace(/\/\* ## SETTINGS_START[^]*SETTINGS_END ## \*\//m, `this.settings = ${settingsJson}`);
|
||||
}
|
||||
|
||||
|
||||
getErrorMutator(code: number, description: string): string {
|
||||
const errorHtml = `
|
||||
<div id="flistError" style="
|
|
@ -23,7 +23,6 @@ const includedPaths = [
|
|||
// 'spellchecker/build/Release/spellchecker.node',
|
||||
'keytar/build/Release/keytar.node',
|
||||
'throat',
|
||||
'@cliqz/adblocker-electron',
|
||||
'node-fetch',
|
||||
'jquery'
|
||||
];
|
||||
|
|
|
@ -25,7 +25,8 @@ const mainConfig = {
|
|||
}
|
||||
},
|
||||
{test: path.join(__dirname, 'package.json'), loader: 'file-loader?name=package.json', type: 'javascript/auto'},
|
||||
{test: /\.(png|html)$/, loader: 'file-loader?name=[name].[ext]'}
|
||||
{test: /\.(png|html)$/, loader: 'file-loader?name=[name].[ext]'},
|
||||
{test: /\.raw\.js$/, loader: 'raw-loader'}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
|
@ -82,6 +83,7 @@ const mainConfig = {
|
|||
{test: /\.(png|html)$/, loader: 'file-loader?name=[name].[ext]'},
|
||||
{test: /\.vue\.scss/, loader: ['vue-style-loader','css-loader','sass-loader']},
|
||||
{test: /\.vue\.css/, loader: ['vue-style-loader','css-loader']},
|
||||
{test: /\.raw\.js$/, loader: 'raw-loader'}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
declare module "!!raw-loader!*" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
|
@ -29,6 +29,7 @@
|
|||
"optimize-css-assets-webpack-plugin": "^5.0.1",
|
||||
"qs": "^6.9.1",
|
||||
"raven-js": "^3.27.2",
|
||||
"raw-loader": "^4.0.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sortablejs": "~1.9.0",
|
||||
"style-loader": "^0.23.1",
|
||||
|
|
|
@ -5276,6 +5276,14 @@ raw-body@2.4.0:
|
|||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
raw-loader@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.0.tgz#d639c40fb9d72b5c7f8abc1fb2ddb25b29d3d540"
|
||||
integrity sha512-iINUOYvl1cGEmfoaLjnZXt4bKfT2LJnZZib5N/LLyAphC+Dd11vNP9CNVb38j+SAJpFI1uo8j9frmih53ASy7Q==
|
||||
dependencies:
|
||||
loader-utils "^1.2.3"
|
||||
schema-utils "^2.5.0"
|
||||
|
||||
rc@^1.2.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
|
|
Loading…
Reference in New Issue