feat: offer a non-Mews web page as a simplified view or in the browser
This commit is contained in:
parent
cea66fbb42
commit
00e42c925c
24 changed files with 863 additions and 152 deletions
|
|
@ -8,6 +8,7 @@ import 'package:http/http.dart' as http;
|
|||
import '../../mews/atom.dart';
|
||||
import '../../mews/document.dart';
|
||||
import '../../mews/gemtext.dart';
|
||||
import '../../mews/html.dart';
|
||||
import '../../mews/parser.dart';
|
||||
import '../../protocols/gemini.dart' as gemini;
|
||||
import '../../protocols/spartan.dart' as spartan;
|
||||
|
|
@ -153,12 +154,18 @@ class FetchHttpStatusError extends FetchResult {
|
|||
}
|
||||
|
||||
class FetchParseError extends FetchResult {
|
||||
const FetchParseError(this.message, this.source);
|
||||
const FetchParseError(this.message, {this.simplified, this.declaresMews = false});
|
||||
|
||||
final String message;
|
||||
|
||||
/// The markup that failed to parse, for the "show page text" option.
|
||||
final String source;
|
||||
/// The page as the app can show it, for the simplified view, or null when
|
||||
/// nothing legible came out of the markup.
|
||||
final MewsPage? simplified;
|
||||
|
||||
/// Whether the markup declared the Mews conformance marker. A page that
|
||||
/// claims to be Mews and still will not parse has a real markup error; one
|
||||
/// that never claimed it is just an ordinary web page.
|
||||
final bool declaresMews;
|
||||
}
|
||||
|
||||
/// A Gemini or Spartan status carrying a message for the reader: a temporary
|
||||
|
|
@ -304,7 +311,8 @@ class FetchHandler with Handler<FetchCommand, FetchResult> {
|
|||
|
||||
final newEtag = response.headers['etag'];
|
||||
final newLastModified = response.headers['last-modified'];
|
||||
return _parse(response.body, url, etag: newEtag, lastModified: newLastModified);
|
||||
return _parse(response.body, url,
|
||||
bytes: response.bodyBytes, etag: newEtag, lastModified: newLastModified);
|
||||
}
|
||||
|
||||
/// The page could not be revalidated; use the cached copy when there is one.
|
||||
|
|
@ -315,14 +323,32 @@ class FetchHandler with Handler<FetchCommand, FetchResult> {
|
|||
etag: etag, lastModified: lastModified, notModified: true);
|
||||
}
|
||||
|
||||
/// [bytes] are the undecoded body when there is one. The HTML conversion
|
||||
/// reads the document's own charset from them, which an already-decoded
|
||||
/// string has lost.
|
||||
FetchResult _parse(String source, String url,
|
||||
{String? etag, String? lastModified, bool notModified = false}) {
|
||||
{List<int>? bytes, String? etag, String? lastModified, bool notModified = false}) {
|
||||
try {
|
||||
final page = parseMewsPage(source: source, url: url);
|
||||
return FetchPageOk(
|
||||
page: page, source: source, etag: etag, lastModified: lastModified, notModified: notModified);
|
||||
} on MewsParseException catch (e) {
|
||||
return FetchParseError(e.message, source);
|
||||
return _parseFailure(e, source, bytes, url);
|
||||
}
|
||||
}
|
||||
|
||||
/// Markup the strict parse refused is converted for the simplified view, so
|
||||
/// the reader is offered the structure Mews supports rather than nothing.
|
||||
/// Converting here keeps the work off the main isolate.
|
||||
FetchResult _parseFailure(
|
||||
MewsParseException error, String source, List<int>? bytes, String url) {
|
||||
try {
|
||||
final converted = convertHtmlPage(url: url, source: source, bytes: bytes);
|
||||
return FetchParseError(error.message,
|
||||
simplified: converted.page, declaresMews: converted.declaresMews);
|
||||
} on Exception {
|
||||
// Nothing legible in it; the error page stands on its own.
|
||||
return FetchParseError(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -497,7 +523,7 @@ class FetchHandler with Handler<FetchCommand, FetchResult> {
|
|||
entries: parseAtomEntries(source: response.body, feedUrl: url),
|
||||
);
|
||||
} on MewsParseException catch (e) {
|
||||
return FetchParseError(e.message, response.body);
|
||||
return FetchParseError(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -532,7 +558,7 @@ class FetchHandler with Handler<FetchCommand, FetchResult> {
|
|||
return const FetchNetworkError();
|
||||
}
|
||||
if (response.statusCode != 200) return FetchHttpStatusError(response.statusCode);
|
||||
return _parse(response.body, url);
|
||||
return _parse(response.body, url, bytes: response.bodyBytes);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue