Make `HTMLEditor::SplitAncestorStyledInlineElementsAt` return "not handled" if there is no splitable element at given point

When given point is **in** a void element, e.g., this can be when JS inserts
nodes into a void element like `<meta>`,
`HTMLEditor::SplitNodeDeepWithTransaction` may return "not handled" state.
So, it's possible case, we shouldn't assert the case.

This patch adds both WPT and crashtests because I couldn't reproduce it
with WPT's simpler API use.

Differential Revision: https://phabricator.services.mozilla.com/D111231

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1699866
gecko-commit: 30f71808849762b4fb1de1a6ddd7effcaa088f12
gecko-reviewers: m_kato
diff --git a/editing/other/editing-style-of-range-around-void-element-child.tentative.html b/editing/other/editing-style-of-range-around-void-element-child.tentative.html
new file mode 100644
index 0000000..864074c
--- /dev/null
+++ b/editing/other/editing-style-of-range-around-void-element-child.tentative.html
@@ -0,0 +1,157 @@
+<!doctype html>
+<html>
+<meta charset=utf-8>
+<title>Test toggling style a range which starts from or ends by a child of a void element</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+<div contenteditable></div>
+<script>
+"use strict";
+
+/**
+ * The expected behavior is based on Chromium, but this is edge case tests.
+ * So, failures of this are not important unless crash.
+ */
+
+const editor = document.querySelector("div[contenteditable]");
+
+promise_test(async () => {
+  await new Promise(resolve => {
+    addEventListener("load", () => {
+      assert_true(true, "The document is loaded");
+      resolve();
+    }, { once: true });
+  });
+}, "Waiting for load...");
+
+promise_test(async () => {
+  editor.innerHTML = "<meta>bar";
+  const meta = editor.querySelector("meta");
+  const text = document.createTextNode("foo");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(meta.firstChild, 1, meta.nextSibling, 1);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "<meta><b>b</b>ar",
+      "<meta><b>b</b>ar<br>",
+    ]
+  );
+}, "Try to apply style from void element child");
+
+promise_test(async () => {
+  editor.innerHTML = "foo<meta>";
+  const meta = editor.querySelector("meta");
+  const text = document.createTextNode("bar");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(editor.firstChild, 1, meta.firstChild, 2);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "f<b>oo</b><meta>",
+      "f<b>oo</b><meta><br>",
+    ]
+  );
+}, "Try to apply style by void element child");
+
+promise_test(async () => {
+  editor.innerHTML = "<meta>";
+  const meta = editor.querySelector("meta");
+  const text = document.createTextNode("foo");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(meta.firstChild, 1, meta.firstChild, 2);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "<meta>",
+      "<meta><br>",
+    ]
+  );
+}, "Try to apply style in void element child");
+
+promise_test(async () => {
+  editor.innerHTML = "<meta>bar";
+  const meta = editor.querySelector("meta");
+  meta.setAttribute("style", "font-weight: bold");
+  const text = document.createTextNode("foo");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(meta.firstChild, 1, meta.nextSibling, 1);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "<meta><b>b</b>ar",
+      "<meta><b>b</b>ar<br>",
+      "<meta style=\"\"><b>b</b>ar",
+      "<meta style=\"\"><b>b</b>ar<br>",
+    ]
+  );
+}, "Try to remove style from void element child");
+
+promise_test(async () => {
+  editor.innerHTML = "<meta>bar";
+  const meta = editor.querySelector("meta");
+  meta.setAttribute("style", "font-weight: bold");
+  const text = document.createTextNode("foo");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(meta.firstChild, meta.firstChild.length, meta.nextSibling, 1);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "<meta><b>b</b>ar",
+      "<meta><b>b</b>ar<br>",
+      "<meta style=\"\"><b>b</b>ar",
+      "<meta style=\"\"><b>b</b>ar<br>",
+    ]
+  );
+}, "Try to remove style from end of void element child");
+
+promise_test(async () => {
+  editor.innerHTML = "foo<meta>";
+  const meta = editor.querySelector("meta");
+  const text = document.createTextNode("bar");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(editor.firstChild, 1, meta.firstChild, 2);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "f<b>oo</b><meta>",
+      "f<b>oo</b><meta><br>",
+      "f<b>oo</b><meta style=\"\">",
+      "f<b>oo</b><meta style=\"\"><br>",
+    ]
+  );
+}, "Try to remove style by void element child");
+
+promise_test(async () => {
+  editor.innerHTML = "foo<meta>";
+  const meta = editor.querySelector("meta");
+  const text = document.createTextNode("bar");
+  meta.append(text);
+  assert_equals(meta.firstChild, text);
+  getSelection().setBaseAndExtent(editor.firstChild, 1, meta.firstChild, 0);
+  document.execCommand("bold");
+  assert_in_array(
+    editor.innerHTML,
+    [
+      "f<b>oo</b><meta>",
+      "f<b>oo</b><meta><br>",
+      "f<b>oo</b><meta style=\"\">",
+      "f<b>oo</b><meta style=\"\"><br>",
+    ]
+  );
+}, "Try to remove style by start of void element child");
+</script>
+</body>
\ No newline at end of file