accessible/src/base/nsCoreUtils.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsCoreUtils.h"
michael@0 7
michael@0 8 #include "nsIAccessibleTypes.h"
michael@0 9
michael@0 10 #include "nsIBaseWindow.h"
michael@0 11 #include "nsIDocShellTreeOwner.h"
michael@0 12 #include "nsIDocument.h"
michael@0 13 #include "nsIDOMHTMLDocument.h"
michael@0 14 #include "nsIDOMHTMLElement.h"
michael@0 15 #include "nsRange.h"
michael@0 16 #include "nsIBoxObject.h"
michael@0 17 #include "nsIDOMXULElement.h"
michael@0 18 #include "nsIDocShell.h"
michael@0 19 #include "nsIPresShell.h"
michael@0 20 #include "nsPresContext.h"
michael@0 21 #include "nsIScrollableFrame.h"
michael@0 22 #include "nsISelectionPrivate.h"
michael@0 23 #include "nsISelectionController.h"
michael@0 24 #include "mozilla/dom/TouchEvent.h"
michael@0 25 #include "mozilla/EventListenerManager.h"
michael@0 26 #include "mozilla/EventStateManager.h"
michael@0 27 #include "mozilla/MouseEvents.h"
michael@0 28 #include "mozilla/TouchEvents.h"
michael@0 29 #include "nsView.h"
michael@0 30 #include "nsGkAtoms.h"
michael@0 31
michael@0 32 #include "nsComponentManagerUtils.h"
michael@0 33
michael@0 34 #include "nsITreeBoxObject.h"
michael@0 35 #include "nsITreeColumns.h"
michael@0 36 #include "mozilla/dom/Element.h"
michael@0 37
michael@0 38 using namespace mozilla;
michael@0 39
michael@0 40 ////////////////////////////////////////////////////////////////////////////////
michael@0 41 // nsCoreUtils
michael@0 42 ////////////////////////////////////////////////////////////////////////////////
michael@0 43
michael@0 44 bool
michael@0 45 nsCoreUtils::HasClickListener(nsIContent *aContent)
michael@0 46 {
michael@0 47 NS_ENSURE_TRUE(aContent, false);
michael@0 48 EventListenerManager* listenerManager =
michael@0 49 aContent->GetExistingListenerManager();
michael@0 50
michael@0 51 return listenerManager &&
michael@0 52 (listenerManager->HasListenersFor(nsGkAtoms::onclick) ||
michael@0 53 listenerManager->HasListenersFor(nsGkAtoms::onmousedown) ||
michael@0 54 listenerManager->HasListenersFor(nsGkAtoms::onmouseup));
michael@0 55 }
michael@0 56
michael@0 57 void
michael@0 58 nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
michael@0 59 int32_t aRowIndex, nsITreeColumn *aColumn,
michael@0 60 const nsCString& aPseudoElt)
michael@0 61 {
michael@0 62 nsCOMPtr<nsIDOMElement> tcElm;
michael@0 63 aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
michael@0 64 if (!tcElm)
michael@0 65 return;
michael@0 66
michael@0 67 nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
michael@0 68 nsIDocument *document = tcContent->GetCurrentDoc();
michael@0 69 if (!document)
michael@0 70 return;
michael@0 71
michael@0 72 nsCOMPtr<nsIPresShell> presShell = document->GetShell();
michael@0 73 if (!presShell)
michael@0 74 return;
michael@0 75
michael@0 76 // Ensure row is visible.
michael@0 77 aTreeBoxObj->EnsureRowIsVisible(aRowIndex);
michael@0 78
michael@0 79 // Calculate x and y coordinates.
michael@0 80 int32_t x = 0, y = 0, width = 0, height = 0;
michael@0 81 nsresult rv = aTreeBoxObj->GetCoordsForCellItem(aRowIndex, aColumn,
michael@0 82 aPseudoElt,
michael@0 83 &x, &y, &width, &height);
michael@0 84 if (NS_FAILED(rv))
michael@0 85 return;
michael@0 86
michael@0 87 nsCOMPtr<nsIDOMXULElement> tcXULElm(do_QueryInterface(tcElm));
michael@0 88 nsCOMPtr<nsIBoxObject> tcBoxObj;
michael@0 89 tcXULElm->GetBoxObject(getter_AddRefs(tcBoxObj));
michael@0 90
michael@0 91 int32_t tcX = 0;
michael@0 92 tcBoxObj->GetX(&tcX);
michael@0 93
michael@0 94 int32_t tcY = 0;
michael@0 95 tcBoxObj->GetY(&tcY);
michael@0 96
michael@0 97 // Dispatch mouse events.
michael@0 98 nsWeakFrame tcFrame = tcContent->GetPrimaryFrame();
michael@0 99 nsIFrame* rootFrame = presShell->GetRootFrame();
michael@0 100
michael@0 101 nsPoint offset;
michael@0 102 nsIWidget *rootWidget =
michael@0 103 rootFrame->GetViewExternal()->GetNearestWidget(&offset);
michael@0 104
michael@0 105 nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
michael@0 106
michael@0 107 int32_t cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
michael@0 108 presContext->AppUnitsToDevPixels(offset.x);
michael@0 109 int32_t cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
michael@0 110 presContext->AppUnitsToDevPixels(offset.y);
michael@0 111
michael@0 112 // XUL is just desktop, so there is no real reason for senfing touch events.
michael@0 113 DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, cnvdX, cnvdY,
michael@0 114 tcContent, tcFrame, presShell, rootWidget);
michael@0 115
michael@0 116 DispatchMouseEvent(NS_MOUSE_BUTTON_UP, cnvdX, cnvdY,
michael@0 117 tcContent, tcFrame, presShell, rootWidget);
michael@0 118 }
michael@0 119
michael@0 120 void
michael@0 121 nsCoreUtils::DispatchMouseEvent(uint32_t aEventType, int32_t aX, int32_t aY,
michael@0 122 nsIContent *aContent, nsIFrame *aFrame,
michael@0 123 nsIPresShell *aPresShell, nsIWidget *aRootWidget)
michael@0 124 {
michael@0 125 WidgetMouseEvent event(true, aEventType, aRootWidget,
michael@0 126 WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
michael@0 127
michael@0 128 event.refPoint = LayoutDeviceIntPoint(aX, aY);
michael@0 129
michael@0 130 event.clickCount = 1;
michael@0 131 event.button = WidgetMouseEvent::eLeftButton;
michael@0 132 event.time = PR_IntervalNow();
michael@0 133 event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
michael@0 134
michael@0 135 nsEventStatus status = nsEventStatus_eIgnore;
michael@0 136 aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
michael@0 137 }
michael@0 138
michael@0 139 void
michael@0 140 nsCoreUtils::DispatchTouchEvent(uint32_t aEventType, int32_t aX, int32_t aY,
michael@0 141 nsIContent* aContent, nsIFrame* aFrame,
michael@0 142 nsIPresShell* aPresShell, nsIWidget* aRootWidget)
michael@0 143 {
michael@0 144 if (!dom::TouchEvent::PrefEnabled())
michael@0 145 return;
michael@0 146
michael@0 147 WidgetTouchEvent event(true, aEventType, aRootWidget);
michael@0 148
michael@0 149 event.time = PR_IntervalNow();
michael@0 150
michael@0 151 // XXX: Touch has an identifier of -1 to hint that it is synthesized.
michael@0 152 nsRefPtr<dom::Touch> t = new dom::Touch(-1, nsIntPoint(aX, aY),
michael@0 153 nsIntPoint(1, 1), 0.0f, 1.0f);
michael@0 154 t->SetTarget(aContent);
michael@0 155 event.touches.AppendElement(t);
michael@0 156 nsEventStatus status = nsEventStatus_eIgnore;
michael@0 157 aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
michael@0 158 }
michael@0 159
michael@0 160 uint32_t
michael@0 161 nsCoreUtils::GetAccessKeyFor(nsIContent* aContent)
michael@0 162 {
michael@0 163 // Accesskeys are registered by @accesskey attribute only. At first check
michael@0 164 // whether it is presented on the given element to avoid the slow
michael@0 165 // EventStateManager::GetRegisteredAccessKey() method.
michael@0 166 if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
michael@0 167 return 0;
michael@0 168
michael@0 169 nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
michael@0 170 if (!presShell)
michael@0 171 return 0;
michael@0 172
michael@0 173 nsPresContext *presContext = presShell->GetPresContext();
michael@0 174 if (!presContext)
michael@0 175 return 0;
michael@0 176
michael@0 177 EventStateManager *esm = presContext->EventStateManager();
michael@0 178 if (!esm)
michael@0 179 return 0;
michael@0 180
michael@0 181 return esm->GetRegisteredAccessKey(aContent);
michael@0 182 }
michael@0 183
michael@0 184 nsIContent *
michael@0 185 nsCoreUtils::GetDOMElementFor(nsIContent *aContent)
michael@0 186 {
michael@0 187 if (aContent->IsElement())
michael@0 188 return aContent;
michael@0 189
michael@0 190 if (aContent->IsNodeOfType(nsINode::eTEXT))
michael@0 191 return aContent->GetFlattenedTreeParent();
michael@0 192
michael@0 193 return nullptr;
michael@0 194 }
michael@0 195
michael@0 196 nsINode *
michael@0 197 nsCoreUtils::GetDOMNodeFromDOMPoint(nsINode *aNode, uint32_t aOffset)
michael@0 198 {
michael@0 199 if (aNode && aNode->IsElement()) {
michael@0 200 uint32_t childCount = aNode->GetChildCount();
michael@0 201 NS_ASSERTION(aOffset <= childCount, "Wrong offset of the DOM point!");
michael@0 202
michael@0 203 // The offset can be after last child of container node that means DOM point
michael@0 204 // is placed immediately after the last child. In this case use the DOM node
michael@0 205 // from the given DOM point is used as result node.
michael@0 206 if (aOffset != childCount)
michael@0 207 return aNode->GetChildAt(aOffset);
michael@0 208 }
michael@0 209
michael@0 210 return aNode;
michael@0 211 }
michael@0 212
michael@0 213 nsIContent*
michael@0 214 nsCoreUtils::GetRoleContent(nsINode *aNode)
michael@0 215 {
michael@0 216 nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
michael@0 217 if (!content) {
michael@0 218 nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
michael@0 219 if (doc) {
michael@0 220 nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(aNode));
michael@0 221 if (htmlDoc) {
michael@0 222 nsCOMPtr<nsIDOMHTMLElement> bodyElement;
michael@0 223 htmlDoc->GetBody(getter_AddRefs(bodyElement));
michael@0 224 content = do_QueryInterface(bodyElement);
michael@0 225 }
michael@0 226 else {
michael@0 227 return doc->GetDocumentElement();
michael@0 228 }
michael@0 229 }
michael@0 230 }
michael@0 231
michael@0 232 return content;
michael@0 233 }
michael@0 234
michael@0 235 bool
michael@0 236 nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
michael@0 237 nsINode *aPossibleDescendantNode,
michael@0 238 nsINode *aRootNode)
michael@0 239 {
michael@0 240 NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, false);
michael@0 241
michael@0 242 nsINode *parentNode = aPossibleDescendantNode;
michael@0 243 while ((parentNode = parentNode->GetParentNode()) &&
michael@0 244 parentNode != aRootNode) {
michael@0 245 if (parentNode == aPossibleAncestorNode)
michael@0 246 return true;
michael@0 247 }
michael@0 248
michael@0 249 return false;
michael@0 250 }
michael@0 251
michael@0 252 nsresult
michael@0 253 nsCoreUtils::ScrollSubstringTo(nsIFrame* aFrame, nsRange* aRange,
michael@0 254 uint32_t aScrollType)
michael@0 255 {
michael@0 256 nsIPresShell::ScrollAxis vertical, horizontal;
michael@0 257 ConvertScrollTypeToPercents(aScrollType, &vertical, &horizontal);
michael@0 258
michael@0 259 return ScrollSubstringTo(aFrame, aRange, vertical, horizontal);
michael@0 260 }
michael@0 261
michael@0 262 nsresult
michael@0 263 nsCoreUtils::ScrollSubstringTo(nsIFrame* aFrame, nsRange* aRange,
michael@0 264 nsIPresShell::ScrollAxis aVertical,
michael@0 265 nsIPresShell::ScrollAxis aHorizontal)
michael@0 266 {
michael@0 267 if (!aFrame)
michael@0 268 return NS_ERROR_FAILURE;
michael@0 269
michael@0 270 nsPresContext *presContext = aFrame->PresContext();
michael@0 271
michael@0 272 nsCOMPtr<nsISelectionController> selCon;
michael@0 273 aFrame->GetSelectionController(presContext, getter_AddRefs(selCon));
michael@0 274 NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
michael@0 275
michael@0 276 nsCOMPtr<nsISelection> selection;
michael@0 277 selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY,
michael@0 278 getter_AddRefs(selection));
michael@0 279
michael@0 280 nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(selection));
michael@0 281 selection->RemoveAllRanges();
michael@0 282 selection->AddRange(aRange);
michael@0 283
michael@0 284 privSel->ScrollIntoViewInternal(
michael@0 285 nsISelectionController::SELECTION_ANCHOR_REGION,
michael@0 286 true, aVertical, aHorizontal);
michael@0 287
michael@0 288 selection->CollapseToStart();
michael@0 289
michael@0 290 return NS_OK;
michael@0 291 }
michael@0 292
michael@0 293 void
michael@0 294 nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
michael@0 295 nsIFrame *aFrame,
michael@0 296 const nsIntPoint& aPoint)
michael@0 297 {
michael@0 298 nsIScrollableFrame* scrollableFrame = do_QueryFrame(aScrollableFrame);
michael@0 299 if (!scrollableFrame)
michael@0 300 return;
michael@0 301
michael@0 302 nsPoint point =
michael@0 303 aPoint.ToAppUnits(aFrame->PresContext()->AppUnitsPerDevPixel());
michael@0 304 nsRect frameRect = aFrame->GetScreenRectInAppUnits();
michael@0 305 nsPoint deltaPoint(point.x - frameRect.x, point.y - frameRect.y);
michael@0 306
michael@0 307 nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
michael@0 308 scrollPoint -= deltaPoint;
michael@0 309
michael@0 310 scrollableFrame->ScrollTo(scrollPoint, nsIScrollableFrame::INSTANT);
michael@0 311 }
michael@0 312
michael@0 313 void
michael@0 314 nsCoreUtils::ConvertScrollTypeToPercents(uint32_t aScrollType,
michael@0 315 nsIPresShell::ScrollAxis *aVertical,
michael@0 316 nsIPresShell::ScrollAxis *aHorizontal)
michael@0 317 {
michael@0 318 int16_t whereY, whereX;
michael@0 319 nsIPresShell::WhenToScroll whenY, whenX;
michael@0 320 switch (aScrollType)
michael@0 321 {
michael@0 322 case nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT:
michael@0 323 whereY = nsIPresShell::SCROLL_TOP;
michael@0 324 whenY = nsIPresShell::SCROLL_ALWAYS;
michael@0 325 whereX = nsIPresShell::SCROLL_LEFT;
michael@0 326 whenX = nsIPresShell::SCROLL_ALWAYS;
michael@0 327 break;
michael@0 328 case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT:
michael@0 329 whereY = nsIPresShell::SCROLL_BOTTOM;
michael@0 330 whenY = nsIPresShell::SCROLL_ALWAYS;
michael@0 331 whereX = nsIPresShell::SCROLL_RIGHT;
michael@0 332 whenX = nsIPresShell::SCROLL_ALWAYS;
michael@0 333 break;
michael@0 334 case nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE:
michael@0 335 whereY = nsIPresShell::SCROLL_TOP;
michael@0 336 whenY = nsIPresShell::SCROLL_ALWAYS;
michael@0 337 whereX = nsIPresShell::SCROLL_MINIMUM;
michael@0 338 whenX = nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
michael@0 339 break;
michael@0 340 case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_EDGE:
michael@0 341 whereY = nsIPresShell::SCROLL_BOTTOM;
michael@0 342 whenY = nsIPresShell::SCROLL_ALWAYS;
michael@0 343 whereX = nsIPresShell::SCROLL_MINIMUM;
michael@0 344 whenX = nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
michael@0 345 break;
michael@0 346 case nsIAccessibleScrollType::SCROLL_TYPE_LEFT_EDGE:
michael@0 347 whereY = nsIPresShell::SCROLL_MINIMUM;
michael@0 348 whenY = nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
michael@0 349 whereX = nsIPresShell::SCROLL_LEFT;
michael@0 350 whenX = nsIPresShell::SCROLL_ALWAYS;
michael@0 351 break;
michael@0 352 case nsIAccessibleScrollType::SCROLL_TYPE_RIGHT_EDGE:
michael@0 353 whereY = nsIPresShell::SCROLL_MINIMUM;
michael@0 354 whenY = nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
michael@0 355 whereX = nsIPresShell::SCROLL_RIGHT;
michael@0 356 whenX = nsIPresShell::SCROLL_ALWAYS;
michael@0 357 break;
michael@0 358 default:
michael@0 359 whereY = nsIPresShell::SCROLL_MINIMUM;
michael@0 360 whenY = nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
michael@0 361 whereX = nsIPresShell::SCROLL_MINIMUM;
michael@0 362 whenX = nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
michael@0 363 }
michael@0 364 *aVertical = nsIPresShell::ScrollAxis(whereY, whenY);
michael@0 365 *aHorizontal = nsIPresShell::ScrollAxis(whereX, whenX);
michael@0 366 }
michael@0 367
michael@0 368 nsIntPoint
michael@0 369 nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
michael@0 370 {
michael@0 371 nsIntPoint coords(0, 0);
michael@0 372 nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellFor(aNode));
michael@0 373 if (!treeItem)
michael@0 374 return coords;
michael@0 375
michael@0 376 nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
michael@0 377 treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
michael@0 378 if (!treeOwner)
michael@0 379 return coords;
michael@0 380
michael@0 381 nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(treeOwner);
michael@0 382 if (baseWindow)
michael@0 383 baseWindow->GetPosition(&coords.x, &coords.y); // in device pixels
michael@0 384
michael@0 385 return coords;
michael@0 386 }
michael@0 387
michael@0 388 already_AddRefed<nsIDocShell>
michael@0 389 nsCoreUtils::GetDocShellFor(nsINode *aNode)
michael@0 390 {
michael@0 391 if (!aNode)
michael@0 392 return nullptr;
michael@0 393
michael@0 394 nsCOMPtr<nsIDocShell> docShell = aNode->OwnerDoc()->GetDocShell();
michael@0 395 return docShell.forget();
michael@0 396 }
michael@0 397
michael@0 398 bool
michael@0 399 nsCoreUtils::IsRootDocument(nsIDocument *aDocument)
michael@0 400 {
michael@0 401 nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aDocument->GetDocShell();
michael@0 402 NS_ASSERTION(docShellTreeItem, "No document shell for document!");
michael@0 403
michael@0 404 nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
michael@0 405 docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
michael@0 406
michael@0 407 return !parentTreeItem;
michael@0 408 }
michael@0 409
michael@0 410 bool
michael@0 411 nsCoreUtils::IsContentDocument(nsIDocument *aDocument)
michael@0 412 {
michael@0 413 nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aDocument->GetDocShell();
michael@0 414 NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!");
michael@0 415
michael@0 416 return (docShellTreeItem->ItemType() == nsIDocShellTreeItem::typeContent);
michael@0 417 }
michael@0 418
michael@0 419 bool
michael@0 420 nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode)
michael@0 421 {
michael@0 422 nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell());
michael@0 423
michael@0 424 nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
michael@0 425 treeItem->GetParent(getter_AddRefs(parentTreeItem));
michael@0 426
michael@0 427 // Tab document running in own process doesn't have parent.
michael@0 428 if (XRE_GetProcessType() == GeckoProcessType_Content)
michael@0 429 return !parentTreeItem;
michael@0 430
michael@0 431 // Parent of docshell for tab document running in chrome process is root.
michael@0 432 nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
michael@0 433 treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
michael@0 434
michael@0 435 return parentTreeItem == rootTreeItem;
michael@0 436 }
michael@0 437
michael@0 438 bool
michael@0 439 nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
michael@0 440 {
michael@0 441 nsIURI *uri = aDocument->GetDocumentURI();
michael@0 442 bool isAboutScheme = false;
michael@0 443 uri->SchemeIs("about", &isAboutScheme);
michael@0 444 if (!isAboutScheme)
michael@0 445 return false;
michael@0 446
michael@0 447 nsAutoCString path;
michael@0 448 uri->GetPath(path);
michael@0 449
michael@0 450 NS_NAMED_LITERAL_CSTRING(neterror, "neterror");
michael@0 451 NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
michael@0 452
michael@0 453 return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
michael@0 454 }
michael@0 455
michael@0 456 bool
michael@0 457 nsCoreUtils::GetID(nsIContent *aContent, nsAString& aID)
michael@0 458 {
michael@0 459 nsIAtom *idAttribute = aContent->GetIDAttributeName();
michael@0 460 return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : false;
michael@0 461 }
michael@0 462
michael@0 463 bool
michael@0 464 nsCoreUtils::GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr, int32_t *aUInt)
michael@0 465 {
michael@0 466 nsAutoString value;
michael@0 467 aContent->GetAttr(kNameSpaceID_None, aAttr, value);
michael@0 468 if (!value.IsEmpty()) {
michael@0 469 nsresult error = NS_OK;
michael@0 470 int32_t integer = value.ToInteger(&error);
michael@0 471 if (NS_SUCCEEDED(error) && integer > 0) {
michael@0 472 *aUInt = integer;
michael@0 473 return true;
michael@0 474 }
michael@0 475 }
michael@0 476
michael@0 477 return false;
michael@0 478 }
michael@0 479
michael@0 480 void
michael@0 481 nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
michael@0 482 nsAString& aLanguage)
michael@0 483 {
michael@0 484 aLanguage.Truncate();
michael@0 485
michael@0 486 nsIContent *walkUp = aContent;
michael@0 487 while (walkUp && walkUp != aRootContent &&
michael@0 488 !walkUp->GetAttr(kNameSpaceID_None, nsGkAtoms::lang, aLanguage))
michael@0 489 walkUp = walkUp->GetParent();
michael@0 490 }
michael@0 491
michael@0 492 already_AddRefed<nsIBoxObject>
michael@0 493 nsCoreUtils::GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj)
michael@0 494 {
michael@0 495 nsCOMPtr<nsIDOMElement> tcElm;
michael@0 496 aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
michael@0 497 nsCOMPtr<nsIDOMXULElement> tcXULElm(do_QueryInterface(tcElm));
michael@0 498 if (!tcXULElm)
michael@0 499 return nullptr;
michael@0 500
michael@0 501 nsCOMPtr<nsIBoxObject> boxObj;
michael@0 502 tcXULElm->GetBoxObject(getter_AddRefs(boxObj));
michael@0 503 return boxObj.forget();
michael@0 504 }
michael@0 505
michael@0 506 already_AddRefed<nsITreeBoxObject>
michael@0 507 nsCoreUtils::GetTreeBoxObject(nsIContent *aContent)
michael@0 508 {
michael@0 509 // Find DOMNode's parents recursively until reach the <tree> tag
michael@0 510 nsIContent* currentContent = aContent;
michael@0 511 while (currentContent) {
michael@0 512 if (currentContent->NodeInfo()->Equals(nsGkAtoms::tree,
michael@0 513 kNameSpaceID_XUL)) {
michael@0 514 // We will get the nsITreeBoxObject from the tree node
michael@0 515 nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(currentContent));
michael@0 516 if (xulElement) {
michael@0 517 nsCOMPtr<nsIBoxObject> box;
michael@0 518 xulElement->GetBoxObject(getter_AddRefs(box));
michael@0 519 nsCOMPtr<nsITreeBoxObject> treeBox(do_QueryInterface(box));
michael@0 520 if (treeBox)
michael@0 521 return treeBox.forget();
michael@0 522 }
michael@0 523 }
michael@0 524 currentContent = currentContent->GetFlattenedTreeParent();
michael@0 525 }
michael@0 526
michael@0 527 return nullptr;
michael@0 528 }
michael@0 529
michael@0 530 already_AddRefed<nsITreeColumn>
michael@0 531 nsCoreUtils::GetFirstSensibleColumn(nsITreeBoxObject *aTree)
michael@0 532 {
michael@0 533 nsCOMPtr<nsITreeColumns> cols;
michael@0 534 aTree->GetColumns(getter_AddRefs(cols));
michael@0 535 if (!cols)
michael@0 536 return nullptr;
michael@0 537
michael@0 538 nsCOMPtr<nsITreeColumn> column;
michael@0 539 cols->GetFirstColumn(getter_AddRefs(column));
michael@0 540 if (column && IsColumnHidden(column))
michael@0 541 return GetNextSensibleColumn(column);
michael@0 542
michael@0 543 return column.forget();
michael@0 544 }
michael@0 545
michael@0 546 uint32_t
michael@0 547 nsCoreUtils::GetSensibleColumnCount(nsITreeBoxObject *aTree)
michael@0 548 {
michael@0 549 uint32_t count = 0;
michael@0 550
michael@0 551 nsCOMPtr<nsITreeColumns> cols;
michael@0 552 aTree->GetColumns(getter_AddRefs(cols));
michael@0 553 if (!cols)
michael@0 554 return count;
michael@0 555
michael@0 556 nsCOMPtr<nsITreeColumn> column;
michael@0 557 cols->GetFirstColumn(getter_AddRefs(column));
michael@0 558
michael@0 559 while (column) {
michael@0 560 if (!IsColumnHidden(column))
michael@0 561 count++;
michael@0 562
michael@0 563 nsCOMPtr<nsITreeColumn> nextColumn;
michael@0 564 column->GetNext(getter_AddRefs(nextColumn));
michael@0 565 column.swap(nextColumn);
michael@0 566 }
michael@0 567
michael@0 568 return count;
michael@0 569 }
michael@0 570
michael@0 571 already_AddRefed<nsITreeColumn>
michael@0 572 nsCoreUtils::GetSensibleColumnAt(nsITreeBoxObject *aTree, uint32_t aIndex)
michael@0 573 {
michael@0 574 uint32_t idx = aIndex;
michael@0 575
michael@0 576 nsCOMPtr<nsITreeColumn> column = GetFirstSensibleColumn(aTree);
michael@0 577 while (column) {
michael@0 578 if (idx == 0)
michael@0 579 return column.forget();
michael@0 580
michael@0 581 idx--;
michael@0 582 column = GetNextSensibleColumn(column);
michael@0 583 }
michael@0 584
michael@0 585 return nullptr;
michael@0 586 }
michael@0 587
michael@0 588 already_AddRefed<nsITreeColumn>
michael@0 589 nsCoreUtils::GetNextSensibleColumn(nsITreeColumn *aColumn)
michael@0 590 {
michael@0 591 nsCOMPtr<nsITreeColumn> nextColumn;
michael@0 592 aColumn->GetNext(getter_AddRefs(nextColumn));
michael@0 593
michael@0 594 while (nextColumn && IsColumnHidden(nextColumn)) {
michael@0 595 nsCOMPtr<nsITreeColumn> tempColumn;
michael@0 596 nextColumn->GetNext(getter_AddRefs(tempColumn));
michael@0 597 nextColumn.swap(tempColumn);
michael@0 598 }
michael@0 599
michael@0 600 return nextColumn.forget();
michael@0 601 }
michael@0 602
michael@0 603 already_AddRefed<nsITreeColumn>
michael@0 604 nsCoreUtils::GetPreviousSensibleColumn(nsITreeColumn *aColumn)
michael@0 605 {
michael@0 606 nsCOMPtr<nsITreeColumn> prevColumn;
michael@0 607 aColumn->GetPrevious(getter_AddRefs(prevColumn));
michael@0 608
michael@0 609 while (prevColumn && IsColumnHidden(prevColumn)) {
michael@0 610 nsCOMPtr<nsITreeColumn> tempColumn;
michael@0 611 prevColumn->GetPrevious(getter_AddRefs(tempColumn));
michael@0 612 prevColumn.swap(tempColumn);
michael@0 613 }
michael@0 614
michael@0 615 return prevColumn.forget();
michael@0 616 }
michael@0 617
michael@0 618 bool
michael@0 619 nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
michael@0 620 {
michael@0 621 nsCOMPtr<nsIDOMElement> element;
michael@0 622 aColumn->GetElement(getter_AddRefs(element));
michael@0 623 nsCOMPtr<nsIContent> content = do_QueryInterface(element);
michael@0 624 return content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
michael@0 625 nsGkAtoms::_true, eCaseMatters);
michael@0 626 }
michael@0 627
michael@0 628 void
michael@0 629 nsCoreUtils::ScrollTo(nsIPresShell* aPresShell, nsIContent* aContent,
michael@0 630 uint32_t aScrollType)
michael@0 631 {
michael@0 632 nsIPresShell::ScrollAxis vertical, horizontal;
michael@0 633 ConvertScrollTypeToPercents(aScrollType, &vertical, &horizontal);
michael@0 634 aPresShell->ScrollContentIntoView(aContent, vertical, horizontal,
michael@0 635 nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
michael@0 636 }
michael@0 637
michael@0 638 bool
michael@0 639 nsCoreUtils::IsWhitespaceString(const nsSubstring& aString)
michael@0 640 {
michael@0 641 nsSubstring::const_char_iterator iterBegin, iterEnd;
michael@0 642
michael@0 643 aString.BeginReading(iterBegin);
michael@0 644 aString.EndReading(iterEnd);
michael@0 645
michael@0 646 while (iterBegin != iterEnd && IsWhitespace(*iterBegin))
michael@0 647 ++iterBegin;
michael@0 648
michael@0 649 return iterBegin == iterEnd;
michael@0 650 }

mercurial