mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-05 07:41:01 +00:00
LibWeb: Implement the "superscript" editing command
This commit is contained in:
parent
ef8af01e1d
commit
679fbb5eda
Notes:
github-actions[bot]
2025-01-10 22:36:10 +00:00
Author: https://github.com/gmta
Commit: 679fbb5eda
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3216
4 changed files with 100 additions and 0 deletions
|
@ -1369,6 +1369,59 @@ bool command_subscript_indeterminate(DOM::Document const& document)
|
||||||
return has_mixed_value;
|
return has_mixed_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/editing/docs/execCommand/#the-superscript-command
|
||||||
|
bool command_superscript_action(DOM::Document& document, String const&)
|
||||||
|
{
|
||||||
|
// 1. Call queryCommandState("superscript"), and let state be the result.
|
||||||
|
auto state = document.query_command_state(CommandNames::superscript);
|
||||||
|
|
||||||
|
// 2. Set the selection's value to null.
|
||||||
|
set_the_selections_value(document, CommandNames::superscript, {});
|
||||||
|
|
||||||
|
// 3. If state is false, set the selection's value to "superscript".
|
||||||
|
if (!state)
|
||||||
|
set_the_selections_value(document, CommandNames::superscript, "superscript"_string);
|
||||||
|
|
||||||
|
// 4. Return true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/editing/docs/execCommand/#the-superscript-command
|
||||||
|
bool command_superscript_indeterminate(DOM::Document const& document)
|
||||||
|
{
|
||||||
|
// True if either among formattable nodes that are effectively contained in the active range, there is at least one
|
||||||
|
// with effective command value "superscript" and at least one with some other effective command value;
|
||||||
|
bool has_superscript_value = false;
|
||||||
|
bool has_other_value = false;
|
||||||
|
bool has_mixed_value = false;
|
||||||
|
for_each_node_effectively_contained_in_range(active_range(document), [&](GC::Ref<DOM::Node> descendant) {
|
||||||
|
if (!is_formattable_node(descendant))
|
||||||
|
return TraversalDecision::Continue;
|
||||||
|
|
||||||
|
auto node_value = effective_command_value(descendant, CommandNames::superscript);
|
||||||
|
if (!node_value.has_value())
|
||||||
|
return TraversalDecision::Continue;
|
||||||
|
|
||||||
|
if (node_value.value() == "superscript"sv) {
|
||||||
|
has_superscript_value = true;
|
||||||
|
} else {
|
||||||
|
has_other_value = true;
|
||||||
|
if (!has_mixed_value && node_value.value() == "mixed"sv)
|
||||||
|
has_mixed_value = true;
|
||||||
|
}
|
||||||
|
if (has_superscript_value && has_other_value)
|
||||||
|
return TraversalDecision::Break;
|
||||||
|
|
||||||
|
return TraversalDecision::Continue;
|
||||||
|
});
|
||||||
|
if (has_superscript_value && has_other_value)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// or if there is some formattable node effectively contained in the active range with effective command value
|
||||||
|
// "mixed". Otherwise false.
|
||||||
|
return has_mixed_value;
|
||||||
|
}
|
||||||
|
|
||||||
static Array const commands {
|
static Array const commands {
|
||||||
// https://w3c.github.io/editing/docs/execCommand/#the-backcolor-command
|
// https://w3c.github.io/editing/docs/execCommand/#the-backcolor-command
|
||||||
CommandDefinition {
|
CommandDefinition {
|
||||||
|
@ -1474,6 +1527,13 @@ static Array const commands {
|
||||||
.indeterminate = command_subscript_indeterminate,
|
.indeterminate = command_subscript_indeterminate,
|
||||||
.inline_activated_values = { "subscript"sv },
|
.inline_activated_values = { "subscript"sv },
|
||||||
},
|
},
|
||||||
|
// https://w3c.github.io/editing/docs/execCommand/#the-superscript-command
|
||||||
|
CommandDefinition {
|
||||||
|
.command = CommandNames::superscript,
|
||||||
|
.action = command_superscript_action,
|
||||||
|
.indeterminate = command_superscript_indeterminate,
|
||||||
|
.inline_activated_values = { "superscript"sv },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<CommandDefinition const&> find_command_definition(FlyString const& command)
|
Optional<CommandDefinition const&> find_command_definition(FlyString const& command)
|
||||||
|
|
|
@ -49,5 +49,7 @@ bool command_style_with_css_action(DOM::Document&, String const&);
|
||||||
bool command_style_with_css_state(DOM::Document const&);
|
bool command_style_with_css_state(DOM::Document const&);
|
||||||
bool command_subscript_action(DOM::Document&, String const&);
|
bool command_subscript_action(DOM::Document&, String const&);
|
||||||
bool command_subscript_indeterminate(DOM::Document const&);
|
bool command_subscript_indeterminate(DOM::Document const&);
|
||||||
|
bool command_superscript_action(DOM::Document&, String const&);
|
||||||
|
bool command_superscript_indeterminate(DOM::Document const&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Div contents: "foobar" state: false selection: #document 0 #document 0
|
||||||
|
Div contents: "foo<sup>bar</sup>" state: true selection: #text 0 #text 3
|
||||||
|
Div contents: "<sup>foobar</sup>" state: true selection: #text 0 #text 3
|
||||||
|
Div contents: "<sup>foo</sup>bar" state: false selection: #text 0 #text 3
|
34
Tests/LibWeb/Text/input/Editing/execCommand-superscript.html
Normal file
34
Tests/LibWeb/Text/input/Editing/execCommand-superscript.html
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<div contenteditable="true">foobar</div>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
const range = document.createRange();
|
||||||
|
getSelection().addRange(range);
|
||||||
|
|
||||||
|
const divElm = document.querySelector('div');
|
||||||
|
const printableSelection = () => {
|
||||||
|
let activeRange = getSelection().getRangeAt(0);
|
||||||
|
return `${activeRange.startContainer.nodeName} ${activeRange.startOffset} ${activeRange.endContainer.nodeName} ${activeRange.endOffset}`;
|
||||||
|
};
|
||||||
|
const report = () => println(`Div contents: "${divElm.innerHTML}" state: ${document.queryCommandState('superscript')} selection: ${printableSelection()}`);
|
||||||
|
report();
|
||||||
|
|
||||||
|
// Add superscript to 'bar'
|
||||||
|
range.setStart(divElm.childNodes[0], 3);
|
||||||
|
range.setEnd(divElm.childNodes[0], 6);
|
||||||
|
document.execCommand('superscript');
|
||||||
|
report();
|
||||||
|
|
||||||
|
// Add superscript to 'foo'
|
||||||
|
range.setStart(divElm.childNodes[0], 0);
|
||||||
|
range.setEnd(divElm.childNodes[0], 3);
|
||||||
|
document.execCommand('superscript');
|
||||||
|
report();
|
||||||
|
|
||||||
|
// Desuperscriptify 'bar'
|
||||||
|
range.setStart(divElm.childNodes[0].childNodes[1], 0);
|
||||||
|
range.setEnd(divElm.childNodes[0].childNodes[1], 3);
|
||||||
|
document.execCommand('superscript');
|
||||||
|
report();
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue