Bug 1155493 - Part 3: Dispatch event when carets are updated, pressed, released, tap, longpressonemptycontent, hidden. r=roc
☠☠ backed out by cb33de12c0b5 ☠ ☠
authorMorris Tseng <mtseng@mozilla.com>
Wed, 13 May 2015 20:10:00 -0400
changeset 245485 0380b1684e6b9f0c0cc20c27e30c32e0bd62657d
parent 245484 58b7c1eaf3c82d3c546bef8f85ee36222421da57
child 245486 3bd7adb9f591c5eb7b234085537a7f82ecd361f2
push id60186
push userryanvm@gmail.com
push dateMon, 25 May 2015 15:22:35 +0000
treeherdermozilla-inbound@00aff9bcfd9a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1155493
milestone41.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 1155493 - Part 3: Dispatch event when carets are updated, pressed, released, tap, longpressonemptycontent, hidden. r=roc
layout/base/AccessibleCaretManager.cpp
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -85,16 +85,17 @@ AccessibleCaretManager::OnSelectionChang
 
 void
 AccessibleCaretManager::HideCarets()
 {
   if (mFirstCaret->IsLogicallyVisible() || mSecondCaret->IsLogicallyVisible()) {
     AC_LOG("%s", __FUNCTION__);
     mFirstCaret->SetAppearance(Appearance::None);
     mSecondCaret->SetAppearance(Appearance::None);
+    DispatchCaretStateChangedEvent(CaretChangedReason::Visibilitychange);
     CancelCaretTimeoutTimer();
   }
 }
 
 void
 AccessibleCaretManager::UpdateCarets()
 {
   mCaretMode = GetCaretMode();
@@ -149,26 +150,32 @@ AccessibleCaretManager::UpdateCaretsForC
   if (!editingHost) {
     HideCarets();
     return;
   }
 
   // No need to consider whether the caret's position is out of scrollport.
   // According to the spec, we need to explicitly hide it after the scrolling is
   // ended.
-  mFirstCaret->SetPosition(frame, offset);
+  bool oldSecondCaretVisible = mSecondCaret->IsLogicallyVisible();
+  PositionChangedResult caretResult = mFirstCaret->SetPosition(frame, offset);
   mFirstCaret->SetSelectionBarEnabled(false);
   if (nsContentUtils::HasNonEmptyTextContent(
         editingHost, nsContentUtils::eRecurseIntoChildren)) {
     mFirstCaret->SetAppearance(Appearance::Normal);
     LaunchCaretTimeoutTimer();
   } else {
     mFirstCaret->SetAppearance(Appearance::NormalNotShown);
   }
   mSecondCaret->SetAppearance(Appearance::None);
+
+  if ((caretResult == PositionChangedResult::Changed ||
+      oldSecondCaretVisible) && !mActiveCaret) {
+    DispatchCaretStateChangedEvent(CaretChangedReason::Updateposition);
+  }
 }
 
 void
 AccessibleCaretManager::UpdateCaretsForSelectionMode()
 {
   AC_LOG("%s, selection: %p", __FUNCTION__, GetSelection());
 
   int32_t startOffset = 0;
@@ -209,16 +216,24 @@ AccessibleCaretManager::UpdateCaretsForS
 
   if (firstCaretResult == PositionChangedResult::Changed ||
       secondCaretResult == PositionChangedResult::Changed) {
     // Flush layout to make the carets intersection correct.
     mPresShell->FlushPendingNotifications(Flush_Layout);
   }
 
   UpdateCaretsForTilt();
+
+  if ((firstCaretResult == PositionChangedResult::Changed ||
+       secondCaretResult == PositionChangedResult::Changed ||
+       firstCaretResult == PositionChangedResult::Invisible ||
+       secondCaretResult == PositionChangedResult::Invisible) &&
+      !mActiveCaret) {
+    DispatchCaretStateChangedEvent(CaretChangedReason::Updateposition);
+  }
 }
 
 void
 AccessibleCaretManager::UpdateCaretsForTilt()
 {
   if (mFirstCaret->IsVisuallyVisible() && mSecondCaret->IsVisuallyVisible()) {
     if (mFirstCaret->Intersects(*mSecondCaret)) {
       if (mFirstCaret->LogicalPosition().x <=
@@ -248,16 +263,17 @@ AccessibleCaretManager::PressCaret(const
     mActiveCaret = mSecondCaret.get();
     SetSelectionDirection(eDirNext);
   }
 
   if (mActiveCaret) {
     mOffsetYToCaretLogicalPosition =
       mActiveCaret->LogicalPosition().y - aPoint.y;
     SetSelectionDragState(true);
+    DispatchCaretStateChangedEvent(CaretChangedReason::Presscaret);
     CancelCaretTimeoutTimer();
     rv = NS_OK;
   }
 
   return rv;
 }
 
 nsresult
@@ -274,28 +290,30 @@ AccessibleCaretManager::DragCaret(const 
 
 nsresult
 AccessibleCaretManager::ReleaseCaret()
 {
   MOZ_ASSERT(mActiveCaret);
 
   mActiveCaret = nullptr;
   SetSelectionDragState(false);
+  DispatchCaretStateChangedEvent(CaretChangedReason::Releasecaret);
   LaunchCaretTimeoutTimer();
   return NS_OK;
 }
 
 nsresult
 AccessibleCaretManager::TapCaret(const nsPoint& aPoint)
 {
   MOZ_ASSERT(GetCaretMode() != CaretMode::None);
 
   nsresult rv = NS_ERROR_FAILURE;
 
   if (GetCaretMode() == CaretMode::Cursor) {
+    DispatchCaretStateChangedEvent(CaretChangedReason::Taponcaret);
     rv = NS_OK;
   }
 
   return rv;
 }
 
 nsresult
 AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint)
@@ -326,16 +344,17 @@ AccessibleCaretManager::SelectWordOrShor
   nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame);
 
   nsIContent* editingHost = ptFrame->GetContent()->GetEditingHost();
   if (ChangeFocus(ptFrame) &&
       (editingHost && !nsContentUtils::HasNonEmptyTextContent(
                          editingHost, nsContentUtils::eRecurseIntoChildren))) {
     // Content is empty. No need to select word.
     AC_LOG("%s, Cannot select word bacause content is empty", __FUNCTION__);
+    DispatchCaretStateChangedEvent(CaretChangedReason::Longpressonemptycontent);
     return NS_OK;
   }
 
   nsresult rv = SelectWord(ptFrame, ptInFrame);
   UpdateCarets();
   return rv;
 }