nsCoreUtils.h (13180B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nsCoreUtils_h_ 7 #define nsCoreUtils_h_ 8 9 #include "AttrArray.h" 10 #include "mozilla/EventForwards.h" 11 #include "nsCaseTreatment.h" 12 #include "nsIAccessibleEvent.h" 13 #include "nsIContent.h" 14 #include "mozilla/FlushType.h" 15 #include "mozilla/PresShellForwards.h" 16 17 #include "nsPoint.h" 18 #include "nsTArray.h" 19 #include "Units.h" 20 21 class nsAttrValue; 22 class nsGenericHTMLElement; 23 class nsRange; 24 class nsTreeColumn; 25 class nsIFrame; 26 class nsIDocShell; 27 class nsIWidget; 28 29 namespace mozilla { 30 class PresShell; 31 namespace dom { 32 class Document; 33 class Element; 34 class XULTreeElement; 35 } // namespace dom 36 } // namespace mozilla 37 38 /** 39 * Core utils. 40 */ 41 class nsCoreUtils { 42 public: 43 typedef mozilla::PresShell PresShell; 44 typedef mozilla::dom::Document Document; 45 typedef mozilla::dom::Element Element; 46 47 /** 48 * Return true if the given node is a label of a control. 49 */ 50 static bool IsLabelWithControl(nsIContent* aContent); 51 52 /** 53 * Return true if the given node has registered click, mousedown or mouseup 54 * event listeners. 55 */ 56 static bool HasClickListener(nsIContent* aContent); 57 58 /** 59 * Dispatch click event to XUL tree cell. 60 * 61 * @param aTree [in] tree 62 * @param aRowIndex [in] row index 63 * @param aColumn [in] column object 64 * @param aPseudoElm [in] pseudo element inside the cell, see 65 * XULTreeElement for available values 66 */ 67 MOZ_CAN_RUN_SCRIPT 68 static void DispatchClickEvent(mozilla::dom::XULTreeElement* aTree, 69 int32_t aRowIndex, nsTreeColumn* aColumn, 70 const nsAString& aPseudoElt = u""_ns); 71 72 /** 73 * Send mouse event to the given element. 74 * 75 * @param aMessage [in] an event message (see EventForwards.h) 76 * @param aX [in] x coordinate in dev pixels 77 * @param aY [in] y coordinate in dev pixels 78 * @param aContent [in] the element 79 * @param aFrame [in] frame of the element 80 * @param aPresShell [in] the presshell for the element 81 * @param aRootWidget [in] the root widget of the element 82 */ 83 MOZ_CAN_RUN_SCRIPT 84 static void DispatchMouseEvent(mozilla::EventMessage aMessage, int32_t aX, 85 int32_t aY, nsIContent* aContent, 86 nsIFrame* aFrame, PresShell* aPresShell, 87 nsIWidget* aRootWidget); 88 89 /** 90 * Send a touch event with a single touch point to the given element. 91 * 92 * @param aMessage [in] an event message (see EventForwards.h) 93 * @param aX [in] x coordinate in dev pixels 94 * @param aY [in] y coordinate in dev pixels 95 * @param aContent [in] the element 96 * @param aFrame [in] frame of the element 97 * @param aPresShell [in] the presshell for the element 98 * @param aRootWidget [in] the root widget of the element 99 */ 100 MOZ_CAN_RUN_SCRIPT 101 static void DispatchTouchEvent(mozilla::EventMessage aMessage, int32_t aX, 102 int32_t aY, nsIContent* aContent, 103 nsIFrame* aFrame, PresShell* aPresShell, 104 nsIWidget* aRootWidget); 105 106 /** 107 * Return an accesskey registered on the given element by 108 * EventStateManager or 0 if there is no registered accesskey. 109 * 110 * @param aContent - the given element. 111 */ 112 static uint32_t GetAccessKeyFor(nsIContent* aContent); 113 114 /** 115 * Return DOM element related with the given node, i.e. 116 * a) itself if it is DOM element 117 * b) parent element if it is text node 118 * c) otherwise nullptr 119 * 120 * @param aNode [in] the given DOM node 121 */ 122 static nsIContent* GetDOMElementFor(nsIContent* aContent); 123 124 /** 125 * Return DOM node for the given DOM point. 126 */ 127 static nsINode* GetDOMNodeFromDOMPoint(nsINode* aNode, uint32_t aOffset); 128 129 /** 130 * Is the first passed in node an ancestor of the second? 131 * Note: A node is not considered to be the ancestor of itself. 132 * 133 * @param aPossibleAncestorNode [in] node to test for ancestor-ness of 134 * aPossibleDescendantNode 135 * @param aPossibleDescendantNode [in] node to test for descendant-ness of 136 * aPossibleAncestorNode 137 * @param aRootNode [in, optional] the root node that search 138 * search should be performed within 139 * @return true if aPossibleAncestorNode is an ancestor of 140 * aPossibleDescendantNode 141 */ 142 static bool IsAncestorOf(nsINode* aPossibleAncestorNode, 143 nsINode* aPossibleDescendantNode, 144 nsINode* aRootNode = nullptr); 145 146 /** 147 * Helper method to scroll range into view, used for implementation of 148 * nsIAccessibleText::scrollSubstringTo(). 149 * 150 * @param aFrame the frame for accessible the range belongs to. 151 * @param aRange the range to scroll to 152 * @param aScrollType the place a range should be scrolled to 153 */ 154 MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult ScrollSubstringTo( 155 nsIFrame* aFrame, nsRange* aRange, uint32_t aScrollType); 156 157 /** Helper method to scroll range into view, used for implementation of 158 * nsIAccessibleText::scrollSubstringTo[Point](). 159 * 160 * @param aFrame the frame for accessible the range belongs to. 161 * @param aRange the range to scroll to 162 * @param aVertical how to align vertically, specified in percents, and 163 * when. 164 * @param aHorizontal how to align horizontally, specified in percents, 165 * and when. 166 */ 167 MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult ScrollSubstringTo( 168 nsIFrame* aFrame, nsRange* aRange, mozilla::ScrollAxis aVertical, 169 mozilla::ScrollAxis aHorizontal); 170 171 /** 172 * Scrolls the given frame to the point, used for implememntation of 173 * nsIAccessible::scrollToPoint and nsIAccessibleText::scrollSubstringToPoint. 174 * 175 * @param aScrollContainerFrame the scroll container frame 176 * @param aFrame the frame to scroll 177 * @param aPoint the point scroll to (in dev pixels) 178 */ 179 static void ScrollFrameToPoint(nsIFrame* aScrollContainerFrame, 180 nsIFrame* aFrame, 181 const mozilla::LayoutDeviceIntPoint& aPoint); 182 183 /** 184 * Converts scroll type constant defined in nsIAccessibleScrollType to 185 * vertical and horizontal parameters. 186 */ 187 static void ConvertScrollTypeToPercents(uint32_t aScrollType, 188 mozilla::ScrollAxis* aVertical, 189 mozilla::ScrollAxis* aHorizontal); 190 191 /** 192 * Return document shell for the given DOM node. 193 */ 194 static already_AddRefed<nsIDocShell> GetDocShellFor(nsINode* aNode); 195 196 /** 197 * Return true if the given document is root document. 198 */ 199 static bool IsRootDocument(Document* aDocument); 200 201 /** 202 * Return true if the given document is a top level content document in this 203 * process. 204 * This will be true for tab documents and out-of-process iframe documents. 205 */ 206 static bool IsTopLevelContentDocInProcess(Document* aDocumentNode); 207 208 /** 209 * Return true if the given document is an error page. 210 */ 211 static bool IsErrorPage(Document* aDocument); 212 213 /** 214 * Return presShell for the document containing the given DOM node. 215 */ 216 static PresShell* GetPresShellFor(nsINode* aNode); 217 218 /** 219 * Get the ID for an element, in some types of XML this may not be the ID 220 * attribute 221 * @param aContent Node to get the ID for 222 * @param aID Where to put ID string 223 * @return true if there is an ID set for this node 224 */ 225 static bool GetID(nsIContent* aContent, nsAString& aID); 226 227 /** 228 * Convert attribute value of the given node to positive integer. If no 229 * attribute or wrong value then false is returned. 230 */ 231 static bool GetUIntAttr(nsIContent* aContent, nsAtom* aAttr, int32_t* aUInt); 232 static bool GetUIntAttrValue(const nsAttrValue* aVal, int32_t* aUInt); 233 234 /** 235 * Returns language for the given node. 236 * 237 * @param aContent [in] the given node 238 * @param aRootContent [in] container of the given node 239 * @param aLanguage [out] language 240 */ 241 static void GetLanguageFor(nsIContent* aContent, nsIContent* aRootContent, 242 nsAString& aLanguage); 243 244 /** 245 * Return tree from any levels DOMNode under the XUL tree. 246 */ 247 static mozilla::dom::XULTreeElement* GetTree(nsIContent* aContent); 248 249 /** 250 * Return first sensible column for the given tree box object. 251 */ 252 static already_AddRefed<nsTreeColumn> GetFirstSensibleColumn( 253 mozilla::dom::XULTreeElement* aTree, 254 mozilla::FlushType = mozilla::FlushType::Frames); 255 256 /** 257 * Return sensible columns count for the given tree box object. 258 */ 259 static uint32_t GetSensibleColumnCount(mozilla::dom::XULTreeElement* aTree); 260 261 /** 262 * Return sensible column at the given index for the given tree box object. 263 */ 264 static already_AddRefed<nsTreeColumn> GetSensibleColumnAt( 265 mozilla::dom::XULTreeElement* aTree, uint32_t aIndex); 266 267 /** 268 * Return next sensible column for the given column. 269 */ 270 static already_AddRefed<nsTreeColumn> GetNextSensibleColumn( 271 nsTreeColumn* aColumn); 272 273 /** 274 * Return previous sensible column for the given column. 275 */ 276 static already_AddRefed<nsTreeColumn> GetPreviousSensibleColumn( 277 nsTreeColumn* aColumn); 278 279 /** 280 * Return true if the given column is hidden (i.e. not sensible). 281 */ 282 static bool IsColumnHidden(nsTreeColumn* aColumn); 283 284 /** 285 * Scroll content into view. 286 */ 287 MOZ_CAN_RUN_SCRIPT 288 static void ScrollTo(PresShell* aPresShell, nsIContent* aContent, 289 uint32_t aScrollType); 290 291 /** 292 * Return true if the given node is table header element. 293 */ 294 static bool IsHTMLTableHeader(nsIContent* aContent); 295 296 /** 297 * Returns true if the given string is empty or contains whitespace symbols 298 * only. In contrast to nsWhitespaceTokenizer class it takes into account 299 * non-breaking space (0xa0). 300 */ 301 static bool IsWhitespaceString(const nsAString& aString); 302 303 /** 304 * Returns true if the given character is whitespace symbol. 305 */ 306 static bool IsWhitespace(char16_t aChar) { 307 return aChar == ' ' || aChar == '\n' || aChar == '\r' || aChar == '\t' || 308 aChar == 0xa0; 309 } 310 311 /* 312 * Return true if there are any observers of accessible events. 313 */ 314 static bool AccEventObserversExist(); 315 316 /** 317 * Notify accessible event observers of an event. 318 */ 319 static void DispatchAccEvent(RefPtr<nsIAccessibleEvent> aEvent); 320 321 static bool IsDisplayContents(nsIContent* aContent); 322 static bool CanCreateAccessibleWithoutFrame(nsIContent* aContent); 323 324 /** 325 * Return whether the document and all its in-process ancestors are visible in 326 * the sense of pageshow / hide. 327 */ 328 static bool IsDocumentVisibleConsideringInProcessAncestors( 329 const Document* aDocument); 330 331 /** 332 * Return true if `aDescendant` is a descendant of any of `aStartAncestor`'s 333 * shadow-including ancestors. 334 */ 335 static bool IsDescendantOfAnyShadowIncludingAncestor(nsINode* aDescendant, 336 nsINode* aStartAncestor); 337 338 static Element* GetAriaActiveDescendantElement(Element* aElement); 339 340 /** 341 * Return true if the given text frame is 0 width whitespace before a hard 342 * line break. This is not visible and is semantically irrelevant. This can 343 * happen if there is whitespace before an invisible element at the end of a 344 * block. For example: 345 * <div><span>a</span> <span hidden>b</span></div> 346 * This results in a text node for "a" and a text node for " ". This function 347 * will return true for the latter node. 348 */ 349 static bool IsTrimmedWhitespaceBeforeHardLineBreak(nsIFrame* aFrame); 350 351 static bool IsPseudoElement(nsIContent* aContent) { 352 return aContent->IsGeneratedContentContainerForBefore() || 353 aContent->IsGeneratedContentContainerForAfter() || 354 aContent->IsGeneratedContentContainerForMarker(); 355 } 356 357 /** 358 * Return the anchor frame for the given CSS positioned frame, or null if: 359 * 1. there is none, 360 * 2. there is more than one anchor, 361 * 3. or, there is one or more anchor used for sizing/margin only. 362 */ 363 static const nsIFrame* GetAnchorForPositionedFrame( 364 const PresShell* aPresShell, const nsIFrame* aPositionedFrame); 365 366 /** 367 * Return the CSS positioned frame for the given anchor frame, or null if: 368 * 1. there is none, 369 * 2. the anchor has more than one positioned frame, 370 * 3. or, there is one or more positioned frame using this anchor for 371 * sizing/margin only. 372 */ 373 static nsIFrame* GetPositionedFrameForAnchor(const PresShell* aPresShell, 374 const nsIFrame* aAnchorFrame); 375 }; 376 377 #endif