Bug 1341230 - Part 3: Add nsIDOMWindowUtils API to add/remove manually managed EventStates bits. r=smaug draft
authorCameron McCormack <cam@mcc.id.au>
Mon, 06 Mar 2017 12:49:04 +0800
changeset 493833 f532dde551e347deae7b9f5a4d678658c5dc0c70
parent 493793 6881181ab9e8bfd9559a4f92d77a8b2796daa9dc
child 547943 99bd3596bdec27900503b5084849088306fb1e8e
push id47859
push userbmo:cam@mcc.id.au
push dateMon, 06 Mar 2017 06:04:52 +0000
reviewerssmaug
bugs1341230
milestone54.0a1
Bug 1341230 - Part 3: Add nsIDOMWindowUtils API to add/remove manually managed EventStates bits. r=smaug MozReview-Commit-ID: 8brJct2tkTo
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -4090,16 +4090,80 @@ nsDOMWindowUtils::IsTimeoutTracking(uint
   NS_ENSURE_STATE(window);
   nsCOMPtr<nsPIDOMWindowInner> innerWindow = window->GetCurrentInnerWindow();
   NS_ENSURE_STATE(innerWindow);
 
   *aResult = innerWindow->TimeoutManager().IsTimeoutTracking(aTimeoutId);
   return NS_OK;
 }
 
+struct StateTableEntry
+{
+  const char* mStateString;
+  EventStates mState;
+};
+
+static constexpr StateTableEntry kManuallyManagedStates[] = {
+  // none yet; but for example: { "highlight", NS_EVENT_STATE_HIGHLIGHT },
+  { nullptr, EventStates() },
+};
+
+static_assert(!kManuallyManagedStates[ArrayLength(kManuallyManagedStates) - 1]
+               .mStateString,
+              "last kManuallyManagedStates entry must be a sentinel with "
+              "mStateString == nullptr");
+
+static EventStates
+GetEventStateForString(const nsAString& aStateString)
+{
+  for (const StateTableEntry* entry = kManuallyManagedStates;
+       entry->mStateString; ++entry) {
+    if (aStateString.EqualsASCII(entry->mStateString)) {
+      return entry->mState;
+    }
+  }
+  return EventStates();
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::AddManuallyManagedState(nsIDOMElement* aElement,
+                                          const nsAString& aStateString)
+{
+  nsCOMPtr<Element> element = do_QueryInterface(aElement);
+  if (!element) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  EventStates state = GetEventStateForString(aStateString);
+  if (state.IsEmpty()) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  element->AddManuallyManagedStates(state);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::RemoveManuallyManagedState(nsIDOMElement* aElement,
+                                             const nsAString& aStateString)
+{
+  nsCOMPtr<Element> element = do_QueryInterface(aElement);
+  if (!element) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  EventStates state = GetEventStateForString(aStateString);
+  if (state.IsEmpty()) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  element->RemoveManuallyManagedStates(state);
+  return NS_OK;
+}
+
 NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsTranslationNodeList)
 NS_IMPL_RELEASE(nsTranslationNodeList)
 
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1971,16 +1971,36 @@ interface nsIDOMWindowUtils : nsISupport
   readonly attribute int32_t gpuProcessPid;
 
   /**
    * Returns true if the given timeout ID is in the list of tracking
    * timeouts.
    */
   boolean isTimeoutTracking(in unsigned long timeoutId);
 
+  /**
+   * Adds an EventStates bit to the element.
+   *
+   * The state string must be one of the following:
+   *   * (none yet; but for example "higlighted" for NS_EVENT_STATE_HIGHLIGHTED)
+   *
+   * The supported state strings are defined in kManuallyManagedStates
+   * in nsDOMWindowUtils.cpp.
+   */
+  void addManuallyManagedState(in nsIDOMElement element,
+                               in AString state);
+
+  /**
+   * Removes the specified EventStates bits from the element.
+   *
+   * See above for the strings that can be passed for |state|.
+   */
+  void removeManuallyManagedState(in nsIDOMElement element,
+                                  in AString state);
+
   // These consts are only for testing purposes.
   const long DEFAULT_MOUSE_POINTER_ID = 0;
   const long DEFAULT_PEN_POINTER_ID   = 1;
   const long DEFAULT_TOUCH_POINTER_ID = 2;
 
   // Match WidgetMouseEventBase::buttonType.
   const long MOUSE_BUTTON_LEFT_BUTTON   = 0;
   const long MOUSE_BUTTON_MIDDLE_BUTTON = 1;