mirror of
https://github.com/servo/servo
synced 2026-04-26 01:25:32 +02:00
script: Record state for nodes prior to executing commands (#43177)
There is a chicken and egg problem here: to be able to restore the state
of nodes, we need the implementation of several other commands. However,
those commands then need some of the algorithms that are implemented for
storing the state.
Therefore, this PR has no behavioral changes, but includes preparations
to be able to first implement the functionality of the relevant
commands.
To that end, several changes were necessary:
1. Remove BaseCommand and instead use CommandName enum to define
behavior. The majority of the action part of the commands still exists
in separate files for readability (turn off whitespace changes in the
diff to make things readable)
2. Change the usages of a DOMString to the new CommandName enum in the
methods of execCommand. Both to make the enum work, but also as an
improvement to avoid operating on strings.
3. The {value,state}_override values in document need to be a map, not a
single boolean. I didn't understand these when I first implemented it,
but now it's clearer to me what their structure is.
In the end, the relevant recording and restoring state is implemented,
to the extent that it is possible. It does some light-weight
interaction, but most of the code doesn't do anything yet since the
relevant commands aren't implemented.
Part of #25005
Testing: no behavioral changes, only preparations for future work
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
committed by
GitHub
parent
0d764f0d20
commit
15b74e04b6
@@ -4,37 +4,95 @@
|
||||
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::execcommand::commands::defaultparagraphseparator::execute_default_paragraph_separator_command;
|
||||
use crate::dom::execcommand::commands::delete::execute_delete_command;
|
||||
use crate::dom::execcommand::commands::stylewithcss::execute_style_with_css_command;
|
||||
use crate::dom::selection::Selection;
|
||||
|
||||
pub(crate) trait BaseCommand {
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#indeterminate>
|
||||
fn is_indeterminate(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#state>
|
||||
fn current_state(&self, _document: &Document) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#value>
|
||||
fn current_value(&self, _document: &Document) -> Option<DOMString> {
|
||||
None
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#action>
|
||||
fn execute(
|
||||
&self,
|
||||
cx: &mut js::context::JSContext,
|
||||
document: &Document,
|
||||
selection: &Selection,
|
||||
value: DOMString,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, MallocSizeOf)]
|
||||
pub(crate) enum DefaultSingleLineContainerName {
|
||||
#[default]
|
||||
Div,
|
||||
Paragraph,
|
||||
}
|
||||
|
||||
impl From<DefaultSingleLineContainerName> for DOMString {
|
||||
fn from(default_single_line_container_name: DefaultSingleLineContainerName) -> Self {
|
||||
match default_single_line_container_name {
|
||||
DefaultSingleLineContainerName::Div => DOMString::from("div"),
|
||||
DefaultSingleLineContainerName::Paragraph => DOMString::from("p"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||
#[expect(unused)] // TODO(25005): implement all commands
|
||||
pub(crate) enum CommandName {
|
||||
BackColor,
|
||||
Bold,
|
||||
CreateLink,
|
||||
DefaultParagraphSeparator,
|
||||
Delete,
|
||||
FontSize,
|
||||
HiliteColor,
|
||||
Italic,
|
||||
Redo,
|
||||
SelectAll,
|
||||
Strikethrough,
|
||||
StyleWithCss,
|
||||
Subscript,
|
||||
Superscript,
|
||||
Underline,
|
||||
Undo,
|
||||
Unlink,
|
||||
Usecss,
|
||||
}
|
||||
|
||||
impl CommandName {
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#indeterminate>
|
||||
pub(crate) fn is_indeterminate(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#state>
|
||||
pub(crate) fn current_state(&self, document: &Document) -> Option<bool> {
|
||||
Some(match self {
|
||||
CommandName::StyleWithCss => {
|
||||
// https://w3c.github.io/editing/docs/execCommand/#the-stylewithcss-command
|
||||
// > True if the CSS styling flag is true, otherwise false.
|
||||
document.css_styling_flag()
|
||||
},
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#value>
|
||||
pub(crate) fn current_value(&self, document: &Document) -> Option<DOMString> {
|
||||
Some(match self {
|
||||
CommandName::DefaultParagraphSeparator => {
|
||||
// https://w3c.github.io/editing/docs/execCommand/#the-defaultparagraphseparator-command
|
||||
// > Return the context object's default single-line container name.
|
||||
document.default_single_line_container_name().into()
|
||||
},
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/editing/docs/execCommand/#action>
|
||||
pub(crate) fn execute(
|
||||
&self,
|
||||
cx: &mut js::context::JSContext,
|
||||
document: &Document,
|
||||
selection: &Selection,
|
||||
value: DOMString,
|
||||
) -> bool {
|
||||
match self {
|
||||
CommandName::DefaultParagraphSeparator => {
|
||||
execute_default_paragraph_separator_command(document, value)
|
||||
},
|
||||
CommandName::Delete => execute_delete_command(cx, document, selection),
|
||||
CommandName::StyleWithCss => execute_style_with_css_command(document, value),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user