Greasy Fork is available in English.
process html, store and filter data
Ce script ne devrait pas être installé directement. C'est une librairie créée pour d'autres scripts. Elle doit être inclus avec la commande // @require https://update.greasyfork.org/scripts/548610/1656007/data-manager2.js
// ==UserScript==
// @name data-manager2
// @namespace Violentmonkey Scripts
// @version 1.5
// @license MIT
// @description process html, store and filter data
// @author smartacephale
// @match *://*/*
// @grant unsafeWindow
// @grant GM_addStyle
// @downloadURL https://update.greasyfork.org/scripts/494204/data-manager.user.js
// @updateURL https://update.greasyfork.org/scripts/494204/data-manager.meta.js
// ==/UserScript==
class DataFilter {
constructor(rules, state) {
this.state = state;
this.rules = rules;
const methods = Object.getOwnPropertyNames(this);
this.filters = methods.reduce((acc, k) => {
if (k in this.state) {
acc[k] = this[k];
GM_addStyle(`.filter-${k.toLowerCase().slice(6)} { display: none !important; }`);
}
return acc;
}, {});
}
filterPublic = () => {
return (v) => {
const isPublic = !this.rules.IS_PRIVATE(v.element);
return {
tag: 'filter-public',
condition: this.state.filterPublic && isPublic
};
}
}
filterPrivate = () => {
return (v) => {
const isPrivate = this.rules.IS_PRIVATE(v.element);
return {
tag: 'filter-private',
condition: this.state.filterPrivate && isPrivate
};
}
}
filterDuration = () => {
return (v) => {
const notInRange = v.duration < this.state.filterDurationFrom || v.duration > this.state.filterDurationTo;
return {
tag: 'filter-duration',
condition: this.state.filterDuration && notInRange
};
}
}
filterExclude = () => {
const tags = DataManager.filterDSLToRegex(this.state.filterExcludeWords);
return (v) => {
const containTags = tags.some(tag => tag.test(v.title));
return {
tag: 'filter-exclude',
condition: this.state.filterExclude && containTags
};
}
}
filterInclude = () => {
const tags = DataManager.filterDSLToRegex(this.state.filterIncludeWords);
return (v) => {
const containTagsNot = tags.some(tag => !tag.test(v.title));
return {
tag: 'filter-include',
condition: this.state.filterInclude && containTagsNot
};
}
}
}
class DataManager {
constructor(rules, state) {
this.rules = rules;
this.state = state;
this.data = new Map();
this.lazyImgLoader = new unsafeWindow.bhutils.LazyImgLoader((target) => !this.isFiltered(target));
this.dataFilters = new DataFilter(rules, state).filters;
}
static filterDSLToRegex(str) {
const toFullWord = w => `(^|\ )${w}($|\ )`;
const str_ = str.replace(/f\:(\w+)/g, (_, w) => toFullWord(w));
return unsafeWindow.bhutils.stringToWords(str_).map(expr => new RegExp(expr, 'i'));
}
isFiltered(el) {
return el.className.includes('filtered');
}
applyFilters = (filters, offset = 0) => {
const filtersToApply = Object.keys(filters)
.filter(k => Object.hasOwn(this.dataFilters, k))
.map(k => this.dataFilters[k]());
if (filtersToApply.length === 0) return;
let updates = [];
let offset_counter = 1;
for (const v of this.data.values()) {
if (++offset_counter > offset) {
for (const f of filtersToApply) {
const {tag, condition} = f(v);
updates.push(() => v.element.classList.toggle(tag, condition));
}
}
}
requestAnimationFrame(() => {
updates.forEach(update => update());
});
}
filterAll = (offset) => {
const filters = Object.assign({}, ...Object.keys(this.dataFilters).map(f => ({ [f]: this.state[f] })));
this.applyFilters(filters, offset);
}
handleLoadedHTML = (html, container, removeDuplicates = false, shouldLazify = true) => {
const thumbs = this.rules.GET_THUMBS(html);
const data_offset = this.data.size;
for (const thumbElement of thumbs) {
const url = this.rules.THUMB_URL(thumbElement);
if (!url || this.data.has(url)) {
if (removeDuplicates) thumbElement.remove();
continue;
}
const { title, duration } = this.rules.THUMB_DATA(thumbElement);
this.data.set(url, { element: thumbElement, duration, title });
if (shouldLazify) {
const { img, imgSrc } = this.rules.THUMB_IMG_DATA(thumbElement);
this.lazyImgLoader.lazify(thumbElement, img, imgSrc);
}
const parent = container || this.rules.CONTAINER;
if (!parent.contains(thumbElement)) parent.appendChild(thumbElement);
}
this.filterAll(data_offset);
};
}