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.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corp.
19 : * Portions created by the Initial Developer are Copyright (C) 2003
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Daniel Glazman (glazman@netscape.com) (Original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * 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 "nsHTMLObjectResizer.h"
40 :
41 : #include "nsIDOMEventTarget.h"
42 : #include "nsIDOMText.h"
43 :
44 : #include "nsIDOMCSSValue.h"
45 : #include "nsIDOMCSSPrimitiveValue.h"
46 :
47 : #include "nsIContent.h"
48 : #include "nsIDocument.h"
49 : #include "nsIDocumentObserver.h"
50 : #include "nsIEditor.h"
51 : #include "nsIPresShell.h"
52 : #include "nsPIDOMWindow.h"
53 :
54 : #include "nsHTMLEditor.h"
55 : #include "nsEditor.h"
56 : #include "nsEditorUtils.h"
57 : #include "nsHTMLEditUtils.h"
58 :
59 : #include "nsPoint.h"
60 :
61 : #include "nsIServiceManager.h"
62 : #include "mozilla/Preferences.h"
63 :
64 : #include "mozilla/LookAndFeel.h"
65 :
66 : using namespace mozilla;
67 :
68 : class nsHTMLEditUtils;
69 :
70 : // ==================================================================
71 : // DocumentResizeEventListener
72 : // ==================================================================
73 0 : NS_IMPL_ISUPPORTS1(DocumentResizeEventListener, nsIDOMEventListener)
74 :
75 0 : DocumentResizeEventListener::DocumentResizeEventListener(nsIHTMLEditor * aEditor)
76 : {
77 0 : mEditor = do_GetWeakReference(aEditor);
78 0 : }
79 :
80 0 : DocumentResizeEventListener::~DocumentResizeEventListener()
81 : {
82 0 : }
83 :
84 : NS_IMETHODIMP
85 0 : DocumentResizeEventListener::HandleEvent(nsIDOMEvent* aMouseEvent)
86 : {
87 0 : nsCOMPtr<nsIHTMLObjectResizer> objectResizer = do_QueryReferent(mEditor);
88 0 : if (objectResizer)
89 0 : return objectResizer->RefreshResizers();
90 0 : return NS_OK;
91 : }
92 :
93 : // ==================================================================
94 : // ResizerSelectionListener
95 : // ==================================================================
96 :
97 0 : NS_IMPL_ISUPPORTS1(ResizerSelectionListener, nsISelectionListener)
98 :
99 0 : ResizerSelectionListener::ResizerSelectionListener(nsIHTMLEditor * aEditor)
100 : {
101 0 : mEditor = do_GetWeakReference(aEditor);
102 0 : }
103 :
104 0 : ResizerSelectionListener::~ResizerSelectionListener()
105 : {
106 0 : }
107 :
108 : NS_IMETHODIMP
109 0 : ResizerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *aSelection, PRInt16 aReason)
110 : {
111 0 : if ((aReason & (nsISelectionListener::MOUSEDOWN_REASON |
112 : nsISelectionListener::KEYPRESS_REASON |
113 : nsISelectionListener::SELECTALL_REASON)) && aSelection)
114 : {
115 : // the selection changed and we need to check if we have to
116 : // hide and/or redisplay resizing handles
117 0 : nsCOMPtr<nsIHTMLEditor> editor = do_QueryReferent(mEditor);
118 0 : if (editor)
119 0 : editor->CheckSelectionStateForAnonymousButtons(aSelection);
120 : }
121 :
122 0 : return NS_OK;
123 : }
124 :
125 : // ==================================================================
126 : // ResizerMouseMotionListener
127 : // ==================================================================
128 :
129 0 : NS_IMPL_ISUPPORTS1(ResizerMouseMotionListener, nsIDOMEventListener)
130 :
131 0 : ResizerMouseMotionListener::ResizerMouseMotionListener(nsIHTMLEditor * aEditor)
132 : {
133 0 : mEditor = do_GetWeakReference(aEditor);
134 0 : }
135 :
136 0 : ResizerMouseMotionListener::~ResizerMouseMotionListener()
137 : {
138 0 : }
139 :
140 : NS_IMETHODIMP
141 0 : ResizerMouseMotionListener::HandleEvent(nsIDOMEvent* aMouseEvent)
142 : {
143 0 : nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
144 0 : if (!mouseEvent) {
145 : //non-ui event passed in. bad things.
146 0 : return NS_OK;
147 : }
148 :
149 : // Don't do anything special if not an HTML object resizer editor
150 0 : nsCOMPtr<nsIHTMLObjectResizer> objectResizer = do_QueryReferent(mEditor);
151 0 : if (objectResizer)
152 : {
153 : // check if we have to redisplay a resizing shadow
154 0 : objectResizer->MouseMove(aMouseEvent);
155 : }
156 :
157 0 : return NS_OK;
158 : }
159 :
160 : // ==================================================================
161 : // nsHTMLEditor
162 : // ==================================================================
163 :
164 : nsresult
165 0 : nsHTMLEditor::CreateResizer(nsIDOMElement ** aReturn, PRInt16 aLocation, nsIDOMNode * aParentNode)
166 : {
167 0 : nsresult res = CreateAnonymousElement(NS_LITERAL_STRING("span"),
168 : aParentNode,
169 0 : NS_LITERAL_STRING("mozResizer"),
170 : false,
171 0 : aReturn);
172 :
173 0 : NS_ENSURE_SUCCESS(res, res);
174 0 : NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE);
175 :
176 : // add the mouse listener so we can detect a click on a resizer
177 0 : nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(*aReturn));
178 0 : evtTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), mEventListener,
179 0 : true);
180 :
181 0 : nsAutoString locationStr;
182 0 : switch (aLocation) {
183 : case nsIHTMLObjectResizer::eTopLeft:
184 0 : locationStr = kTopLeft;
185 0 : break;
186 : case nsIHTMLObjectResizer::eTop:
187 0 : locationStr = kTop;
188 0 : break;
189 : case nsIHTMLObjectResizer::eTopRight:
190 0 : locationStr = kTopRight;
191 0 : break;
192 :
193 : case nsIHTMLObjectResizer::eLeft:
194 0 : locationStr = kLeft;
195 0 : break;
196 : case nsIHTMLObjectResizer::eRight:
197 0 : locationStr = kRight;
198 0 : break;
199 :
200 : case nsIHTMLObjectResizer::eBottomLeft:
201 0 : locationStr = kBottomLeft;
202 0 : break;
203 : case nsIHTMLObjectResizer::eBottom:
204 0 : locationStr = kBottom;
205 0 : break;
206 : case nsIHTMLObjectResizer::eBottomRight:
207 0 : locationStr = kBottomRight;
208 0 : break;
209 : }
210 :
211 0 : res = (*aReturn)->SetAttribute(NS_LITERAL_STRING("anonlocation"),
212 0 : locationStr);
213 0 : return res;
214 : }
215 :
216 : nsresult
217 0 : nsHTMLEditor::CreateShadow(nsIDOMElement ** aReturn, nsIDOMNode * aParentNode,
218 : nsIDOMElement * aOriginalObject)
219 : {
220 : // let's create an image through the element factory
221 0 : nsAutoString name;
222 0 : if (nsHTMLEditUtils::IsImage(aOriginalObject))
223 0 : name.AssignLiteral("img");
224 : else
225 0 : name.AssignLiteral("span");
226 : nsresult res = CreateAnonymousElement(name,
227 : aParentNode,
228 0 : NS_LITERAL_STRING("mozResizingShadow"),
229 : true,
230 0 : aReturn);
231 :
232 0 : NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE);
233 :
234 0 : return res;
235 : }
236 :
237 : nsresult
238 0 : nsHTMLEditor::CreateResizingInfo(nsIDOMElement ** aReturn, nsIDOMNode * aParentNode)
239 : {
240 : // let's create an info box through the element factory
241 0 : nsresult res = CreateAnonymousElement(NS_LITERAL_STRING("span"),
242 : aParentNode,
243 0 : NS_LITERAL_STRING("mozResizingInfo"),
244 : true,
245 0 : aReturn);
246 :
247 0 : NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE);
248 :
249 0 : return res;
250 : }
251 :
252 : nsresult
253 0 : nsHTMLEditor::SetAllResizersPosition()
254 : {
255 0 : NS_ENSURE_TRUE(mTopLeftHandle, NS_ERROR_FAILURE);
256 :
257 0 : PRInt32 x = mResizedObjectX;
258 0 : PRInt32 y = mResizedObjectY;
259 0 : PRInt32 w = mResizedObjectWidth;
260 0 : PRInt32 h = mResizedObjectHeight;
261 :
262 : // now let's place all the resizers around the image
263 :
264 : // get the size of resizers
265 0 : nsAutoString value;
266 : float resizerWidth, resizerHeight;
267 0 : nsCOMPtr<nsIAtom> dummyUnit;
268 0 : mHTMLCSSUtils->GetComputedProperty(mTopLeftHandle, nsEditProperty::cssWidth, value);
269 0 : mHTMLCSSUtils->ParseLength(value, &resizerWidth, getter_AddRefs(dummyUnit));
270 0 : mHTMLCSSUtils->GetComputedProperty(mTopLeftHandle, nsEditProperty::cssHeight, value);
271 0 : mHTMLCSSUtils->ParseLength(value, &resizerHeight, getter_AddRefs(dummyUnit));
272 :
273 0 : PRInt32 rw = (PRInt32)((resizerWidth + 1) / 2);
274 0 : PRInt32 rh = (PRInt32)((resizerHeight+ 1) / 2);
275 :
276 0 : SetAnonymousElementPosition(x-rw, y-rh, mTopLeftHandle);
277 0 : SetAnonymousElementPosition(x+w/2-rw, y-rh, mTopHandle);
278 0 : SetAnonymousElementPosition(x+w-rw-1, y-rh, mTopRightHandle);
279 :
280 0 : SetAnonymousElementPosition(x-rw, y+h/2-rh, mLeftHandle);
281 0 : SetAnonymousElementPosition(x+w-rw-1, y+h/2-rh, mRightHandle);
282 :
283 0 : SetAnonymousElementPosition(x-rw, y+h-rh-1, mBottomLeftHandle);
284 0 : SetAnonymousElementPosition(x+w/2-rw, y+h-rh-1, mBottomHandle);
285 0 : SetAnonymousElementPosition(x+w-rw-1, y+h-rh-1, mBottomRightHandle);
286 :
287 0 : return NS_OK;
288 : }
289 :
290 : NS_IMETHODIMP
291 0 : nsHTMLEditor::RefreshResizers()
292 : {
293 : // nothing to do if resizers are not displayed...
294 0 : NS_ENSURE_TRUE(mResizedObject, NS_OK);
295 :
296 : nsresult res = GetPositionAndDimensions(mResizedObject,
297 : mResizedObjectX,
298 : mResizedObjectY,
299 : mResizedObjectWidth,
300 : mResizedObjectHeight,
301 : mResizedObjectBorderLeft,
302 : mResizedObjectBorderTop,
303 : mResizedObjectMarginLeft,
304 0 : mResizedObjectMarginTop);
305 :
306 0 : NS_ENSURE_SUCCESS(res, res);
307 0 : res = SetAllResizersPosition();
308 0 : NS_ENSURE_SUCCESS(res, res);
309 : return SetShadowPosition(mResizingShadow, mResizedObject,
310 0 : mResizedObjectX, mResizedObjectY);
311 : }
312 :
313 : NS_IMETHODIMP
314 0 : nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
315 : {
316 0 : nsresult res = ShowResizersInner(aResizedElement);
317 0 : if (NS_FAILED(res))
318 0 : HideResizers();
319 0 : return res;
320 : }
321 :
322 : nsresult
323 0 : nsHTMLEditor::ShowResizersInner(nsIDOMElement *aResizedElement)
324 : {
325 0 : NS_ENSURE_ARG_POINTER(aResizedElement);
326 : nsresult res;
327 :
328 0 : nsCOMPtr<nsIDOMNode> parentNode;
329 0 : res = aResizedElement->GetParentNode(getter_AddRefs(parentNode));
330 0 : NS_ENSURE_SUCCESS(res, res);
331 :
332 0 : if (mResizedObject) {
333 0 : NS_ERROR("call HideResizers first");
334 0 : return NS_ERROR_UNEXPECTED;
335 : }
336 0 : mResizedObject = aResizedElement;
337 :
338 : // The resizers and the shadow will be anonymous siblings of the element.
339 0 : res = CreateResizer(getter_AddRefs(mTopLeftHandle),
340 0 : nsIHTMLObjectResizer::eTopLeft, parentNode);
341 0 : NS_ENSURE_SUCCESS(res, res);
342 0 : res = CreateResizer(getter_AddRefs(mTopHandle),
343 0 : nsIHTMLObjectResizer::eTop, parentNode);
344 0 : NS_ENSURE_SUCCESS(res, res);
345 0 : res = CreateResizer(getter_AddRefs(mTopRightHandle),
346 0 : nsIHTMLObjectResizer::eTopRight, parentNode);
347 0 : NS_ENSURE_SUCCESS(res, res);
348 :
349 0 : res = CreateResizer(getter_AddRefs(mLeftHandle),
350 0 : nsIHTMLObjectResizer::eLeft, parentNode);
351 0 : NS_ENSURE_SUCCESS(res, res);
352 0 : res = CreateResizer(getter_AddRefs(mRightHandle),
353 0 : nsIHTMLObjectResizer::eRight, parentNode);
354 0 : NS_ENSURE_SUCCESS(res, res);
355 :
356 0 : res = CreateResizer(getter_AddRefs(mBottomLeftHandle),
357 0 : nsIHTMLObjectResizer::eBottomLeft, parentNode);
358 0 : NS_ENSURE_SUCCESS(res, res);
359 0 : res = CreateResizer(getter_AddRefs(mBottomHandle),
360 0 : nsIHTMLObjectResizer::eBottom, parentNode);
361 0 : NS_ENSURE_SUCCESS(res, res);
362 0 : res = CreateResizer(getter_AddRefs(mBottomRightHandle),
363 0 : nsIHTMLObjectResizer::eBottomRight, parentNode);
364 0 : NS_ENSURE_SUCCESS(res, res);
365 :
366 : res = GetPositionAndDimensions(aResizedElement,
367 : mResizedObjectX,
368 : mResizedObjectY,
369 : mResizedObjectWidth,
370 : mResizedObjectHeight,
371 : mResizedObjectBorderLeft,
372 : mResizedObjectBorderTop,
373 : mResizedObjectMarginLeft,
374 0 : mResizedObjectMarginTop);
375 0 : NS_ENSURE_SUCCESS(res, res);
376 :
377 : // and let's set their absolute positions in the document
378 0 : res = SetAllResizersPosition();
379 0 : NS_ENSURE_SUCCESS(res, res);
380 :
381 : // now, let's create the resizing shadow
382 0 : res = CreateShadow(getter_AddRefs(mResizingShadow), parentNode,
383 0 : aResizedElement);
384 0 : NS_ENSURE_SUCCESS(res, res);
385 : // and set its position
386 : res = SetShadowPosition(mResizingShadow, mResizedObject,
387 0 : mResizedObjectX, mResizedObjectY);
388 0 : NS_ENSURE_SUCCESS(res, res);
389 :
390 : // and then the resizing info tooltip
391 0 : res = CreateResizingInfo(getter_AddRefs(mResizingInfo), parentNode);
392 0 : NS_ENSURE_SUCCESS(res, res);
393 :
394 : // and listen to the "resize" event on the window first, get the
395 : // window from the document...
396 0 : nsCOMPtr<nsIDOMDocument> domDoc;
397 0 : GetDocument(getter_AddRefs(domDoc));
398 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
399 0 : NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER);
400 :
401 0 : nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(doc->GetWindow());
402 0 : if (!target) { return NS_ERROR_NULL_POINTER; }
403 :
404 0 : mResizeEventListenerP = new DocumentResizeEventListener(this);
405 0 : if (!mResizeEventListenerP) { return NS_ERROR_OUT_OF_MEMORY; }
406 0 : res = target->AddEventListener(NS_LITERAL_STRING("resize"), mResizeEventListenerP, false);
407 :
408 0 : aResizedElement->SetAttribute(NS_LITERAL_STRING("_moz_resizing"), NS_LITERAL_STRING("true"));
409 0 : return res;
410 : }
411 :
412 : NS_IMETHODIMP
413 0 : nsHTMLEditor::HideResizers(void)
414 : {
415 0 : NS_ENSURE_TRUE(mResizedObject, NS_OK);
416 :
417 : // get the presshell's document observer interface.
418 0 : nsCOMPtr<nsIPresShell> ps = GetPresShell();
419 : // We allow the pres shell to be null; when it is, we presume there
420 : // are no document observers to notify, but we still want to
421 : // UnbindFromTree.
422 :
423 : nsresult res;
424 0 : nsCOMPtr<nsIDOMNode> parentNode;
425 0 : nsCOMPtr<nsIContent> parentContent;
426 :
427 0 : if (mTopLeftHandle) {
428 0 : res = mTopLeftHandle->GetParentNode(getter_AddRefs(parentNode));
429 0 : NS_ENSURE_SUCCESS(res, res);
430 0 : parentContent = do_QueryInterface(parentNode);
431 : }
432 :
433 0 : NS_NAMED_LITERAL_STRING(mousedown, "mousedown");
434 :
435 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
436 0 : mTopLeftHandle, parentContent, ps);
437 0 : mTopLeftHandle = nsnull;
438 :
439 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
440 0 : mTopHandle, parentContent, ps);
441 0 : mTopHandle = nsnull;
442 :
443 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
444 0 : mTopRightHandle, parentContent, ps);
445 0 : mTopRightHandle = nsnull;
446 :
447 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
448 0 : mLeftHandle, parentContent, ps);
449 0 : mLeftHandle = nsnull;
450 :
451 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
452 0 : mRightHandle, parentContent, ps);
453 0 : mRightHandle = nsnull;
454 :
455 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
456 0 : mBottomLeftHandle, parentContent, ps);
457 0 : mBottomLeftHandle = nsnull;
458 :
459 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
460 0 : mBottomHandle, parentContent, ps);
461 0 : mBottomHandle = nsnull;
462 :
463 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
464 0 : mBottomRightHandle, parentContent, ps);
465 0 : mBottomRightHandle = nsnull;
466 :
467 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
468 0 : mResizingShadow, parentContent, ps);
469 0 : mResizingShadow = nsnull;
470 :
471 : RemoveListenerAndDeleteRef(mousedown, mEventListener, true,
472 0 : mResizingInfo, parentContent, ps);
473 0 : mResizingInfo = nsnull;
474 :
475 0 : if (mActivatedHandle) {
476 0 : mActivatedHandle->RemoveAttribute(NS_LITERAL_STRING("_moz_activated"));
477 0 : mActivatedHandle = nsnull;
478 : }
479 :
480 : // don't forget to remove the listeners !
481 :
482 0 : nsCOMPtr<nsIDOMEventTarget> target = GetDOMEventTarget();
483 :
484 0 : if (target && mMouseMotionListenerP)
485 : {
486 0 : res = target->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
487 0 : mMouseMotionListenerP, true);
488 0 : NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener");
489 : }
490 0 : mMouseMotionListenerP = nsnull;
491 :
492 0 : nsCOMPtr<nsIDOMDocument> domDoc;
493 0 : GetDocument(getter_AddRefs(domDoc));
494 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
495 0 : if (!doc) { return NS_ERROR_NULL_POINTER; }
496 0 : target = do_QueryInterface(doc->GetWindow());
497 0 : if (!target) { return NS_ERROR_NULL_POINTER; }
498 :
499 0 : if (mResizeEventListenerP) {
500 0 : res = target->RemoveEventListener(NS_LITERAL_STRING("resize"), mResizeEventListenerP, false);
501 0 : NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove resize event listener");
502 : }
503 0 : mResizeEventListenerP = nsnull;
504 :
505 0 : mResizedObject->RemoveAttribute(NS_LITERAL_STRING("_moz_resizing"));
506 0 : mResizedObject = nsnull;
507 :
508 0 : return NS_OK;
509 : }
510 :
511 : void
512 0 : nsHTMLEditor::HideShadowAndInfo()
513 : {
514 0 : if (mResizingShadow)
515 0 : mResizingShadow->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden"));
516 0 : if (mResizingInfo)
517 0 : mResizingInfo->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden"));
518 0 : }
519 :
520 : nsresult
521 0 : nsHTMLEditor::StartResizing(nsIDOMElement *aHandle)
522 : {
523 : // First notify the listeners if any
524 0 : PRInt32 listenersCount = objectResizeEventListeners.Count();
525 0 : if (listenersCount) {
526 0 : nsCOMPtr<nsIHTMLObjectResizeListener> listener;
527 : PRInt32 index;
528 0 : for (index = 0; index < listenersCount; index++) {
529 0 : listener = objectResizeEventListeners[index];
530 0 : listener->OnStartResizing(mResizedObject);
531 : }
532 : }
533 :
534 0 : mIsResizing = true;
535 0 : mActivatedHandle = aHandle;
536 0 : mActivatedHandle->SetAttribute(NS_LITERAL_STRING("_moz_activated"), NS_LITERAL_STRING("true"));
537 :
538 : // do we want to preserve ratio or not?
539 0 : bool preserveRatio = nsHTMLEditUtils::IsImage(mResizedObject) &&
540 0 : Preferences::GetBool("editor.resizing.preserve_ratio", true);
541 :
542 : // the way we change the position/size of the shadow depends on
543 : // the handle
544 0 : nsAutoString locationStr;
545 0 : aHandle->GetAttribute(NS_LITERAL_STRING("anonlocation"), locationStr);
546 0 : if (locationStr.Equals(kTopLeft)) {
547 0 : SetResizeIncrements(1, 1, -1, -1, preserveRatio);
548 : }
549 0 : else if (locationStr.Equals(kTop)) {
550 0 : SetResizeIncrements(0, 1, 0, -1, false);
551 : }
552 0 : else if (locationStr.Equals(kTopRight)) {
553 0 : SetResizeIncrements(0, 1, 1, -1, preserveRatio);
554 : }
555 0 : else if (locationStr.Equals(kLeft)) {
556 0 : SetResizeIncrements(1, 0, -1, 0, false);
557 : }
558 0 : else if (locationStr.Equals(kRight)) {
559 0 : SetResizeIncrements(0, 0, 1, 0, false);
560 : }
561 0 : else if (locationStr.Equals(kBottomLeft)) {
562 0 : SetResizeIncrements(1, 0, -1, 1, preserveRatio);
563 : }
564 0 : else if (locationStr.Equals(kBottom)) {
565 0 : SetResizeIncrements(0, 0, 0, 1, false);
566 : }
567 0 : else if (locationStr.Equals(kBottomRight)) {
568 0 : SetResizeIncrements(0, 0, 1, 1, preserveRatio);
569 : }
570 :
571 : // make the shadow appear
572 0 : mResizingShadow->RemoveAttribute(NS_LITERAL_STRING("class"));
573 :
574 : // position it
575 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
576 0 : NS_LITERAL_STRING("width"),
577 0 : mResizedObjectWidth);
578 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
579 0 : NS_LITERAL_STRING("height"),
580 0 : mResizedObjectHeight);
581 :
582 : // add a mouse move listener to the editor
583 0 : nsresult result = NS_OK;
584 0 : if (!mMouseMotionListenerP) {
585 0 : mMouseMotionListenerP = new ResizerMouseMotionListener(this);
586 0 : if (!mMouseMotionListenerP) {
587 0 : return NS_ERROR_OUT_OF_MEMORY;
588 : }
589 :
590 0 : nsCOMPtr<nsIDOMEventTarget> target = GetDOMEventTarget();
591 0 : NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
592 :
593 0 : result = target->AddEventListener(NS_LITERAL_STRING("mousemove"),
594 0 : mMouseMotionListenerP, true);
595 0 : NS_ASSERTION(NS_SUCCEEDED(result),
596 : "failed to register mouse motion listener");
597 : }
598 0 : return result;
599 : }
600 :
601 :
602 : NS_IMETHODIMP
603 0 : nsHTMLEditor::MouseDown(PRInt32 aClientX, PRInt32 aClientY,
604 : nsIDOMElement *aTarget, nsIDOMEvent* aEvent)
605 : {
606 0 : bool anonElement = false;
607 0 : if (aTarget && NS_SUCCEEDED(aTarget->HasAttribute(NS_LITERAL_STRING("_moz_anonclass"), &anonElement)))
608 : // we caught a click on an anonymous element
609 0 : if (anonElement) {
610 0 : nsAutoString anonclass;
611 0 : nsresult res = aTarget->GetAttribute(NS_LITERAL_STRING("_moz_anonclass"), anonclass);
612 0 : NS_ENSURE_SUCCESS(res, res);
613 0 : if (anonclass.EqualsLiteral("mozResizer")) {
614 : // and that element is a resizer, let's start resizing!
615 0 : aEvent->PreventDefault();
616 :
617 0 : mOriginalX = aClientX;
618 0 : mOriginalY = aClientY;
619 0 : return StartResizing(aTarget);
620 : }
621 0 : if (anonclass.EqualsLiteral("mozGrabber")) {
622 : // and that element is a grabber, let's start moving the element!
623 0 : mOriginalX = aClientX;
624 0 : mOriginalY = aClientY;
625 0 : return GrabberClicked();
626 : }
627 : }
628 0 : return NS_OK;
629 : }
630 :
631 : NS_IMETHODIMP
632 0 : nsHTMLEditor::MouseUp(PRInt32 aClientX, PRInt32 aClientY,
633 : nsIDOMElement *aTarget)
634 : {
635 0 : if (mIsResizing) {
636 : // we are resizing and release the mouse button, so let's
637 : // end the resizing process
638 0 : mIsResizing = false;
639 0 : HideShadowAndInfo();
640 0 : SetFinalSize(aClientX, aClientY);
641 : }
642 0 : else if (mIsMoving || mGrabberClicked) {
643 0 : if (mIsMoving) {
644 0 : mPositioningShadow->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden"));
645 0 : SetFinalPosition(aClientX, aClientY);
646 : }
647 0 : if (mGrabberClicked) {
648 0 : EndMoving();
649 : }
650 : }
651 0 : return NS_OK;
652 : }
653 :
654 :
655 : void
656 0 : nsHTMLEditor::SetResizeIncrements(PRInt32 aX, PRInt32 aY,
657 : PRInt32 aW, PRInt32 aH,
658 : bool aPreserveRatio)
659 : {
660 0 : mXIncrementFactor = aX;
661 0 : mYIncrementFactor = aY;
662 0 : mWidthIncrementFactor = aW;
663 0 : mHeightIncrementFactor = aH;
664 0 : mPreserveRatio = aPreserveRatio;
665 0 : }
666 :
667 : nsresult
668 0 : nsHTMLEditor::SetResizingInfoPosition(PRInt32 aX, PRInt32 aY, PRInt32 aW, PRInt32 aH)
669 : {
670 0 : nsCOMPtr<nsIDOMDocument> domdoc;
671 0 : nsEditor::GetDocument(getter_AddRefs(domdoc));
672 :
673 0 : NS_NAMED_LITERAL_STRING(leftStr, "left");
674 0 : NS_NAMED_LITERAL_STRING(topStr, "top");
675 :
676 : // Determine the position of the resizing info box based upon the new
677 : // position and size of the element (aX, aY, aW, aH), and which
678 : // resizer is the "activated handle". For example, place the resizing
679 : // info box at the bottom-right corner of the new element, if the element
680 : // is being resized by the bottom-right resizer.
681 : PRInt32 infoXPosition;
682 : PRInt32 infoYPosition;
683 :
684 0 : if (mActivatedHandle == mTopLeftHandle ||
685 0 : mActivatedHandle == mLeftHandle ||
686 0 : mActivatedHandle == mBottomLeftHandle)
687 0 : infoXPosition = aX;
688 0 : else if (mActivatedHandle == mTopHandle ||
689 0 : mActivatedHandle == mBottomHandle)
690 0 : infoXPosition = aX + (aW / 2);
691 : else
692 : // should only occur when mActivatedHandle is one of the 3 right-side
693 : // handles, but this is a reasonable default if it isn't any of them (?)
694 0 : infoXPosition = aX + aW;
695 :
696 0 : if (mActivatedHandle == mTopLeftHandle ||
697 0 : mActivatedHandle == mTopHandle ||
698 0 : mActivatedHandle == mTopRightHandle)
699 0 : infoYPosition = aY;
700 0 : else if (mActivatedHandle == mLeftHandle ||
701 0 : mActivatedHandle == mRightHandle)
702 0 : infoYPosition = aY + (aH / 2);
703 : else
704 : // should only occur when mActivatedHandle is one of the 3 bottom-side
705 : // handles, but this is a reasonable default if it isn't any of them (?)
706 0 : infoYPosition = aY + aH;
707 :
708 : // Offset info box by 20 so it's not directly under the mouse cursor.
709 0 : const int mouseCursorOffset = 20;
710 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingInfo, leftStr,
711 0 : infoXPosition + mouseCursorOffset);
712 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingInfo, topStr,
713 0 : infoYPosition + mouseCursorOffset);
714 :
715 0 : nsCOMPtr<nsIDOMNode> textInfo;
716 0 : nsresult res = mResizingInfo->GetFirstChild(getter_AddRefs(textInfo));
717 0 : NS_ENSURE_SUCCESS(res, res);
718 0 : nsCOMPtr<nsIDOMNode> junk;
719 0 : if (textInfo) {
720 0 : res = mResizingInfo->RemoveChild(textInfo, getter_AddRefs(junk));
721 0 : NS_ENSURE_SUCCESS(res, res);
722 0 : textInfo = nsnull;
723 0 : junk = nsnull;
724 : }
725 :
726 0 : nsAutoString widthStr, heightStr, diffWidthStr, diffHeightStr;
727 0 : widthStr.AppendInt(aW);
728 0 : heightStr.AppendInt(aH);
729 0 : PRInt32 diffWidth = aW - mResizedObjectWidth;
730 0 : PRInt32 diffHeight = aH - mResizedObjectHeight;
731 0 : if (diffWidth > 0)
732 0 : diffWidthStr.AssignLiteral("+");
733 0 : if (diffHeight > 0)
734 0 : diffHeightStr.AssignLiteral("+");
735 0 : diffWidthStr.AppendInt(diffWidth);
736 0 : diffHeightStr.AppendInt(diffHeight);
737 :
738 0 : nsAutoString info(widthStr + NS_LITERAL_STRING(" x ") + heightStr +
739 0 : NS_LITERAL_STRING(" (") + diffWidthStr +
740 0 : NS_LITERAL_STRING(", ") + diffHeightStr +
741 0 : NS_LITERAL_STRING(")"));
742 :
743 0 : nsCOMPtr<nsIDOMText> nodeAsText;
744 0 : res = domdoc->CreateTextNode(info, getter_AddRefs(nodeAsText));
745 0 : NS_ENSURE_SUCCESS(res, res);
746 0 : textInfo = do_QueryInterface(nodeAsText);
747 0 : res = mResizingInfo->AppendChild(textInfo, getter_AddRefs(junk));
748 0 : NS_ENSURE_SUCCESS(res, res);
749 :
750 0 : bool hasClass = false;
751 0 : if (NS_SUCCEEDED(mResizingInfo->HasAttribute(NS_LITERAL_STRING("class"), &hasClass )) && hasClass)
752 0 : res = mResizingInfo->RemoveAttribute(NS_LITERAL_STRING("class"));
753 :
754 0 : return res;
755 : }
756 :
757 : nsresult
758 0 : nsHTMLEditor::SetShadowPosition(nsIDOMElement * aShadow,
759 : nsIDOMElement * aOriginalObject,
760 : PRInt32 aOriginalObjectX,
761 : PRInt32 aOriginalObjectY)
762 : {
763 0 : SetAnonymousElementPosition(aOriginalObjectX, aOriginalObjectY, aShadow);
764 :
765 0 : if (nsHTMLEditUtils::IsImage(aOriginalObject)) {
766 0 : nsAutoString imageSource;
767 0 : nsresult res = aOriginalObject->GetAttribute(NS_LITERAL_STRING("src"),
768 0 : imageSource);
769 0 : NS_ENSURE_SUCCESS(res, res);
770 0 : res = aShadow->SetAttribute(NS_LITERAL_STRING("src"), imageSource);
771 0 : NS_ENSURE_SUCCESS(res, res);
772 : }
773 0 : return NS_OK;
774 : }
775 :
776 : PRInt32
777 0 : nsHTMLEditor::GetNewResizingIncrement(PRInt32 aX, PRInt32 aY, PRInt32 aID)
778 : {
779 0 : PRInt32 result = 0;
780 0 : if (!mPreserveRatio) {
781 0 : switch (aID) {
782 : case kX:
783 : case kWidth:
784 0 : result = aX - mOriginalX;
785 0 : break;
786 : case kY:
787 : case kHeight:
788 0 : result = aY - mOriginalY;
789 0 : break;
790 : }
791 0 : return result;
792 : }
793 :
794 0 : PRInt32 xi = (aX - mOriginalX) * mWidthIncrementFactor;
795 0 : PRInt32 yi = (aY - mOriginalY) * mHeightIncrementFactor;
796 : float objectSizeRatio =
797 0 : ((float)mResizedObjectWidth) / ((float)mResizedObjectHeight);
798 0 : result = (xi > yi) ? xi : yi;
799 0 : switch (aID) {
800 : case kX:
801 : case kWidth:
802 0 : if (result == yi)
803 0 : result = (PRInt32) (((float) result) * objectSizeRatio);
804 0 : result = (PRInt32) (((float) result) * mWidthIncrementFactor);
805 0 : break;
806 : case kY:
807 : case kHeight:
808 0 : if (result == xi)
809 0 : result = (PRInt32) (((float) result) / objectSizeRatio);
810 0 : result = (PRInt32) (((float) result) * mHeightIncrementFactor);
811 0 : break;
812 : }
813 0 : return result;
814 : }
815 :
816 : PRInt32
817 0 : nsHTMLEditor::GetNewResizingX(PRInt32 aX, PRInt32 aY)
818 : {
819 : PRInt32 resized = mResizedObjectX +
820 0 : GetNewResizingIncrement(aX, aY, kX) * mXIncrementFactor;
821 0 : PRInt32 max = mResizedObjectX + mResizedObjectWidth;
822 0 : return NS_MIN(resized, max);
823 : }
824 :
825 : PRInt32
826 0 : nsHTMLEditor::GetNewResizingY(PRInt32 aX, PRInt32 aY)
827 : {
828 : PRInt32 resized = mResizedObjectY +
829 0 : GetNewResizingIncrement(aX, aY, kY) * mYIncrementFactor;
830 0 : PRInt32 max = mResizedObjectY + mResizedObjectHeight;
831 0 : return NS_MIN(resized, max);
832 : }
833 :
834 : PRInt32
835 0 : nsHTMLEditor::GetNewResizingWidth(PRInt32 aX, PRInt32 aY)
836 : {
837 : PRInt32 resized = mResizedObjectWidth +
838 0 : GetNewResizingIncrement(aX, aY, kWidth) *
839 0 : mWidthIncrementFactor;
840 0 : return NS_MAX(resized, 1);
841 : }
842 :
843 : PRInt32
844 0 : nsHTMLEditor::GetNewResizingHeight(PRInt32 aX, PRInt32 aY)
845 : {
846 : PRInt32 resized = mResizedObjectHeight +
847 0 : GetNewResizingIncrement(aX, aY, kHeight) *
848 0 : mHeightIncrementFactor;
849 0 : return NS_MAX(resized, 1);
850 : }
851 :
852 :
853 : NS_IMETHODIMP
854 0 : nsHTMLEditor::MouseMove(nsIDOMEvent* aMouseEvent)
855 : {
856 0 : NS_NAMED_LITERAL_STRING(leftStr, "left");
857 0 : NS_NAMED_LITERAL_STRING(topStr, "top");
858 :
859 0 : if (mIsResizing) {
860 : // we are resizing and the mouse pointer's position has changed
861 : // we have to resdisplay the shadow
862 0 : nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
863 : PRInt32 clientX, clientY;
864 0 : mouseEvent->GetClientX(&clientX);
865 0 : mouseEvent->GetClientY(&clientY);
866 :
867 0 : PRInt32 newX = GetNewResizingX(clientX, clientY);
868 0 : PRInt32 newY = GetNewResizingY(clientX, clientY);
869 0 : PRInt32 newWidth = GetNewResizingWidth(clientX, clientY);
870 0 : PRInt32 newHeight = GetNewResizingHeight(clientX, clientY);
871 :
872 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
873 : leftStr,
874 0 : newX);
875 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
876 : topStr,
877 0 : newY);
878 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
879 0 : NS_LITERAL_STRING("width"),
880 0 : newWidth);
881 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow,
882 0 : NS_LITERAL_STRING("height"),
883 0 : newHeight);
884 :
885 0 : return SetResizingInfoPosition(newX, newY, newWidth, newHeight);
886 : }
887 :
888 0 : if (mGrabberClicked) {
889 0 : nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
890 : PRInt32 clientX, clientY;
891 0 : mouseEvent->GetClientX(&clientX);
892 0 : mouseEvent->GetClientY(&clientY);
893 :
894 : PRInt32 xThreshold =
895 0 : LookAndFeel::GetInt(LookAndFeel::eIntID_DragThresholdX, 1);
896 : PRInt32 yThreshold =
897 0 : LookAndFeel::GetInt(LookAndFeel::eIntID_DragThresholdY, 1);
898 :
899 0 : if (NS_ABS(clientX - mOriginalX ) * 2 >= xThreshold ||
900 0 : NS_ABS(clientY - mOriginalY ) * 2 >= yThreshold) {
901 0 : mGrabberClicked = false;
902 0 : StartMoving(nsnull);
903 : }
904 : }
905 0 : if (mIsMoving) {
906 0 : nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
907 : PRInt32 clientX, clientY;
908 0 : mouseEvent->GetClientX(&clientX);
909 0 : mouseEvent->GetClientY(&clientY);
910 :
911 0 : PRInt32 newX = mPositionedObjectX + clientX - mOriginalX;
912 0 : PRInt32 newY = mPositionedObjectY + clientY - mOriginalY;
913 :
914 0 : SnapToGrid(newX, newY);
915 :
916 0 : mHTMLCSSUtils->SetCSSPropertyPixels(mPositioningShadow, leftStr, newX);
917 0 : mHTMLCSSUtils->SetCSSPropertyPixels(mPositioningShadow, topStr, newY);
918 : }
919 0 : return NS_OK;
920 : }
921 :
922 : void
923 0 : nsHTMLEditor::SetFinalSize(PRInt32 aX, PRInt32 aY)
924 : {
925 0 : if (!mResizedObject) {
926 : // paranoia
927 0 : return;
928 : }
929 :
930 0 : if (mActivatedHandle) {
931 0 : mActivatedHandle->RemoveAttribute(NS_LITERAL_STRING("_moz_activated"));
932 0 : mActivatedHandle = nsnull;
933 : }
934 :
935 : // we have now to set the new width and height of the resized object
936 : // we don't set the x and y position because we don't control that in
937 : // a normal HTML layout
938 0 : PRInt32 left = GetNewResizingX(aX, aY);
939 0 : PRInt32 top = GetNewResizingY(aX, aY);
940 0 : PRInt32 width = GetNewResizingWidth(aX, aY);
941 0 : PRInt32 height = GetNewResizingHeight(aX, aY);
942 0 : bool setWidth = !mResizedObjectIsAbsolutelyPositioned || (width != mResizedObjectWidth);
943 0 : bool setHeight = !mResizedObjectIsAbsolutelyPositioned || (height != mResizedObjectHeight);
944 :
945 : PRInt32 x, y;
946 0 : x = left - ((mResizedObjectIsAbsolutelyPositioned) ? mResizedObjectBorderLeft+mResizedObjectMarginLeft : 0);
947 0 : y = top - ((mResizedObjectIsAbsolutelyPositioned) ? mResizedObjectBorderTop+mResizedObjectMarginTop : 0);
948 :
949 : // we want one transaction only from a user's point of view
950 0 : nsAutoEditBatch batchIt(this);
951 :
952 0 : NS_NAMED_LITERAL_STRING(widthStr, "width");
953 0 : NS_NAMED_LITERAL_STRING(heightStr, "height");
954 :
955 0 : bool hasAttr = false;
956 0 : if (mResizedObjectIsAbsolutelyPositioned) {
957 0 : if (setHeight)
958 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject,
959 : nsEditProperty::cssTop,
960 : y,
961 0 : false);
962 0 : if (setWidth)
963 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject,
964 : nsEditProperty::cssLeft,
965 : x,
966 0 : false);
967 : }
968 0 : if (IsCSSEnabled() || mResizedObjectIsAbsolutelyPositioned) {
969 0 : if (setWidth && NS_SUCCEEDED(mResizedObject->HasAttribute(widthStr, &hasAttr)) && hasAttr)
970 0 : RemoveAttribute(mResizedObject, widthStr);
971 :
972 0 : hasAttr = false;
973 0 : if (setHeight && NS_SUCCEEDED(mResizedObject->HasAttribute(heightStr, &hasAttr)) && hasAttr)
974 0 : RemoveAttribute(mResizedObject, heightStr);
975 :
976 0 : if (setWidth)
977 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject,
978 : nsEditProperty::cssWidth,
979 : width,
980 0 : false);
981 0 : if (setHeight)
982 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject,
983 : nsEditProperty::cssHeight,
984 : height,
985 0 : false);
986 : }
987 : else {
988 : // we use HTML size and remove all equivalent CSS properties
989 :
990 : // we set the CSS width and height to remove it later,
991 : // triggering an immediate reflow; otherwise, we have problems
992 : // with asynchronous reflow
993 0 : if (setWidth)
994 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject,
995 : nsEditProperty::cssWidth,
996 : width,
997 0 : false);
998 0 : if (setHeight)
999 : mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject,
1000 : nsEditProperty::cssHeight,
1001 : height,
1002 0 : false);
1003 :
1004 0 : if (setWidth) {
1005 0 : nsAutoString w;
1006 0 : w.AppendInt(width);
1007 0 : SetAttribute(mResizedObject, widthStr, w);
1008 : }
1009 0 : if (setHeight) {
1010 0 : nsAutoString h;
1011 0 : h.AppendInt(height);
1012 0 : SetAttribute(mResizedObject, heightStr, h);
1013 : }
1014 :
1015 0 : if (setWidth)
1016 : mHTMLCSSUtils->RemoveCSSProperty(mResizedObject,
1017 : nsEditProperty::cssWidth,
1018 0 : EmptyString(),
1019 0 : false);
1020 0 : if (setHeight)
1021 : mHTMLCSSUtils->RemoveCSSProperty(mResizedObject,
1022 : nsEditProperty::cssHeight,
1023 0 : EmptyString(),
1024 0 : false);
1025 : }
1026 : // finally notify the listeners if any
1027 0 : PRInt32 listenersCount = objectResizeEventListeners.Count();
1028 0 : if (listenersCount) {
1029 0 : nsCOMPtr<nsIHTMLObjectResizeListener> listener;
1030 : PRInt32 index;
1031 0 : for (index = 0; index < listenersCount; index++) {
1032 0 : listener = objectResizeEventListeners[index];
1033 0 : listener->OnEndResizing(mResizedObject,
1034 : mResizedObjectWidth, mResizedObjectHeight,
1035 0 : width, height);
1036 : }
1037 : }
1038 :
1039 : // keep track of that size
1040 0 : mResizedObjectWidth = width;
1041 0 : mResizedObjectHeight = height;
1042 :
1043 0 : RefreshResizers();
1044 : }
1045 :
1046 : NS_IMETHODIMP
1047 0 : nsHTMLEditor::GetResizedObject(nsIDOMElement * *aResizedObject)
1048 : {
1049 0 : *aResizedObject = mResizedObject;
1050 0 : NS_IF_ADDREF(*aResizedObject);
1051 0 : return NS_OK;
1052 : }
1053 :
1054 : NS_IMETHODIMP
1055 0 : nsHTMLEditor::GetObjectResizingEnabled(bool *aIsObjectResizingEnabled)
1056 : {
1057 0 : *aIsObjectResizingEnabled = mIsObjectResizingEnabled;
1058 0 : return NS_OK;
1059 : }
1060 :
1061 : NS_IMETHODIMP
1062 0 : nsHTMLEditor::SetObjectResizingEnabled(bool aObjectResizingEnabled)
1063 : {
1064 0 : mIsObjectResizingEnabled = aObjectResizingEnabled;
1065 0 : return NS_OK;
1066 : }
1067 :
1068 : NS_IMETHODIMP
1069 0 : nsHTMLEditor::AddObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener)
1070 : {
1071 0 : NS_ENSURE_ARG_POINTER(aListener);
1072 0 : if (objectResizeEventListeners.Count() &&
1073 0 : objectResizeEventListeners.IndexOf(aListener) != -1) {
1074 : /* listener already registered */
1075 0 : NS_ASSERTION(false,
1076 : "trying to register an already registered object resize event listener");
1077 0 : return NS_OK;
1078 : }
1079 0 : objectResizeEventListeners.AppendObject(aListener);
1080 0 : return NS_OK;
1081 : }
1082 :
1083 : NS_IMETHODIMP
1084 0 : nsHTMLEditor::RemoveObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener)
1085 : {
1086 0 : NS_ENSURE_ARG_POINTER(aListener);
1087 0 : if (!objectResizeEventListeners.Count() ||
1088 0 : objectResizeEventListeners.IndexOf(aListener) == -1) {
1089 : /* listener was not registered */
1090 0 : NS_ASSERTION(false,
1091 : "trying to remove an object resize event listener that was not already registered");
1092 0 : return NS_OK;
1093 : }
1094 0 : objectResizeEventListeners.RemoveObject(aListener);
1095 0 : return NS_OK;
1096 : }
1097 :
|