1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/editor/libeditor/html/nsHTMLObjectResizer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1076 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/LookAndFeel.h" 1.10 +#include "mozilla/MathAlgorithms.h" 1.11 +#include "mozilla/Preferences.h" 1.12 +#include "mozilla/mozalloc.h" 1.13 +#include "nsAString.h" 1.14 +#include "nsAlgorithm.h" 1.15 +#include "nsAutoPtr.h" 1.16 +#include "nsCOMArray.h" 1.17 +#include "nsCOMPtr.h" 1.18 +#include "nsDebug.h" 1.19 +#include "nsEditProperty.h" 1.20 +#include "nsEditorUtils.h" 1.21 +#include "nsError.h" 1.22 +#include "nsHTMLCSSUtils.h" 1.23 +#include "nsHTMLEditUtils.h" 1.24 +#include "nsHTMLEditor.h" 1.25 +#include "nsHTMLObjectResizer.h" 1.26 +#include "nsIAtom.h" 1.27 +#include "nsIContent.h" 1.28 +#include "nsID.h" 1.29 +#include "nsIDOMDocument.h" 1.30 +#include "nsIDOMElement.h" 1.31 +#include "nsIDOMEvent.h" 1.32 +#include "nsIDOMEventTarget.h" 1.33 +#include "nsIDOMMouseEvent.h" 1.34 +#include "nsIDOMNode.h" 1.35 +#include "nsIDOMText.h" 1.36 +#include "nsIDocument.h" 1.37 +#include "nsIEditor.h" 1.38 +#include "nsIHTMLEditor.h" 1.39 +#include "nsIHTMLObjectResizeListener.h" 1.40 +#include "nsIHTMLObjectResizer.h" 1.41 +#include "nsIPresShell.h" 1.42 +#include "nsISupportsUtils.h" 1.43 +#include "nsPIDOMWindow.h" 1.44 +#include "nsReadableUtils.h" 1.45 +#include "nsString.h" 1.46 +#include "nsStringFwd.h" 1.47 +#include "nsSubstringTuple.h" 1.48 +#include "nscore.h" 1.49 +#include <algorithm> 1.50 + 1.51 +class nsISelection; 1.52 + 1.53 +using namespace mozilla; 1.54 + 1.55 +class nsHTMLEditUtils; 1.56 + 1.57 +// ================================================================== 1.58 +// DocumentResizeEventListener 1.59 +// ================================================================== 1.60 +NS_IMPL_ISUPPORTS(DocumentResizeEventListener, nsIDOMEventListener) 1.61 + 1.62 +DocumentResizeEventListener::DocumentResizeEventListener(nsIHTMLEditor * aEditor) 1.63 +{ 1.64 + mEditor = do_GetWeakReference(aEditor); 1.65 +} 1.66 + 1.67 +DocumentResizeEventListener::~DocumentResizeEventListener() 1.68 +{ 1.69 +} 1.70 + 1.71 +NS_IMETHODIMP 1.72 +DocumentResizeEventListener::HandleEvent(nsIDOMEvent* aMouseEvent) 1.73 +{ 1.74 + nsCOMPtr<nsIHTMLObjectResizer> objectResizer = do_QueryReferent(mEditor); 1.75 + if (objectResizer) 1.76 + return objectResizer->RefreshResizers(); 1.77 + return NS_OK; 1.78 +} 1.79 + 1.80 +// ================================================================== 1.81 +// ResizerSelectionListener 1.82 +// ================================================================== 1.83 + 1.84 +NS_IMPL_ISUPPORTS(ResizerSelectionListener, nsISelectionListener) 1.85 + 1.86 +ResizerSelectionListener::ResizerSelectionListener(nsIHTMLEditor * aEditor) 1.87 +{ 1.88 + mEditor = do_GetWeakReference(aEditor); 1.89 +} 1.90 + 1.91 +ResizerSelectionListener::~ResizerSelectionListener() 1.92 +{ 1.93 +} 1.94 + 1.95 +NS_IMETHODIMP 1.96 +ResizerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *aSelection, int16_t aReason) 1.97 +{ 1.98 + if ((aReason & (nsISelectionListener::MOUSEDOWN_REASON | 1.99 + nsISelectionListener::KEYPRESS_REASON | 1.100 + nsISelectionListener::SELECTALL_REASON)) && aSelection) 1.101 + { 1.102 + // the selection changed and we need to check if we have to 1.103 + // hide and/or redisplay resizing handles 1.104 + nsCOMPtr<nsIHTMLEditor> editor = do_QueryReferent(mEditor); 1.105 + if (editor) 1.106 + editor->CheckSelectionStateForAnonymousButtons(aSelection); 1.107 + } 1.108 + 1.109 + return NS_OK; 1.110 +} 1.111 + 1.112 +// ================================================================== 1.113 +// ResizerMouseMotionListener 1.114 +// ================================================================== 1.115 + 1.116 +NS_IMPL_ISUPPORTS(ResizerMouseMotionListener, nsIDOMEventListener) 1.117 + 1.118 +ResizerMouseMotionListener::ResizerMouseMotionListener(nsIHTMLEditor * aEditor) 1.119 +{ 1.120 + mEditor = do_GetWeakReference(aEditor); 1.121 +} 1.122 + 1.123 +ResizerMouseMotionListener::~ResizerMouseMotionListener() 1.124 +{ 1.125 +} 1.126 + 1.127 +NS_IMETHODIMP 1.128 +ResizerMouseMotionListener::HandleEvent(nsIDOMEvent* aMouseEvent) 1.129 +{ 1.130 + nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) ); 1.131 + if (!mouseEvent) { 1.132 + //non-ui event passed in. bad things. 1.133 + return NS_OK; 1.134 + } 1.135 + 1.136 + // Don't do anything special if not an HTML object resizer editor 1.137 + nsCOMPtr<nsIHTMLObjectResizer> objectResizer = do_QueryReferent(mEditor); 1.138 + if (objectResizer) 1.139 + { 1.140 + // check if we have to redisplay a resizing shadow 1.141 + objectResizer->MouseMove(aMouseEvent); 1.142 + } 1.143 + 1.144 + return NS_OK; 1.145 +} 1.146 + 1.147 +// ================================================================== 1.148 +// nsHTMLEditor 1.149 +// ================================================================== 1.150 + 1.151 +nsresult 1.152 +nsHTMLEditor::CreateResizer(nsIDOMElement ** aReturn, int16_t aLocation, nsIDOMNode * aParentNode) 1.153 +{ 1.154 + nsresult res = CreateAnonymousElement(NS_LITERAL_STRING("span"), 1.155 + aParentNode, 1.156 + NS_LITERAL_STRING("mozResizer"), 1.157 + false, 1.158 + aReturn); 1.159 + 1.160 + NS_ENSURE_SUCCESS(res, res); 1.161 + NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE); 1.162 + 1.163 + // add the mouse listener so we can detect a click on a resizer 1.164 + nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(*aReturn)); 1.165 + evtTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), mEventListener, 1.166 + true); 1.167 + 1.168 + nsAutoString locationStr; 1.169 + switch (aLocation) { 1.170 + case nsIHTMLObjectResizer::eTopLeft: 1.171 + locationStr = kTopLeft; 1.172 + break; 1.173 + case nsIHTMLObjectResizer::eTop: 1.174 + locationStr = kTop; 1.175 + break; 1.176 + case nsIHTMLObjectResizer::eTopRight: 1.177 + locationStr = kTopRight; 1.178 + break; 1.179 + 1.180 + case nsIHTMLObjectResizer::eLeft: 1.181 + locationStr = kLeft; 1.182 + break; 1.183 + case nsIHTMLObjectResizer::eRight: 1.184 + locationStr = kRight; 1.185 + break; 1.186 + 1.187 + case nsIHTMLObjectResizer::eBottomLeft: 1.188 + locationStr = kBottomLeft; 1.189 + break; 1.190 + case nsIHTMLObjectResizer::eBottom: 1.191 + locationStr = kBottom; 1.192 + break; 1.193 + case nsIHTMLObjectResizer::eBottomRight: 1.194 + locationStr = kBottomRight; 1.195 + break; 1.196 + } 1.197 + 1.198 + res = (*aReturn)->SetAttribute(NS_LITERAL_STRING("anonlocation"), 1.199 + locationStr); 1.200 + return res; 1.201 +} 1.202 + 1.203 +nsresult 1.204 +nsHTMLEditor::CreateShadow(nsIDOMElement ** aReturn, nsIDOMNode * aParentNode, 1.205 + nsIDOMElement * aOriginalObject) 1.206 +{ 1.207 + // let's create an image through the element factory 1.208 + nsAutoString name; 1.209 + if (nsHTMLEditUtils::IsImage(aOriginalObject)) 1.210 + name.AssignLiteral("img"); 1.211 + else 1.212 + name.AssignLiteral("span"); 1.213 + nsresult res = CreateAnonymousElement(name, 1.214 + aParentNode, 1.215 + NS_LITERAL_STRING("mozResizingShadow"), 1.216 + true, 1.217 + aReturn); 1.218 + 1.219 + NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE); 1.220 + 1.221 + return res; 1.222 +} 1.223 + 1.224 +nsresult 1.225 +nsHTMLEditor::CreateResizingInfo(nsIDOMElement ** aReturn, nsIDOMNode * aParentNode) 1.226 +{ 1.227 + // let's create an info box through the element factory 1.228 + nsresult res = CreateAnonymousElement(NS_LITERAL_STRING("span"), 1.229 + aParentNode, 1.230 + NS_LITERAL_STRING("mozResizingInfo"), 1.231 + true, 1.232 + aReturn); 1.233 + 1.234 + NS_ENSURE_TRUE(*aReturn, NS_ERROR_FAILURE); 1.235 + 1.236 + return res; 1.237 +} 1.238 + 1.239 +nsresult 1.240 +nsHTMLEditor::SetAllResizersPosition() 1.241 +{ 1.242 + NS_ENSURE_TRUE(mTopLeftHandle, NS_ERROR_FAILURE); 1.243 + 1.244 + int32_t x = mResizedObjectX; 1.245 + int32_t y = mResizedObjectY; 1.246 + int32_t w = mResizedObjectWidth; 1.247 + int32_t h = mResizedObjectHeight; 1.248 + 1.249 + // now let's place all the resizers around the image 1.250 + 1.251 + // get the size of resizers 1.252 + nsAutoString value; 1.253 + float resizerWidth, resizerHeight; 1.254 + nsCOMPtr<nsIAtom> dummyUnit; 1.255 + mHTMLCSSUtils->GetComputedProperty(mTopLeftHandle, nsEditProperty::cssWidth, value); 1.256 + mHTMLCSSUtils->ParseLength(value, &resizerWidth, getter_AddRefs(dummyUnit)); 1.257 + mHTMLCSSUtils->GetComputedProperty(mTopLeftHandle, nsEditProperty::cssHeight, value); 1.258 + mHTMLCSSUtils->ParseLength(value, &resizerHeight, getter_AddRefs(dummyUnit)); 1.259 + 1.260 + int32_t rw = (int32_t)((resizerWidth + 1) / 2); 1.261 + int32_t rh = (int32_t)((resizerHeight+ 1) / 2); 1.262 + 1.263 + SetAnonymousElementPosition(x-rw, y-rh, mTopLeftHandle); 1.264 + SetAnonymousElementPosition(x+w/2-rw, y-rh, mTopHandle); 1.265 + SetAnonymousElementPosition(x+w-rw-1, y-rh, mTopRightHandle); 1.266 + 1.267 + SetAnonymousElementPosition(x-rw, y+h/2-rh, mLeftHandle); 1.268 + SetAnonymousElementPosition(x+w-rw-1, y+h/2-rh, mRightHandle); 1.269 + 1.270 + SetAnonymousElementPosition(x-rw, y+h-rh-1, mBottomLeftHandle); 1.271 + SetAnonymousElementPosition(x+w/2-rw, y+h-rh-1, mBottomHandle); 1.272 + SetAnonymousElementPosition(x+w-rw-1, y+h-rh-1, mBottomRightHandle); 1.273 + 1.274 + return NS_OK; 1.275 +} 1.276 + 1.277 +NS_IMETHODIMP 1.278 +nsHTMLEditor::RefreshResizers() 1.279 +{ 1.280 + // nothing to do if resizers are not displayed... 1.281 + NS_ENSURE_TRUE(mResizedObject, NS_OK); 1.282 + 1.283 + nsresult res = GetPositionAndDimensions(mResizedObject, 1.284 + mResizedObjectX, 1.285 + mResizedObjectY, 1.286 + mResizedObjectWidth, 1.287 + mResizedObjectHeight, 1.288 + mResizedObjectBorderLeft, 1.289 + mResizedObjectBorderTop, 1.290 + mResizedObjectMarginLeft, 1.291 + mResizedObjectMarginTop); 1.292 + 1.293 + NS_ENSURE_SUCCESS(res, res); 1.294 + res = SetAllResizersPosition(); 1.295 + NS_ENSURE_SUCCESS(res, res); 1.296 + return SetShadowPosition(mResizingShadow, mResizedObject, 1.297 + mResizedObjectX, mResizedObjectY); 1.298 +} 1.299 + 1.300 +NS_IMETHODIMP 1.301 +nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement) 1.302 +{ 1.303 + nsresult res = ShowResizersInner(aResizedElement); 1.304 + if (NS_FAILED(res)) 1.305 + HideResizers(); 1.306 + return res; 1.307 +} 1.308 + 1.309 +nsresult 1.310 +nsHTMLEditor::ShowResizersInner(nsIDOMElement *aResizedElement) 1.311 +{ 1.312 + NS_ENSURE_ARG_POINTER(aResizedElement); 1.313 + nsresult res; 1.314 + 1.315 + nsCOMPtr<nsIDOMNode> parentNode; 1.316 + res = aResizedElement->GetParentNode(getter_AddRefs(parentNode)); 1.317 + NS_ENSURE_SUCCESS(res, res); 1.318 + 1.319 + if (mResizedObject) { 1.320 + NS_ERROR("call HideResizers first"); 1.321 + return NS_ERROR_UNEXPECTED; 1.322 + } 1.323 + mResizedObject = aResizedElement; 1.324 + 1.325 + // The resizers and the shadow will be anonymous siblings of the element. 1.326 + res = CreateResizer(getter_AddRefs(mTopLeftHandle), 1.327 + nsIHTMLObjectResizer::eTopLeft, parentNode); 1.328 + NS_ENSURE_SUCCESS(res, res); 1.329 + res = CreateResizer(getter_AddRefs(mTopHandle), 1.330 + nsIHTMLObjectResizer::eTop, parentNode); 1.331 + NS_ENSURE_SUCCESS(res, res); 1.332 + res = CreateResizer(getter_AddRefs(mTopRightHandle), 1.333 + nsIHTMLObjectResizer::eTopRight, parentNode); 1.334 + NS_ENSURE_SUCCESS(res, res); 1.335 + 1.336 + res = CreateResizer(getter_AddRefs(mLeftHandle), 1.337 + nsIHTMLObjectResizer::eLeft, parentNode); 1.338 + NS_ENSURE_SUCCESS(res, res); 1.339 + res = CreateResizer(getter_AddRefs(mRightHandle), 1.340 + nsIHTMLObjectResizer::eRight, parentNode); 1.341 + NS_ENSURE_SUCCESS(res, res); 1.342 + 1.343 + res = CreateResizer(getter_AddRefs(mBottomLeftHandle), 1.344 + nsIHTMLObjectResizer::eBottomLeft, parentNode); 1.345 + NS_ENSURE_SUCCESS(res, res); 1.346 + res = CreateResizer(getter_AddRefs(mBottomHandle), 1.347 + nsIHTMLObjectResizer::eBottom, parentNode); 1.348 + NS_ENSURE_SUCCESS(res, res); 1.349 + res = CreateResizer(getter_AddRefs(mBottomRightHandle), 1.350 + nsIHTMLObjectResizer::eBottomRight, parentNode); 1.351 + NS_ENSURE_SUCCESS(res, res); 1.352 + 1.353 + res = GetPositionAndDimensions(aResizedElement, 1.354 + mResizedObjectX, 1.355 + mResizedObjectY, 1.356 + mResizedObjectWidth, 1.357 + mResizedObjectHeight, 1.358 + mResizedObjectBorderLeft, 1.359 + mResizedObjectBorderTop, 1.360 + mResizedObjectMarginLeft, 1.361 + mResizedObjectMarginTop); 1.362 + NS_ENSURE_SUCCESS(res, res); 1.363 + 1.364 + // and let's set their absolute positions in the document 1.365 + res = SetAllResizersPosition(); 1.366 + NS_ENSURE_SUCCESS(res, res); 1.367 + 1.368 + // now, let's create the resizing shadow 1.369 + res = CreateShadow(getter_AddRefs(mResizingShadow), parentNode, 1.370 + aResizedElement); 1.371 + NS_ENSURE_SUCCESS(res, res); 1.372 + // and set its position 1.373 + res = SetShadowPosition(mResizingShadow, mResizedObject, 1.374 + mResizedObjectX, mResizedObjectY); 1.375 + NS_ENSURE_SUCCESS(res, res); 1.376 + 1.377 + // and then the resizing info tooltip 1.378 + res = CreateResizingInfo(getter_AddRefs(mResizingInfo), parentNode); 1.379 + NS_ENSURE_SUCCESS(res, res); 1.380 + 1.381 + // and listen to the "resize" event on the window first, get the 1.382 + // window from the document... 1.383 + nsCOMPtr<nsIDocument> doc = GetDocument(); 1.384 + NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER); 1.385 + 1.386 + nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(doc->GetWindow()); 1.387 + if (!target) { return NS_ERROR_NULL_POINTER; } 1.388 + 1.389 + mResizeEventListenerP = new DocumentResizeEventListener(this); 1.390 + if (!mResizeEventListenerP) { return NS_ERROR_OUT_OF_MEMORY; } 1.391 + res = target->AddEventListener(NS_LITERAL_STRING("resize"), mResizeEventListenerP, false); 1.392 + 1.393 + aResizedElement->SetAttribute(NS_LITERAL_STRING("_moz_resizing"), NS_LITERAL_STRING("true")); 1.394 + return res; 1.395 +} 1.396 + 1.397 +NS_IMETHODIMP 1.398 +nsHTMLEditor::HideResizers(void) 1.399 +{ 1.400 + NS_ENSURE_TRUE(mResizedObject, NS_OK); 1.401 + 1.402 + // get the presshell's document observer interface. 1.403 + nsCOMPtr<nsIPresShell> ps = GetPresShell(); 1.404 + // We allow the pres shell to be null; when it is, we presume there 1.405 + // are no document observers to notify, but we still want to 1.406 + // UnbindFromTree. 1.407 + 1.408 + nsresult res; 1.409 + nsCOMPtr<nsIDOMNode> parentNode; 1.410 + nsCOMPtr<nsIContent> parentContent; 1.411 + 1.412 + if (mTopLeftHandle) { 1.413 + res = mTopLeftHandle->GetParentNode(getter_AddRefs(parentNode)); 1.414 + NS_ENSURE_SUCCESS(res, res); 1.415 + parentContent = do_QueryInterface(parentNode); 1.416 + } 1.417 + 1.418 + NS_NAMED_LITERAL_STRING(mousedown, "mousedown"); 1.419 + 1.420 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.421 + mTopLeftHandle, parentContent, ps); 1.422 + mTopLeftHandle = nullptr; 1.423 + 1.424 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.425 + mTopHandle, parentContent, ps); 1.426 + mTopHandle = nullptr; 1.427 + 1.428 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.429 + mTopRightHandle, parentContent, ps); 1.430 + mTopRightHandle = nullptr; 1.431 + 1.432 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.433 + mLeftHandle, parentContent, ps); 1.434 + mLeftHandle = nullptr; 1.435 + 1.436 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.437 + mRightHandle, parentContent, ps); 1.438 + mRightHandle = nullptr; 1.439 + 1.440 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.441 + mBottomLeftHandle, parentContent, ps); 1.442 + mBottomLeftHandle = nullptr; 1.443 + 1.444 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.445 + mBottomHandle, parentContent, ps); 1.446 + mBottomHandle = nullptr; 1.447 + 1.448 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.449 + mBottomRightHandle, parentContent, ps); 1.450 + mBottomRightHandle = nullptr; 1.451 + 1.452 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.453 + mResizingShadow, parentContent, ps); 1.454 + mResizingShadow = nullptr; 1.455 + 1.456 + RemoveListenerAndDeleteRef(mousedown, mEventListener, true, 1.457 + mResizingInfo, parentContent, ps); 1.458 + mResizingInfo = nullptr; 1.459 + 1.460 + if (mActivatedHandle) { 1.461 + mActivatedHandle->RemoveAttribute(NS_LITERAL_STRING("_moz_activated")); 1.462 + mActivatedHandle = nullptr; 1.463 + } 1.464 + 1.465 + // don't forget to remove the listeners ! 1.466 + 1.467 + nsCOMPtr<nsIDOMEventTarget> target = GetDOMEventTarget(); 1.468 + 1.469 + if (target && mMouseMotionListenerP) 1.470 + { 1.471 + res = target->RemoveEventListener(NS_LITERAL_STRING("mousemove"), 1.472 + mMouseMotionListenerP, true); 1.473 + NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener"); 1.474 + } 1.475 + mMouseMotionListenerP = nullptr; 1.476 + 1.477 + nsCOMPtr<nsIDocument> doc = GetDocument(); 1.478 + if (!doc) { return NS_ERROR_NULL_POINTER; } 1.479 + target = do_QueryInterface(doc->GetWindow()); 1.480 + if (!target) { return NS_ERROR_NULL_POINTER; } 1.481 + 1.482 + if (mResizeEventListenerP) { 1.483 + res = target->RemoveEventListener(NS_LITERAL_STRING("resize"), mResizeEventListenerP, false); 1.484 + NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove resize event listener"); 1.485 + } 1.486 + mResizeEventListenerP = nullptr; 1.487 + 1.488 + mResizedObject->RemoveAttribute(NS_LITERAL_STRING("_moz_resizing")); 1.489 + mResizedObject = nullptr; 1.490 + 1.491 + return NS_OK; 1.492 +} 1.493 + 1.494 +void 1.495 +nsHTMLEditor::HideShadowAndInfo() 1.496 +{ 1.497 + if (mResizingShadow) 1.498 + mResizingShadow->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden")); 1.499 + if (mResizingInfo) 1.500 + mResizingInfo->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden")); 1.501 +} 1.502 + 1.503 +nsresult 1.504 +nsHTMLEditor::StartResizing(nsIDOMElement *aHandle) 1.505 +{ 1.506 + // First notify the listeners if any 1.507 + int32_t listenersCount = objectResizeEventListeners.Count(); 1.508 + if (listenersCount) { 1.509 + nsCOMPtr<nsIHTMLObjectResizeListener> listener; 1.510 + int32_t index; 1.511 + for (index = 0; index < listenersCount; index++) { 1.512 + listener = objectResizeEventListeners[index]; 1.513 + listener->OnStartResizing(mResizedObject); 1.514 + } 1.515 + } 1.516 + 1.517 + mIsResizing = true; 1.518 + mActivatedHandle = aHandle; 1.519 + mActivatedHandle->SetAttribute(NS_LITERAL_STRING("_moz_activated"), NS_LITERAL_STRING("true")); 1.520 + 1.521 + // do we want to preserve ratio or not? 1.522 + bool preserveRatio = nsHTMLEditUtils::IsImage(mResizedObject) && 1.523 + Preferences::GetBool("editor.resizing.preserve_ratio", true); 1.524 + 1.525 + // the way we change the position/size of the shadow depends on 1.526 + // the handle 1.527 + nsAutoString locationStr; 1.528 + aHandle->GetAttribute(NS_LITERAL_STRING("anonlocation"), locationStr); 1.529 + if (locationStr.Equals(kTopLeft)) { 1.530 + SetResizeIncrements(1, 1, -1, -1, preserveRatio); 1.531 + } 1.532 + else if (locationStr.Equals(kTop)) { 1.533 + SetResizeIncrements(0, 1, 0, -1, false); 1.534 + } 1.535 + else if (locationStr.Equals(kTopRight)) { 1.536 + SetResizeIncrements(0, 1, 1, -1, preserveRatio); 1.537 + } 1.538 + else if (locationStr.Equals(kLeft)) { 1.539 + SetResizeIncrements(1, 0, -1, 0, false); 1.540 + } 1.541 + else if (locationStr.Equals(kRight)) { 1.542 + SetResizeIncrements(0, 0, 1, 0, false); 1.543 + } 1.544 + else if (locationStr.Equals(kBottomLeft)) { 1.545 + SetResizeIncrements(1, 0, -1, 1, preserveRatio); 1.546 + } 1.547 + else if (locationStr.Equals(kBottom)) { 1.548 + SetResizeIncrements(0, 0, 0, 1, false); 1.549 + } 1.550 + else if (locationStr.Equals(kBottomRight)) { 1.551 + SetResizeIncrements(0, 0, 1, 1, preserveRatio); 1.552 + } 1.553 + 1.554 + // make the shadow appear 1.555 + mResizingShadow->RemoveAttribute(NS_LITERAL_STRING("class")); 1.556 + 1.557 + // position it 1.558 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow, 1.559 + NS_LITERAL_STRING("width"), 1.560 + mResizedObjectWidth); 1.561 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow, 1.562 + NS_LITERAL_STRING("height"), 1.563 + mResizedObjectHeight); 1.564 + 1.565 + // add a mouse move listener to the editor 1.566 + nsresult result = NS_OK; 1.567 + if (!mMouseMotionListenerP) { 1.568 + mMouseMotionListenerP = new ResizerMouseMotionListener(this); 1.569 + if (!mMouseMotionListenerP) { 1.570 + return NS_ERROR_OUT_OF_MEMORY; 1.571 + } 1.572 + 1.573 + nsCOMPtr<nsIDOMEventTarget> target = GetDOMEventTarget(); 1.574 + NS_ENSURE_TRUE(target, NS_ERROR_FAILURE); 1.575 + 1.576 + result = target->AddEventListener(NS_LITERAL_STRING("mousemove"), 1.577 + mMouseMotionListenerP, true); 1.578 + NS_ASSERTION(NS_SUCCEEDED(result), 1.579 + "failed to register mouse motion listener"); 1.580 + } 1.581 + return result; 1.582 +} 1.583 + 1.584 + 1.585 +NS_IMETHODIMP 1.586 +nsHTMLEditor::MouseDown(int32_t aClientX, int32_t aClientY, 1.587 + nsIDOMElement *aTarget, nsIDOMEvent* aEvent) 1.588 +{ 1.589 + bool anonElement = false; 1.590 + if (aTarget && NS_SUCCEEDED(aTarget->HasAttribute(NS_LITERAL_STRING("_moz_anonclass"), &anonElement))) 1.591 + // we caught a click on an anonymous element 1.592 + if (anonElement) { 1.593 + nsAutoString anonclass; 1.594 + nsresult res = aTarget->GetAttribute(NS_LITERAL_STRING("_moz_anonclass"), anonclass); 1.595 + NS_ENSURE_SUCCESS(res, res); 1.596 + if (anonclass.EqualsLiteral("mozResizer")) { 1.597 + // and that element is a resizer, let's start resizing! 1.598 + aEvent->PreventDefault(); 1.599 + 1.600 + mOriginalX = aClientX; 1.601 + mOriginalY = aClientY; 1.602 + return StartResizing(aTarget); 1.603 + } 1.604 + if (anonclass.EqualsLiteral("mozGrabber")) { 1.605 + // and that element is a grabber, let's start moving the element! 1.606 + mOriginalX = aClientX; 1.607 + mOriginalY = aClientY; 1.608 + return GrabberClicked(); 1.609 + } 1.610 + } 1.611 + return NS_OK; 1.612 +} 1.613 + 1.614 +NS_IMETHODIMP 1.615 +nsHTMLEditor::MouseUp(int32_t aClientX, int32_t aClientY, 1.616 + nsIDOMElement *aTarget) 1.617 +{ 1.618 + if (mIsResizing) { 1.619 + // we are resizing and release the mouse button, so let's 1.620 + // end the resizing process 1.621 + mIsResizing = false; 1.622 + HideShadowAndInfo(); 1.623 + SetFinalSize(aClientX, aClientY); 1.624 + } 1.625 + else if (mIsMoving || mGrabberClicked) { 1.626 + if (mIsMoving) { 1.627 + mPositioningShadow->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden")); 1.628 + SetFinalPosition(aClientX, aClientY); 1.629 + } 1.630 + if (mGrabberClicked) { 1.631 + EndMoving(); 1.632 + } 1.633 + } 1.634 + return NS_OK; 1.635 +} 1.636 + 1.637 + 1.638 +void 1.639 +nsHTMLEditor::SetResizeIncrements(int32_t aX, int32_t aY, 1.640 + int32_t aW, int32_t aH, 1.641 + bool aPreserveRatio) 1.642 +{ 1.643 + mXIncrementFactor = aX; 1.644 + mYIncrementFactor = aY; 1.645 + mWidthIncrementFactor = aW; 1.646 + mHeightIncrementFactor = aH; 1.647 + mPreserveRatio = aPreserveRatio; 1.648 +} 1.649 + 1.650 +nsresult 1.651 +nsHTMLEditor::SetResizingInfoPosition(int32_t aX, int32_t aY, int32_t aW, int32_t aH) 1.652 +{ 1.653 + nsCOMPtr<nsIDOMDocument> domdoc = GetDOMDocument(); 1.654 + 1.655 + NS_NAMED_LITERAL_STRING(leftStr, "left"); 1.656 + NS_NAMED_LITERAL_STRING(topStr, "top"); 1.657 + 1.658 + // Determine the position of the resizing info box based upon the new 1.659 + // position and size of the element (aX, aY, aW, aH), and which 1.660 + // resizer is the "activated handle". For example, place the resizing 1.661 + // info box at the bottom-right corner of the new element, if the element 1.662 + // is being resized by the bottom-right resizer. 1.663 + int32_t infoXPosition; 1.664 + int32_t infoYPosition; 1.665 + 1.666 + if (mActivatedHandle == mTopLeftHandle || 1.667 + mActivatedHandle == mLeftHandle || 1.668 + mActivatedHandle == mBottomLeftHandle) 1.669 + infoXPosition = aX; 1.670 + else if (mActivatedHandle == mTopHandle || 1.671 + mActivatedHandle == mBottomHandle) 1.672 + infoXPosition = aX + (aW / 2); 1.673 + else 1.674 + // should only occur when mActivatedHandle is one of the 3 right-side 1.675 + // handles, but this is a reasonable default if it isn't any of them (?) 1.676 + infoXPosition = aX + aW; 1.677 + 1.678 + if (mActivatedHandle == mTopLeftHandle || 1.679 + mActivatedHandle == mTopHandle || 1.680 + mActivatedHandle == mTopRightHandle) 1.681 + infoYPosition = aY; 1.682 + else if (mActivatedHandle == mLeftHandle || 1.683 + mActivatedHandle == mRightHandle) 1.684 + infoYPosition = aY + (aH / 2); 1.685 + else 1.686 + // should only occur when mActivatedHandle is one of the 3 bottom-side 1.687 + // handles, but this is a reasonable default if it isn't any of them (?) 1.688 + infoYPosition = aY + aH; 1.689 + 1.690 + // Offset info box by 20 so it's not directly under the mouse cursor. 1.691 + const int mouseCursorOffset = 20; 1.692 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingInfo, leftStr, 1.693 + infoXPosition + mouseCursorOffset); 1.694 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingInfo, topStr, 1.695 + infoYPosition + mouseCursorOffset); 1.696 + 1.697 + nsCOMPtr<nsIDOMNode> textInfo; 1.698 + nsresult res = mResizingInfo->GetFirstChild(getter_AddRefs(textInfo)); 1.699 + NS_ENSURE_SUCCESS(res, res); 1.700 + nsCOMPtr<nsIDOMNode> junk; 1.701 + if (textInfo) { 1.702 + res = mResizingInfo->RemoveChild(textInfo, getter_AddRefs(junk)); 1.703 + NS_ENSURE_SUCCESS(res, res); 1.704 + textInfo = nullptr; 1.705 + junk = nullptr; 1.706 + } 1.707 + 1.708 + nsAutoString widthStr, heightStr, diffWidthStr, diffHeightStr; 1.709 + widthStr.AppendInt(aW); 1.710 + heightStr.AppendInt(aH); 1.711 + int32_t diffWidth = aW - mResizedObjectWidth; 1.712 + int32_t diffHeight = aH - mResizedObjectHeight; 1.713 + if (diffWidth > 0) 1.714 + diffWidthStr.AssignLiteral("+"); 1.715 + if (diffHeight > 0) 1.716 + diffHeightStr.AssignLiteral("+"); 1.717 + diffWidthStr.AppendInt(diffWidth); 1.718 + diffHeightStr.AppendInt(diffHeight); 1.719 + 1.720 + nsAutoString info(widthStr + NS_LITERAL_STRING(" x ") + heightStr + 1.721 + NS_LITERAL_STRING(" (") + diffWidthStr + 1.722 + NS_LITERAL_STRING(", ") + diffHeightStr + 1.723 + NS_LITERAL_STRING(")")); 1.724 + 1.725 + nsCOMPtr<nsIDOMText> nodeAsText; 1.726 + res = domdoc->CreateTextNode(info, getter_AddRefs(nodeAsText)); 1.727 + NS_ENSURE_SUCCESS(res, res); 1.728 + textInfo = do_QueryInterface(nodeAsText); 1.729 + res = mResizingInfo->AppendChild(textInfo, getter_AddRefs(junk)); 1.730 + NS_ENSURE_SUCCESS(res, res); 1.731 + 1.732 + bool hasClass = false; 1.733 + if (NS_SUCCEEDED(mResizingInfo->HasAttribute(NS_LITERAL_STRING("class"), &hasClass )) && hasClass) 1.734 + res = mResizingInfo->RemoveAttribute(NS_LITERAL_STRING("class")); 1.735 + 1.736 + return res; 1.737 +} 1.738 + 1.739 +nsresult 1.740 +nsHTMLEditor::SetShadowPosition(nsIDOMElement * aShadow, 1.741 + nsIDOMElement * aOriginalObject, 1.742 + int32_t aOriginalObjectX, 1.743 + int32_t aOriginalObjectY) 1.744 +{ 1.745 + SetAnonymousElementPosition(aOriginalObjectX, aOriginalObjectY, aShadow); 1.746 + 1.747 + if (nsHTMLEditUtils::IsImage(aOriginalObject)) { 1.748 + nsAutoString imageSource; 1.749 + nsresult res = aOriginalObject->GetAttribute(NS_LITERAL_STRING("src"), 1.750 + imageSource); 1.751 + NS_ENSURE_SUCCESS(res, res); 1.752 + res = aShadow->SetAttribute(NS_LITERAL_STRING("src"), imageSource); 1.753 + NS_ENSURE_SUCCESS(res, res); 1.754 + } 1.755 + return NS_OK; 1.756 +} 1.757 + 1.758 +int32_t 1.759 +nsHTMLEditor::GetNewResizingIncrement(int32_t aX, int32_t aY, int32_t aID) 1.760 +{ 1.761 + int32_t result = 0; 1.762 + if (!mPreserveRatio) { 1.763 + switch (aID) { 1.764 + case kX: 1.765 + case kWidth: 1.766 + result = aX - mOriginalX; 1.767 + break; 1.768 + case kY: 1.769 + case kHeight: 1.770 + result = aY - mOriginalY; 1.771 + break; 1.772 + } 1.773 + return result; 1.774 + } 1.775 + 1.776 + int32_t xi = (aX - mOriginalX) * mWidthIncrementFactor; 1.777 + int32_t yi = (aY - mOriginalY) * mHeightIncrementFactor; 1.778 + float objectSizeRatio = 1.779 + ((float)mResizedObjectWidth) / ((float)mResizedObjectHeight); 1.780 + result = (xi > yi) ? xi : yi; 1.781 + switch (aID) { 1.782 + case kX: 1.783 + case kWidth: 1.784 + if (result == yi) 1.785 + result = (int32_t) (((float) result) * objectSizeRatio); 1.786 + result = (int32_t) (((float) result) * mWidthIncrementFactor); 1.787 + break; 1.788 + case kY: 1.789 + case kHeight: 1.790 + if (result == xi) 1.791 + result = (int32_t) (((float) result) / objectSizeRatio); 1.792 + result = (int32_t) (((float) result) * mHeightIncrementFactor); 1.793 + break; 1.794 + } 1.795 + return result; 1.796 +} 1.797 + 1.798 +int32_t 1.799 +nsHTMLEditor::GetNewResizingX(int32_t aX, int32_t aY) 1.800 +{ 1.801 + int32_t resized = mResizedObjectX + 1.802 + GetNewResizingIncrement(aX, aY, kX) * mXIncrementFactor; 1.803 + int32_t max = mResizedObjectX + mResizedObjectWidth; 1.804 + return std::min(resized, max); 1.805 +} 1.806 + 1.807 +int32_t 1.808 +nsHTMLEditor::GetNewResizingY(int32_t aX, int32_t aY) 1.809 +{ 1.810 + int32_t resized = mResizedObjectY + 1.811 + GetNewResizingIncrement(aX, aY, kY) * mYIncrementFactor; 1.812 + int32_t max = mResizedObjectY + mResizedObjectHeight; 1.813 + return std::min(resized, max); 1.814 +} 1.815 + 1.816 +int32_t 1.817 +nsHTMLEditor::GetNewResizingWidth(int32_t aX, int32_t aY) 1.818 +{ 1.819 + int32_t resized = mResizedObjectWidth + 1.820 + GetNewResizingIncrement(aX, aY, kWidth) * 1.821 + mWidthIncrementFactor; 1.822 + return std::max(resized, 1); 1.823 +} 1.824 + 1.825 +int32_t 1.826 +nsHTMLEditor::GetNewResizingHeight(int32_t aX, int32_t aY) 1.827 +{ 1.828 + int32_t resized = mResizedObjectHeight + 1.829 + GetNewResizingIncrement(aX, aY, kHeight) * 1.830 + mHeightIncrementFactor; 1.831 + return std::max(resized, 1); 1.832 +} 1.833 + 1.834 + 1.835 +NS_IMETHODIMP 1.836 +nsHTMLEditor::MouseMove(nsIDOMEvent* aMouseEvent) 1.837 +{ 1.838 + NS_NAMED_LITERAL_STRING(leftStr, "left"); 1.839 + NS_NAMED_LITERAL_STRING(topStr, "top"); 1.840 + 1.841 + if (mIsResizing) { 1.842 + // we are resizing and the mouse pointer's position has changed 1.843 + // we have to resdisplay the shadow 1.844 + nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) ); 1.845 + int32_t clientX, clientY; 1.846 + mouseEvent->GetClientX(&clientX); 1.847 + mouseEvent->GetClientY(&clientY); 1.848 + 1.849 + int32_t newX = GetNewResizingX(clientX, clientY); 1.850 + int32_t newY = GetNewResizingY(clientX, clientY); 1.851 + int32_t newWidth = GetNewResizingWidth(clientX, clientY); 1.852 + int32_t newHeight = GetNewResizingHeight(clientX, clientY); 1.853 + 1.854 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow, 1.855 + leftStr, 1.856 + newX); 1.857 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow, 1.858 + topStr, 1.859 + newY); 1.860 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow, 1.861 + NS_LITERAL_STRING("width"), 1.862 + newWidth); 1.863 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizingShadow, 1.864 + NS_LITERAL_STRING("height"), 1.865 + newHeight); 1.866 + 1.867 + return SetResizingInfoPosition(newX, newY, newWidth, newHeight); 1.868 + } 1.869 + 1.870 + if (mGrabberClicked) { 1.871 + nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) ); 1.872 + int32_t clientX, clientY; 1.873 + mouseEvent->GetClientX(&clientX); 1.874 + mouseEvent->GetClientY(&clientY); 1.875 + 1.876 + int32_t xThreshold = 1.877 + LookAndFeel::GetInt(LookAndFeel::eIntID_DragThresholdX, 1); 1.878 + int32_t yThreshold = 1.879 + LookAndFeel::GetInt(LookAndFeel::eIntID_DragThresholdY, 1); 1.880 + 1.881 + if (DeprecatedAbs(clientX - mOriginalX) * 2 >= xThreshold || 1.882 + DeprecatedAbs(clientY - mOriginalY) * 2 >= yThreshold) { 1.883 + mGrabberClicked = false; 1.884 + StartMoving(nullptr); 1.885 + } 1.886 + } 1.887 + if (mIsMoving) { 1.888 + nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) ); 1.889 + int32_t clientX, clientY; 1.890 + mouseEvent->GetClientX(&clientX); 1.891 + mouseEvent->GetClientY(&clientY); 1.892 + 1.893 + int32_t newX = mPositionedObjectX + clientX - mOriginalX; 1.894 + int32_t newY = mPositionedObjectY + clientY - mOriginalY; 1.895 + 1.896 + SnapToGrid(newX, newY); 1.897 + 1.898 + mHTMLCSSUtils->SetCSSPropertyPixels(mPositioningShadow, leftStr, newX); 1.899 + mHTMLCSSUtils->SetCSSPropertyPixels(mPositioningShadow, topStr, newY); 1.900 + } 1.901 + return NS_OK; 1.902 +} 1.903 + 1.904 +void 1.905 +nsHTMLEditor::SetFinalSize(int32_t aX, int32_t aY) 1.906 +{ 1.907 + if (!mResizedObject) { 1.908 + // paranoia 1.909 + return; 1.910 + } 1.911 + 1.912 + if (mActivatedHandle) { 1.913 + mActivatedHandle->RemoveAttribute(NS_LITERAL_STRING("_moz_activated")); 1.914 + mActivatedHandle = nullptr; 1.915 + } 1.916 + 1.917 + // we have now to set the new width and height of the resized object 1.918 + // we don't set the x and y position because we don't control that in 1.919 + // a normal HTML layout 1.920 + int32_t left = GetNewResizingX(aX, aY); 1.921 + int32_t top = GetNewResizingY(aX, aY); 1.922 + int32_t width = GetNewResizingWidth(aX, aY); 1.923 + int32_t height = GetNewResizingHeight(aX, aY); 1.924 + bool setWidth = !mResizedObjectIsAbsolutelyPositioned || (width != mResizedObjectWidth); 1.925 + bool setHeight = !mResizedObjectIsAbsolutelyPositioned || (height != mResizedObjectHeight); 1.926 + 1.927 + int32_t x, y; 1.928 + x = left - ((mResizedObjectIsAbsolutelyPositioned) ? mResizedObjectBorderLeft+mResizedObjectMarginLeft : 0); 1.929 + y = top - ((mResizedObjectIsAbsolutelyPositioned) ? mResizedObjectBorderTop+mResizedObjectMarginTop : 0); 1.930 + 1.931 + // we want one transaction only from a user's point of view 1.932 + nsAutoEditBatch batchIt(this); 1.933 + 1.934 + NS_NAMED_LITERAL_STRING(widthStr, "width"); 1.935 + NS_NAMED_LITERAL_STRING(heightStr, "height"); 1.936 + 1.937 + bool hasAttr = false; 1.938 + if (mResizedObjectIsAbsolutelyPositioned) { 1.939 + if (setHeight) 1.940 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject, 1.941 + nsEditProperty::cssTop, 1.942 + y, 1.943 + false); 1.944 + if (setWidth) 1.945 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject, 1.946 + nsEditProperty::cssLeft, 1.947 + x, 1.948 + false); 1.949 + } 1.950 + if (IsCSSEnabled() || mResizedObjectIsAbsolutelyPositioned) { 1.951 + if (setWidth && NS_SUCCEEDED(mResizedObject->HasAttribute(widthStr, &hasAttr)) && hasAttr) 1.952 + RemoveAttribute(mResizedObject, widthStr); 1.953 + 1.954 + hasAttr = false; 1.955 + if (setHeight && NS_SUCCEEDED(mResizedObject->HasAttribute(heightStr, &hasAttr)) && hasAttr) 1.956 + RemoveAttribute(mResizedObject, heightStr); 1.957 + 1.958 + if (setWidth) 1.959 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject, 1.960 + nsEditProperty::cssWidth, 1.961 + width, 1.962 + false); 1.963 + if (setHeight) 1.964 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject, 1.965 + nsEditProperty::cssHeight, 1.966 + height, 1.967 + false); 1.968 + } 1.969 + else { 1.970 + // we use HTML size and remove all equivalent CSS properties 1.971 + 1.972 + // we set the CSS width and height to remove it later, 1.973 + // triggering an immediate reflow; otherwise, we have problems 1.974 + // with asynchronous reflow 1.975 + if (setWidth) 1.976 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject, 1.977 + nsEditProperty::cssWidth, 1.978 + width, 1.979 + false); 1.980 + if (setHeight) 1.981 + mHTMLCSSUtils->SetCSSPropertyPixels(mResizedObject, 1.982 + nsEditProperty::cssHeight, 1.983 + height, 1.984 + false); 1.985 + 1.986 + if (setWidth) { 1.987 + nsAutoString w; 1.988 + w.AppendInt(width); 1.989 + SetAttribute(mResizedObject, widthStr, w); 1.990 + } 1.991 + if (setHeight) { 1.992 + nsAutoString h; 1.993 + h.AppendInt(height); 1.994 + SetAttribute(mResizedObject, heightStr, h); 1.995 + } 1.996 + 1.997 + if (setWidth) 1.998 + mHTMLCSSUtils->RemoveCSSProperty(mResizedObject, 1.999 + nsEditProperty::cssWidth, 1.1000 + EmptyString(), 1.1001 + false); 1.1002 + if (setHeight) 1.1003 + mHTMLCSSUtils->RemoveCSSProperty(mResizedObject, 1.1004 + nsEditProperty::cssHeight, 1.1005 + EmptyString(), 1.1006 + false); 1.1007 + } 1.1008 + // finally notify the listeners if any 1.1009 + int32_t listenersCount = objectResizeEventListeners.Count(); 1.1010 + if (listenersCount) { 1.1011 + nsCOMPtr<nsIHTMLObjectResizeListener> listener; 1.1012 + int32_t index; 1.1013 + for (index = 0; index < listenersCount; index++) { 1.1014 + listener = objectResizeEventListeners[index]; 1.1015 + listener->OnEndResizing(mResizedObject, 1.1016 + mResizedObjectWidth, mResizedObjectHeight, 1.1017 + width, height); 1.1018 + } 1.1019 + } 1.1020 + 1.1021 + // keep track of that size 1.1022 + mResizedObjectWidth = width; 1.1023 + mResizedObjectHeight = height; 1.1024 + 1.1025 + RefreshResizers(); 1.1026 +} 1.1027 + 1.1028 +NS_IMETHODIMP 1.1029 +nsHTMLEditor::GetResizedObject(nsIDOMElement * *aResizedObject) 1.1030 +{ 1.1031 + *aResizedObject = mResizedObject; 1.1032 + NS_IF_ADDREF(*aResizedObject); 1.1033 + return NS_OK; 1.1034 +} 1.1035 + 1.1036 +NS_IMETHODIMP 1.1037 +nsHTMLEditor::GetObjectResizingEnabled(bool *aIsObjectResizingEnabled) 1.1038 +{ 1.1039 + *aIsObjectResizingEnabled = mIsObjectResizingEnabled; 1.1040 + return NS_OK; 1.1041 +} 1.1042 + 1.1043 +NS_IMETHODIMP 1.1044 +nsHTMLEditor::SetObjectResizingEnabled(bool aObjectResizingEnabled) 1.1045 +{ 1.1046 + mIsObjectResizingEnabled = aObjectResizingEnabled; 1.1047 + return NS_OK; 1.1048 +} 1.1049 + 1.1050 +NS_IMETHODIMP 1.1051 +nsHTMLEditor::AddObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener) 1.1052 +{ 1.1053 + NS_ENSURE_ARG_POINTER(aListener); 1.1054 + if (objectResizeEventListeners.Count() && 1.1055 + objectResizeEventListeners.IndexOf(aListener) != -1) { 1.1056 + /* listener already registered */ 1.1057 + NS_ASSERTION(false, 1.1058 + "trying to register an already registered object resize event listener"); 1.1059 + return NS_OK; 1.1060 + } 1.1061 + objectResizeEventListeners.AppendObject(aListener); 1.1062 + return NS_OK; 1.1063 +} 1.1064 + 1.1065 +NS_IMETHODIMP 1.1066 +nsHTMLEditor::RemoveObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener) 1.1067 +{ 1.1068 + NS_ENSURE_ARG_POINTER(aListener); 1.1069 + if (!objectResizeEventListeners.Count() || 1.1070 + objectResizeEventListeners.IndexOf(aListener) == -1) { 1.1071 + /* listener was not registered */ 1.1072 + NS_ASSERTION(false, 1.1073 + "trying to remove an object resize event listener that was not already registered"); 1.1074 + return NS_OK; 1.1075 + } 1.1076 + objectResizeEventListeners.RemoveObject(aListener); 1.1077 + return NS_OK; 1.1078 +} 1.1079 +