diff --git a/mozilla/editor/composer/src/res/EditorOverride.css b/mozilla/editor/composer/src/res/EditorOverride.css index ce607a873f6..3c732877fd0 100644 --- a/mozilla/editor/composer/src/res/EditorOverride.css +++ b/mozilla/editor/composer/src/res/EditorOverride.css @@ -93,3 +93,66 @@ label { option { -moz-user-select: text !important; } + +/* the following rules are for Image Resizing */ + +*[anonclass="mozResizer"] { + width: 4px; + height: 4px; + position: absolute; + display: block; + border: 1px black solid; + background-color: black; + -moz-user-select: none; +} + +*[anonclass="mozResizer"].hidden, +*[anonclass="mozResizingShadow"].hidden, +*[anonclass="mozResizingInfo"].hidden { + display: none ! important; +} + +*[anonclass="mozResizer"][anonlocation="nw"] { + cursor: nw-resize; +} +*[anonclass="mozResizer"][anonlocation="n"] { + cursor: n-resize; +} +*[anonclass="mozResizer"][anonlocation="ne"] { + cursor: ne-resize; +} +*[anonclass="mozResizer"][anonlocation="w"] { + cursor: w-resize; +} +*[anonclass="mozResizer"][anonlocation="e"] { + cursor: e-resize; +} +*[anonclass="mozResizer"][anonlocation="sw"] { + cursor: sw-resize; +} +*[anonclass="mozResizer"][anonlocation="s"] { + cursor: s-resize; +} +*[anonclass="mozResizer"][anonlocation="se"] { + cursor: se-resize; +} + +*[anonclass="mozResizingShadow"] { + border: thin dashed black; + -moz-user-select: none; + display: block; + -moz-opacity: 0.5; + position: absolute; +} + +*[anonclass="mozResizingInfo"] { + font-family: sans-serif; + font-size: x-small; + color: black; + background-color: #d0d0d0; + border: ridge 2px #d0d0d0; + padding: 2px; + position: absolute; + display: block; +} + diff --git a/mozilla/editor/idl/MANIFEST b/mozilla/editor/idl/MANIFEST index 65de68b466e..9248b89d035 100644 --- a/mozilla/editor/idl/MANIFEST +++ b/mozilla/editor/idl/MANIFEST @@ -28,6 +28,7 @@ nsIEditorController.idl nsPIEditorTransaction.idl nsIEditor.idl nsIHTMLEditor.idl +nsIHTMLObjectResizer.idl nsIURIRefObject.idl nsICiter.idl nsIEditActionListener.idl diff --git a/mozilla/editor/idl/Makefile.in b/mozilla/editor/idl/Makefile.in index 12210d39076..601f0aedaaf 100644 --- a/mozilla/editor/idl/Makefile.in +++ b/mozilla/editor/idl/Makefile.in @@ -42,6 +42,7 @@ XPIDLSRCS = \ nsIEditorSpellCheck.idl \ nsIEditorStyleSheets.idl \ nsIHTMLEditor.idl \ + nsIHTMLObjectResizer.idl \ nsIPlaintextEditor.idl \ nsITableEditor.idl \ nsIURIRefObject.idl \ diff --git a/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.cpp b/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.cpp index aa048471e38..dceb5db7df7 100644 --- a/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.cpp +++ b/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.cpp @@ -49,6 +49,7 @@ #include "nsUnicharUtils.h" #include "nsCRT.h" #include "nsIAtom.h" +#include "nsIHTMLObjectResizer.h" void ChangeCSSInlineStyleTxn::AppendDeclaration(nsAString & aOutputString, @@ -261,6 +262,8 @@ NS_IMETHODIMP ChangeCSSInlineStyleTxn::DoTransaction(void) else mRedoAttributeWasSet = PR_TRUE; + CheckObjectResizing(); + return cssDecl->GetPropertyValue(propertyNameString, mRedoValue); } @@ -304,12 +307,18 @@ nsresult ChangeCSSInlineStyleTxn::SetStyle(PRBool aAttributeWasSet, NS_IMETHODIMP ChangeCSSInlineStyleTxn::UndoTransaction(void) { - return SetStyle(mUndoAttributeWasSet, mUndoValue); + nsresult res = SetStyle(mUndoAttributeWasSet, mUndoValue); + if (NS_SUCCEEDED(res)) + CheckObjectResizing(); + return res; } NS_IMETHODIMP ChangeCSSInlineStyleTxn::RedoTransaction(void) { - return SetStyle(mRedoAttributeWasSet, mRedoValue); + nsresult res = SetStyle(mRedoAttributeWasSet, mRedoValue); + if (NS_SUCCEEDED(res)) + CheckObjectResizing(); + return res; } NS_IMETHODIMP ChangeCSSInlineStyleTxn::Merge(nsITransaction *aTransaction, PRBool *aDidMerge) @@ -364,3 +373,18 @@ ChangeCSSInlineStyleTxn::AddValueToMultivalueProperty(nsAString & aValues, const return NS_OK; } +void +ChangeCSSInlineStyleTxn::CheckObjectResizing() +{ + // HACK !!!!! We absolutely need this because setting an inline CSS + // property does not trigger a DOMAttrModified event related to the + // style attribute (perf reasons I suppose) + + nsCOMPtr imageResizer = do_QueryInterface(mEditor); + if (imageResizer) { + nsCOMPtr resizedObject; + imageResizer->GetResizedObject(getter_AddRefs(resizedObject)); + if (resizedObject == mElement) + imageResizer->RefreshResizers(); + } +} diff --git a/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.h b/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.h index 4bf98a8bcad..154bbfbf0f1 100644 --- a/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.h +++ b/mozilla/editor/libeditor/base/ChangeCSSInlineStyleTxn.h @@ -124,6 +124,8 @@ private: */ nsresult SetStyle(PRBool aAttributeWasSet, nsAString & aValue); + void CheckObjectResizing(); + public: NS_IMETHOD DoTransaction(void); diff --git a/mozilla/editor/libeditor/base/nsIEditProperty.h b/mozilla/editor/libeditor/base/nsIEditProperty.h index 94e95a00762..976917cbaba 100644 --- a/mozilla/editor/libeditor/base/nsIEditProperty.h +++ b/mozilla/editor/libeditor/base/nsIEditProperty.h @@ -159,16 +159,18 @@ public: static nsIAtom *cssFontStyle; static nsIAtom *cssFontWeight; static nsIAtom *cssHeight; + static nsIAtom *cssLeft; static nsIAtom *cssListStyleType; static nsIAtom *cssMarginLeft; static nsIAtom *cssMarginRight; static nsIAtom *cssTextAlign; static nsIAtom *cssTextDecoration; + static nsIAtom *cssTop; static nsIAtom *cssVerticalAlign; static nsIAtom *cssWhitespace; static nsIAtom *cssWidth; - static nsIAtom *cssMozUserSelect; + static nsIAtom *cssMozUserSelect; static nsIAtom *cssPxUnit; static nsIAtom *cssEmUnit; diff --git a/mozilla/editor/libeditor/html/Makefile.in b/mozilla/editor/libeditor/html/Makefile.in index 8e174e7c11d..6e8e67da97e 100644 --- a/mozilla/editor/libeditor/html/Makefile.in +++ b/mozilla/editor/libeditor/html/Makefile.in @@ -42,6 +42,7 @@ REQUIRES = xpcom \ pref \ gfx \ widget \ + view \ $(NULL) # Building the full blown HTML Editor so add its source files and objects: @@ -54,6 +55,7 @@ CPPSRCS = \ nsHTMLEditorStyle.cpp \ nsHTMLEditRules.cpp \ nsHTMLEditUtils.cpp \ + nsHTMLObjectResizer.cpp \ nsHTMLEditorMouseListener.cpp \ nsHTMLURIRefObject.cpp \ nsTableEditor.cpp \ diff --git a/mozilla/editor/libeditor/html/nsEditProperty.cpp b/mozilla/editor/libeditor/html/nsEditProperty.cpp index 9ad88c3fc8f..c2a0823bf6f 100644 --- a/mozilla/editor/libeditor/html/nsEditProperty.cpp +++ b/mozilla/editor/libeditor/html/nsEditProperty.cpp @@ -136,16 +136,18 @@ nsIAtom * nsIEditProperty::cssFontSize; nsIAtom * nsIEditProperty::cssFontStyle; nsIAtom * nsIEditProperty::cssFontWeight; nsIAtom * nsIEditProperty::cssHeight; +nsIAtom * nsIEditProperty::cssLeft; nsIAtom * nsIEditProperty::cssListStyleType; nsIAtom * nsIEditProperty::cssMarginLeft; nsIAtom * nsIEditProperty::cssMarginRight; nsIAtom * nsIEditProperty::cssTextAlign; nsIAtom * nsIEditProperty::cssTextDecoration; +nsIAtom * nsIEditProperty::cssTop; nsIAtom * nsIEditProperty::cssVerticalAlign; nsIAtom * nsIEditProperty::cssWhitespace; nsIAtom * nsIEditProperty::cssWidth; -nsIAtom * nsIEditProperty::cssMozUserSelect; +nsIAtom * nsIEditProperty::cssMozUserSelect; nsIAtom * nsIEditProperty::cssPxUnit; nsIAtom * nsIEditProperty::cssEmUnit; @@ -276,15 +278,17 @@ nsEditProperty::nsEditProperty() nsIEditProperty::cssFontWeight = NS_NewAtom("font-weight"); nsIEditProperty::cssHeight = NS_NewAtom("height"); nsIEditProperty::cssListStyleType = NS_NewAtom("list-style-type"); + nsIEditProperty::cssLeft = NS_NewAtom("left"); nsIEditProperty::cssMarginRight = NS_NewAtom("margin-right"); nsIEditProperty::cssMarginLeft = NS_NewAtom("margin-left"); nsIEditProperty::cssTextAlign = NS_NewAtom("text-align"); nsIEditProperty::cssTextDecoration = NS_NewAtom("text-decoration"); + nsIEditProperty::cssTop = NS_NewAtom("top"); nsIEditProperty::cssVerticalAlign = NS_NewAtom("vertical-align"); nsIEditProperty::cssWhitespace = NS_NewAtom("white-space"); nsIEditProperty::cssWidth = NS_NewAtom("width"); - nsIEditProperty::cssMozUserSelect = NS_NewAtom("-moz-user-select"); + nsIEditProperty::cssMozUserSelect = NS_NewAtom("-moz-user-select"); nsIEditProperty::cssPxUnit = NS_NewAtom("px"); nsIEditProperty::cssEmUnit = NS_NewAtom("em"); @@ -389,13 +393,16 @@ nsEditProperty::~nsEditProperty() NS_IF_RELEASE(nsIEditProperty::cssFontWeight); NS_IF_RELEASE(nsIEditProperty::cssHeight); NS_IF_RELEASE(nsIEditProperty::cssListStyleType); + NS_IF_RELEASE(nsIEditProperty::cssLeft); NS_IF_RELEASE(nsIEditProperty::cssMarginRight); NS_IF_RELEASE(nsIEditProperty::cssMarginLeft); NS_IF_RELEASE(nsIEditProperty::cssTextAlign); NS_IF_RELEASE(nsIEditProperty::cssTextDecoration); + NS_IF_RELEASE(nsIEditProperty::cssTop); NS_IF_RELEASE(nsIEditProperty::cssVerticalAlign); NS_IF_RELEASE(nsIEditProperty::cssWhitespace); NS_IF_RELEASE(nsIEditProperty::cssWidth); + NS_IF_RELEASE(nsIEditProperty::cssMozUserSelect); NS_IF_RELEASE(nsIEditProperty::cssPxUnit); diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index f23a5486fce..1bf10007187 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -134,6 +134,11 @@ #include "nsParserCIID.h" #include "nsITextContent.h" #include "nsWSRunObject.h" +#include "nsHTMLObjectResizer.h" + +#include "nsIFrame.h" +#include "nsIView.h" +#include "nsIWidget.h" static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID); static NS_DEFINE_IID(kSubtreeIteratorCID, NS_SUBTREEITERATOR_CID); @@ -154,6 +159,9 @@ static char hrefText[] = "href"; static char anchorTxt[] = "anchor"; static char namedanchorText[] = "namedanchor"; +#define kBaseEditorStyleSheet NS_LITERAL_STRING("chrome://editor/content/EditorOverride.css") +#define kNormalStyleSheet NS_LITERAL_STRING("chrome://editor/content/EditorContent.css") + nsCOMPtr nsHTMLEditor::sParserService; PRInt32 nsHTMLEditor::sInstanceCount = 0; @@ -170,6 +178,10 @@ nsHTMLEditor::nsHTMLEditor() , mTypeInState(nsnull) , mSelectedCellIndex(0) , mHTMLCSSUtils(nsnull) +, mIsImageResizingEnabled(PR_TRUE) // this can be overriden +, mIsShowingResizeHandles(PR_FALSE) +, mIsResizing(PR_FALSE) +, mResizedObject(nsnull) { // Done in nsEditor // NS_INIT_ISUPPORTS(); @@ -201,9 +213,14 @@ nsHTMLEditor::~nsHTMLEditor() if (listener) { selPriv->RemoveSelectionListener(listener); } + listener = do_QueryInterface(mSelectionListenerP); + if (listener) { + selPriv->RemoveSelectionListener(listener); + } } NS_IF_RELEASE(mTypeInState); + mSelectionListenerP = nsnull; if (--sInstanceCount == 0 && sParserService) sParserService = 0; @@ -233,6 +250,11 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_ADDREF_THIS(); return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsIHTMLObjectResizer))) { + *aInstancePtr = NS_STATIC_CAST(nsIHTMLObjectResizer*, this); + NS_ADDREF_THIS(); + return NS_OK; + } if (aIID.Equals(NS_GET_IID(nsIEditorMailSupport))) { *aInstancePtr = NS_STATIC_CAST(nsIEditorMailSupport*, this); NS_ADDREF_THIS(); @@ -316,6 +338,10 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, if (!mTypeInState) {return NS_ERROR_NULL_POINTER;} NS_ADDREF(mTypeInState); + // init the selection listener for image resizing + mSelectionListenerP = new ResizerSelectionListener(this); + if (!mSelectionListenerP) {return NS_ERROR_NULL_POINTER;} + nsCOMPtrselection; result = GetSelection(getter_AddRefs(selection)); if (NS_FAILED(result)) { return result; } @@ -327,10 +353,19 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, if (listener) { selPriv->AddSelectionListener(listener); } + listener = do_QueryInterface(mSelectionListenerP); + if (listener) { + selPriv->AddSelectionListener(listener); + } } } if (NS_FAILED(rulesRes)) return rulesRes; + + result = AddOverrideStyleSheet(kBaseEditorStyleSheet); + if (NS_FAILED(result)) return result; + return AddOverrideStyleSheet(kNormalStyleSheet); + return result; } @@ -5985,3 +6020,56 @@ nsHTMLEditor::CopyLastEditableChildStyles(nsIDOMNode * aPreviousBlock, nsIDOMNod } return NS_OK; } + +nsresult +nsHTMLEditor::GetElementOrigin(nsIDOMElement * aElement, PRInt32 & aX, PRInt32 & aY) +{ + // we are going to need the PresShell + if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; + nsCOMPtr ps = do_QueryReferent(mPresShellWeak); + if (!ps) return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr content = do_QueryInterface(aElement); + nsIFrame *frame = 0; // not ref-counted + ps->GetPrimaryFrameFor(content, &frame); + + float t2p; + nsCOMPtr pcontext; + ps->GetPresContext(getter_AddRefs(pcontext)); + pcontext->GetTwipsToPixels(&t2p); + + + if (NodeIsType(aElement, NS_LITERAL_STRING("hr"))) { + nsIFrame* childFrame; + //frame->FirstChild(pcontext, nsnull, &childFrame); + frame->GetNextSibling(&childFrame); + frame = childFrame; + } + PRInt32 offsetX = 0, offsetY = 0; + nsCOMPtr widget; + nsresult rv; + while (frame) { + // Look for a widget so we can get screen coordinates + nsIView* view = nsnull; + rv = frame->GetView(pcontext, &view); + if (NS_SUCCEEDED(rv) && view) { + rv = view->GetWidget(*getter_AddRefs(widget)); + if (widget) + break; + } + + // No widget yet, so count up the coordinates of the frame + nsPoint origin; + frame->GetOrigin(origin); + offsetX += origin.x; + offsetY += origin.y; + + frame->GetParent(&frame); + } + + aX = NSTwipsToIntPixels(offsetX , t2p); + aY = NSTwipsToIntPixels(offsetY , t2p); + + return NS_OK; +} + diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 5ca703b1361..63f1f0dca2d 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -65,6 +65,10 @@ #include "nsVoidArray.h" +#include "nsHTMLObjectResizer.h" + +#include "nsPoint.h" + class nsIDOMKeyEvent; class nsITransferable; class nsIDOMEventReceiver; @@ -79,6 +83,7 @@ class TypeInState; */ class nsHTMLEditor : public nsPlaintextEditor, public nsIHTMLEditor, + public nsIHTMLObjectResizer, public nsITableEditor, public nsIEditorStyleSheets, public nsICSSLoaderObserver @@ -105,6 +110,13 @@ public: kOpLoadHTML = 3013 }; + enum ResizingRequestID + { + kX = 0, + kY = 1, + kWidth = 2, + kHeight = 3 + }; // see nsIHTMLEditor for documentation @@ -123,6 +135,9 @@ public: NS_IMETHOD GetIsDocumentEditable(PRBool *aIsDocumentEditable); NS_IMETHODIMP BeginningOfDocument(); + /* ------------ nsIHTMLObjectResizer methods -------------- */ + NS_DECL_NSIHTMLOBJECTRESIZER + /* ------------ nsIHTMLEditor methods -------------- */ NS_IMETHOD CopyLastEditableChildStyles(nsIDOMNode *aPreviousBlock, nsIDOMNode *aNewBlock, nsIDOMNode **aOutBrNode); @@ -837,6 +852,66 @@ protected: // ... which means that we need an instance count to know when to delete it static PRInt32 sInstanceCount; +protected: + PRPackedBool mIsImageResizingEnabled; + PRPackedBool mIsShowingResizeHandles; + PRPackedBool mIsResizing; + PRPackedBool mPreserveRatio; + PRPackedBool mResizedObjectIsAnImage; + + nsCOMPtr mTopLeftHandle; + nsCOMPtr mTopHandle; + nsCOMPtr mTopRightHandle; + nsCOMPtr mLeftHandle; + nsCOMPtr mRightHandle; + nsCOMPtr mBottomLeftHandle; + nsCOMPtr mBottomHandle; + nsCOMPtr mBottomRightHandle; + + nsCOMPtr mResizingShadow; + nsCOMPtr mResizingInfo; + + nsCOMPtr mResizedObject; + + nsCOMPtr mMouseMotionListenerP; + nsCOMPtr mMutationListenerP; + nsCOMPtr mSelectionListenerP; + nsCOMPtr mResizeEventListenerP; + + PRInt32 mOriginalX; + PRInt32 mOriginalY; + + PRInt32 mResizedObjectX; + PRInt32 mResizedObjectY; + PRInt32 mResizedObjectWidth; + PRInt32 mResizedObjectHeight; + + PRInt32 mXIncrementFactor; + PRInt32 mYIncrementFactor; + PRInt32 mWidthIncrementFactor; + PRInt32 mHeightIncrementFactor; + + nsresult CreateResizer(nsIDOMElement ** aReturn, PRInt16 aLocation, nsISupportsArray * aArray); + void SetResizerPosition(PRInt32 aX, PRInt32 aY, nsIDOMElement *aResizer); + nsresult SetAllResizersPosition(nsIDOMElement * aResizedElement, PRInt32 & aX, PRInt32 & aY); + nsresult CreateShadow(nsIDOMElement ** aReturn, nsISupportsArray * aArray); + nsresult SetShadowPosition(nsIDOMElement *aResizedObject, + PRInt32 aX, PRInt32 aY); + nsresult CreateResizingInfo(nsIDOMElement ** aReturn, nsISupportsArray * aArray); + nsresult SetResizingInfoPosition(PRInt32 aX, PRInt32 aY, + PRInt32 aW, PRInt32 aH); + + PRInt32 GetNewResizingIncrement(PRInt32 aX, PRInt32 aY, PRInt32 aID); + nsresult StartResizing(nsIDOMElement * aHandle); + PRInt32 GetNewResizingX(PRInt32 aX, PRInt32 aY); + PRInt32 GetNewResizingY(PRInt32 aX, PRInt32 aY); + PRInt32 GetNewResizingWidth(PRInt32 aX, PRInt32 aY); + PRInt32 GetNewResizingHeight(PRInt32 aX, PRInt32 aY); + void HideShadowAndInfo(); + void SetFinalSize(PRInt32 aX, PRInt32 aY); + void DeleteAnonymousFrameFor(nsIDOMNode * aNode); + void SetResizeIncrements(PRInt32 aX, PRInt32 aY, PRInt32 aW, PRInt32 aH, PRBool aPreserveRatio); + nsresult GetElementOrigin(nsIDOMElement * aElement, PRInt32 & aX, PRInt32 & aY); public: // friends diff --git a/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.cpp b/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.cpp index 730d87936be..aae0405ee5a 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Charles Manske (cmanske@netscape.com) + * Daniel Glazman (glazman@netscape.com) * * * Alternatively, the contents of this file may be used under the terms of @@ -53,6 +54,7 @@ #include "nsIEditor.h" #include "nsIHTMLEditor.h" +#include "nsIHTMLObjectResizer.h" #include "nsIEditProperty.h" #include "nsTextEditUtils.h" @@ -74,6 +76,36 @@ nsHTMLEditorMouseListener::~nsHTMLEditorMouseListener() NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLEditorMouseListener, nsTextEditorMouseListener, nsIDOMMouseListener) +nsresult +nsHTMLEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent) +{ + NS_ENSURE_ARG_POINTER(aMouseEvent); + nsCOMPtr mouseEvent ( do_QueryInterface(aMouseEvent) ); + if (!mouseEvent) { + //non-ui event passed in. bad things. + return NS_OK; + } + nsresult res; + + // Don't do anything special if not an HTML editor + nsCOMPtr htmlEditor = do_QueryInterface(mEditor); + if (htmlEditor) + { + nsCOMPtr target; + nsresult res = aMouseEvent->GetTarget(getter_AddRefs(target)); + if (NS_FAILED(res)) return res; + if (!target) return NS_ERROR_NULL_POINTER; + nsCOMPtr element = do_QueryInterface(target); + + nsCOMPtr imageResizer = do_QueryInterface(htmlEditor); + PRInt32 clientX, clientY; + mouseEvent->GetClientX(&clientX); + mouseEvent->GetClientY(&clientY); + imageResizer->MouseUp(clientX, clientY, element); + } + return NS_OK; +} + nsresult nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) { @@ -111,14 +143,14 @@ nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) res = mouseEvent->GetDetail(&clickCount); if (NS_FAILED(res)) return res; + nsCOMPtr target; + res = aMouseEvent->GetTarget(getter_AddRefs(target)); + if (NS_FAILED(res)) return res; + if (!target) return NS_ERROR_NULL_POINTER; + nsCOMPtr element = do_QueryInterface(target); + if (isContextClick || (buttonNumber == 0 && clickCount == 2)) { - nsCOMPtr target; - res = aMouseEvent->GetTarget(getter_AddRefs(target)); - if (NS_FAILED(res)) return res; - if (!target) return NS_ERROR_NULL_POINTER; - nsCOMPtr element = do_QueryInterface(target); - PRInt32 clickCount; res = mouseEvent->GetDetail(&clickCount); if (NS_FAILED(res)) return res; @@ -209,6 +241,11 @@ nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) } } } + // HACK !!! Context click places the caret but the context menu consumes + // the event; so we need to check resizing state ourselves + nsCOMPtr imageResizer = do_QueryInterface(htmlEditor); + imageResizer->CheckResizingState(selection); + // Prevent bubbling if we changed selection or // for all context clicks if (element || isContextClick) @@ -217,6 +254,15 @@ nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) return NS_OK; } } + else if (!isContextClick & buttonNumber == 0 && clickCount == 1) + { + // if the target element is an image, we have to display resizers + nsCOMPtr imageResizer = do_QueryInterface(htmlEditor); + PRInt32 clientX, clientY; + mouseEvent->GetClientX(&clientX); + mouseEvent->GetClientY(&clientY); + imageResizer->MouseDown(clientX, clientY, element); + } } return nsTextEditorMouseListener::MouseDown(aMouseEvent); diff --git a/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.h b/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.h index 880be4726ea..3dcb2855756 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditorMouseListener.h @@ -21,6 +21,7 @@ * * Contributor(s): * Charles Manske (cmanske@netscape.com) + * Daniel Glazman (glazman@netscape.com) * * * Alternatively, the contents of this file may be used under the terms of @@ -67,6 +68,7 @@ public: /*BEGIN implementations of mouseevent handler interface*/ NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent); + NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent); /*END implementations of mouseevent handler interface*/ }; diff --git a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp index eda7354cd03..2299173120f 100644 --- a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp @@ -81,8 +81,8 @@ ResizeEventListener::~ResizeEventListener() NS_IMETHODIMP ResizeEventListener::HandleEvent(nsIDOMEvent* aMouseEvent) { - nsCOMPtr objectResizer = do_QueryInterface(mEditor); - objectResizer->RefreshResizers(); + nsCOMPtr imageResizer = do_QueryInterface(mEditor); + imageResizer->RefreshResizers(); return NS_OK; } @@ -115,8 +115,8 @@ ResizerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection nsISelectionListener::SELECTALL_REASON)) && aSelection) { // the selection changed and we need to check if we have to // hide and/or redisplay resizing handles - nsCOMPtr objectResizer = do_QueryInterface(mEditor); - objectResizer->CheckResizingState(aSelection); + nsCOMPtr imageResizer = do_QueryInterface(mEditor); + imageResizer->CheckResizingState(aSelection); } return NS_OK; @@ -154,16 +154,16 @@ ResizerMutationListener::NodeInserted(nsIDOMEvent* aMutationEvent) NS_IMETHODIMP ResizerMutationListener::NodeRemoved(nsIDOMEvent* aMutationEvent) { - nsCOMPtr objectResizer = do_QueryInterface(mEditor); + nsCOMPtr imageResizer = do_QueryInterface(mEditor); nsCOMPtr target; nsresult res = aMutationEvent->GetTarget(getter_AddRefs(target)); if (NS_FAILED(res)) return res; if (!target) return NS_ERROR_NULL_POINTER; nsCOMPtr targetElement = do_QueryInterface(target); nsCOMPtr resizedElt; - objectResizer->GetResizedObject(getter_AddRefs(resizedElt)); + imageResizer->GetResizedObject(getter_AddRefs(resizedElt)); if (resizedElt == targetElement) - return objectResizer->HideResizers(); + return imageResizer->HideResizers(); return NS_OK; } @@ -183,9 +183,9 @@ ResizerMutationListener::NodeInsertedIntoDocument(nsIDOMEvent* aMutationEvent) NS_IMETHODIMP ResizerMutationListener::AttrModified(nsIDOMEvent* aMutationEvent) { - nsCOMPtr objectResizer = do_QueryInterface(mEditor); + nsCOMPtr imageResizer = do_QueryInterface(mEditor); nsCOMPtr elt; - objectResizer->GetResizedObject(getter_AddRefs(elt)); + imageResizer->GetResizedObject(getter_AddRefs(elt)); PRInt32 w, h; nsCOMPtr nsElement = do_QueryInterface(elt); if (!nsElement) {return NS_ERROR_NULL_POINTER; } @@ -196,11 +196,11 @@ ResizerMutationListener::AttrModified(nsIDOMEvent* aMutationEvent) // and let's get the last size we dealt with PRInt32 objectW, objectH; - objectResizer->GetResizedObjectSize(&objectW, &objectH); + imageResizer->GetResizedObjectSize(&objectW, &objectH); // if the sizes are different, let's refresh the resizers if (w != objectW || h != objectH) - objectResizer->RefreshResizers(); + imageResizer->RefreshResizers(); return NS_OK; } @@ -255,8 +255,8 @@ ResizerMouseMotionListener::MouseMove(nsIDOMEvent* aMouseEvent) if (htmlEditor) { // check if we have to redisplay a resizing shadow - nsCOMPtr objectResizer = do_QueryInterface(htmlEditor); - objectResizer->MouseMove(aMouseEvent); + nsCOMPtr imageResizer = do_QueryInterface(htmlEditor); + imageResizer->MouseMove(aMouseEvent); } return NS_OK; @@ -333,7 +333,7 @@ nsHTMLEditor::CreateResizer(nsIDOMElement ** aReturn, PRInt16 aLocation, nsISupp } - res = newElement->SetAttribute(NS_LITERAL_STRING("_moz_anonclass"), + res = newElement->SetAttribute(NS_LITERAL_STRING("anonclass"), NS_LITERAL_STRING("mozResizer")); if (NS_FAILED(res)) return res; res = newElement->SetAttribute(NS_LITERAL_STRING("anonlocation"), @@ -379,7 +379,7 @@ nsHTMLEditor::CreateResizingInfo(nsIDOMElement ** aReturn, nsISupportsArray * aA *aReturn = newElement; NS_ADDREF(*aReturn); - res = newElement->SetAttribute(NS_LITERAL_STRING("_moz_anonclass"), + res = newElement->SetAttribute(NS_LITERAL_STRING("anonclass"), NS_LITERAL_STRING("mozResizingInfo")); if (NS_FAILED(res)) return res; res = newElement->SetAttribute(NS_LITERAL_STRING("class"), @@ -568,17 +568,12 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement) } void -nsHTMLEditor::DeleteRefToAnonymousNode(nsIDOMNode * aNode) +nsHTMLEditor::DeleteAnonymousFrameFor(nsIDOMNode * aNode) { nsCOMPtr elt = do_QueryInterface(aNode); NS_ASSERTION(elt, "anonymous node is not an element"); // let's destroy element's frame elt->SetAttribute(NS_LITERAL_STRING("class"), NS_LITERAL_STRING("hidden")); - - nsCOMPtr content = do_QueryInterface(aNode); - content->SetParent(nsnull); - content->SetDocument(nsnull, PR_TRUE, PR_TRUE); - content->SetBindingParent(nsnull); } NS_IMETHODIMP @@ -587,26 +582,26 @@ nsHTMLEditor::HideResizers(void) if (!mIsShowingResizeHandles || !mResizedObject) return NS_OK; - DeleteRefToAnonymousNode(mTopLeftHandle); + DeleteAnonymousFrameFor(mTopLeftHandle); mTopLeftHandle = nsnull; - DeleteRefToAnonymousNode(mTopHandle); + DeleteAnonymousFrameFor(mTopHandle); mTopHandle = nsnull; - DeleteRefToAnonymousNode(mTopRightHandle); + DeleteAnonymousFrameFor(mTopRightHandle); mTopRightHandle = nsnull; - DeleteRefToAnonymousNode(mLeftHandle); + DeleteAnonymousFrameFor(mLeftHandle); mLeftHandle = nsnull; - DeleteRefToAnonymousNode(mRightHandle); + DeleteAnonymousFrameFor(mRightHandle); mRightHandle = nsnull; - DeleteRefToAnonymousNode(mBottomLeftHandle); + DeleteAnonymousFrameFor(mBottomLeftHandle); mBottomLeftHandle = nsnull; - DeleteRefToAnonymousNode(mBottomHandle); + DeleteAnonymousFrameFor(mBottomHandle); mBottomHandle = nsnull; - DeleteRefToAnonymousNode(mBottomRightHandle); + DeleteAnonymousFrameFor(mBottomRightHandle); mBottomRightHandle = nsnull; - DeleteRefToAnonymousNode(mResizingShadow); + DeleteAnonymousFrameFor(mResizingShadow); mResizingShadow = nsnull; - DeleteRefToAnonymousNode(mResizingInfo); + DeleteAnonymousFrameFor(mResizingInfo); mResizingInfo = nsnull; // don't forget to remove the listeners ! @@ -720,11 +715,11 @@ nsHTMLEditor::MouseDown(PRInt32 aClientX, PRInt32 aClientY, nsIDOMElement *aTarget) { PRBool anonElement = PR_FALSE; - if (aTarget && NS_SUCCEEDED(aTarget->HasAttribute(NS_LITERAL_STRING("_moz_anonclass"), &anonElement))) + if (aTarget && NS_SUCCEEDED(aTarget->HasAttribute(NS_LITERAL_STRING("anonclass"), &anonElement))) // we caught a click on an anonymous element if (anonElement) { nsAutoString anonclass; - nsresult res = aTarget->GetAttribute(NS_LITERAL_STRING("_moz_anonclass"), anonclass); + nsresult res = aTarget->GetAttribute(NS_LITERAL_STRING("anonclass"), anonclass); if (NS_FAILED(res)) return res; if (anonclass.Equals(NS_LITERAL_STRING("mozResizer"))) { // and that element is a resizer, let's start resizing! @@ -849,7 +844,7 @@ nsHTMLEditor::SetShadowPosition(nsIDOMElement *aResizedObject, res = mResizingShadow->SetAttribute(NS_LITERAL_STRING("src"), imageSource); if (NS_FAILED(res)) return res; } - return mResizingShadow->SetAttribute(NS_LITERAL_STRING("_moz_anonclass"), + return mResizingShadow->SetAttribute(NS_LITERAL_STRING("anonclass"), NS_LITERAL_STRING("mozResizingShadow")); } diff --git a/mozilla/editor/ui/composer/content/EditorOverride.css b/mozilla/editor/ui/composer/content/EditorOverride.css index ce607a873f6..3c732877fd0 100644 --- a/mozilla/editor/ui/composer/content/EditorOverride.css +++ b/mozilla/editor/ui/composer/content/EditorOverride.css @@ -93,3 +93,66 @@ label { option { -moz-user-select: text !important; } + +/* the following rules are for Image Resizing */ + +*[anonclass="mozResizer"] { + width: 4px; + height: 4px; + position: absolute; + display: block; + border: 1px black solid; + background-color: black; + -moz-user-select: none; +} + +*[anonclass="mozResizer"].hidden, +*[anonclass="mozResizingShadow"].hidden, +*[anonclass="mozResizingInfo"].hidden { + display: none ! important; +} + +*[anonclass="mozResizer"][anonlocation="nw"] { + cursor: nw-resize; +} +*[anonclass="mozResizer"][anonlocation="n"] { + cursor: n-resize; +} +*[anonclass="mozResizer"][anonlocation="ne"] { + cursor: ne-resize; +} +*[anonclass="mozResizer"][anonlocation="w"] { + cursor: w-resize; +} +*[anonclass="mozResizer"][anonlocation="e"] { + cursor: e-resize; +} +*[anonclass="mozResizer"][anonlocation="sw"] { + cursor: sw-resize; +} +*[anonclass="mozResizer"][anonlocation="s"] { + cursor: s-resize; +} +*[anonclass="mozResizer"][anonlocation="se"] { + cursor: se-resize; +} + +*[anonclass="mozResizingShadow"] { + border: thin dashed black; + -moz-user-select: none; + display: block; + -moz-opacity: 0.5; + position: absolute; +} + +*[anonclass="mozResizingInfo"] { + font-family: sans-serif; + font-size: x-small; + color: black; + background-color: #d0d0d0; + border: ridge 2px #d0d0d0; + padding: 2px; + position: absolute; + display: block; +} +