Bug 1452538 - Add telemetry probes HTMLEditors which have shown Gecko build-in editing UIs and count of user interaction with them r?ehsan draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 09 Apr 2018 17:31:23 +0900
changeset 789002 b9e235c8558abb4205c663e012b3461972d0d60a
parent 788940 35b8da0bc07fa9d91e886995739648a76e3e66f8
child 789003 5f39b488c197b0527cf08e594dd577d020f66a93
push id108130
push usermasayuki@d-toybox.com
push dateFri, 27 Apr 2018 10:14:11 +0000
reviewersehsan
bugs1452538
milestone61.0a1
Bug 1452538 - Add telemetry probes HTMLEditors which have shown Gecko build-in editing UIs and count of user interaction with them r?ehsan Gecko has some built-in UIs: * to edit size of objects like <img>, <table> and absolute positioned elements. * to edit position of absolute positioned elements. * to add/remove table columns and rows. Currently, those UIs are available in both designMode editor and contenteditable editor only on Gecko. I.e., the other browsers' users cannot modify as such without web apps implement such function. So, for compatibility with the other browsers, we should hide those UIs by default. On the other hand, if this is too risky for backward compatibility, we should not do that. So, before doing that, we should collect actual usage data of object resizers, inline table editing UI, positioning UI of absolute positioned elements with telemetry probes. This patch adds 3 sets of probes for each UI. One is percentage of showing each UI in all instantiated HTMLEditor. The other is number of user interaction of each UI in HTMLEditors which has shown the UI. This patch makes all new probes as "opt-out" because they are really important data since used for deciding whether those UIs are necessary or unnecessary. MozReview-Commit-ID: B9Y6GTiCPw6
editor/libeditor/HTMLAbsPositionEditor.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLEditorObjectResizer.cpp
editor/libeditor/HTMLInlineTableEditor.cpp
toolkit/components/telemetry/Histograms.json
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -301,16 +301,18 @@ HTMLEditor::ShowGrabber(Element& aElemen
   nsIContent* parentContent = aElement.GetParent();
   if (NS_WARN_IF(!parentContent)) {
     return NS_ERROR_FAILURE;
   }
 
   mGrabber = CreateGrabber(*parentContent);
   NS_ENSURE_TRUE(mGrabber, NS_ERROR_FAILURE);
 
+  mHasShownGrabber = true;
+
   // and set its position
   return RefreshGrabber();
 }
 
 nsresult
 HTMLEditor::StartMoving()
 {
   nsCOMPtr<nsIContent> parentContent = mGrabber->GetParent();
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -6,16 +6,17 @@
 #include "mozilla/HTMLEditor.h"
 
 #include "mozilla/ComposerCommandsUpdater.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/EditAction.h"
 #include "mozilla/EditorDOMPoint.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/mozInlineSpellChecker.h"
+#include "mozilla/Telemetry.h"
 #include "mozilla/TextEvents.h"
 
 #include "nsCRT.h"
 
 #include "nsUnicharUtils.h"
 
 #include "HTMLEditorEventListener.h"
 #include "HTMLEditRules.h"
@@ -98,40 +99,46 @@ HTMLEditor::InsertNodeIntoProperAncestor
               nsIContent& aNode,
               const EditorRawDOMPoint& aPointToInsert,
               SplitAtEdges aSplitAtEdges);
 
 HTMLEditor::HTMLEditor()
   : mCRInParagraphCreatesParagraph(false)
   , mCSSAware(false)
   , mSelectedCellIndex(0)
+  , mHasShownResizers(false)
   , mIsObjectResizingEnabled(true)
   , mIsResizing(false)
   , mPreserveRatio(false)
   , mResizedObjectIsAnImage(false)
   , mIsAbsolutelyPositioningEnabled(true)
   , mResizedObjectIsAbsolutelyPositioned(false)
+  , mHasShownGrabber(false)
   , mGrabberClicked(false)
   , mIsMoving(false)
   , mSnapToGridEnabled(false)
+  , mHasShownInlineTableEditor(false)
   , mIsInlineTableEditingEnabled(true)
   , mOriginalX(0)
   , mOriginalY(0)
   , mResizedObjectX(0)
   , mResizedObjectY(0)
   , mResizedObjectWidth(0)
   , mResizedObjectHeight(0)
   , mResizedObjectMarginLeft(0)
   , mResizedObjectMarginTop(0)
   , mResizedObjectBorderLeft(0)
   , mResizedObjectBorderTop(0)
   , mXIncrementFactor(0)
   , mYIncrementFactor(0)
   , mWidthIncrementFactor(0)
   , mHeightIncrementFactor(0)
+  , mResizerUsedCount(0)
+  , mGrabberUsedCount(0)
+  , mInlineTableEditorUsedCount(0)
   , mInfoXIncrement(20)
   , mInfoYIncrement(20)
   , mPositionedObjectX(0)
   , mPositionedObjectY(0)
   , mPositionedObjectWidth(0)
   , mPositionedObjectHeight(0)
   , mPositionedObjectMarginLeft(0)
   , mPositionedObjectMarginTop(0)
