1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "mozilla/dom/TreeBoxObject.h"
8 #include "nsCOMPtr.h"
9 #include "nsXULElement.h"
10 #include "nsIScriptableRegion.h"
11 #include "nsTreeContentView.h"
12 #include "nsITreeSelection.h"
13 #include "ChildIterator.h"
14 #include "nsContentUtils.h"
15 #include "nsError.h"
16 #include "nsTreeBodyFrame.h"
17 #include "mozilla/dom/TreeBoxObjectBinding.h"
18 #include "nsITreeColumns.h"
19 #include "mozilla/dom/DOMRect.h"
20 #include "mozilla/dom/BindingUtils.h"
21 #include "mozilla/dom/Element.h"
22 #include "mozilla/dom/ToJSValue.h"
23
24 namespace mozilla {
25 namespace dom {
26
NS_IMPL_CYCLE_COLLECTION_INHERITED(TreeBoxObject,BoxObject,mView)27 NS_IMPL_CYCLE_COLLECTION_INHERITED(TreeBoxObject, BoxObject, mView)
28
29 NS_IMPL_ADDREF_INHERITED(TreeBoxObject, BoxObject)
30 NS_IMPL_RELEASE_INHERITED(TreeBoxObject, BoxObject)
31
32 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TreeBoxObject)
33 NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject)
34 NS_INTERFACE_MAP_END_INHERITING(BoxObject)
35
36 void TreeBoxObject::Clear() {
37 ClearCachedValues();
38
39 // Drop the view's ref to us.
40 if (mView) {
41 nsCOMPtr<nsITreeSelection> sel;
42 mView->GetSelection(getter_AddRefs(sel));
43 if (sel) sel->SetTree(nullptr);
44 mView->SetTree(nullptr); // Break the circular ref between the view and us.
45 }
46 mView = nullptr;
47
48 BoxObject::Clear();
49 }
50
TreeBoxObject()51 TreeBoxObject::TreeBoxObject() : mTreeBody(nullptr) {}
52
~TreeBoxObject()53 TreeBoxObject::~TreeBoxObject() {}
54
FindBodyElement(nsIContent * aParent)55 static nsIContent* FindBodyElement(nsIContent* aParent) {
56 mozilla::dom::FlattenedChildIterator iter(aParent);
57 for (nsIContent* content = iter.GetNextChild(); content;
58 content = iter.GetNextChild()) {
59 mozilla::dom::NodeInfo* ni = content->NodeInfo();
60 if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) {
61 return content;
62 } else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
63 // There are nesting tree elements. Only the innermost should
64 // find the treechilren.
65 return nullptr;
66 } else if (content->IsElement() &&
67 !ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) {
68 nsIContent* result = FindBodyElement(content);
69 if (result) return result;
70 }
71 }
72
73 return nullptr;
74 }
75
GetTreeBodyFrame(bool aFlushLayout)76 nsTreeBodyFrame* TreeBoxObject::GetTreeBodyFrame(bool aFlushLayout) {
77 // Make sure our frames are up to date, and layout as needed. We
78 // have to do this before checking for our cached mTreeBody, since
79 // it might go away on style flush, and in any case if aFlushLayout
80 // is true we need to make sure to flush no matter what.
81 // XXXbz except that flushing style when we were not asked to flush
82 // layout here breaks things. See bug 585123.
83 nsIFrame* frame = nullptr;
84 if (aFlushLayout) {
85 frame = GetFrame(aFlushLayout);
86 if (!frame) return nullptr;
87 }
88
89 if (mTreeBody) {
90 // Have one cached already.
91 return mTreeBody;
92 }
93
94 if (!aFlushLayout) {
95 frame = GetFrame(aFlushLayout);
96 if (!frame) return nullptr;
97 }
98
99 // Iterate over our content model children looking for the body.
100 nsCOMPtr<nsIContent> content = FindBodyElement(frame->GetContent());
101 if (!content) return nullptr;
102
103 frame = content->GetPrimaryFrame();
104 if (!frame) return nullptr;
105
106 // Make sure that the treebodyframe has a pointer to |this|.
107 nsTreeBodyFrame* treeBody = do_QueryFrame(frame);
108 NS_ENSURE_TRUE(treeBody && treeBody->GetTreeBoxObject() == this, nullptr);
109
110 mTreeBody = treeBody;
111 return mTreeBody;
112 }
113
114 NS_IMETHODIMP
GetView(nsITreeView ** aView)115 TreeBoxObject::GetView(nsITreeView** aView) {
116 if (!mTreeBody) {
117 if (!GetTreeBodyFrame()) {
118 // Don't return an uninitialised view
119 *aView = nullptr;
120 return NS_OK;
121 }
122
123 if (mView)
124 // Our new frame needs to initialise itself
125 return mTreeBody->GetView(aView);
126 }
127 if (!mView) {
128 RefPtr<nsXULElement> xulele = nsXULElement::FromContentOrNull(mContent);
129 if (xulele) {
130 // No tree builder, create a tree content view.
131 nsresult rv = NS_NewTreeContentView(getter_AddRefs(mView));
132 NS_ENSURE_SUCCESS(rv, rv);
133
134 // Initialise the frame and view
135 mTreeBody->SetView(mView);
136 }
137 }
138 NS_IF_ADDREF(*aView = mView);
139 return NS_OK;
140 }
141
GetView(CallerType)142 already_AddRefed<nsITreeView> TreeBoxObject::GetView(CallerType /* unused */) {
143 nsCOMPtr<nsITreeView> view;
144 GetView(getter_AddRefs(view));
145 return view.forget();
146 }
147
148 NS_IMETHODIMP
SetView(nsITreeView * aView)149 TreeBoxObject::SetView(nsITreeView* aView) {
150 ErrorResult rv;
151 SetView(aView, CallerType::System, rv);
152 return rv.StealNSResult();
153 }
154
SetView(nsITreeView * aView,CallerType aCallerType,ErrorResult & aRv)155 void TreeBoxObject::SetView(nsITreeView* aView, CallerType aCallerType,
156 ErrorResult& aRv) {
157 if (aCallerType != CallerType::System) {
158 // Don't trust views coming from random places.
159 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
160 return;
161 }
162
163 mView = aView;
164 nsTreeBodyFrame* body = GetTreeBodyFrame();
165 if (body) body->SetView(aView);
166 }
167
Focused()168 bool TreeBoxObject::Focused() {
169 nsTreeBodyFrame* body = GetTreeBodyFrame();
170 if (body) return body->GetFocused();
171 return false;
172 }
173
GetFocused(bool * aFocused)174 NS_IMETHODIMP TreeBoxObject::GetFocused(bool* aFocused) {
175 *aFocused = Focused();
176 return NS_OK;
177 }
178
SetFocused(bool aFocused)179 NS_IMETHODIMP TreeBoxObject::SetFocused(bool aFocused) {
180 nsTreeBodyFrame* body = GetTreeBodyFrame();
181 if (body) return body->SetFocused(aFocused);
182 return NS_OK;
183 }
184
GetTreeBody(nsIDOMElement ** aElement)185 NS_IMETHODIMP TreeBoxObject::GetTreeBody(nsIDOMElement** aElement) {
186 *aElement = nullptr;
187 nsTreeBodyFrame* body = GetTreeBodyFrame();
188 if (body) return body->GetTreeBody(aElement);
189 return NS_OK;
190 }
191
GetTreeBody()192 already_AddRefed<Element> TreeBoxObject::GetTreeBody() {
193 nsCOMPtr<nsIDOMElement> el;
194 GetTreeBody(getter_AddRefs(el));
195 nsCOMPtr<Element> ret(do_QueryInterface(el));
196 return ret.forget();
197 }
198
GetColumns()199 already_AddRefed<nsTreeColumns> TreeBoxObject::GetColumns() {
200 nsTreeBodyFrame* body = GetTreeBodyFrame();
201 if (body) return body->Columns();
202 return nullptr;
203 }
204
GetColumns(nsITreeColumns ** aColumns)205 NS_IMETHODIMP TreeBoxObject::GetColumns(nsITreeColumns** aColumns) {
206 *aColumns = GetColumns().take();
207 return NS_OK;
208 }
209
RowHeight()210 int32_t TreeBoxObject::RowHeight() {
211 nsTreeBodyFrame* body = GetTreeBodyFrame();
212 if (body) return body->RowHeight();
213 return 0;
214 }
215
RowWidth()216 int32_t TreeBoxObject::RowWidth() {
217 nsTreeBodyFrame* body = GetTreeBodyFrame();
218 if (body) return body->RowWidth();
219 return 0;
220 }
221
GetRowHeight(int32_t * aRowHeight)222 NS_IMETHODIMP TreeBoxObject::GetRowHeight(int32_t* aRowHeight) {
223 *aRowHeight = RowHeight();
224 return NS_OK;
225 }
226
GetRowWidth(int32_t * aRowWidth)227 NS_IMETHODIMP TreeBoxObject::GetRowWidth(int32_t* aRowWidth) {
228 *aRowWidth = RowWidth();
229 return NS_OK;
230 }
231
GetFirstVisibleRow()232 int32_t TreeBoxObject::GetFirstVisibleRow() {
233 nsTreeBodyFrame* body = GetTreeBodyFrame();
234 if (body) return body->FirstVisibleRow();
235 return 0;
236 }
237
GetFirstVisibleRow(int32_t * aFirstVisibleRow)238 NS_IMETHODIMP TreeBoxObject::GetFirstVisibleRow(int32_t* aFirstVisibleRow) {
239 *aFirstVisibleRow = GetFirstVisibleRow();
240 return NS_OK;
241 }
242
GetLastVisibleRow()243 int32_t TreeBoxObject::GetLastVisibleRow() {
244 nsTreeBodyFrame* body = GetTreeBodyFrame();
245 if (body) return body->LastVisibleRow();
246 return 0;
247 }
248
GetLastVisibleRow(int32_t * aLastVisibleRow)249 NS_IMETHODIMP TreeBoxObject::GetLastVisibleRow(int32_t* aLastVisibleRow) {
250 *aLastVisibleRow = GetLastVisibleRow();
251 return NS_OK;
252 }
253
HorizontalPosition()254 int32_t TreeBoxObject::HorizontalPosition() {
255 nsTreeBodyFrame* body = GetTreeBodyFrame();
256 if (body) return body->GetHorizontalPosition();
257 return 0;
258 }
259
GetHorizontalPosition(int32_t * aHorizontalPosition)260 NS_IMETHODIMP TreeBoxObject::GetHorizontalPosition(
261 int32_t* aHorizontalPosition) {
262 *aHorizontalPosition = HorizontalPosition();
263 return NS_OK;
264 }
265
GetPageLength()266 int32_t TreeBoxObject::GetPageLength() {
267 nsTreeBodyFrame* body = GetTreeBodyFrame();
268 if (body) return body->PageLength();
269 return 0;
270 }
271
GetPageLength(int32_t * aPageLength)272 NS_IMETHODIMP TreeBoxObject::GetPageLength(int32_t* aPageLength) {
273 *aPageLength = GetPageLength();
274 return NS_OK;
275 }
276
GetSelectionRegion(nsIScriptableRegion ** aRegion)277 NS_IMETHODIMP TreeBoxObject::GetSelectionRegion(nsIScriptableRegion** aRegion) {
278 *aRegion = nullptr;
279 nsTreeBodyFrame* body = GetTreeBodyFrame();
280 if (body) return body->GetSelectionRegion(aRegion);
281 return NS_OK;
282 }
283
SelectionRegion()284 already_AddRefed<nsIScriptableRegion> TreeBoxObject::SelectionRegion() {
285 nsCOMPtr<nsIScriptableRegion> region;
286 GetSelectionRegion(getter_AddRefs(region));
287 return region.forget();
288 }
289
290 NS_IMETHODIMP
EnsureRowIsVisible(int32_t aRow)291 TreeBoxObject::EnsureRowIsVisible(int32_t aRow) {
292 nsTreeBodyFrame* body = GetTreeBodyFrame();
293 if (body) return body->EnsureRowIsVisible(aRow);
294 return NS_OK;
295 }
296
297 NS_IMETHODIMP
EnsureCellIsVisible(int32_t aRow,nsITreeColumn * aCol)298 TreeBoxObject::EnsureCellIsVisible(int32_t aRow, nsITreeColumn* aCol) {
299 nsTreeBodyFrame* body = GetTreeBodyFrame();
300 if (body) return body->EnsureCellIsVisible(aRow, aCol);
301 return NS_OK;
302 }
303
304 NS_IMETHODIMP
ScrollToRow(int32_t aRow)305 TreeBoxObject::ScrollToRow(int32_t aRow) {
306 nsTreeBodyFrame* body = GetTreeBodyFrame(true);
307 if (body) return body->ScrollToRow(aRow);
308 return NS_OK;
309 }
310
311 NS_IMETHODIMP
ScrollByLines(int32_t aNumLines)312 TreeBoxObject::ScrollByLines(int32_t aNumLines) {
313 nsTreeBodyFrame* body = GetTreeBodyFrame();
314 if (body) return body->ScrollByLines(aNumLines);
315 return NS_OK;
316 }
317
318 NS_IMETHODIMP
ScrollByPages(int32_t aNumPages)319 TreeBoxObject::ScrollByPages(int32_t aNumPages) {
320 nsTreeBodyFrame* body = GetTreeBodyFrame();
321 if (body) return body->ScrollByPages(aNumPages);
322 return NS_OK;
323 }
324
325 NS_IMETHODIMP
ScrollToCell(int32_t aRow,nsITreeColumn * aCol)326 TreeBoxObject::ScrollToCell(int32_t aRow, nsITreeColumn* aCol) {
327 nsTreeBodyFrame* body = GetTreeBodyFrame();
328 if (body) return body->ScrollToCell(aRow, aCol);
329 return NS_OK;
330 }
331
332 NS_IMETHODIMP
ScrollToColumn(nsITreeColumn * aCol)333 TreeBoxObject::ScrollToColumn(nsITreeColumn* aCol) {
334 nsTreeBodyFrame* body = GetTreeBodyFrame();
335 if (body) return body->ScrollToColumn(aCol);
336 return NS_OK;
337 }
338
339 NS_IMETHODIMP
ScrollToHorizontalPosition(int32_t aHorizontalPosition)340 TreeBoxObject::ScrollToHorizontalPosition(int32_t aHorizontalPosition) {
341 nsTreeBodyFrame* body = GetTreeBodyFrame();
342 if (body) return body->ScrollToHorizontalPosition(aHorizontalPosition);
343 return NS_OK;
344 }
345
Invalidate()346 NS_IMETHODIMP TreeBoxObject::Invalidate() {
347 nsTreeBodyFrame* body = GetTreeBodyFrame();
348 if (body) return body->Invalidate();
349 return NS_OK;
350 }
351
352 NS_IMETHODIMP
InvalidateColumn(nsITreeColumn * aCol)353 TreeBoxObject::InvalidateColumn(nsITreeColumn* aCol) {
354 nsTreeBodyFrame* body = GetTreeBodyFrame();
355 if (body) return body->InvalidateColumn(aCol);
356 return NS_OK;
357 }
358
359 NS_IMETHODIMP
InvalidateRow(int32_t aIndex)360 TreeBoxObject::InvalidateRow(int32_t aIndex) {
361 nsTreeBodyFrame* body = GetTreeBodyFrame();
362 if (body) return body->InvalidateRow(aIndex);
363 return NS_OK;
364 }
365
366 NS_IMETHODIMP
InvalidateCell(int32_t aRow,nsITreeColumn * aCol)367 TreeBoxObject::InvalidateCell(int32_t aRow, nsITreeColumn* aCol) {
368 nsTreeBodyFrame* body = GetTreeBodyFrame();
369 if (body) return body->InvalidateCell(aRow, aCol);
370 return NS_OK;
371 }
372
373 NS_IMETHODIMP
InvalidateRange(int32_t aStart,int32_t aEnd)374 TreeBoxObject::InvalidateRange(int32_t aStart, int32_t aEnd) {
375 nsTreeBodyFrame* body = GetTreeBodyFrame();
376 if (body) return body->InvalidateRange(aStart, aEnd);
377 return NS_OK;
378 }
379
380 NS_IMETHODIMP
InvalidateColumnRange(int32_t aStart,int32_t aEnd,nsITreeColumn * aCol)381 TreeBoxObject::InvalidateColumnRange(int32_t aStart, int32_t aEnd,
382 nsITreeColumn* aCol) {
383 nsTreeBodyFrame* body = GetTreeBodyFrame();
384 if (body) return body->InvalidateColumnRange(aStart, aEnd, aCol);
385 return NS_OK;
386 }
387
388 NS_IMETHODIMP
GetRowAt(int32_t x,int32_t y,int32_t * aRow)389 TreeBoxObject::GetRowAt(int32_t x, int32_t y, int32_t* aRow) {
390 *aRow = 0;
391 nsTreeBodyFrame* body = GetTreeBodyFrame();
392 if (body) return body->GetRowAt(x, y, aRow);
393 return NS_OK;
394 }
395
GetRowAt(int32_t x,int32_t y)396 int32_t TreeBoxObject::GetRowAt(int32_t x, int32_t y) {
397 int32_t row;
398 GetRowAt(x, y, &row);
399 return row;
400 }
401
402 NS_IMETHODIMP
GetCellAt(int32_t aX,int32_t aY,int32_t * aRow,nsITreeColumn ** aCol,nsAString & aChildElt)403 TreeBoxObject::GetCellAt(int32_t aX, int32_t aY, int32_t* aRow,
404 nsITreeColumn** aCol, nsAString& aChildElt) {
405 *aRow = 0;
406 *aCol = nullptr;
407 nsTreeBodyFrame* body = GetTreeBodyFrame();
408 if (body) {
409 nsAutoCString element;
410 nsresult retval = body->GetCellAt(aX, aY, aRow, aCol, element);
411 CopyUTF8toUTF16(element, aChildElt);
412 return retval;
413 }
414 return NS_OK;
415 }
416
GetCellAt(int32_t x,int32_t y,TreeCellInfo & aRetVal,ErrorResult & aRv)417 void TreeBoxObject::GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal,
418 ErrorResult& aRv) {
419 nsCOMPtr<nsITreeColumn> col;
420 GetCellAt(x, y, &aRetVal.mRow, getter_AddRefs(col), aRetVal.mChildElt);
421 aRetVal.mCol = col.forget().downcast<nsTreeColumn>();
422 }
423
GetCellAt(JSContext * cx,int32_t x,int32_t y,JS::Handle<JSObject * > rowOut,JS::Handle<JSObject * > colOut,JS::Handle<JSObject * > childEltOut,ErrorResult & aRv)424 void TreeBoxObject::GetCellAt(JSContext* cx, int32_t x, int32_t y,
425 JS::Handle<JSObject*> rowOut,
426 JS::Handle<JSObject*> colOut,
427 JS::Handle<JSObject*> childEltOut,
428 ErrorResult& aRv) {
429 int32_t row;
430 nsITreeColumn* col;
431 nsAutoString childElt;
432 GetCellAt(x, y, &row, &col, childElt);
433
434 JS::Rooted<JS::Value> v(cx);
435
436 if (!ToJSValue(cx, row, &v) || !JS_SetProperty(cx, rowOut, "value", v)) {
437 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
438 return;
439 }
440 if (!dom::WrapObject(cx, col, &v) ||
441 !JS_SetProperty(cx, colOut, "value", v)) {
442 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
443 return;
444 }
445 if (!ToJSValue(cx, childElt, &v) ||
446 !JS_SetProperty(cx, childEltOut, "value", v)) {
447 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
448 return;
449 }
450 }
451
452 NS_IMETHODIMP
GetCoordsForCellItem(int32_t aRow,nsITreeColumn * aCol,const nsAString & aElement,int32_t * aX,int32_t * aY,int32_t * aWidth,int32_t * aHeight)453 TreeBoxObject::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol,
454 const nsAString& aElement, int32_t* aX,
455 int32_t* aY, int32_t* aWidth,
456 int32_t* aHeight) {
457 *aX = *aY = *aWidth = *aHeight = 0;
458 nsTreeBodyFrame* body = GetTreeBodyFrame();
459 NS_ConvertUTF16toUTF8 element(aElement);
460 if (body)
461 return body->GetCoordsForCellItem(aRow, aCol, element, aX, aY, aWidth,
462 aHeight);
463 return NS_OK;
464 }
465
GetCoordsForCellItem(int32_t row,nsTreeColumn & col,const nsAString & element,ErrorResult & aRv)466 already_AddRefed<DOMRect> TreeBoxObject::GetCoordsForCellItem(
467 int32_t row, nsTreeColumn& col, const nsAString& element,
468 ErrorResult& aRv) {
469 int32_t x, y, w, h;
470 GetCoordsForCellItem(row, &col, element, &x, &y, &w, &h);
471 RefPtr<DOMRect> rect = new DOMRect(mContent, x, y, w, h);
472 return rect.forget();
473 }
474
GetCoordsForCellItem(JSContext * cx,int32_t row,nsTreeColumn & col,const nsAString & element,JS::Handle<JSObject * > xOut,JS::Handle<JSObject * > yOut,JS::Handle<JSObject * > widthOut,JS::Handle<JSObject * > heightOut,ErrorResult & aRv)475 void TreeBoxObject::GetCoordsForCellItem(
476 JSContext* cx, int32_t row, nsTreeColumn& col, const nsAString& element,
477 JS::Handle<JSObject*> xOut, JS::Handle<JSObject*> yOut,
478 JS::Handle<JSObject*> widthOut, JS::Handle<JSObject*> heightOut,
479 ErrorResult& aRv) {
480 int32_t x, y, w, h;
481 GetCoordsForCellItem(row, &col, element, &x, &y, &w, &h);
482 JS::Rooted<JS::Value> v(cx, JS::Int32Value(x));
483 if (!JS_SetProperty(cx, xOut, "value", v)) {
484 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
485 return;
486 }
487 v.setInt32(y);
488 if (!JS_SetProperty(cx, yOut, "value", v)) {
489 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
490 return;
491 }
492 v.setInt32(w);
493 if (!JS_SetProperty(cx, widthOut, "value", v)) {
494 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
495 return;
496 }
497 v.setInt32(h);
498 if (!JS_SetProperty(cx, heightOut, "value", v)) {
499 aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
500 return;
501 }
502 }
503
504 NS_IMETHODIMP
IsCellCropped(int32_t aRow,nsITreeColumn * aCol,bool * aIsCropped)505 TreeBoxObject::IsCellCropped(int32_t aRow, nsITreeColumn* aCol,
506 bool* aIsCropped) {
507 *aIsCropped = false;
508 nsTreeBodyFrame* body = GetTreeBodyFrame();
509 if (body) return body->IsCellCropped(aRow, aCol, aIsCropped);
510 return NS_OK;
511 }
512
IsCellCropped(int32_t row,nsITreeColumn * col,ErrorResult & aRv)513 bool TreeBoxObject::IsCellCropped(int32_t row, nsITreeColumn* col,
514 ErrorResult& aRv) {
515 bool ret;
516 aRv = IsCellCropped(row, col, &ret);
517 return ret;
518 }
519
520 NS_IMETHODIMP
RowCountChanged(int32_t aIndex,int32_t aDelta)521 TreeBoxObject::RowCountChanged(int32_t aIndex, int32_t aDelta) {
522 nsTreeBodyFrame* body = GetTreeBodyFrame();
523 if (body) return body->RowCountChanged(aIndex, aDelta);
524 return NS_OK;
525 }
526
527 NS_IMETHODIMP
BeginUpdateBatch()528 TreeBoxObject::BeginUpdateBatch() {
529 nsTreeBodyFrame* body = GetTreeBodyFrame();
530 if (body) return body->BeginUpdateBatch();
531 return NS_OK;
532 }
533
534 NS_IMETHODIMP
EndUpdateBatch()535 TreeBoxObject::EndUpdateBatch() {
536 nsTreeBodyFrame* body = GetTreeBodyFrame();
537 if (body) return body->EndUpdateBatch();
538 return NS_OK;
539 }
540
541 NS_IMETHODIMP
ClearStyleAndImageCaches()542 TreeBoxObject::ClearStyleAndImageCaches() {
543 nsTreeBodyFrame* body = GetTreeBodyFrame();
544 if (body) return body->ClearStyleAndImageCaches();
545 return NS_OK;
546 }
547
548 NS_IMETHODIMP
RemoveImageCacheEntry(int32_t aRowIndex,nsITreeColumn * aCol)549 TreeBoxObject::RemoveImageCacheEntry(int32_t aRowIndex, nsITreeColumn* aCol) {
550 NS_ENSURE_ARG(aCol);
551 NS_ENSURE_TRUE(aRowIndex >= 0, NS_ERROR_INVALID_ARG);
552 nsTreeBodyFrame* body = GetTreeBodyFrame();
553 if (body) {
554 return body->RemoveImageCacheEntry(aRowIndex, aCol);
555 }
556 return NS_OK;
557 }
558
RemoveImageCacheEntry(int32_t row,nsITreeColumn & col,ErrorResult & aRv)559 void TreeBoxObject::RemoveImageCacheEntry(int32_t row, nsITreeColumn& col,
560 ErrorResult& aRv) {
561 aRv = RemoveImageCacheEntry(row, &col);
562 }
563
ClearCachedValues()564 void TreeBoxObject::ClearCachedValues() { mTreeBody = nullptr; }
565
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)566 JSObject* TreeBoxObject::WrapObject(JSContext* aCx,
567 JS::Handle<JSObject*> aGivenProto) {
568 return TreeBoxObjectBinding::Wrap(aCx, this, aGivenProto);
569 }
570
571 } // namespace dom
572 } // namespace mozilla
573
574 // Creation Routine
575 // ///////////////////////////////////////////////////////////////////////
576
577 using namespace mozilla::dom;
578
NS_NewTreeBoxObject(nsIBoxObject ** aResult)579 nsresult NS_NewTreeBoxObject(nsIBoxObject** aResult) {
580 NS_ADDREF(*aResult = new TreeBoxObject());
581 return NS_OK;
582 }
583