some refactoring

This commit is contained in:
Schnitzel5 2025-10-11 21:59:46 +02:00
parent b8a7bbbbb4
commit 5e05c4e9aa
5 changed files with 85 additions and 17 deletions

View file

@ -219,17 +219,45 @@ class ElementCollection {
this.elements = elements;
}
text() {
return this.map(function(i, el) {
return el.text();
}).toArray().join("\\n") ?? "";
}
html() {
return this.first()?.html();
}
outerHtml() {
return this.first()?.outerHtml();
}
attr(name) {
return this.first()?.attr(name);
}
hasClass(cls) {
return this.first()?.hasClass(cls);
}
each(fn) {
this.elements.forEach((el, i) => fn(i, el));
return this;
}
map(fn) {
return this.elements.map((el, i) => fn(el, i));
return new ElementCollection(this.elements.map((el, i) => fn(i, el)));
}
filter(fn) {
return new ElementCollection(this.elements.filter((el, i) => fn(el, i)));
return new ElementCollection(this.elements.filter(function (el, i) {
try {
return fn(i, el);
} catch (_) {
return false;
}
}));
}
addClass(cls) {
@ -309,37 +337,62 @@ class ElementCollection {
}
first() {
return this.elements[0] || null;
return this.get(0);
}
last() {
return this.elements[this.elements.length - 1] || null;
return this.get(this.elements.length - 1);
}
get(index) {
return this.elements[index] || null;
return this.elements[index] || new Stub();
}
length() {
return this.elements.length;
}
toArray() {
return this.elements;
}
[Symbol.iterator]() {
return this.elements[Symbol.iterator]();
}
}
class Stub {
text() {
return null;
}
html() {
return null;
}
outerHtml() {
return null;
}
val() {
return null;
}
attr(name) {
return null;
}
hasClass(cls) {
return false;
}
}
function load(html) {
const rootKey = sendMessage("load", JSON.stringify([html]));
const root = new Element(rootKey);
const \$ = function(input) {
if (typeof input === "string") {
return root.find(input); // returns ElementCollection
} else if (input instanceof ElementCollection) {
if (input instanceof ElementCollection) {
return input;
} else if (input instanceof Element) {
return input;
} else if (typeof input === "string") {
return root.find(input); // returns ElementCollection
} else if (input && input._key) {
return new ElementCollection([new Element(input._key)]);
} else {
@ -347,6 +400,9 @@ function load(html) {
}
};
\$.html = function() {
return root.html();
};
\$.root = root;
\$.Element = Element;
\$.Collection = ElementCollection;

View file

@ -72,6 +72,10 @@ String.prototype.substringBetween = function(left, right) {
return this.substring(leftIndex, rightIndex);
}
async function jsonStringify(fn) {
return JSON.stringify(await fn());
}
const isUrlAbsolute = url => {
if (url) {
if (url.indexOf("//") === 0) {

View file

@ -6,7 +6,19 @@ class JsPolyfills {
void init() {
runtime.evaluate('''
const global="object"==typeof globalThis?globalThis:"object"==typeof window?window:"object"==typeof self?self:this,_FormData=global.FormData,_send=global.XMLHttpRequest&&global.XMLHttpRequest.prototype.send,_fetch=global.Request&&global.fetch,_sendBeacon=global.navigator&&global.navigator.sendBeacon,_match=global.Element&&global.Element.prototype,stringTag=global.Symbol&&Symbol.toStringTag;function ensureArgs(e,t){if(e.length<t)throw new TypeError(`\${t} argument required, but only \${e.length} present.`)}function normalizeArgs(e,t,a){return[String(e),String(t)]}function normalizeLinefeeds(e){return e.replace(/\r?\n|\r/g,"\r\n")}function each(e,t){for(let a=0;a<e.length;a++)t(e[a])}stringTag&&"File"in global&&!File.prototype[stringTag]&&(File.prototype[stringTag]="File");const escape=e=>e.replace(/\n/g,"%0A").replace(/\r/g,"%0D").replace(/"/g,"%22");class FormData{constructor(e){this._data=[];const t=this;e&&each(e.elements,(e=>{if(e.name&&!e.disabled&&"submit"!==e.type&&"button"!==e.type&&!e.matches("form fieldset[disabled] *"))if("file"===e.type){each(e.files&&e.files.length?e.files:[new File([],"",{type:"application/octet-stream"})],(a=>{t.append(e.name,a)}))}else if("select-multiple"===e.type||"select-one"===e.type)each(e.options,(a=>{!a.disabled&&a.selected&&t.append(e.name,a.value)}));else if("checkbox"===e.type||"radio"===e.type)e.checked&&t.append(e.name,e.value);else{const a="textarea"===e.type?normalizeLinefeeds(e.value):e.value;t.append(e.name,a)}}))}append(e,t,a){ensureArgs(arguments,2),this._data.push(normalizeArgs(e,t,a))}delete(e){ensureArgs(arguments,1);const t=[];e=String(e),each(this._data,(a=>{a[0]!==e&&t.push(a)})),this._data=t}*entries(){for(var e=0;e<this._data.length;e++)yield this._data[e]}forEach(e,t){ensureArgs(arguments,1);for(const[a,n]of this)e.call(t,n,a,this)}get(e){ensureArgs(arguments,1);const t=this._data;e=String(e);for(let a=0;a<t.length;a++)if(t[a][0]===e)return t[a][1];return null}getAll(e){ensureArgs(arguments,1);const t=[];return e=String(e),each(this._data,(a=>{a[0]===e&&t.push(a[1])})),t}has(e){ensureArgs(arguments,1),e=String(e);for(let t=0;t<this._data.length;t++)if(this._data[t][0]===e)return!0;return!1}*keys(){for(const[e]of this)yield e}set(e,t,a){ensureArgs(arguments,2),e=String(e);const n=[],r=normalizeArgs(e,t,a);let s=!0;each(this._data,(t=>{t[0]===e?s&&(s=!n.push(r)):n.push(t)})),s&&n.push(r),this._data=n}*values(){for(const[,e]of this)yield e}_asNative(){const e=new _FormData;for(const[t,a]of this)e.append(t,a);return e}_blob(){const e="----formdata-polyfill-"+Math.random(),t=[],a=`--\${e}\r\nContent-Disposition: form-data; name="`;return this.forEach(((e,n)=>"string"==typeof e?t.push(a+escape(normalizeLinefeeds(n))+`"\r\n\r\n\${normalizeLinefeeds(e)}\r\n`):t.push(a+escape(normalizeLinefeeds(n))+`"; filename="\${escape(e.name)}"\r\nContent-Type: \${e.type||"application/octet-stream"}\r\n\r\n`,e,"\r\n"))),t.push(`--\${e}--`),new Blob(t,{type:"multipart/form-data; boundary="+e})}[Symbol.iterator](){return this.entries()}toString(){return"[object FormData]"}}stringTag&&(FormData.prototype[stringTag]="FormData");
class FormData {
constructor() {
this.params = {};
}
append(key, value) {
this.params[key] = value;
}
toJSON() {
return this.params;
}
}
''');
runtime.evaluate('''
/**!

View file

@ -1,5 +1,3 @@
import 'dart:convert';
class ChapterItem {
String name;
String path;
@ -20,9 +18,10 @@ class ChapterItem {
name: json['name'],
path: json['path'],
releaseTime: json['releaseTime'],
chapterNumber:
int.tryParse(json['chapterNumber']) ??
(json['chapterNumber'] as num?)?.toInt(),
chapterNumber: json['chapterNumber'] != null
? (json['chapterNumber'] as num?)?.toInt() ??
int.tryParse(json['chapterNumber'])
: null,
page: json['page'],
);
}

View file

@ -45,9 +45,6 @@ module={},exports=Function("return this")(),Object.defineProperties(module,{name
JsHtmlParser(runtime).init();
JsCheerio(runtime).init();
runtime.evaluate('''
async function jsonStringify(fn) {
return JSON.stringify(await fn());
}
const require = (package) => {
switch (package) {
case "htmlparser2":