added DOM HTML WRAPPERS (Document & Element)

This commit is contained in:
kodjomoustapha 2023-12-20 15:02:30 +01:00
parent 06f35dcc70
commit 68ff513932
8 changed files with 710 additions and 5 deletions

View file

@ -0,0 +1,212 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:html/dom.dart';
import 'package:mangayomi/eval/bridge/element.dart';
import 'package:mangayomi/eval/model/document.dart';
import 'package:mangayomi/eval/model/element.dart';
class $MDocument implements MDocument, $Instance {
$MDocument.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MDocument'));
static const $declaration = BridgeClassDef(BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
BridgeParameter('document',
BridgeTypeAnnotation($Element.$type, nullable: true), false),
]),
)
},
fields: {
'document': BridgeFieldDef(BridgeTypeAnnotation($Element.$type)),
},
getters: {
'body': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
)),
'documentElement': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
)),
'head': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
)),
'parent': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
)),
'outerHtml': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'text': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'children': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list, [$MElement.$type]),
nullable: true),
)),
},
methods: {
'select': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list, [$MElement.$type]),
nullable: true),
params: [
BridgeParameter(
'selector',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
false)
]),
),
'selectFirst': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
params: [
BridgeParameter(
'selector',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
false)
]),
),
},
wrap: true);
@override
get $reified => $value;
@override
final MDocument $value;
final $Instance _superclass;
@override
$Value? $getProperty(Runtime runtime, String identifier) {
switch (identifier) {
case 'body':
final res = $value.body;
return res == null ? const $null() : $MElement.wrap(res);
case 'documentElement':
final res = $value.documentElement;
return res == null ? const $null() : $MElement.wrap(res);
case 'head':
final res = $value.head;
return res == null ? const $null() : $MElement.wrap(res);
case 'parent':
final res = $value.parent;
return res == null ? const $null() : $MElement.wrap(res);
case 'outerHtml':
final res = $value.outerHtml;
return res == null ? const $null() : $String(res);
case 'text':
final res = $value.text;
return res == null ? const $null() : $String(res);
case 'children':
final res = $value.children;
return res == null
? const $null()
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
case 'select':
return __select;
case 'selectFirst':
return __selectFirst;
default:
return _superclass.$getProperty(runtime, identifier);
}
}
@override
int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);
@override
void $setProperty(Runtime runtime, String identifier, $Value value) {}
static const $Function __select = $Function(_select);
static $Value? _select(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
final res = (target!.$value as MDocument).select(args[0]?.$value);
return res == null
? const $null()
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
}
static const $Function __selectFirst = $Function(_selectFirst);
static $Value? _selectFirst(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
final res = (target!.$value as MDocument).selectFirst(args[0]?.$value);
return res == null ? const $null() : $MElement.wrap(res);
}
static $Value? $new(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
return $MDocument.wrap(MDocument(args[0]?.$value));
}
@override
List<MElement>? select(String selector) => $value.select(selector);
@override
MElement? selectFirst(String selector) => $value.selectFirst(selector);
@override
MElement? get body => $value.body;
@override
List<MElement>? get children => $value.children;
@override
MElement? get documentElement => $value.documentElement;
@override
MElement? get head => $value.head;
@override
String? get outerHtml => $value.outerHtml;
@override
MElement? get parent => $value.parent;
@override
String? get text => $value.text;
}
class $Document implements $Instance {
$Document.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Document'));
static const $declaration = BridgeClassDef(
BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type, nullable: true)))
},
wrap: true,
);
@override
get $reified => $value;
@override
final Document $value;
final $Instance _superclass;
@override
$Value? $getProperty(Runtime runtime, String identifier) {
return _superclass.$getProperty(runtime, identifier);
}
@override
int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);
@override
void $setProperty(Runtime runtime, String identifier, $Value value) {}
}

View file

