mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-01-11 22:40:36 +00:00
+
This commit is contained in:
parent
5ef46ec13d
commit
b8a7bbbbb4
5 changed files with 425 additions and 130 deletions
|
|
@ -58,10 +58,16 @@ class Response {
|
|||
return this.response.body;
|
||||
}
|
||||
json() {
|
||||
return JSON.parse(this.body);
|
||||
const val = JSON.parse(this.body);
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(val);
|
||||
});
|
||||
}
|
||||
text() {
|
||||
return this.body;
|
||||
const val = this.body;
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class JsCheerio {
|
|||
final html = args[0];
|
||||
final doc = parse(html);
|
||||
_elementKey++;
|
||||
_elements[_elementKey] = doc.documentElement;
|
||||
_elements[_elementKey] = doc.body;
|
||||
return _elementKey;
|
||||
});
|
||||
|
||||
|
|
@ -156,114 +156,203 @@ class JsCheerio {
|
|||
});
|
||||
|
||||
runtime.evaluate('''
|
||||
function \$(key) {
|
||||
return {
|
||||
_key: key,
|
||||
_call: function(method, args) {
|
||||
if (!args) {
|
||||
args = [];
|
||||
}
|
||||
return sendMessage("element_call", JSON.stringify([method, this._key, args]));
|
||||
},
|
||||
text: function() {
|
||||
return this._call("text");
|
||||
},
|
||||
html: function() {
|
||||
return this._call("html");
|
||||
},
|
||||
outerHtml: function() {
|
||||
return this._call("outerHtml");
|
||||
},
|
||||
addClass: function(cls) {
|
||||
this._call("addClass", [cls]);
|
||||
return this;
|
||||
},
|
||||
removeClass: function(cls) {
|
||||
this._call("removeClass", [cls]);
|
||||
return this;
|
||||
},
|
||||
hasClass: function(cls) {
|
||||
return this._call("hasClass", [cls]);
|
||||
},
|
||||
attr: function(name) {
|
||||
return this._call("attr", [name]);
|
||||
},
|
||||
setAttr: function(name, value) {
|
||||
this._call("setAttr", [name, value]);
|
||||
return this;
|
||||
},
|
||||
removeAttr: function(name) {
|
||||
this._call("removeAttr", [name]);
|
||||
return this;
|
||||
},
|
||||
val: function() {
|
||||
return this._call("val");
|
||||
},
|
||||
setVal: function(value) {
|
||||
this._call("setVal", [value]);
|
||||
return this;
|
||||
},
|
||||
children: function() {
|
||||
let result = this._call("children");
|
||||
return JSON.parse(result).map(k => \$(k));
|
||||
},
|
||||
parent: function() {
|
||||
let k = this._call("parent");
|
||||
return \$(k);
|
||||
},
|
||||
find: function(selector) {
|
||||
let result = this._call("find", [selector]);
|
||||
return JSON.parse(result).map(k => \$(k));
|
||||
},
|
||||
first: function() {
|
||||
let k = this._call("first");
|
||||
return \$(k);
|
||||
},
|
||||
last: function() {
|
||||
let k = this._call("last");
|
||||
return \$(k);
|
||||
},
|
||||
next: function() {
|
||||
let k = this._call("next");
|
||||
return \$(k);
|
||||
},
|
||||
prev: function() {
|
||||
let k = this._call("prev");
|
||||
return \$(k);
|
||||
},
|
||||
append: function(html) {
|
||||
this._call("append", [html]);
|
||||
return this;
|
||||
},
|
||||
prepend: function(html) {
|
||||
this._call("prepend", [html]);
|
||||
return this;
|
||||
},
|
||||
empty: function() {
|
||||
this._call("empty");
|
||||
return this;
|
||||
},
|
||||
remove: function() {
|
||||
this._call("remove");
|
||||
return this;
|
||||
},
|
||||
each: function(fn) {
|
||||
this.children().forEach((child, i) => fn(child, i));
|
||||
return this;
|
||||
},
|
||||
map(fn) {
|
||||
return this.children().map((child, i) => fn(child, i));
|
||||
},
|
||||
filter(fn) {
|
||||
return this.children().filter((child, i) => fn(child, i));
|
||||
}
|
||||
};
|
||||
}
|
||||
class Element {
|
||||
constructor(key) {
|
||||
this._key = key;
|
||||
}
|
||||
|
||||
function load(html) {
|
||||
const key = sendMessage("load", JSON.stringify([html]));
|
||||
return \$(key);
|
||||
_call(method, args = []) {
|
||||
return sendMessage("element_call", JSON.stringify([method, this._key, args]));
|
||||
}
|
||||
|
||||
text() { return this._call("text"); }
|
||||
html() { return this._call("html"); }
|
||||
outerHtml() { return this._call("outerHtml"); }
|
||||
val() { return this._call("val"); }
|
||||
attr(name) { return this._call("attr", [name]); }
|
||||
hasClass(cls) { return this._call("hasClass", [cls]); }
|
||||
|
||||
addClass(cls) { this._call("addClass", [cls]); return this; }
|
||||
removeClass(cls) { this._call("removeClass", [cls]); return this; }
|
||||
setAttr(name, value) { this._call("setAttr", [name, value]); return this; }
|
||||
removeAttr(name) { this._call("removeAttr", [name]); return this; }
|
||||
setVal(value) { this._call("setVal", [value]); return this; }
|
||||
|
||||
append(html) { this._call("append", [html]); return this; }
|
||||
prepend(html) { this._call("prepend", [html]); return this; }
|
||||
empty() { this._call("empty"); return this; }
|
||||
remove() { this._call("remove"); return this; }
|
||||
|
||||
children() {
|
||||
const keys = JSON.parse(this._call("children"));
|
||||
return new ElementCollection(keys.map(k => new Element(k)));
|
||||
}
|
||||
|
||||
find(selector) {
|
||||
const keys = JSON.parse(this._call("find", [selector]));
|
||||
return new ElementCollection(keys.map(k => new Element(k)));
|
||||
}
|
||||
|
||||
parent() {
|
||||
return new Element(this._call("parent"));
|
||||
}
|
||||
|
||||
next() {
|
||||
return new Element(this._call("next"));
|
||||
}
|
||||
|
||||
prev() {
|
||||
return new Element(this._call("prev"));
|
||||
}
|
||||
|
||||
first() {
|
||||
return new Element(this._call("first"));
|
||||
}
|
||||
|
||||
last() {
|
||||
return new Element(this._call("last"));
|
||||
}
|
||||
}
|
||||
|
||||
class ElementCollection {
|
||||
constructor(elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
each(fn) {
|
||||
this.elements.forEach((el, i) => fn(i, el));
|
||||
return this;
|
||||
}
|
||||
|
||||
map(fn) {
|
||||
return this.elements.map((el, i) => fn(el, i));
|
||||
}
|
||||
|
||||
filter(fn) {
|
||||
return new ElementCollection(this.elements.filter((el, i) => fn(el, i)));
|
||||
}
|
||||
|
||||
addClass(cls) {
|
||||
this.elements.forEach(el => el.addClass(cls));
|
||||
return this;
|
||||
}
|
||||
|
||||
removeClass(cls) {
|
||||
this.elements.forEach(el => el.removeClass(cls));
|
||||
return this;
|
||||
}
|
||||
|
||||
setAttr(name, value) {
|
||||
this.elements.forEach(el => el.setAttr(name, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
removeAttr(name) {
|
||||
this.elements.forEach(el => el.removeAttr(name));
|
||||
return this;
|
||||
}
|
||||
|
||||
setVal(value) {
|
||||
this.elements.forEach(el => el.setVal(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
append(html) {
|
||||
this.elements.forEach(el => el.append(html));
|
||||
return this;
|
||||
}
|
||||
|
||||
prepend(html) {
|
||||
this.elements.forEach(el => el.prepend(html));
|
||||
return this;
|
||||
}
|
||||
|
||||
empty() {
|
||||
this.elements.forEach(el => el.empty());
|
||||
return this;
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.elements.forEach(el => el.remove());
|
||||
return this;
|
||||
}
|
||||
|
||||
find(selector) {
|
||||
const found = this.elements.flatMap(el => {
|
||||
const keys = JSON.parse(el._call("find", [selector]));
|
||||
return keys.map(k => new Element(k));
|
||||
});
|
||||
return new ElementCollection(found);
|
||||
}
|
||||
|
||||
children() {
|
||||
const children = this.elements.flatMap(el => {
|
||||
const keys = JSON.parse(el._call("children"));
|
||||
return keys.map(k => new Element(k));
|
||||
});
|
||||
return new ElementCollection(children);
|
||||
}
|
||||
|
||||
parent() {
|
||||
const parents = this.elements.map(el => new Element(el._call("parent")));
|
||||
return new ElementCollection(parents);
|
||||
}
|
||||
|
||||
next() {
|
||||
const nextEls = this.elements.map(el => new Element(el._call("next")));
|
||||
return new ElementCollection(nextEls);
|
||||
}
|
||||
|
||||
prev() {
|
||||
const prevEls = this.elements.map(el => new Element(el._call("prev")));
|
||||
return new ElementCollection(prevEls);
|
||||
}
|
||||
|
||||
first() {
|
||||
return this.elements[0] || null;
|
||||
}
|
||||
|
||||
last() {
|
||||
return this.elements[this.elements.length - 1] || null;
|
||||
}
|
||||
|
||||
get(index) {
|
||||
return this.elements[index] || null;
|
||||
}
|
||||
|
||||
length() {
|
||||
return this.elements.length;
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.elements[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return input;
|
||||
} else if (input instanceof Element) {
|
||||
return input;
|
||||
} else if (input && input._key) {
|
||||
return new ElementCollection([new Element(input._key)]);
|
||||
} else {
|
||||
return new ElementCollection([new Element(input)]);
|
||||
}
|
||||
};
|
||||
|
||||
\$.root = root;
|
||||
\$.Element = Element;
|
||||
\$.Collection = ElementCollection;
|
||||
|
||||
return \$;
|
||||
}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,197 @@ class JsHtmlParser {
|
|||
|
||||
void init() {
|
||||
runtime.evaluate('''
|
||||
class Parser{constructor(t={}){this.options=t,this.buffer=""}write(t){this.buffer+=t;let s=0,o=0;const i=this.buffer.length;let n=null;for(;s<i;){const t=this.buffer[s];if('"'!==t&&"'"!==t)if("<"===t&&null===n){if(s>o&&this.options.ontext){const t=this.buffer.slice(o,s);this.options.ontext(t)}s++;const t="/"===this.buffer[s];t&&s++;const n=s;for(;s<i&&/[a-zA-Z0-9:-]/.test(this.buffer[s]);)s++;const e=s,f=this.buffer.slice(n,e);t?this.options.onclosetag&&this.options.onclosetag(f):this.options.onopentagname&&this.options.onopentagname(f);let h={},r="",l="",u=null;for(;s<i&&">"!==this.buffer[s];){const n=this.buffer[s];if(/\\s/.test(n)){s++;continue}if("/"===n&&">"===this.buffer[s+1])return!t&&this.options.onselfclosingtag&&this.options.onselfclosingtag(),s+=2,o=s,this.options.onopentag&&this.options.onopentag(f,h),void(this.options.onopentagend&&this.options.onopentagend());let e=s;for(;s<i&&/[^\\s=>]/.test(this.buffer[s]);)s++;for(r=this.buffer.slice(e,s);s<i&&/\\s/.test(this.buffer[s]);)s++;if("="===this.buffer[s]){for(s++;s<i&&/\\s/.test(this.buffer[s]);)s++;const t=this.buffer[s];if('"'===t||"'"===t){u=t,s++;const o=s;for(;s<i&&this.buffer[s]!==u;)s++;l=this.buffer.slice(o,s),s++}else{const t=s;for(;s<i&&/[^\\s>]/.test(this.buffer[s]);)s++;l=this.buffer.slice(t,s)}this.options.onattribute&&this.options.onattribute(r,l),h[r]=l,r="",l=""}else this.options.onattribute&&this.options.onattribute(r,null),h[r]=null,r=""}s++,!t&&this.options.onopentag&&this.options.onopentag(f,h),this.options.onopentagend&&this.options.onopentagend(),o=s}else s++;else n===t?n=null:null===n&&(n=t),s++}if(o<i&&this.options.ontext){const t=this.buffer.slice(o,i);this.options.ontext(t)}}end(){this.options.onend&&this.options.onend()}}
|
||||
class Parser {
|
||||
constructor(options = {}) {
|
||||
this.options = options;
|
||||
this.buffer = '';
|
||||
}
|
||||
|
||||
isVoidElement(name) {
|
||||
return [
|
||||
"area",
|
||||
"base",
|
||||
"basefont",
|
||||
"br",
|
||||
"col",
|
||||
"command",
|
||||
"embed",
|
||||
"frame",
|
||||
"hr",
|
||||
"img",
|
||||
"input",
|
||||
"isindex",
|
||||
"keygen",
|
||||
"link",
|
||||
"meta",
|
||||
"param",
|
||||
"source",
|
||||
"track",
|
||||
"wbr",
|
||||
].includes(name);
|
||||
}
|
||||
|
||||
write(html) {
|
||||
this.buffer += html;
|
||||
let i = 0;
|
||||
let textStart = 0;
|
||||
const len = this.buffer.length;
|
||||
let insideQuote = null;
|
||||
|
||||
while (i < len) {
|
||||
const ch = this.buffer[i];
|
||||
|
||||
// Track string literals
|
||||
if ((ch === '"' || ch === "'")) {
|
||||
if (insideQuote === ch) {
|
||||
insideQuote = null;
|
||||
} else if (insideQuote === null) {
|
||||
insideQuote = ch;
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === '<' && insideQuote === null) {
|
||||
// Emit any text before the tag
|
||||
if (i > textStart && this.options.ontext) {
|
||||
const text = this.buffer.slice(textStart, i);
|
||||
this.options.ontext(text);
|
||||
}
|
||||
|
||||
const tagStart = i;
|
||||
i++;
|
||||
|
||||
const isClosing = this.buffer[i] === '/';
|
||||
if (isClosing) i++;
|
||||
|
||||
// Parse tag name
|
||||
const nameStart = i;
|
||||
while (i < len && /[a-zA-Z0-9:-]/.test(this.buffer[i])) i++;
|
||||
const nameEnd = i;
|
||||
const tagName = this.buffer.slice(nameStart, nameEnd);
|
||||
|
||||
if (isClosing) {
|
||||
if (this.options.onclosetag) {
|
||||
this.options.onclosetag(tagName);
|
||||
}
|
||||
} else {
|
||||
if (this.options.onopentagname) {
|
||||
this.options.onopentagname(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse attributes
|
||||
let attrs = {};
|
||||
let attrName = '';
|
||||
let attrValue = '';
|
||||
let readingAttrName = true;
|
||||
let inAttrQuote = null;
|
||||
|
||||
while (i < len && this.buffer[i] !== '>') {
|
||||
const c = this.buffer[i];
|
||||
|
||||
// Skip over whitespace
|
||||
if (/\\s/.test(c)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle self-closing tag
|
||||
if (c === '/' && this.buffer[i + 1] === '>') {
|
||||
if (!isClosing && this.options.onselfclosingtag) {
|
||||
this.options.onselfclosingtag();
|
||||
}
|
||||
i += 2;
|
||||
textStart = i;
|
||||
if (this.options.onopentag) {
|
||||
this.options.onopentag(tagName, attrs);
|
||||
}
|
||||
if (this.options.onopentagend) {
|
||||
this.options.onopentagend();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse attribute name
|
||||
let attrStart = i;
|
||||
while (i < len && /[^\\s=>]/.test(this.buffer[i])) i++;
|
||||
attrName = this.buffer.slice(attrStart, i);
|
||||
|
||||
// Skip whitespace after name
|
||||
while (i < len && /\\s/.test(this.buffer[i])) i++;
|
||||
|
||||
// Expect '='
|
||||
if (this.buffer[i] === '=') {
|
||||
i++; // skip '='
|
||||
|
||||
// Skip whitespace after '='
|
||||
while (i < len && /\\s/.test(this.buffer[i])) i++;
|
||||
|
||||
const quote = this.buffer[i];
|
||||
if (quote === '"' || quote === "'") {
|
||||
inAttrQuote = quote;
|
||||
i++; // skip quote
|
||||
|
||||
const valStart = i;
|
||||
while (i < len && this.buffer[i] !== inAttrQuote) i++;
|
||||
attrValue = this.buffer.slice(valStart, i);
|
||||
i++; // skip closing quote
|
||||
} else {
|
||||
// Unquoted value
|
||||
const valStart = i;
|
||||
while (i < len && /[^\\s>]/.test(this.buffer[i])) i++;
|
||||
attrValue = this.buffer.slice(valStart, i);
|
||||
}
|
||||
|
||||
// Emit merged attribute callback
|
||||
if (this.options.onattribute) {
|
||||
this.options.onattribute(attrName, attrValue);
|
||||
}
|
||||
|
||||
attrs[attrName] = attrValue;
|
||||
attrName = '';
|
||||
attrValue = '';
|
||||
} else {
|
||||
// attribute without value (e.g. `disabled`)
|
||||
if (this.options.onattribute) {
|
||||
this.options.onattribute(attrName, null);
|
||||
}
|
||||
attrs[attrName] = null;
|
||||
attrName = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Closing normal tag '>'
|
||||
i++; // skip '>'
|
||||
|
||||
if (!isClosing && this.options.onopentag) {
|
||||
this.options.onopentag(tagName, attrs);
|
||||
}
|
||||
|
||||
if (this.options.onopentagend) {
|
||||
this.options.onopentagend();
|
||||
}
|
||||
|
||||
textStart = i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Emit any remaining text
|
||||
if (textStart < len && this.options.ontext) {
|
||||
const text = this.buffer.slice(textStart, len);
|
||||
this.options.ontext(text);
|
||||
}
|
||||
}
|
||||
|
||||
end() {
|
||||
if (this.options.onend) {
|
||||
this.options.onend();
|
||||
}
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class ChapterItem {
|
||||
String name;
|
||||
String path;
|
||||
|
|
@ -18,7 +20,9 @@ class ChapterItem {
|
|||
name: json['name'],
|
||||
path: json['path'],
|
||||
releaseTime: json['releaseTime'],
|
||||
chapterNumber: json['chapterNumber'],
|
||||
chapterNumber:
|
||||
int.tryParse(json['chapterNumber']) ??
|
||||
(json['chapterNumber'] as num?)?.toInt(),
|
||||
page: json['page'],
|
||||
);
|
||||
}
|
||||
|
|
@ -86,7 +90,9 @@ class SourceNovel extends NovelItem {
|
|||
author: json['author'],
|
||||
artist: json['artist'],
|
||||
status: json['status'],
|
||||
rating: json['rating']?.toDouble(),
|
||||
rating: json['rating'] is double
|
||||
? json['rating']
|
||||
: json['rating']?.toDouble(),
|
||||
chapters: (json['chapters'] as List<dynamic>?)
|
||||
?.map((item) => ChapterItem.fromJson(item))
|
||||
.toList(),
|
||||
|
|
@ -117,9 +123,11 @@ class SourcePage {
|
|||
|
||||
factory SourcePage.fromJson(Map<String, dynamic> json) {
|
||||
return SourcePage(
|
||||
chapters: (json['chapters'] as List<dynamic>)
|
||||
.map((item) => ChapterItem.fromJson(item))
|
||||
.toList(),
|
||||
chapters:
|
||||
(json['chapters'] as List<dynamic>?)
|
||||
?.map((item) => ChapterItem.fromJson(item))
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@ JavascriptRuntime getJavascriptRuntime({
|
|||
Map<String, dynamic>? extraArgs = const {},
|
||||
}) {
|
||||
JavascriptRuntime runtime;
|
||||
runtime = QuickJsRuntime2(
|
||||
stackSize: 1024 * 1024 * 4
|
||||
);
|
||||
runtime = QuickJsRuntime2(stackSize: 1024 * 1024 * 4);
|
||||
runtime.enableHandlePromises();
|
||||
return runtime;
|
||||
}
|
||||
|
|
@ -109,9 +107,9 @@ const extension = exports.default;
|
|||
Future<MPages> getPopular(int page) async {
|
||||
final items =
|
||||
((await _extensionCallAsync(
|
||||
'popularNovels($page, {showLatestNovels: false, filters: extension.filters})',
|
||||
))
|
||||
as List<dynamic>)
|
||||
'popularNovels($page, {showLatestNovels: false, filters: extension.filters})',
|
||||
[],
|
||||
)))
|
||||
.map((e) => NovelItem.fromJson(e))
|
||||
.map(
|
||||
(e) => MManga(
|
||||
|
|
@ -129,9 +127,9 @@ const extension = exports.default;
|
|||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final items =
|
||||
((await _extensionCallAsync(
|
||||
'popularNovels($page, {showLatestNovels: true, filters: extension.filters})',
|
||||
))
|
||||
as List<dynamic>)
|
||||
'popularNovels($page, {showLatestNovels: true, filters: extension.filters})',
|
||||
[],
|
||||
)))
|
||||
.map((e) => NovelItem.fromJson(e))
|
||||
.map(
|
||||
(e) => MManga(
|
||||
|
|
@ -148,8 +146,7 @@ const extension = exports.default;
|
|||
@override
|
||||
Future<MPages> search(String query, int page, List<dynamic> filters) async {
|
||||
final items =
|
||||
((await _extensionCallAsync('searchNovels("$query",$page)'))
|
||||
as List<dynamic>)
|
||||
((await _extensionCallAsync('searchNovels("$query",$page)', [])))
|
||||
.map((e) => NovelItem.fromJson(e))
|
||||
.map(
|
||||
(e) => MManga(
|
||||
|
|
@ -166,7 +163,10 @@ const extension = exports.default;
|
|||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final item = SourceNovel.fromJson(
|
||||
await _extensionCallAsync('parseNovel(`$url`)'),
|
||||
await _extensionCallAsync('parseNovel(`$url`)', {}),
|
||||
);
|
||||
final chapters = SourcePage.fromJson(
|
||||
await _extensionCallAsync('parsePage(`${item.path}`, `1`)', {}),
|
||||
);
|
||||
return MManga(
|
||||
name: item.name,
|
||||
|
|
@ -182,7 +182,7 @@ const extension = exports.default;
|
|||
},
|
||||
genre: item.genres?.split(","),
|
||||
chapters:
|
||||
item.chapters
|
||||
(chapters.chapters.isNotEmpty ? chapters.chapters : item.chapters)
|
||||
?.map(
|
||||
(e) => MChapter(
|
||||
name: e.name,
|
||||
|
|
@ -259,12 +259,11 @@ const extension = exports.default;
|
|||
if (def != null) {
|
||||
return def;
|
||||
}
|
||||
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<T> _extensionCallAsync<T>(String call) async {
|
||||
Future<T> _extensionCallAsync<T>(String call, T def) async {
|
||||
_init();
|
||||
|
||||
try {
|
||||
|
|
@ -274,6 +273,9 @@ const extension = exports.default;
|
|||
|
||||
return jsonDecode(promised.stringResult) as T;
|
||||
} catch (e) {
|
||||
if (def != null) {
|
||||
return def;
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue