1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2007
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Alexander Surkov <surkov.alexander@gmail.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsCoreUtils.h"
40 :
41 : #include "nsIAccessibleTypes.h"
42 :
43 : #include "nsAccessNode.h"
44 :
45 : #include "nsIDocument.h"
46 : #include "nsIDOMDocument.h"
47 : #include "nsIDOMHTMLDocument.h"
48 : #include "nsIDOMHTMLElement.h"
49 : #include "nsRange.h"
50 : #include "nsIDOMWindow.h"
51 : #include "nsIDOMXULElement.h"
52 : #include "nsIDocShell.h"
53 : #include "nsIContentViewer.h"
54 : #include "nsEventListenerManager.h"
55 : #include "nsIPresShell.h"
56 : #include "nsPresContext.h"
57 : #include "nsIScrollableFrame.h"
58 : #include "nsEventStateManager.h"
59 : #include "nsISelectionPrivate.h"
60 : #include "nsISelectionController.h"
61 : #include "nsPIDOMWindow.h"
62 : #include "nsGUIEvent.h"
63 : #include "nsIView.h"
64 : #include "nsLayoutUtils.h"
65 :
66 : #include "nsComponentManagerUtils.h"
67 : #include "nsIInterfaceRequestorUtils.h"
68 : #include "mozilla/dom/Element.h"
69 :
70 : ////////////////////////////////////////////////////////////////////////////////
71 : // nsCoreUtils
72 : ////////////////////////////////////////////////////////////////////////////////
73 :
74 : bool
75 0 : nsCoreUtils::HasClickListener(nsIContent *aContent)
76 : {
77 0 : NS_ENSURE_TRUE(aContent, false);
78 : nsEventListenerManager* listenerManager =
79 0 : aContent->GetListenerManager(false);
80 :
81 : return listenerManager &&
82 0 : (listenerManager->HasListenersFor(NS_LITERAL_STRING("click")) ||
83 0 : listenerManager->HasListenersFor(NS_LITERAL_STRING("mousedown")) ||
84 0 : listenerManager->HasListenersFor(NS_LITERAL_STRING("mouseup")));
85 : }
86 :
87 : void
88 0 : nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
89 : PRInt32 aRowIndex, nsITreeColumn *aColumn,
90 : const nsCString& aPseudoElt)
91 : {
92 0 : nsCOMPtr<nsIDOMElement> tcElm;
93 0 : aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
94 0 : if (!tcElm)
95 : return;
96 :
97 0 : nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
98 0 : nsIDocument *document = tcContent->GetCurrentDoc();
99 0 : if (!document)
100 : return;
101 :
102 0 : nsIPresShell *presShell = nsnull;
103 0 : presShell = document->GetShell();
104 0 : if (!presShell)
105 : return;
106 :
107 : // Ensure row is visible.
108 0 : aTreeBoxObj->EnsureRowIsVisible(aRowIndex);
109 :
110 : // Calculate x and y coordinates.
111 0 : PRInt32 x = 0, y = 0, width = 0, height = 0;
112 : nsresult rv = aTreeBoxObj->GetCoordsForCellItem(aRowIndex, aColumn,
113 : aPseudoElt,
114 0 : &x, &y, &width, &height);
115 0 : if (NS_FAILED(rv))
116 : return;
117 :
118 0 : nsCOMPtr<nsIDOMXULElement> tcXULElm(do_QueryInterface(tcElm));
119 0 : nsCOMPtr<nsIBoxObject> tcBoxObj;
120 0 : tcXULElm->GetBoxObject(getter_AddRefs(tcBoxObj));
121 :
122 0 : PRInt32 tcX = 0;
123 0 : tcBoxObj->GetX(&tcX);
124 :
125 0 : PRInt32 tcY = 0;
126 0 : tcBoxObj->GetY(&tcY);
127 :
128 : // Dispatch mouse events.
129 0 : nsIFrame* tcFrame = tcContent->GetPrimaryFrame();
130 0 : nsIFrame* rootFrame = presShell->GetRootFrame();
131 :
132 0 : nsPoint offset;
133 : nsIWidget *rootWidget =
134 0 : rootFrame->GetViewExternal()->GetNearestWidget(&offset);
135 :
136 0 : nsPresContext* presContext = presShell->GetPresContext();
137 :
138 0 : PRInt32 cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
139 0 : presContext->AppUnitsToDevPixels(offset.x);
140 0 : PRInt32 cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
141 0 : presContext->AppUnitsToDevPixels(offset.y);
142 :
143 : DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, cnvdX, cnvdY,
144 0 : tcContent, tcFrame, presShell, rootWidget);
145 :
146 : DispatchMouseEvent(NS_MOUSE_BUTTON_UP, cnvdX, cnvdY,
147 0 : tcContent, tcFrame, presShell, rootWidget);
148 : }
149 :
150 : bool
151 0 : nsCoreUtils::DispatchMouseEvent(PRUint32 aEventType,
152 : nsIPresShell *aPresShell,
153 : nsIContent *aContent)
154 : {
155 0 : nsIFrame *frame = aContent->GetPrimaryFrame();
156 0 : if (!frame)
157 0 : return false;
158 :
159 : // Compute x and y coordinates.
160 0 : nsPoint point;
161 0 : nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget(point);
162 0 : if (!widget)
163 0 : return false;
164 :
165 0 : nsSize size = frame->GetSize();
166 :
167 0 : nsPresContext* presContext = aPresShell->GetPresContext();
168 :
169 0 : PRInt32 x = presContext->AppUnitsToDevPixels(point.x + size.width / 2);
170 0 : PRInt32 y = presContext->AppUnitsToDevPixels(point.y + size.height / 2);
171 :
172 : // Fire mouse event.
173 0 : DispatchMouseEvent(aEventType, x, y, aContent, frame, aPresShell, widget);
174 0 : return true;
175 : }
176 :
177 : void
178 0 : nsCoreUtils::DispatchMouseEvent(PRUint32 aEventType, PRInt32 aX, PRInt32 aY,
179 : nsIContent *aContent, nsIFrame *aFrame,
180 : nsIPresShell *aPresShell, nsIWidget *aRootWidget)
181 : {
182 : nsMouseEvent event(true, aEventType, aRootWidget,
183 0 : nsMouseEvent::eReal, nsMouseEvent::eNormal);
184 :
185 0 : event.refPoint = nsIntPoint(aX, aY);
186 :
187 0 : event.clickCount = 1;
188 0 : event.button = nsMouseEvent::eLeftButton;
189 0 : event.time = PR_IntervalNow();
190 :
191 0 : nsEventStatus status = nsEventStatus_eIgnore;
192 0 : aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
193 0 : }
194 :
195 : PRUint32
196 0 : nsCoreUtils::GetAccessKeyFor(nsIContent *aContent)
197 : {
198 0 : if (!aContent)
199 0 : return 0;
200 :
201 : // Accesskeys are registered by @accesskey attribute only. At first check
202 : // whether it is presented on the given element to avoid the slow
203 : // nsEventStateManager::GetRegisteredAccessKey() method.
204 0 : if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
205 0 : return 0;
206 :
207 0 : nsCOMPtr<nsIPresShell> presShell = aContent->OwnerDoc()->GetShell();
208 0 : if (!presShell)
209 0 : return 0;
210 :
211 0 : nsPresContext *presContext = presShell->GetPresContext();
212 0 : if (!presContext)
213 0 : return 0;
214 :
215 0 : nsEventStateManager *esm = presContext->EventStateManager();
216 0 : if (!esm)
217 0 : return 0;
218 :
219 0 : return esm->GetRegisteredAccessKey(aContent);
220 : }
221 :
222 : nsIContent *
223 0 : nsCoreUtils::GetDOMElementFor(nsIContent *aContent)
224 : {
225 0 : if (aContent->IsElement())
226 0 : return aContent;
227 :
228 0 : if (aContent->IsNodeOfType(nsINode::eTEXT))
229 0 : return aContent->GetParent();
230 :
231 0 : return nsnull;
232 : }
233 :
234 : nsINode *
235 0 : nsCoreUtils::GetDOMNodeFromDOMPoint(nsINode *aNode, PRUint32 aOffset)
236 : {
237 0 : if (aNode && aNode->IsElement()) {
238 0 : PRUint32 childCount = aNode->GetChildCount();
239 0 : NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
240 : "Wrong offset of the DOM point!");
241 :
242 : // The offset can be after last child of container node that means DOM point
243 : // is placed immediately after the last child. In this case use the DOM node
244 : // from the given DOM point is used as result node.
245 0 : if (aOffset != childCount)
246 0 : return aNode->GetChildAt(aOffset);
247 : }
248 :
249 0 : return aNode;
250 : }
251 :
252 : nsIContent*
253 0 : nsCoreUtils::GetRoleContent(nsINode *aNode)
254 : {
255 0 : nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
256 0 : if (!content) {
257 0 : nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aNode));
258 0 : if (domDoc) {
259 0 : nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(aNode));
260 0 : if (htmlDoc) {
261 0 : nsCOMPtr<nsIDOMHTMLElement> bodyElement;
262 0 : htmlDoc->GetBody(getter_AddRefs(bodyElement));
263 0 : content = do_QueryInterface(bodyElement);
264 : }
265 : else {
266 0 : nsCOMPtr<nsIDOMElement> docElement;
267 0 : domDoc->GetDocumentElement(getter_AddRefs(docElement));
268 0 : content = do_QueryInterface(docElement);
269 : }
270 : }
271 : }
272 :
273 0 : return content;
274 : }
275 :
276 : bool
277 0 : nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
278 : nsINode *aPossibleDescendantNode,
279 : nsINode *aRootNode)
280 : {
281 0 : NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, false);
282 :
283 0 : nsINode *parentNode = aPossibleDescendantNode;
284 0 : while ((parentNode = parentNode->GetNodeParent()) &&
285 : parentNode != aRootNode) {
286 0 : if (parentNode == aPossibleAncestorNode)
287 0 : return true;
288 : }
289 :
290 0 : return false;
291 : }
292 :
293 : nsresult
294 0 : nsCoreUtils::ScrollSubstringTo(nsIFrame *aFrame,
295 : nsIDOMNode *aStartNode, PRInt32 aStartIndex,
296 : nsIDOMNode *aEndNode, PRInt32 aEndIndex,
297 : PRUint32 aScrollType)
298 : {
299 : PRInt16 vPercent, hPercent;
300 0 : ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
301 :
302 : return ScrollSubstringTo(aFrame, aStartNode, aStartIndex, aEndNode, aEndIndex,
303 0 : vPercent, hPercent);
304 : }
305 :
306 : nsresult
307 0 : nsCoreUtils::ScrollSubstringTo(nsIFrame *aFrame,
308 : nsIDOMNode *aStartNode, PRInt32 aStartIndex,
309 : nsIDOMNode *aEndNode, PRInt32 aEndIndex,
310 : PRInt16 aVPercent, PRInt16 aHPercent)
311 : {
312 0 : if (!aFrame || !aStartNode || !aEndNode)
313 0 : return NS_ERROR_FAILURE;
314 :
315 0 : nsPresContext *presContext = aFrame->PresContext();
316 :
317 0 : nsRefPtr<nsIDOMRange> scrollToRange = new nsRange();
318 0 : nsCOMPtr<nsISelectionController> selCon;
319 0 : aFrame->GetSelectionController(presContext, getter_AddRefs(selCon));
320 0 : NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
321 :
322 0 : scrollToRange->SetStart(aStartNode, aStartIndex);
323 0 : scrollToRange->SetEnd(aEndNode, aEndIndex);
324 :
325 0 : nsCOMPtr<nsISelection> selection;
326 0 : selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY,
327 0 : getter_AddRefs(selection));
328 :
329 0 : nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(selection));
330 0 : selection->RemoveAllRanges();
331 0 : selection->AddRange(scrollToRange);
332 :
333 0 : privSel->ScrollIntoView(nsISelectionController::SELECTION_ANCHOR_REGION,
334 0 : true, aVPercent, aHPercent);
335 :
336 0 : selection->CollapseToStart();
337 :
338 0 : return NS_OK;
339 : }
340 :
341 : void
342 0 : nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
343 : nsIFrame *aFrame,
344 : const nsIntPoint& aPoint)
345 : {
346 0 : nsIScrollableFrame *scrollableFrame = do_QueryFrame(aScrollableFrame);
347 0 : if (!scrollableFrame)
348 0 : return;
349 :
350 0 : nsPresContext *presContext = aFrame->PresContext();
351 :
352 0 : nsIntRect frameRect = aFrame->GetScreenRectExternal();
353 0 : PRInt32 devDeltaX = aPoint.x - frameRect.x;
354 0 : PRInt32 devDeltaY = aPoint.y - frameRect.y;
355 :
356 0 : nsPoint deltaPoint;
357 0 : deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
358 0 : deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
359 :
360 0 : nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
361 0 : scrollPoint -= deltaPoint;
362 :
363 0 : scrollableFrame->ScrollTo(scrollPoint, nsIScrollableFrame::INSTANT);
364 : }
365 :
366 : void
367 0 : nsCoreUtils::ConvertScrollTypeToPercents(PRUint32 aScrollType,
368 : PRInt16 *aVPercent,
369 : PRInt16 *aHPercent)
370 : {
371 0 : switch (aScrollType)
372 : {
373 : case nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT:
374 0 : *aVPercent = NS_PRESSHELL_SCROLL_TOP;
375 0 : *aHPercent = NS_PRESSHELL_SCROLL_LEFT;
376 0 : break;
377 : case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT:
378 0 : *aVPercent = NS_PRESSHELL_SCROLL_BOTTOM;
379 0 : *aHPercent = NS_PRESSHELL_SCROLL_RIGHT;
380 0 : break;
381 : case nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE:
382 0 : *aVPercent = NS_PRESSHELL_SCROLL_TOP;
383 0 : *aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
384 0 : break;
385 : case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_EDGE:
386 0 : *aVPercent = NS_PRESSHELL_SCROLL_BOTTOM;
387 0 : *aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
388 0 : break;
389 : case nsIAccessibleScrollType::SCROLL_TYPE_LEFT_EDGE:
390 0 : *aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
391 0 : *aHPercent = NS_PRESSHELL_SCROLL_LEFT;
392 0 : break;
393 : case nsIAccessibleScrollType::SCROLL_TYPE_RIGHT_EDGE:
394 0 : *aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
395 0 : *aHPercent = NS_PRESSHELL_SCROLL_RIGHT;
396 0 : break;
397 : default:
398 0 : *aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
399 0 : *aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
400 : }
401 0 : }
402 :
403 : nsIntPoint
404 0 : nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
405 : {
406 0 : nsIntPoint coords(0, 0);
407 0 : nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
408 0 : if (!treeItem)
409 : return coords;
410 :
411 0 : nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
412 0 : treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
413 0 : nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
414 0 : if (!domDoc)
415 : return coords;
416 :
417 0 : nsCOMPtr<nsIDOMWindow> window;
418 0 : domDoc->GetDefaultView(getter_AddRefs(window));
419 0 : if (!window)
420 : return coords;
421 :
422 0 : window->GetScreenX(&coords.x);
423 0 : window->GetScreenY(&coords.y);
424 : return coords;
425 : }
426 :
427 : already_AddRefed<nsIDocShellTreeItem>
428 0 : nsCoreUtils::GetDocShellTreeItemFor(nsINode *aNode)
429 : {
430 0 : if (!aNode)
431 0 : return nsnull;
432 :
433 0 : nsCOMPtr<nsISupports> container = aNode->OwnerDoc()->GetContainer();
434 0 : nsIDocShellTreeItem *docShellTreeItem = nsnull;
435 0 : if (container)
436 0 : CallQueryInterface(container, &docShellTreeItem);
437 :
438 0 : return docShellTreeItem;
439 : }
440 :
441 : bool
442 0 : nsCoreUtils::IsRootDocument(nsIDocument *aDocument)
443 : {
444 0 : nsCOMPtr<nsISupports> container = aDocument->GetContainer();
445 : nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
446 0 : do_QueryInterface(container);
447 0 : NS_ASSERTION(docShellTreeItem, "No document shell for document!");
448 :
449 0 : nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
450 0 : docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
451 :
452 0 : return !parentTreeItem;
453 : }
454 :
455 : bool
456 0 : nsCoreUtils::IsContentDocument(nsIDocument *aDocument)
457 : {
458 0 : nsCOMPtr<nsISupports> container = aDocument->GetContainer();
459 : nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
460 0 : do_QueryInterface(container);
461 0 : NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!");
462 :
463 : PRInt32 contentType;
464 0 : docShellTreeItem->GetItemType(&contentType);
465 0 : return (contentType == nsIDocShellTreeItem::typeContent);
466 : }
467 :
468 : bool
469 0 : nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode)
470 : {
471 0 : nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
472 0 : nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
473 :
474 0 : nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
475 0 : treeItem->GetParent(getter_AddRefs(parentTreeItem));
476 :
477 : // Tab document running in own process doesn't have parent.
478 0 : if (XRE_GetProcessType() == GeckoProcessType_Content)
479 0 : return !parentTreeItem;
480 :
481 : // Parent of docshell for tab document running in chrome process is root.
482 0 : nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
483 0 : treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
484 :
485 0 : return parentTreeItem == rootTreeItem;
486 : }
487 :
488 : bool
489 0 : nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
490 : {
491 0 : nsIURI *uri = aDocument->GetDocumentURI();
492 0 : bool isAboutScheme = false;
493 0 : uri->SchemeIs("about", &isAboutScheme);
494 0 : if (!isAboutScheme)
495 0 : return false;
496 :
497 0 : nsCAutoString path;
498 0 : uri->GetPath(path);
499 :
500 0 : NS_NAMED_LITERAL_CSTRING(neterror, "neterror");
501 0 : NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
502 :
503 0 : return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
504 : }
505 :
506 : already_AddRefed<nsIDOMNode>
507 0 : nsCoreUtils::GetDOMNodeForContainer(nsIDocShellTreeItem *aContainer)
508 : {
509 0 : nsCOMPtr<nsIDocShell> shell = do_QueryInterface(aContainer);
510 :
511 0 : nsCOMPtr<nsIContentViewer> cv;
512 0 : shell->GetContentViewer(getter_AddRefs(cv));
513 :
514 0 : if (!cv)
515 0 : return nsnull;
516 :
517 0 : nsIDocument* doc = cv->GetDocument();
518 0 : if (!doc)
519 0 : return nsnull;
520 :
521 0 : nsIDOMNode* node = nsnull;
522 0 : CallQueryInterface(doc, &node);
523 0 : return node;
524 : }
525 :
526 : bool
527 0 : nsCoreUtils::GetID(nsIContent *aContent, nsAString& aID)
528 : {
529 0 : nsIAtom *idAttribute = aContent->GetIDAttributeName();
530 0 : return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : false;
531 : }
532 :
533 : bool
534 0 : nsCoreUtils::GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr, PRInt32 *aUInt)
535 : {
536 0 : nsAutoString value;
537 0 : aContent->GetAttr(kNameSpaceID_None, aAttr, value);
538 0 : if (!value.IsEmpty()) {
539 0 : PRInt32 error = NS_OK;
540 0 : PRInt32 integer = value.ToInteger(&error);
541 0 : if (NS_SUCCEEDED(error) && integer > 0) {
542 0 : *aUInt = integer;
543 0 : return true;
544 : }
545 : }
546 :
547 0 : return false;
548 : }
549 :
550 : bool
551 0 : nsCoreUtils::IsXLink(nsIContent *aContent)
552 : {
553 0 : if (!aContent)
554 0 : return false;
555 :
556 : return aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
557 0 : nsGkAtoms::simple, eCaseMatters) &&
558 0 : aContent->HasAttr(kNameSpaceID_XLink, nsGkAtoms::href);
559 : }
560 :
561 : void
562 0 : nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
563 : nsAString& aLanguage)
564 : {
565 0 : aLanguage.Truncate();
566 :
567 0 : nsIContent *walkUp = aContent;
568 0 : while (walkUp && walkUp != aRootContent &&
569 0 : !walkUp->GetAttr(kNameSpaceID_None, nsGkAtoms::lang, aLanguage))
570 0 : walkUp = walkUp->GetParent();
571 0 : }
572 :
573 : already_AddRefed<nsIBoxObject>
574 0 : nsCoreUtils::GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj)
575 : {
576 0 : nsCOMPtr<nsIDOMElement> tcElm;
577 0 : aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
578 0 : nsCOMPtr<nsIDOMXULElement> tcXULElm(do_QueryInterface(tcElm));
579 0 : if (!tcXULElm)
580 0 : return nsnull;
581 :
582 0 : nsIBoxObject *boxObj = nsnull;
583 0 : tcXULElm->GetBoxObject(&boxObj);
584 0 : return boxObj;
585 : }
586 :
587 : already_AddRefed<nsITreeBoxObject>
588 0 : nsCoreUtils::GetTreeBoxObject(nsIContent *aContent)
589 : {
590 : // Find DOMNode's parents recursively until reach the <tree> tag
591 0 : nsIContent* currentContent = aContent;
592 0 : while (currentContent) {
593 0 : if (currentContent->NodeInfo()->Equals(nsGkAtoms::tree,
594 0 : kNameSpaceID_XUL)) {
595 : // We will get the nsITreeBoxObject from the tree node
596 0 : nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(currentContent));
597 0 : if (xulElement) {
598 0 : nsCOMPtr<nsIBoxObject> box;
599 0 : xulElement->GetBoxObject(getter_AddRefs(box));
600 0 : nsCOMPtr<nsITreeBoxObject> treeBox(do_QueryInterface(box));
601 0 : if (treeBox)
602 0 : return treeBox.forget();
603 : }
604 : }
605 0 : currentContent = currentContent->GetParent();
606 : }
607 :
608 0 : return nsnull;
609 : }
610 :
611 : already_AddRefed<nsITreeColumn>
612 0 : nsCoreUtils::GetFirstSensibleColumn(nsITreeBoxObject *aTree)
613 : {
614 0 : nsCOMPtr<nsITreeColumns> cols;
615 0 : aTree->GetColumns(getter_AddRefs(cols));
616 0 : if (!cols)
617 0 : return nsnull;
618 :
619 0 : nsCOMPtr<nsITreeColumn> column;
620 0 : cols->GetFirstColumn(getter_AddRefs(column));
621 0 : if (column && IsColumnHidden(column))
622 0 : return GetNextSensibleColumn(column);
623 :
624 0 : return column.forget();
625 : }
626 :
627 : PRUint32
628 0 : nsCoreUtils::GetSensibleColumnCount(nsITreeBoxObject *aTree)
629 : {
630 0 : PRUint32 count = 0;
631 :
632 0 : nsCOMPtr<nsITreeColumns> cols;
633 0 : aTree->GetColumns(getter_AddRefs(cols));
634 0 : if (!cols)
635 0 : return count;
636 :
637 0 : nsCOMPtr<nsITreeColumn> column;
638 0 : cols->GetFirstColumn(getter_AddRefs(column));
639 :
640 0 : while (column) {
641 0 : if (!IsColumnHidden(column))
642 0 : count++;
643 :
644 0 : nsCOMPtr<nsITreeColumn> nextColumn;
645 0 : column->GetNext(getter_AddRefs(nextColumn));
646 0 : column.swap(nextColumn);
647 : }
648 :
649 0 : return count;
650 : }
651 :
652 : already_AddRefed<nsITreeColumn>
653 0 : nsCoreUtils::GetSensibleColumnAt(nsITreeBoxObject *aTree, PRUint32 aIndex)
654 : {
655 0 : PRUint32 idx = aIndex;
656 :
657 0 : nsCOMPtr<nsITreeColumn> column = GetFirstSensibleColumn(aTree);
658 0 : while (column) {
659 0 : if (idx == 0)
660 0 : return column.forget();
661 :
662 0 : idx--;
663 0 : column = GetNextSensibleColumn(column);
664 : }
665 :
666 0 : return nsnull;
667 : }
668 :
669 : already_AddRefed<nsITreeColumn>
670 0 : nsCoreUtils::GetNextSensibleColumn(nsITreeColumn *aColumn)
671 : {
672 0 : nsCOMPtr<nsITreeColumn> nextColumn;
673 0 : aColumn->GetNext(getter_AddRefs(nextColumn));
674 :
675 0 : while (nextColumn && IsColumnHidden(nextColumn)) {
676 0 : nsCOMPtr<nsITreeColumn> tempColumn;
677 0 : nextColumn->GetNext(getter_AddRefs(tempColumn));
678 0 : nextColumn.swap(tempColumn);
679 : }
680 :
681 0 : return nextColumn.forget();
682 : }
683 :
684 : already_AddRefed<nsITreeColumn>
685 0 : nsCoreUtils::GetPreviousSensibleColumn(nsITreeColumn *aColumn)
686 : {
687 0 : nsCOMPtr<nsITreeColumn> prevColumn;
688 0 : aColumn->GetPrevious(getter_AddRefs(prevColumn));
689 :
690 0 : while (prevColumn && IsColumnHidden(prevColumn)) {
691 0 : nsCOMPtr<nsITreeColumn> tempColumn;
692 0 : prevColumn->GetPrevious(getter_AddRefs(tempColumn));
693 0 : prevColumn.swap(tempColumn);
694 : }
695 :
696 0 : return prevColumn.forget();
697 : }
698 :
699 : bool
700 0 : nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
701 : {
702 0 : nsCOMPtr<nsIDOMElement> element;
703 0 : aColumn->GetElement(getter_AddRefs(element));
704 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(element);
705 0 : return content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
706 0 : nsGkAtoms::_true, eCaseMatters);
707 : }
708 :
709 : ////////////////////////////////////////////////////////////////////////////////
710 : // nsAccessibleDOMStringList
711 : ////////////////////////////////////////////////////////////////////////////////
712 :
713 0 : NS_IMPL_ISUPPORTS1(nsAccessibleDOMStringList, nsIDOMDOMStringList)
714 :
715 : NS_IMETHODIMP
716 0 : nsAccessibleDOMStringList::Item(PRUint32 aIndex, nsAString& aResult)
717 : {
718 0 : if (aIndex >= mNames.Length())
719 0 : SetDOMStringToNull(aResult);
720 : else
721 0 : aResult = mNames.ElementAt(aIndex);
722 :
723 0 : return NS_OK;
724 : }
725 :
726 : NS_IMETHODIMP
727 0 : nsAccessibleDOMStringList::GetLength(PRUint32 *aLength)
728 : {
729 0 : *aLength = mNames.Length();
730 :
731 0 : return NS_OK;
732 : }
733 :
734 : NS_IMETHODIMP
735 0 : nsAccessibleDOMStringList::Contains(const nsAString& aString, bool *aResult)
736 : {
737 0 : *aResult = mNames.Contains(aString);
738 :
739 0 : return NS_OK;
740 : }
741 :
|