Bug 1213589 part.9 ContentEventHandler::ShouldBreakLineBefore() should return false if the content is unknown HTML element r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 02 Dec 2015 13:20:01 +0900
changeset 275168 4434a5a96375d3ffe6e5cc05cab67b675b3772c1
parent 275167 5b3f4ce479a5092965a56802193a7343d7008e63
child 275169 6df8e622a79d2dad2608b42eab6d243f6400d7cf
push id29747
push usercbook@mozilla.com
push dateWed, 02 Dec 2015 14:21:19 +0000
treeherdermozilla-central@f6ac392322b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1213589
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1213589 part.9 ContentEventHandler::ShouldBreakLineBefore() should return false if the content is unknown HTML element r=smaug
dom/events/ContentEventHandler.cpp
dom/html/HTMLUnknownElement.cpp
dom/html/HTMLUnknownElement.h
widget/tests/window_composition_text_querycontent.xul
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -3,32 +3,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ContentEventHandler.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/Selection.h"
 #include "nsCaret.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsCopySupport.h"
 #include "nsFocusManager.h"
 #include "nsFontMetrics.h"
 #include "nsFrameSelection.h"
 #include "nsIContentIterator.h"
 #include "nsIPresShell.h"
 #include "nsISelection.h"
 #include "nsISelectionController.h"
 #include "nsIFrame.h"
 #include "nsIObjectFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