@@ -159,16 +166,41 @@ HTMLEditor::~HTMLEditor()
     if (ps && ps->GetPresContext()) {
       ps->GetPresContext()->SetLinkHandler(mLinkHandler);
     }
   }
 
   RemoveEventListeners();
 
   HideAnonymousEditingUIs();
+
+  Telemetry::Accumulate(
+    Telemetry::HTMLEDITORS_WITH_RESIZERS,
+    mHasShownResizers ? 1 : 0);
+  if (mHasShownResizers) {
+    Telemetry::Accumulate(
+      Telemetry::HTMLEDITORS_WHOSE_RESIZERS_USED_BY_USER,
+      mResizerUsedCount);
+  }
+  Telemetry::Accumulate(
+    Telemetry::HTMLEDITORS_WITH_ABSOLUTE_POSITIONER,
+    mHasShownGrabber ? 1 : 0);
+  if (mHasShownGrabber) {
+    Telemetry::Accumulate(
+      Telemetry::HTMLEDITORS_WHOSE_ABSOLUTE_POSITIONER_USED_BY_USER,
+      mGrabberUsedCount);
+  }
+  Telemetry::Accumulate(
+    Telemetry::HTMLEDITORS_WITH_INLINE_TABLE_EDITOR,
+    mHasShownInlineTableEditor ? 1 : 0);
+  if (mHasShownInlineTableEditor) {
+    Telemetry::Accumulate(
+      Telemetry::HTMLEDITORS_WHOSE_INLINE_TABLE_EDITOR_USED_BY_USER,
+      mInlineTableEditorUsedCount);
+  }
 }
 
 void
 HTMLEditor::HideAnonymousEditingUIs()
 {
   if (mAbsolutelyPositionedObject) {
     HideGrabber();
   }
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -1284,31 +1284,39 @@ protected:
                                     int32_t& aMarginLeft,
                                     int32_t& aMarginTop);
 
   bool IsInObservedSubtree(nsIContent* aChild);
 
   void UpdateRootElement();
 
   // resizing
+  // If the instance has shown resizers at least once, mHasShownResizers is
+  // set to true.
+  bool mHasShownResizers;
   bool mIsObjectResizingEnabled;
   bool mIsResizing;
   bool mPreserveRatio;
   bool mResizedObjectIsAnImage;
 
   // absolute positioning
   bool mIsAbsolutelyPositioningEnabled;
   bool mResizedObjectIsAbsolutelyPositioned;
-
+  // If the instance has shown grabber at least once, mHasShownGrabber is
+  // set to true.
+  bool mHasShownGrabber;
   bool mGrabberClicked;
   bool mIsMoving;
 
   bool mSnapToGridEnabled;
 
   // inline table editing
+  // If the instance has shown inline table editor at least once,
+  // mHasShownInlineTableEditor is set to true.
+  bool mHasShownInlineTableEditor;
   bool mIsInlineTableEditingEnabled;
 
   // resizing
   ManualNACPtr mTopLeftHandle;
   ManualNACPtr mTopHandle;
   ManualNACPtr mTopRightHandle;
   ManualNACPtr mLeftHandle;
   ManualNACPtr mRightHandle;
@@ -1339,16 +1347,22 @@ protected:
   int32_t mResizedObjectBorderLeft;
   int32_t mResizedObjectBorderTop;
 
   int32_t mXIncrementFactor;
   int32_t mYIncrementFactor;
   int32_t mWidthIncrementFactor;
   int32_t mHeightIncrementFactor;
 