@ -0,0 +1,301 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:html/dom.dart';
import 'package:mangayomi/eval/model/element.dart';
class $MElement implements MElement, $Instance {
$MElement.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MElement'));
static const $declaration = BridgeClassDef(BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
BridgeParameter('element',
BridgeTypeAnnotation($Element.$type, nullable: true), false),
]),
)
},
fields: {
'element': BridgeFieldDef(BridgeTypeAnnotation($Element.$type)),
},
getters: {
'outerHTML': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'innerHtml': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'text': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'className': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'localName': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'namespaceUri': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'getSrc': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'getImg': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'getHref': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'getDataSrc': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
)),
'children': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]),
nullable: true),
)),
'parent': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type, nullable: true),
)),
'nextElementSibling': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type, nullable: true),
)),
'previousElementSibling': BridgeMethodDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type, nullable: true),
)),
},
methods: {
'attr': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
params: [
BridgeParameter(
'attr',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
false)
]),
),
'text': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true)),
),
'select': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list, [$type]),
nullable: true),
params: [
BridgeParameter(
'selector',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
false)
]),
),
'selectFirst': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation($type, nullable: true),
params: [
BridgeParameter(
'selector',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
false)
]),
),
},
wrap: true);
@override
get $reified => $value;
@override
final MElement $value;
final $Instance _superclass;
@override
$Value? $getProperty(Runtime runtime, String identifier) {
switch (identifier) {
case 'outerHTML':
final res = $value.outerHTML;
return res == null ? const $null() : $String(res);
case 'innerHtml':
final res = $value.innerHtml;
return res == null ? const $null() : $String(res);
case 'text':
final res = $value.text;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'className':
final res = $value.className;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'localName':
final res = $value.localName;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'namespaceUri':
final res = $value.namespaceUri;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'getSrc':
final res = $value.getSrc;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'getImg':
final res = $value.getImg;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'getHref':
final res = $value.getHref;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'getDataSrc':
final res = $value.getDataSrc;
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
case 'parent':
final res = $value.parent;
return res == null ? const $null() : $MElement.wrap(res);
case 'nextElementSibling':
final res = $value.nextElementSibling;
return res == null ? const $null() : $MElement.wrap(res);
case 'previousElementSibling':
final res = $value.previousElementSibling;
return res == null ? const $null() : $MElement.wrap(res);
case 'attr':
return __attr;
case 'select':
return __select;
case 'selectFirst':
return __selectFirst;
default:
return _superclass.$getProperty(runtime, identifier);
}
}
@override
int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);
@override
void $setProperty(Runtime runtime, String identifier, $Value value) {}
static $Value? $new(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
return $MElement.wrap(MElement(args[0]?.$value));
}
static const $Function __attr = $Function(_attr);
static $Value? _attr(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
final res = (target!.$value as MElement).attr(args[0]?.$value ?? "");
return res == null ? const $null() : $String(res);
}
static const $Function __select = $Function(_select);
static $Value? _select(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
final res = (target!.$value as MElement).select(args[0]?.$value);
return res == null
? const $null()
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
}
static const $Function __selectFirst = $Function(_selectFirst);
static $Value? _selectFirst(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
final res = (target!.$value as MElement).selectFirst(args[0]?.$value);
return res == null ? const $null() : $MElement.wrap(res);
}
@override
String? attr(String attr) => $value.attr(attr);
@override
List<MElement>? select(String selector) => $value.select(selector);
@override
MElement? selectFirst(String selector) => $value.selectFirst(selector);
@override
List<MElement>? get children => $value.children;
@override
String? get className => $value.className;
@override
String? get getDataSrc => $value.getDataSrc;
@override
String? get getHref => $value.getHref;
@override
String? get getImg => $value.getImg;
@override
String? get getSrc => $value.getSrc;
@override
String? get innerHtml => $value.innerHtml;
@override
String? get localName => $value.localName;
@override
String? get namespaceUri => $value.namespaceUri;
@override
MElement? get nextElementSibling => $value.nextElementSibling;
@override
String? get outerHTML => $value.outerHTML;
@override
MElement? get parent => $value.parent;
@override
MElement? get previousElementSibling => $value.previousElementSibling;
@override
String? get text => $value.text;
}
class $Element implements $Instance {
$Element.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Element'));
static const $declaration = BridgeClassDef(
BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type, nullable: true)))
},
wrap: true,
);
@override
get $reified => $value;
@override
final Element $value;
final $Instance _superclass;
@override
$Value? $getProperty(Runtime runtime, String identifier) {
return _superclass.$getProperty(runtime, identifier);
}
@override
int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);
@override
void $setProperty(Runtime runtime, String identifier, $Value value) {}
}

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge/document.dart';
import 'package:mangayomi/eval/bridge/filter.dart';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
@ -760,6 +761,17 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
]),
),
'parseHtml': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation($MDocument.$type),
params: [
BridgeParameter(
'html',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
false),
],
namedParams: []),
isStatic: true),
},
bridge: true);
@ -774,6 +786,10 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
return $Future.wrap(MBridge.http(args[0]!.$reified, args[1]!.$reified)
.then((value) => $String(value)));
}),
'parseHtml' => $Function((_, __, List<$Value?> args) {
final res = MBridge.parsHtml(args[0]!.$reified);
return $MDocument.wrap(res);
}),
'getPreferenceValue' => $Function((_, __, List<$Value?> args) {
final value =
getPreferenceValue(args[0]!.$reified, args[1]!.$reified);

View file

@ -0,0 +1,32 @@
import 'package:html/dom.dart';
import 'package:mangayomi/eval/model/element.dart';
import 'package:mangayomi/utils/extensions.dart';
class MDocument {
const MDocument(this._document);
final Document? _document;
MElement? get body => MElement(_document?.body);
MElement? get documentElement => MElement(_document?.documentElement);
MElement? get head => MElement(_document?.head);
MElement? get parent => MElement(_document?.parent);
String? get outerHtml => _document?.outerHtml;
String? get text => _document?.text;
List<MElement>? get children =>
_document?.children.map((e) => MElement(e)).toList();
List<MElement>? select(String selector) {
return _document?.select(selector)?.map((e) => MElement(e)).toList();
}
MElement? selectFirst(String selector) {
return MElement(_document?.selectFirst(selector));
}
}

View file

@ -0,0 +1,51 @@
import 'package:html/dom.dart';
import 'package:mangayomi/utils/extensions.dart';
class MElement {
MElement(this._element);
final Element? _element;
String? get outerHTML => _element?.outerHtml;
String? get innerHtml => _element?.innerHtml;
String? get text => _element?.text;
String? get className => _element?.className;
String? get localName => _element?.localName;
String? get namespaceUri => _element?.namespaceUri;
String? get getSrc => _element?.getSrc;
String? get getImg => _element?.getImg;
String? get getHref => _element?.getHref;
String? get getDataSrc => _element?.getDataSrc;
List<MElement>? get children =>
_element?.children.map((e) => MElement(e)).toList();
MElement? get parent => MElement(_element?.parent);
MElement? get nextElementSibling => MElement(_element?.nextElementSibling);
MElement? get previousElementSibling =>
MElement(_element?.previousElementSibling);
List<MElement>? select(String selector) {
return _element?.select(selector)?.map((e) => MElement(e)).toList();
}
MElement? selectFirst(String selector) {
return MElement(_element?.selectFirst(selector));
}
String? attr(String attribute) {
return _element?.attr(attribute);
}
}

View file

@ -7,10 +7,12 @@ import 'package:dart_eval/stdlib/core.dart';
import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:html/dom.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:js_packer/js_packer.dart';
import 'package:json_path/json_path.dart';
import 'package:mangayomi/eval/model/document.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
import 'package:mangayomi/services/anime_extractors/filemoon.dart';
@ -184,6 +186,10 @@ class MBridge {
}
}
static MDocument parsHtml(String html) {
return MDocument(Document.html(html));
}
///Create query by html string
static const $Function xpath = $Function(_xpath);
@ -483,11 +489,7 @@ class MBridge {
//Utility to use RegExp
static String regExp(
String expression,
String source,
String replace,
int type,
int group) {
String expression, String source, String replace, int type, int group) {
if (type == 0) {
return expression.replaceAll(RegExp(source), replace);
}

View file

@ -1,5 +1,7 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:mangayomi/eval/bridge/document.dart';
import 'package:mangayomi/eval/bridge/element.dart';
import 'package:mangayomi/eval/bridge/m_chapter.dart';
import 'package:mangayomi/eval/bridge/filter.dart';
import 'package:mangayomi/eval/bridge/m_pages.dart';
@ -44,6 +46,11 @@ class MEvalPlugin extends EvalPlugin {
registry.defineBridgeClass($MultiSelectListPreference.$declaration);
registry.defineBridgeClass($CheckBoxPreference.$declaration);
registry.defineBridgeClass($EditTextPreference.$declaration);
//DOM HTML
registry.defineBridgeClass($MElement.$declaration);
registry.defineBridgeClass($Element.$declaration);
registry.defineBridgeClass($MDocument.$declaration);
registry.defineBridgeClass($Document.$declaration);
}
@override
@ -99,5 +106,10 @@ class MEvalPlugin extends EvalPlugin {
'MultiSelectListPreference.', $MultiSelectListPreference.$new);
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
'EditTextPreference.', $EditTextPreference.$new);
//DOM HTML
runtime.registerBridgeFunc(
'package:mangayomi/bridge_lib.dart', 'MElement.', $MElement.$new);
runtime.registerBridgeFunc(
'package:mangayomi/bridge_lib.dart', 'MDocument.', $MDocument.$new);
}
}

View file

@ -1,3 +1,6 @@
import 'package:html/dom.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart';
extension StringExtensions on String {
String substringAfter(String pattern) {
final startIndex = indexOf(pattern);
@ -61,3 +64,79 @@ extension LetExtension<T> on T {
return block(this);
}
}
extension SelectDocumentExtension on Document? {
List<Element>? select(String selector) {
try {
return this?.querySelectorAll(selector);
} catch (e) {
return null;
}
}
Element? selectFirst(String selector) {
try {
return this?.querySelector(selector);
} catch (e) {
return null;
}
}
}
extension SelectElementtExtension on Element {
List<Element>? select(String selector) {
try {
return querySelectorAll(selector);
} catch (e) {
return null;
}
}
Element? selectFirst(String selector) {
try {
return querySelector(selector);
} catch (e) {
return null;
}
}
String? attr(String attribute) {
try {
return attributes[attribute];
} catch (e) {
return null;
}
}
String? get getSrc {
try {
return regSrcMatcher(outerHtml);
} catch (e) {
return null;
}
}
String? get getImg {
try {
return regImgMatcher(outerHtml);
} catch (e) {
return null;
}
}
String? get getHref {
try {
return regHrefMatcher(outerHtml);
} catch (e) {
return null;
}
}
String? get getDataSrc {
try {
return regDataSrcMatcher(outerHtml);
} catch (e) {
return null;
}
}
}