mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-07-31 09:46:05 -04:00
Merge pull request #2886 from lightpanda-io/loader_feature_detect
webapi: implement HTMLScriptElement.supports and DOMTokenList.supports
This commit is contained in:
12
src/browser/tests/element/html/script/supports.html
Normal file
12
src/browser/tests/element/html/script/supports.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../../../testing.js"></script>
|
||||
|
||||
<script id=supports>
|
||||
{
|
||||
testing.expectEqual(true, HTMLScriptElement.supports('classic'));
|
||||
testing.expectEqual(true, HTMLScriptElement.supports('module'));
|
||||
testing.expectEqual(true, HTMLScriptElement.supports('importmap'));
|
||||
testing.expectEqual(false, HTMLScriptElement.supports('speculationrules'));
|
||||
testing.expectEqual(false, HTMLScriptElement.supports('Module'));
|
||||
}
|
||||
</script>
|
||||
23
src/browser/tests/element/rel_list.html
Normal file
23
src/browser/tests/element/rel_list.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../testing.js"></script>
|
||||
|
||||
<link id=l1 rel="stylesheet" href="data:text/css,">
|
||||
<div id=d1 class="foo"></div>
|
||||
|
||||
<script id=supports>
|
||||
{
|
||||
const rl = $('#l1').relList;
|
||||
testing.expectEqual(true, rl.supports('modulepreload'));
|
||||
testing.expectEqual(true, rl.supports('MODULEPRELOAD'));
|
||||
testing.expectEqual(true, rl.supports('preload'));
|
||||
testing.expectEqual(true, rl.supports('stylesheet'));
|
||||
testing.expectEqual(false, rl.supports('prefetch'));
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=supports_undefined_tokens>
|
||||
{
|
||||
// classList's backing attribute defines no supported tokens.
|
||||
testing.expectError('TypeError', () => $('#d1').classList.supports('foo'));
|
||||
}
|
||||
</script>
|
||||
@@ -69,6 +69,22 @@ pub fn item(self: *const DOMTokenList, index: usize, frame: *Frame) !?[]const u8
|
||||
return null;
|
||||
}
|
||||
|
||||
/// https://dom.spec.whatwg.org/#dom-domtokenlist-supports
|
||||
/// Only `rel` defines supported tokens here; per spec every other backing
|
||||
/// attribute throws. Loaders probe `relList.supports("modulepreload")` and
|
||||
/// fall back to fetch()-based legacy loading when it fails.
|
||||
pub fn supports(self: *const DOMTokenList, token: []const u8, frame: *Frame) !bool {
|
||||
if (!std.ascii.eqlIgnoreCase(self._attribute_name.str(), "rel")) {
|
||||
return error.TypeError;
|
||||
}
|
||||
const supported = [_][]const u8{ "stylesheet", "preload", "modulepreload" };
|
||||
const lower = try std.ascii.allocLowerString(frame.local_arena, token);
|
||||
for (supported) |s| {
|
||||
if (std.mem.eql(u8, lower, s)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn contains(self: *const DOMTokenList, search: []const u8) !bool {
|
||||
var it = std.mem.tokenizeAny(u8, self.getValue(), WHITESPACE);
|
||||
while (it.next()) |token| {
|
||||
@@ -310,6 +326,7 @@ pub const JsApi = struct {
|
||||
}
|
||||
|
||||
pub const contains = bridge.function(DOMTokenList.contains, .{ .dom_exception = true });
|
||||
pub const supports = bridge.function(DOMTokenList.supports, .{ .dom_exception = true });
|
||||
pub const add = bridge.function(DOMTokenList.add, .{ .dom_exception = true, .ce_reactions = true });
|
||||
pub const remove = bridge.function(DOMTokenList.remove, .{ .dom_exception = true, .ce_reactions = true });
|
||||
pub const toggle = bridge.function(DOMTokenList.toggle, .{ .dom_exception = true, .ce_reactions = true });
|
||||
|
||||
@@ -115,6 +115,17 @@ pub fn setInnerText(self: *Script, text: []const u8, frame: *Frame) !void {
|
||||
try self.asNode().setTextContent(text, frame);
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/scripting.html#dom-script-supports
|
||||
/// Only the types this engine actually loads; loaders feature-detect module
|
||||
/// support here and fall back to fetch()-based legacy loading when it fails.
|
||||
pub fn supports(value: []const u8) bool {
|
||||
const supported = [_][]const u8{ "classic", "module", "importmap" };
|
||||
for (supported) |s| {
|
||||
if (std.mem.eql(u8, value, s)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
pub const bridge = js.Bridge(Script);
|
||||
|
||||
@@ -131,6 +142,7 @@ pub const JsApi = struct {
|
||||
pub const nonce = bridge.accessor(Script.getNonce, Script.setNonce, .{ .ce_reactions = true });
|
||||
pub const charset = bridge.accessor(Script.getCharset, Script.setCharset, .{ .ce_reactions = true });
|
||||
pub const noModule = bridge.accessor(Script.getNoModule, null, .{});
|
||||
pub const supports = bridge.function(Script.supports, .{ .static = true });
|
||||
pub const innerText = bridge.accessor(_innerText, Script.setInnerText, .{ .ce_reactions = true });
|
||||
fn _innerText(self: *Script, frame: *const Frame) ![]const u8 {
|
||||
var buf = std.Io.Writer.Allocating.init(frame.call_arena);
|
||||
|
||||
Reference in New Issue
Block a user