+  // When resizers, grabber and/or inline table editor are operated by user
+  // actually, the following counters are increased.
+  uint32_t mResizerUsedCount;
+  uint32_t mGrabberUsedCount;
+  uint32_t mInlineTableEditorUsedCount;
+
   int8_t  mInfoXIncrement;
   int8_t  mInfoYIncrement;
 
   nsresult SetAllResizersPosition();
 
   /**
    * Shows active resizers around an element's frame
    * @param aResizedElement [IN] a DOM Element
--- a/editor/libeditor/HTMLEditorObjectResizer.cpp
+++ b/editor/libeditor/HTMLEditorObjectResizer.cpp
@@ -352,16 +352,18 @@ HTMLEditor::ShowResizersInner(Element& a
   }
   // XXX Even when it failed to add event listener, should we need to set
   //     _moz_resizing attribute?
   aResizedElement.SetAttr(kNameSpaceID_None, nsGkAtoms::_moz_resizing,
                           NS_LITERAL_STRING("true"), true);
 
   MOZ_ASSERT(mResizedObject == &aResizedElement);
 
+  mHasShownResizers = true;
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::HideResizers()
 {
   NS_ENSURE_TRUE(mResizedObject, NS_OK);
 
@@ -528,25 +530,26 @@ HTMLEditor::OnMouseDown(int32_t aClientX
 
   nsAutoString anonclass;
   element->GetAttribute(NS_LITERAL_STRING("_moz_anonclass"), anonclass);
 
   if (anonclass.EqualsLiteral("mozResizer")) {
     // If we have an anonymous element and that element is a resizer,
     // let's start resizing!
     aEvent->PreventDefault();
-
+    mResizerUsedCount++;
     mOriginalX = aClientX;
     mOriginalY = aClientY;
     return StartResizing(aTarget);
   }
 
   if (anonclass.EqualsLiteral("mozGrabber")) {
     // If we have an anonymous element and that element is a grabber,
     // let's start moving the element!
+    mGrabberUsedCount++;
     mOriginalX = aClientX;
     mOriginalY = aClientY;
     return GrabberClicked();
   }
 
   return NS_OK;
 }
 
--- a/editor/libeditor/HTMLInlineTableEditor.cpp
+++ b/editor/libeditor/HTMLInlineTableEditor.cpp
@@ -83,16 +83,19 @@ HTMLEditor::ShowInlineTableEditingUI(Ele
   AddMouseClickListener(mAddColumnBeforeButton);
   AddMouseClickListener(mRemoveColumnButton);
   AddMouseClickListener(mAddColumnAfterButton);
   AddMouseClickListener(mAddRowBeforeButton);
   AddMouseClickListener(mRemoveRowButton);
   AddMouseClickListener(mAddRowAfterButton);
 
   mInlineEditedCell = aCell;
+
+  mHasShownInlineTableEditor = true;
+
   return RefreshInlineTableEditingUI();
 }
 
 nsresult
 HTMLEditor::HideInlineTableEditingUI()
 {
   mInlineEditedCell = nullptr;
 
@@ -154,16 +157,18 @@ HTMLEditor::DoInlineTableEditingAction(c
     DeleteTableRow(1);
 #ifndef DISABLE_TABLE_DELETION
     hideUI = (rowCount == 1);
 #endif
   } else {
     return NS_OK;
   }
 
+  ++mInlineTableEditorUsedCount;
+
   // InsertTableRow might causes reframe
   if (Destroyed()) {
     return NS_OK;
   }
 
   if (hideUI) {
     HideInlineTableEditingUI();
     if (hideResizersWithInlineTableUI) {
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -13804,10 +13804,70 @@
   "PERMISSION_REQUEST_HANDLING_USER_INPUT": {
     "record_in_processes": ["main"],
     "alert_emails": ["jhofmann@mozilla.com"],
     "bug_numbers": [1286118],
     "expires_in_version": "64",
     "kind": "boolean",
     "keyed": true,
     "description": "Permission requests (showing a permission prompt) by whether they were requested from code handling a user input event."
+  },
+  "HTMLEDITORS_WITH_RESIZERS": {
+    "record_in_processes": ["content"],
+    "alert_emails": ["mnakano@mozilla.com"],
+    "bug_numbers": [1452538,1449564],
+    "expires_in_version": "65",
+    "kind": "boolean",
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of HTML editors which has shown object resizers."
+  },
+  "HTMLEDITORS_WHOSE_RESIZERS_USED_BY_USER": {
+    "record_in_processes": ["content"],
+    "alert_emails": ["mnakano@mozilla.com"],
+    "bug_numbers": [1452538,1449564],
+    "expires_in_version": "65",
+    "kind": "linear",
+    "high": 50,
+    "n_buckets": 20,
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of HTML editors whose object resizers are actually used by users."
+  },
+  "HTMLEDITORS_WITH_ABSOLUTE_POSITIONER": {
+    "record_in_processes": ["content"],
+    "alert_emails": ["mnakano@mozilla.com"],
+    "bug_numbers": [1452538,1449564],
+    "expires_in_version": "65",
+    "kind": "boolean",
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of HTML editors which has shown grabber to move absolute positioned elements."
+  },
+  "HTMLEDITORS_WHOSE_ABSOLUTE_POSITIONER_USED_BY_USER": {
+    "record_in_processes": ["content"],
+    "alert_emails": ["mnakano@mozilla.com"],
+    "bug_numbers": [1452538,1449564],
+    "expires_in_version": "65",
+    "kind": "linear",
+    "high": 50,
+    "n_buckets": 20,
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of HTML editors whose grabber to move absolute positioned elements is actually used by users."
+  },
+  "HTMLEDITORS_WITH_INLINE_TABLE_EDITOR": {
+    "record_in_processes": ["content"],
+    "alert_emails": ["mnakano@mozilla.com"],
+    "bug_numbers": [1452538,1449564],
+    "expires_in_version": "65",
+    "kind": "boolean",
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of HTML editors which has shown inline table editing UI."
+  },
+  "HTMLEDITORS_WHOSE_INLINE_TABLE_EDITOR_USED_BY_USER": {
+    "record_in_processes": ["content"],
+    "alert_emails": ["mnakano@mozilla.com"],
+    "bug_numbers": [1452538,1449564],
+    "expires_in_version": "65",
+    "kind": "linear",
+    "high": 50,
+    "n_buckets": 20,
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of HTML editors whose inline table editing UI is actually used by users."
   }
 }