+#include "nsQueryObject.h"
 #include "nsRange.h"
 #include "nsTextFragment.h"
 #include "nsTextFrame.h"
 #include "nsView.h"
 
 #include <algorithm>
 
 namespace mozilla {
@@ -491,47 +493,53 @@ ContentEventHandler::ShouldBreakLineBefo
   if (aContent->IsHTMLElement(nsGkAtoms::br)) {
     return IsContentBR(aContent);
   }
 
   // Note that ideally, we should refer the style of the primary frame of
   // aContent for deciding if it's an inline.  However, it's difficult
   // IMEContentObserver to notify IME of text change caused by style change.
   // Therefore, currently, we should check only from the tag for now.
-  // TODO: Check if the element is an unknown HTML element.
-  return !aContent->IsAnyOfHTMLElements(nsGkAtoms::a,
-                                        nsGkAtoms::abbr,
-                                        nsGkAtoms::acronym,
-                                        nsGkAtoms::b,
-                                        nsGkAtoms::bdi,
-                                        nsGkAtoms::bdo,
-                                        nsGkAtoms::big,
-                                        nsGkAtoms::cite,
-                                        nsGkAtoms::code,
-                                        nsGkAtoms::data,
-                                        nsGkAtoms::del,
-                                        nsGkAtoms::dfn,
-                                        nsGkAtoms::em,
-                                        nsGkAtoms::font,
-                                        nsGkAtoms::i,
-                                        nsGkAtoms::ins,
-                                        nsGkAtoms::kbd,
-                                        nsGkAtoms::mark,
-                                        nsGkAtoms::s,
-                                        nsGkAtoms::samp,
-                                        nsGkAtoms::small,
-                                        nsGkAtoms::span,
-                                        nsGkAtoms::strike,
-                                        nsGkAtoms::strong,
-                                        nsGkAtoms::sub,
-                                        nsGkAtoms::sup,
-                                        nsGkAtoms::time,
-                                        nsGkAtoms::tt,
-                                        nsGkAtoms::u,
-                                        nsGkAtoms::var);
+  if (aContent->IsAnyOfHTMLElements(nsGkAtoms::a,
+                                    nsGkAtoms::abbr,
+                                    nsGkAtoms::acronym,
+                                    nsGkAtoms::b,
+                                    nsGkAtoms::bdi,
+                                    nsGkAtoms::bdo,
+                                    nsGkAtoms::big,
+                                    nsGkAtoms::cite,
+                                    nsGkAtoms::code,
+                                    nsGkAtoms::data,
+                                    nsGkAtoms::del,
+                                    nsGkAtoms::dfn,
+                                    nsGkAtoms::em,
+                                    nsGkAtoms::font,
+                                    nsGkAtoms::i,
+                                    nsGkAtoms::ins,
+                                    nsGkAtoms::kbd,
+                                    nsGkAtoms::mark,
+                                    nsGkAtoms::s,
+                                    nsGkAtoms::samp,
+                                    nsGkAtoms::small,
+                                    nsGkAtoms::span,
+                                    nsGkAtoms::strike,
+                                    nsGkAtoms::strong,
+                                    nsGkAtoms::sub,
+                                    nsGkAtoms::sup,
+                                    nsGkAtoms::time,
+                                    nsGkAtoms::tt,
+                                    nsGkAtoms::u,
+                                    nsGkAtoms::var)) {
+    return false;
+  }
+
+  // If the element is unknown element, we shouldn't insert line breaks before
+  // it since unknown elements should be ignored.
+  RefPtr<HTMLUnknownElement> unknownHTMLElement = do_QueryObject(aContent);
+  return !unknownHTMLElement;
 }
 
 nsresult
 ContentEventHandler::GenerateFlatTextContent(nsRange* aRange,
                                              nsAFlatString& aString,
                                              LineBreakType aLineBreakType)
 {
   NS_ASSERTION(aString.IsEmpty(), "aString must be empty string");
--- a/dom/html/HTMLUnknownElement.cpp
+++ b/dom/html/HTMLUnknownElement.cpp
@@ -9,16 +9,19 @@
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "jsapi.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Unknown)
 
 namespace mozilla {
 namespace dom {
 
+NS_IMPL_ISUPPORTS_INHERITED(HTMLUnknownElement, nsGenericHTMLElement,
+                            HTMLUnknownElement)
+
 JSObject*
 HTMLUnknownElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return HTMLUnknownElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ELEMENT_CLONE(HTMLUnknownElement)
 
--- a/dom/html/HTMLUnknownElement.h
+++ b/dom/html/HTMLUnknownElement.h
@@ -7,29 +7,40 @@
 #define mozilla_dom_HTMLUnknownElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 
 namespace mozilla {
 namespace dom {
 
+#define NS_HTMLUNKNOWNELEMENT_IID \
+{ 0xc09e665b, 0x3876, 0x40dd, \
+  { 0x85, 0x28, 0x44, 0xc2, 0x3f, 0xd4, 0x58, 0xf2 } }
+
 class HTMLUnknownElement final : public nsGenericHTMLElement
 {
 public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_HTMLUNKNOWNELEMENT_IID)
+
+  NS_DECL_ISUPPORTS_INHERITED
+
   explicit HTMLUnknownElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
     if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
       SetHasDirAuto();
     }
   }
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
 protected:
+  virtual ~HTMLUnknownElement() {}
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(HTMLUnknownElement, NS_HTMLUNKNOWNELEMENT_IID)
+
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_HTMLUnknownElement_h */
--- a/widget/tests/window_composition_text_querycontent.xul
+++ b/widget/tests/window_composition_text_querycontent.xul
@@ -3186,16 +3186,29 @@ function runSetSelectionEventTest()
      "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection anchor node should be the text node");
   is(selection.anchorOffset, 0,
      "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection anchor offset should be 0");
   is(selection.focusNode, contenteditable.childNodes.item(1).lastChild,
      "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection focus node should be the text node");
   is(selection.focusOffset, 0,
      "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection focus offset should be 0");
   checkSelection(0, "", "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\"");
+
+  // #16
+  contenteditable.innerHTML = "a<blink>b</blink>c";
+  synthesizeSelectionSet(0, 3);
+  is(selection.anchorNode, contenteditable.firstChild,
+     "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection anchor node should be the first text node");
+  is(selection.anchorOffset, 0,
+     "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection anchor offset should be 0");
+  is(selection.focusNode, contenteditable.lastChild,
+     "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection focus node should be the last text node");
+  is(selection.focusOffset, contenteditable.lastChild.wholeText.length,
+     "runSetSelectionEventTest #15 (0, 0), \"" + contenteditable.innerHTML + "\": selection focus offset should be the length of the last text node");
+  checkSelection(0, "abc", "runSetSelectionEventTest #16 (0, 3), \"" + contenteditable.innerHTML + "\"");
 }
 
 function runQueryTextContentEventTest()
 {
   contenteditable.focus();
 
   var result;
 
@@ -3382,16 +3395,22 @@ function runQueryTextContentEventTest()
   result = synthesizeQueryTextContent(kLFLen, kLFLen * 2);
   is(result.text, kLF + kLF, "runQueryTextContentEventTest #8 (kLFLen, kLFLen*2), \"" + contenteditable.innerHTML + "\"");
 
   result = synthesizeQueryTextContent(kLFLen*2, kLFLen);
   is(result.text, kLF, "runQueryTextContentEventTest #8 (kLFLen*2, kLFLen), \"" + contenteditable.innerHTML + "\"");
 
   result = synthesizeQueryTextContent(kLFLen*3, 1);
   is(result.text, "", "runQueryTextContentEventTest #8 (kLFLen*3, 1), \"" + contenteditable.innerHTML + "\"");
+
+  // #16
+  contenteditable.innerHTML = "a<blink>b</blink>c";
+
+  result = synthesizeQueryTextContent(0, 3);
+  is(result.text, "abc", "runQueryTextContentEventTest #16 (0, 3), \"" + contenteditable.innerHTML + "\"");
 }
 
 function runCSSTransformTest()
 {
   textarea.focus();
   textarea.value = "some text";
   textarea.selectionStart = textarea.selectionEnd = textarea.value.length;
   var editorRect = synthesizeQueryEditorRect();