Merge mozilla-central to mozilla-inbound. a=merge on a CLOSED TREE
authorDaniel Varga <dvarga@mozilla.com>
Thu, 25 Oct 2018 12:59:46 +0300
changeset 491276 feb8571f288e22049912d64e3daa133578c8d55b
parent 491259 39af81ab41a7c420e3c4b574739bebcda0cdcbc1 (current diff)
parent 491275 3cc04ee79005058d817daf66da7963dfac3f0a3a (diff)
child 491277 e81ad7034716854a48a3d04a0b53b4b63956b77d
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersmerge
milestone65.0a1
Merge mozilla-central to mozilla-inbound. a=merge on a CLOSED TREE
--- a/accessible/html/HTMLElementAccessibles.cpp
+++ b/accessible/html/HTMLElementAccessibles.cpp
@@ -254,17 +254,17 @@ HTMLHeaderOrFooterAccessible::LandmarkRo
 // HTMLSectionAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 role
 HTMLSectionAccessible::NativeRole() const
 {
   nsAutoString name;
   const_cast<HTMLSectionAccessible*>(this)->Name(name);
-  return name.IsEmpty() ? roles::SECTION : roles::LANDMARK;
+  return name.IsEmpty() ? roles::SECTION : roles::REGION;
 }
 
 nsAtom*
 HTMLSectionAccessible::LandmarkRole() const
 {
   if (!HasOwnContent()) {
     return nullptr;
   }
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -1212,17 +1212,17 @@
         absentAttributes: { "xml-roles": "region" },
         interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
       };
       testElm("section", obj);
 
       // HTML:section with an accessible name
 
       obj = {
-        role: ROLE_LANDMARK,
+        role: ROLE_REGION,
         attributes: { "xml-roles": "region" },
         interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
       };
       testElm("named_section", obj);
 
       // ////////////////////////////////////////////////////////////////////////
       // HTML:small contained by paragraph
 
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -307,20 +307,31 @@ class AnimationInspector {
   }
 
   async onAnimationsMutation(changes) {
     let animations = [...this.state.animations];
     const addedAnimations = [];
 
     for (const {type, player: animation} of changes) {
       if (type === "added") {
+        if (!animation.state.type) {
+          // This animation was added but removed immediately.
+          continue;
+        }
+
         addedAnimations.push(animation);
         animation.on("changed", this.onAnimationStateChanged);
       } else if (type === "removed") {
         const index = animations.indexOf(animation);
+
+        if (index < 0) {
+          // This animation was added but removed immediately.
+          continue;
+        }
+
         animations.splice(index, 1);
         animation.off("changed", this.onAnimationStateChanged);
       }
     }
 
     // Update existing other animations as well since the currentTime would be proceeded
     // sice the scrubber position is related the currentTime.
     // Also, don't update the state of removed animations since React components
--- a/devtools/client/inspector/animation/test/browser.ini
+++ b/devtools/client/inspector/animation/test/browser.ini
@@ -4,16 +4,17 @@ subsuite = devtools
 support-files =
   current-time-scrubber_head.js
   doc_custom_playback_rate.html
   doc_frame_script.js
   doc_infinity_duration.html
   doc_multi_easings.html
   doc_multi_keyframes.html
   doc_multi_timings.html
+  doc_mutations_add_remove_immediately.html
   doc_mutations_fast.html
   doc_negative_playback_rate.html
   doc_overflowed_delay_end_delay.html
   doc_pseudo.html
   doc_short_duration.html
   doc_simple_animation.html
   head.js
   keyframes-graph_keyframe-marker_head.js
@@ -63,16 +64,17 @@ skip-if = (verify && !debug)
 skip-if = (os == "win" && ccov) # Bug 1490981
 [browser_animation_keyframes-progress-bar_after-resuming.js]
 [browser_animation_logic_adjust-time.js]
 [browser_animation_logic_adjust-time-with-playback-rate.js]
 [browser_animation_logic_auto-stop.js]
 [browser_animation_logic_avoid-updating-during-hiding.js]
 [browser_animation_logic_created-time.js]
 [browser_animation_logic_mutations.js]
+[browser_animation_logic_mutations_add_remove_immediately.js]
 [browser_animation_logic_mutations_fast.js]
 skip-if= true # Bug 1500046
 [browser_animation_logic_mutations_properties.js]
 [browser_animation_logic_overflowed_delay_end-delay.js]
 skip-if = debug #bug 1480027
 [browser_animation_logic_scroll-amount.js]
 [browser_animation_pause-resume-button.js]
 [browser_animation_pause-resume-button_end-time.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/test/browser_animation_logic_mutations_add_remove_immediately.js
@@ -0,0 +1,25 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test whether the animation inspector will not crash when add animation then remove
+// immediately.
+
+add_task(async function() {
+  const tab = await addTab(URL_ROOT + "doc_mutations_add_remove_immediately.html");
+  const { inspector, panel } = await openAnimationInspector();
+
+  info("Check state of the animation inspector after fast mutations");
+  const onDispatch = waitForDispatch(inspector, "UPDATE_ANIMATIONS", () => 1);
+  await startMutation(tab);
+  await onDispatch;
+  ok(panel.querySelector(".animation-error-message"),
+     "No animations message should display");
+});
+
+async function startMutation(tab) {
+  await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
+    await content.wrappedJSObject.startMutation();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/test/doc_mutations_add_remove_immediately.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8">
+  </head>
+  <body>
+    <div></div>
+
+    <script>
+    "use strict";
+
+    // This function is called from test.
+    // eslint-disable-next-line
+    function startMutation() {
+      const target = document.querySelector("div");
+      const animation = target.animate({ opacity: [1, 0] }, 100000);
+      animation.currentTime = 1;
+      animation.cancel();
+    }
+    </script>
+  </body>
+</html>
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -1514,16 +1514,36 @@ protected: // Shouldn't be used by frien
    *                            nsIClipboard::kSelectionClipboard.
    * @param aDispatchPasteEvent true if this should dispatch ePaste event
    *                            before pasting.  Otherwise, false.
    */
   nsresult PasteInternal(int32_t aClipboardType,
                          bool aDispatchPasteEvent);
 
   /**
+   * InsertAsCitedQuotationInternal() inserts a <blockquote> element whose
+   * cite attribute is aCitation and whose content is aQuotedText.
+   * Note that this shouldn't be called when IsPlaintextEditor() is true.
+   *
+   * @param aQuotedText     HTML source if aInsertHTML is true.  Otherwise,
+   *                        plain text.  This is inserted into new <blockquote>
+   *                        element.
+   * @param aCitation       cite attribute value of new <blockquote> element.
+   * @param aInsertHTML     true if aQuotedText should be treated as HTML
+   *                        source.
+   *                        false if aQuotedText should be treated as plain
+   *                        text.
+   * @param aNodeInserted   [OUT] The new <blockquote> element.
+   */
+  nsresult InsertAsCitedQuotationInternal(const nsAString& aQuotedText,
+                                          const nsAString& aCitation,
+                                          bool aInsertHTML,
+                                          nsINode** aNodeInserted);
+
+  /**
    * InsertNodeIntoProperAncestorWithTransaction() attempts to insert aNode
    * into the document, at aPointToInsert.  Checks with strict dtd to see if
    * containment is allowed.  If not allowed, will attempt to find a parent
    * in the parent hierarchy of aPointToInsert.GetContainer() that will accept
    * aNode as a child.  If such a parent is found, will split the document
    * tree from aPointToInsert up to parent, and then insert aNode.
    * aPointToInsert is then adjusted to point to the actual location that
    * aNode was inserted at.  aSplitAtEdges specifies if the splitting process
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -1911,24 +1911,33 @@ HTMLEditor::InsertTextWithQuotationsInte
 
   return rv;
 }
 
 nsresult
 HTMLEditor::InsertAsQuotation(const nsAString& aQuotedText,
                               nsINode** aNodeInserted)
 {
-  AutoPlaceholderBatch treatAsOneTransaction(*this);
   if (IsPlaintextEditor()) {
-    return InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
+    AutoPlaceholderBatch treatAsOneTransaction(*this);
+    nsresult rv = InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    return NS_OK;
   }
 
+  AutoPlaceholderBatch treatAsOneTransaction(*this);
   nsAutoString citation;
-  return InsertAsCitedQuotation(aQuotedText, citation, false,
-                                aNodeInserted);
+  nsresult rv =
+    InsertAsCitedQuotationInternal(aQuotedText, citation, false, aNodeInserted);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 // Insert plaintext as a quotation, with cite marks (e.g. "> ").
 // This differs from its corresponding method in TextEditor
 // in that here, quoted material is enclosed in a <pre> tag
 // in order to preserve the original line wrapping.
 nsresult
 HTMLEditor::InsertAsPlaintextQuotation(const nsAString& aQuotedText,
@@ -2072,25 +2081,47 @@ HTMLEditor::Rewrap(bool aRespectNewlines
 }
 
 NS_IMETHODIMP
 HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
                                    const nsAString& aCitation,
                                    bool aInsertHTML,
                                    nsINode** aNodeInserted)
 {
-  AutoPlaceholderBatch treatAsOneTransaction(*this);
 
   // Don't let anyone insert HTML when we're in plaintext mode.
   if (IsPlaintextEditor()) {
     NS_ASSERTION(!aInsertHTML,
       "InsertAsCitedQuotation: trying to insert html into plaintext editor");
-    return InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
+    AutoPlaceholderBatch treatAsOneTransaction(*this);
+    nsresult rv = InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    return NS_OK;
   }
 
+  AutoPlaceholderBatch treatAsOneTransaction(*this);
+  nsresult rv =
+    InsertAsCitedQuotationInternal(aQuotedText, aCitation, aInsertHTML,
+                                   aNodeInserted);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
+}
+
+nsresult
+HTMLEditor::InsertAsCitedQuotationInternal(const nsAString& aQuotedText,
+                                           const nsAString& aCitation,
+                                           bool aInsertHTML,
+                                           nsINode** aNodeInserted)
+{
+  MOZ_ASSERT(!IsPlaintextEditor());
+
   RefPtr<Selection> selection = GetSelection();
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
 
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertQuotation,
                                       nsIEditor::eNext);
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -777,17 +777,17 @@ TextEditRules::WillInsertText(EditSubAct
     outString->Assign(tString);
   }
 
   if (IsPasswordEditor()) {
     // manage the password buffer
     mPasswordText.Insert(*outString, start);
 
     if (LookAndFeel::GetEchoPassword() && !DontEchoPassword()) {
-      nsresult rv = HideLastPWInput();
+      nsresult rv = HideLastPasswordInputInternal();
       mLastStart = start;
       mLastLength = outString->Length();
       if (mTimer) {
         mTimer->Cancel();
       }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
@@ -1089,17 +1089,17 @@ TextEditRules::DeleteSelectionWithTransa
 
     // manage the password buffer
     uint32_t start, end;
     nsContentUtils::GetSelectionInTextControl(&SelectionRef(),
                                               TextEditorRef().GetRoot(),
                                               start, end);
 
     if (LookAndFeel::GetEchoPassword()) {
-      rv = HideLastPWInput();
+      rv = HideLastPasswordInputInternal();
       mLastStart = start;
       mLastLength = 0;
       if (mTimer) {
         mTimer->Cancel();
       }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
@@ -1699,41 +1699,57 @@ NS_IMETHODIMP
 TextEditRules::Notify(nsITimer* aTimer)
 {
   MOZ_ASSERT(mTimer);
 
   if (NS_WARN_IF(!mTextEditor)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  Selection* selection = mTextEditor->GetSelection();
-  if (NS_WARN_IF(!selection)) {
-    return NS_ERROR_FAILURE;
+  // Check whether our text editor's password flag was changed before this
+  // "hide password character" timer actually fires.
+  if (!IsPasswordEditor()) {
+    return NS_OK;
   }
 
-  AutoSafeEditorData setData(*this, *mTextEditor, *selection);
+  RefPtr<TextEditor> textEditor(mTextEditor);
+  nsresult rv = textEditor->HideLastPasswordInput();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
+}
+
+nsresult
+TextEditRules::HideLastPasswordInput(Selection& aSelection)
+{
+  MOZ_ASSERT(IsPasswordEditor());
+
+  AutoSafeEditorData setData(*this, *mTextEditor, aSelection);
 
   // Check whether our text editor's password flag was changed before this
   // "hide password character" timer actually fires.
-  nsresult rv = IsPasswordEditor() ? HideLastPWInput() : NS_OK;
-  NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to hide last password input");
+  nsresult rv = HideLastPasswordInputInternal();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
   ASSERT_PASSWORD_LENGTHS_EQUAL();
   mLastLength = 0;
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 TextEditRules::GetName(nsACString& aName)
 {
   aName.AssignLiteral("TextEditRules");
   return NS_OK;
 }
 
 nsresult
-TextEditRules::HideLastPWInput()
+TextEditRules::HideLastPasswordInputInternal()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   if (!mLastLength) {
     // Special case, we're trying to replace a range that no longer exists
     return NS_OK;
   }
 
--- a/editor/libeditor/TextEditRules.h
+++ b/editor/libeditor/TextEditRules.h
@@ -83,16 +83,17 @@ public:
 
   virtual nsresult Init(TextEditor* aTextEditor);
   virtual nsresult SetInitialValue(const nsAString& aValue);
   virtual nsresult DetachEditor();
   virtual nsresult BeforeEdit(EditSubAction aEditSubAction,
                               nsIEditor::EDirection aDirection);
   virtual nsresult AfterEdit(EditSubAction aEditSubAction,
                              nsIEditor::EDirection aDirection);
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   virtual nsresult WillDoAction(Selection* aSelection,
                                 EditSubActionInfo& aInfo,
                                 bool* aCancel,
                                 bool* aHandled);
   virtual nsresult DidDoAction(Selection* aSelection,
                                EditSubActionInfo& aInfo,
                                nsresult aResult);
 
@@ -145,16 +146,22 @@ public:
    */
   static void FillBufWithPWChars(nsAString* aOutString, int32_t aLength);
 
   bool HasBogusNode()
   {
     return !!mBogusNode;
   }
 
+  /**
+   * HideLastPasswordInput() is called while Nodify() is calling
+   * TextEditor::HideLastPasswordInput().
+   */
+  MOZ_CAN_RUN_SCRIPT nsresult HideLastPasswordInput(Selection& aSelection);
+
 protected:
 
   void InitFields();
 
   // TextEditRules implementation methods
 
   /**
    * Called before inserting text.
@@ -165,16 +172,17 @@ protected:
    *                            or EditSubAction::eInsertText.
    * @param aCancel             Returns true if the operation is canceled.
    * @param aHandled            Returns true if the edit action is handled.
    * @param inString            String to be inserted.
    * @param outString           String actually inserted.
    * @param aMaxLength          The maximum string length which the editor
    *                            allows to set.
    */
+  MOZ_CAN_RUN_SCRIPT
   MOZ_MUST_USE nsresult
   WillInsertText(EditSubAction aEditSubAction, bool* aCancel, bool* aHandled,
                  const nsAString* inString, nsAString* outString,
                  int32_t aMaxLength);
 
   /**
    * Called before inserting a line break into the editor.
    * This method removes selected text if selection isn't collapsed.
@@ -218,31 +226,33 @@ protected:
    * This method may actually remove the selected content with
    * DeleteSelectionWithTransaction().  So, this might cause destroying the
    * editor.
    *
    * @param aCaollapsedAction   Direction to extend the selection.
    * @param aCancel             Returns true if the operation is canceled.
    * @param aHandled            Returns true if the edit action is handled.
    */
+  MOZ_CAN_RUN_SCRIPT
   MOZ_MUST_USE nsresult
   WillDeleteSelection(nsIEditor::EDirection aCollapsedAction,
                       bool* aCancel, bool* aHandled);
 
   /**
    * DeleteSelectionWithTransaction() is internal method of
    * WillDeleteSelection() since it needs to create SelectionBatcher in
    * big scope and destroying it might causes destroying the editor.
    * So, after calling this method, callers need to check CanHandleEditAction()
    * manually.
    *
    * @param aCaollapsedAction   Direction to extend the selection.
    * @param aCancel             Returns true if the operation is canceled.
    * @param aHandled            Returns true if the edit action is handled.
    */
+  MOZ_CAN_RUN_SCRIPT
   MOZ_MUST_USE nsresult
   DeleteSelectionWithTransaction(nsIEditor::EDirection aCollapsedAction,
                                  bool* aCancel, bool* aHandled);
 
   /**
    * Called after deleted selected content.
    * This method may remove empty text node and makes guarantee that caret
    * is never at left of <br> element.
@@ -348,21 +358,22 @@ protected:
 
   void UndefineCaretBidiLevel();
 
   nsresult CheckBidiLevelForDeletion(const EditorRawDOMPoint& aSelectionPoint,
                                      nsIEditor::EDirection aAction,
                                      bool* aCancel);
 
   /**
-   * HideLastPWInput() replaces last password characters which have not
-   * been replaced with mask character like '*' with with the mask character.
-   * This method may cause destroying the editor.
+   * HideLastPasswordInputInternal() replaces last password characters which
+   * have not been replaced with mask character like '*' with with the mask
+   * character.  This method may cause destroying the editor.
    */
-  MOZ_MUST_USE nsresult HideLastPWInput();
+  MOZ_CAN_RUN_SCRIPT
+  MOZ_MUST_USE nsresult HideLastPasswordInputInternal();
 
   /**
    * CollapseSelectionToTrailingBRIfNeeded() collapses selection after the
    * text node if:
    * - the editor is text editor
    * - and Selection is collapsed at the end of the text node
    * - and the text node is followed by moz-<br>.
    */
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -2171,9 +2171,29 @@ TextEditor::RemoveAttributeOrEquivalent(
                                         bool aSuppressTransaction)
 {
   if (NS_WARN_IF(!aElement) || NS_WARN_IF(!aAttribute)) {
     return NS_ERROR_INVALID_ARG;
   }
   return RemoveAttributeWithTransaction(*aElement, *aAttribute);
 }
 
+nsresult
+TextEditor::HideLastPasswordInput()
+{
+  // This method should be called only by TextEditRules::Notify().
+  MOZ_ASSERT(mRules);
+  MOZ_ASSERT(IsPasswordEditor());
+
+  RefPtr<Selection> selection = GetSelection();
+  if (NS_WARN_IF(!selection)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  RefPtr<TextEditRules> rules(mRules);
+  nsresult rv = rules->HideLastPasswordInput(*selection);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
+}
+
 } // namespace mozilla
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -331,16 +331,24 @@ protected: // May be called by friends.
   /**
    * Extends the selection for given deletion operation
    * If done, also update aAction to what's actually left to do after the
    * extension.
    */
   nsresult ExtendSelectionForDelete(Selection* aSelection,
                                     nsIEditor::EDirection* aAction);
 
+  /**
+   * HideLastPasswordInput() is called by timer callback of TextEditRules.
+   * This should be called only by TextEditRules::Notify().
+   * When this is called, the TextEditRules wants to call its
+   * HideLastPasswordInput().
+   */
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult HideLastPasswordInput();
+
   static void GetDefaultEditorPrefs(int32_t& aNewLineHandling,
                                     int32_t& aCaretStyle);
 
 protected: // Called by helper classes.
 
   virtual void
   OnStartToHandleTopLevelEditSubAction(
     EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;
--- a/testing/web-platform/meta/cookies/samesite/form-post-blank-reload.html.ini
+++ b/testing/web-platform/meta/cookies/samesite/form-post-blank-reload.html.ini
@@ -1,8 +1,21 @@
 [form-post-blank-reload.html]
   expected:
     if os == "android": TIMEOUT
     ERROR
   [Untitled]
     expected:
       if os == "android": NOTRUN
       FAIL
+
+  [Reloaded same-host top-level form POSTs are strictly same-site]
+    expected:
+      if os == "android": TIMEOUT
+
+  [Reloaded subdomain top-level form POSTs are strictly same-site]
+    expected:
+      if os == "android": NOTRUN
+
+  [Reloaded cross-site top-level form POSTs are not same-site]
+    expected:
+      if os == "android": NOTRUN
+
--- a/testing/web-platform/meta/pointerevents/extension/idlharness.window.js.ini
+++ b/testing/web-platform/meta/pointerevents/extension/idlharness.window.js.ini
@@ -1,7 +1,15 @@
 [idlharness.window.html]
   [PointerEvent interface: operation getPredictedEvents()]
     expected: FAIL
 
   [PointerEvent interface: new PointerEvent("pointer") must inherit property "getPredictedEvents()" with the proper type]
     expected: FAIL
 
+  [PointerEvent interface: operation getCoalescedEvents()]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("pointer") must inherit property "getCoalescedEvents()" with the proper type]
+    expected:
+      if os == "android": FAIL
+
--- a/testing/web-platform/meta/pointerevents/idlharness.window.js.ini
+++ b/testing/web-platform/meta/pointerevents/idlharness.window.js.ini
@@ -24,8 +24,300 @@
     expected: FAIL
 
   [Window interface: attribute onpointerrawmove]
     expected: FAIL
 
   [Window interface: window must inherit property "onpointerrawmove" with the proper type]
     expected: FAIL
 
+  [PointerEvent interface object name]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "isPrimary" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointerout]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointermove" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute tangentialPressure]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointerenter]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute tiltX]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute tiltY]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointerleave]
+    expected:
+      if os == "android": FAIL
+
+  [Navigator interface: navigator must inherit property "maxTouchPoints" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointerout" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointerleave]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "height" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointerleave]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointermove]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute ongotpointercapture]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointerup]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "pointerType" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointerdown]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointerup" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "ongotpointercapture" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute pressure]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute pointerId]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute ongotpointercapture]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface object length]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointermove]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointerleave" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute isPrimary]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onlostpointercapture]
+    expected:
+      if os == "android": FAIL
+
+  [Element interface: operation setPointerCapture(long)]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointerenter" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Element interface: operation hasPointerCapture(long)]
+    expected:
+      if os == "android": FAIL
+
+  [Navigator interface: attribute maxTouchPoints]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: existence and properties of interface prototype object]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointerenter]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointercancel]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute pointerType]
+    expected:
+      if os == "android": FAIL
+
+  [Stringification of new PointerEvent("type")]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointercancel" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "twist" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute height]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "pressure" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointerup]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "width" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointerdown" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent must be primary interface of new PointerEvent("type")]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointerdown]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointerenter]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onlostpointercapture" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: window must inherit property "onpointerover" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onlostpointercapture]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointerover]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointerdown]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute width]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "tangentialPressure" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "tiltY" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: attribute twist]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointercancel]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointerover]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute ongotpointercapture]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointercancel]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onlostpointercapture]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "pointerId" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: existence and properties of interface prototype object's @@unscopables property]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: new PointerEvent("type") must inherit property "tiltX" with the proper type]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointerover]
+    expected:
+      if os == "android": FAIL
+
+  [HTMLElement interface: attribute onpointerout]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: existence and properties of interface object]
+    expected:
+      if os == "android": FAIL
+
+  [PointerEvent interface: existence and properties of interface prototype object's "constructor" property]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointerout]
+    expected:
+      if os == "android": FAIL
+
+  [Document interface: attribute onpointermove]
+    expected:
+      if os == "android": FAIL
+
+  [Window interface: attribute onpointerup]
+    expected:
+      if os == "android": FAIL
+
+  [Element interface: operation releasePointerCapture(long)]
+    expected:
+      if os == "android": FAIL
+