Support for Absolute Positioning, Snap to Grid, and Inline Table Editing in Composer
r=brade, sr=jst
|
@ -83,6 +83,25 @@ EXTRA_DSO_LDOPTS += \
|
|||
|
||||
_FILES = \
|
||||
$(srcdir)/res/EditorOverride.css \
|
||||
$(srcdir)/res/grabber.gif \
|
||||
$(srcdir)/res/table-add-column-after-active.gif \
|
||||
$(srcdir)/res/table-add-column-after-hover.gif \
|
||||
$(srcdir)/res/table-add-column-after.gif \
|
||||
$(srcdir)/res/table-add-column-before-active.gif \
|
||||
$(srcdir)/res/table-add-column-before-hover.gif \
|
||||
$(srcdir)/res/table-add-column-before.gif \
|
||||
$(srcdir)/res/table-add-row-after-active.gif \
|
||||
$(srcdir)/res/table-add-row-after-hover.gif \
|
||||
$(srcdir)/res/table-add-row-after.gif \
|
||||
$(srcdir)/res/table-add-row-before-active.gif \
|
||||
$(srcdir)/res/table-add-row-before-hover.gif \
|
||||
$(srcdir)/res/table-add-row-before.gif \
|
||||
$(srcdir)/res/table-remove-column-active.gif \
|
||||
$(srcdir)/res/table-remove-column-hover.gif \
|
||||
$(srcdir)/res/table-remove-column.gif \
|
||||
$(srcdir)/res/table-remove-row-active.gif \
|
||||
$(srcdir)/res/table-remove-row-hover.gif \
|
||||
$(srcdir)/res/table-remove-row.gif \
|
||||
$(NULL)
|
||||
|
||||
libs::
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "nsIHTMLEditor.h"
|
||||
#include "nsIEditingSession.h"
|
||||
|
||||
#include "nsIHTMLAbsPosEditor.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
#include "nsIClipboard.h"
|
||||
|
@ -1090,6 +1092,203 @@ nsAlignCommand::SetState(nsIEditor *aEditor, nsString& newState)
|
|||
#pragma mark -
|
||||
#endif
|
||||
|
||||
|
||||
nsAbsolutePositioningCommand::nsAbsolutePositioningCommand()
|
||||
: nsBaseStateUpdatingCommand("")
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbsolutePositioningCommand::IsCommandEnabled(const char * aCommandName,
|
||||
nsISupports *aCommandRefCon,
|
||||
PRBool *_retval)
|
||||
{
|
||||
NS_ASSERTION(aCommandRefCon, "Need an editor here");
|
||||
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aCommandRefCon);
|
||||
if (!htmlEditor) return NS_ERROR_FAILURE;
|
||||
|
||||
htmlEditor->GetAbsolutePositioningEnabled(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbsolutePositioningCommand::GetCurrentState(nsIEditor *aEditor, const char* aTagName, nsICommandParams *aParams)
|
||||
{
|
||||
NS_ASSERTION(aEditor, "Need an editor here");
|
||||
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aEditor);
|
||||
if (!htmlEditor) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool isEnabled;
|
||||
htmlEditor->GetAbsolutePositioningEnabled(&isEnabled);
|
||||
if (!isEnabled) {
|
||||
aParams->SetBooleanValue(STATE_MIXED,PR_FALSE);
|
||||
aParams->SetCStringValue(STATE_ATTRIBUTE, "");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elt;
|
||||
nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsAutoString outStateString;
|
||||
if (elt)
|
||||
outStateString.Assign(NS_LITERAL_STRING("absolute"));
|
||||
|
||||
aParams->SetBooleanValue(STATE_MIXED,PR_FALSE);
|
||||
aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUCS2toUTF8(outStateString).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbsolutePositioningCommand::ToggleState(nsIEditor *aEditor, const char* aTagName)
|
||||
{
|
||||
NS_ASSERTION(aEditor, "Need an editor here");
|
||||
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aEditor);
|
||||
if (!htmlEditor) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elt;
|
||||
nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (elt) {
|
||||
// we have to remove positioning on an element
|
||||
rv = htmlEditor->AbsolutePositionSelection(PR_FALSE);
|
||||
}
|
||||
else {
|
||||
rv = htmlEditor->AbsolutePositionSelection(PR_TRUE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDecreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
|
||||
nsISupports *refCon,
|
||||
PRBool *outCmdEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
|
||||
if (!htmlEditor) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool isEnabled;
|
||||
htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
|
||||
if (!(*outCmdEnabled))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> positionedElement;
|
||||
htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement));
|
||||
*outCmdEnabled = PR_FALSE;
|
||||
if (positionedElement) {
|
||||
PRInt32 z;
|
||||
nsresult res = htmlEditor->GetElementZIndex(positionedElement, &z);
|
||||
if (NS_FAILED(res)) return res;
|
||||
*outCmdEnabled = (z > 0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDecreaseZIndexCommand::DoCommand(const char *aCommandName,
|
||||
nsISupports *refCon)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
|
||||
if (!htmlEditor)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return htmlEditor->RelativeChangeZIndex(-1);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDecreaseZIndexCommand::DoCommandParams(const char *aCommandName,
|
||||
nsICommandParams *aParams,
|
||||
nsISupports *refCon)
|
||||
{
|
||||
return DoCommand(aCommandName, refCon);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDecreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
|
||||
nsICommandParams *aParams,
|
||||
nsISupports *refCon)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aParams);
|
||||
|
||||
PRBool enabled = PR_FALSE;
|
||||
nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aParams->SetBooleanValue(STATE_ENABLED, enabled);
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIncreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
|
||||
nsISupports *refCon,
|
||||
PRBool *outCmdEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
|
||||
if (!htmlEditor) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool isEnabled;
|
||||
htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
|
||||
if (!(*outCmdEnabled))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> positionedElement;
|
||||
htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement));
|
||||
*outCmdEnabled = (nsnull != positionedElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIncreaseZIndexCommand::DoCommand(const char *aCommandName,
|
||||
nsISupports *refCon)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
|
||||
if (!htmlEditor)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return htmlEditor->RelativeChangeZIndex(1);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIncreaseZIndexCommand::DoCommandParams(const char *aCommandName,
|
||||
nsICommandParams *aParams,
|
||||
nsISupports *refCon)
|
||||
{
|
||||
return DoCommand(aCommandName, refCon);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIncreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
|
||||
nsICommandParams *aParams,
|
||||
nsISupports *refCon)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aParams);
|
||||
|
||||
PRBool enabled = PR_FALSE;
|
||||
nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aParams->SetBooleanValue(STATE_ENABLED, enabled);
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRemoveStylesCommand::IsCommandEnabled(const char * aCommandName,
|
||||
nsISupports *refCon,
|
||||
|
|
|
@ -271,7 +271,17 @@ protected:
|
|||
virtual nsresult SetState(nsIEditor *aEditor, nsString& newState);
|
||||
};
|
||||
|
||||
class nsAbsolutePositioningCommand : public nsBaseStateUpdatingCommand
|
||||
{
|
||||
public:
|
||||
nsAbsolutePositioningCommand();
|
||||
|
||||
protected:
|
||||
|
||||
NS_IMETHOD IsCommandEnabled(const char *aCommandName, nsISupports *aCommandRefCon, PRBool *_retval);
|
||||
virtual nsresult GetCurrentState(nsIEditor *aEditor, const char* aTagName, nsICommandParams *aParams);
|
||||
virtual nsresult ToggleState(nsIEditor *aEditor, const char* aTagName);
|
||||
};
|
||||
|
||||
// composer commands
|
||||
|
||||
|
@ -281,6 +291,9 @@ NS_DECL_COMPOSER_COMMAND(nsSetDocumentStateCommand)
|
|||
NS_DECL_COMPOSER_COMMAND(nsSetDocumentOptionsCommand)
|
||||
//NS_DECL_COMPOSER_COMMAND(nsPrintingCommands)
|
||||
|
||||
NS_DECL_COMPOSER_COMMAND(nsDecreaseZIndexCommand)
|
||||
NS_DECL_COMPOSER_COMMAND(nsIncreaseZIndexCommand)
|
||||
|
||||
// Generic commands
|
||||
|
||||
// File menu
|
||||
|
|
|
@ -171,5 +171,9 @@ nsComposerController::RegisterHTMLEditorCommands(
|
|||
NS_REGISTER_TAG_COMMAND(nsInsertTagCommand, "cmd_insertImageNoUI", "img");
|
||||
NS_REGISTER_TAG_COMMAND(nsInsertTagCommand, "cmd_insertHR", "hr");
|
||||
|
||||
NS_REGISTER_ONE_COMMAND(nsAbsolutePositioningCommand, "cmd_absPos");
|
||||
NS_REGISTER_ONE_COMMAND(nsDecreaseZIndexCommand, "cmd_decreaseZIndex");
|
||||
NS_REGISTER_ONE_COMMAND(nsIncreaseZIndexCommand, "cmd_increaseZIndex");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -105,26 +105,35 @@ option {
|
|||
|
||||
#mozToc.readonly {
|
||||
-moz-user-select: all !important;
|
||||
-moz-user-input: none ! important;
|
||||
-moz-user-input: none !important;
|
||||
}
|
||||
|
||||
/* the following rules are for Image Resizing */
|
||||
|
||||
span[\_moz_anonclass="mozResizer"] {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
border: 1px black solid;
|
||||
background-color: black;
|
||||
background-color: white;
|
||||
-moz-user-select: none;
|
||||
z-index: 2147483646; /* max value -1 for this property */
|
||||
}
|
||||
|
||||
/* we can't use :active below */
|
||||
span[\_moz_anonclass="mozResizer"][\_moz_activated],
|
||||
span[\_moz_anonclass="mozResizer"]:hover {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
span[\_moz_anonclass="mozResizer"].hidden,
|
||||
span[\_moz_anonclass="mozResizingShadow"].hidden,
|
||||
img[\_moz_anonclass="mozResizingShadow"].hidden,
|
||||
span[\_moz_anonclass="mozResizingInfo"].hidden {
|
||||
display: none ! important;
|
||||
span[\_moz_anonclass="mozGrabber"].hidden,
|
||||
span[\_moz_anonclass="mozResizingInfo"].hidden,
|
||||
a[\_moz_anonclass="mozTableRemoveRow"].hidden,
|
||||
a[\_moz_anonclass="mozTableRemoveColumn"].hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
span[\_moz_anonclass="mozResizer"][anonlocation="nw"] {
|
||||
|
@ -153,12 +162,12 @@ span[\_moz_anonclass="mozResizer"][anonlocation="se"] {
|
|||
}
|
||||
|
||||
span[\_moz_anonclass="mozResizingShadow"],
|
||||
img[\_moz_anonclass="mozResizingShadow"]{
|
||||
border: thin dashed black;
|
||||
img[\_moz_anonclass="mozResizingShadow"] {
|
||||
-moz-outline: thin dashed black;
|
||||
-moz-user-select: none;
|
||||
display: block;
|
||||
-moz-opacity: 0.5;
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
}
|
||||
|
||||
span[\_moz_anonclass="mozResizingInfo"] {
|
||||
|
@ -169,5 +178,167 @@ span[\_moz_anonclass="mozResizingInfo"] {
|
|||
border: ridge 2px #d0d0d0;
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
}
|
||||
|
||||
img[\_moz_resizing] {
|
||||
-moz-outline: thin solid black;
|
||||
}
|
||||
|
||||
*[\_moz_abspos] {
|
||||
-moz-outline: silver ridge 2px;
|
||||
z-index: 2147483645 !important; /* max value -2 for this property */
|
||||
}
|
||||
*[\_moz_abspos="white"] {
|
||||
background-color: white !important;
|
||||
}
|
||||
*[\_moz_abspos="black"] {
|
||||
background-color: black !important;
|
||||
}
|
||||
|
||||
span[\_moz_anonclass="mozGrabber"] {
|
||||
-moz-outline: ridge 2px silver;
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-image: url("resource:/res/grabber.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
/* INLINE TABLE EDITING */
|
||||
|
||||
a[\_moz_anonclass="mozTableAddColumnBefore"] {
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
text-decoration: none !important;
|
||||
border: none 0px !important;
|
||||
width: 4px;
|
||||
height: 8px;
|
||||
background-image: url("resource:/res/table-add-column-before.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: none !important;
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddColumnBefore"]:hover {
|
||||
background-image: url("resource:/res/table-add-column-before-hover.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddColumnBefore"]:active {
|
||||
background-image: url("resource:/res/table-add-column-before-active.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddColumnAfter"] {
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
text-decoration: none !important;
|
||||
border: none 0px !important;
|
||||
width: 4px;
|
||||
height: 8px;
|
||||
background-image: url("resource:/res/table-add-column-after.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: none !important;
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddColumnAfter"]:hover {
|
||||
background-image: url("resource:/res/table-add-column-after-hover.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddColumnAfter"]:active {
|
||||
background-image: url("resource:/res/table-add-column-after-active.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableRemoveColumn"] {
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
text-decoration: none !important;
|
||||
border: none 0px !important;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-image: url("resource:/res/table-remove-column.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: none !important;
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableRemoveColumn"]:hover {
|
||||
background-image: url("resource:/res/table-remove-column-hover.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableRemoveColumn"]:active {
|
||||
background-image: url("resource:/res/table-remove-column-active.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddRowBefore"] {
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
text-decoration: none !important;
|
||||
border: none 0px !important;
|
||||
width: 8px;
|
||||
height: 4px;
|
||||
background-image: url("resource:/res/table-add-row-before.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: none !important;
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddRowBefore"]:hover {
|
||||
background-image: url("resource:/res/table-add-row-before-hover.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddRowBefore"]:active {
|
||||
background-image: url("resource:/res/table-add-row-before-active.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddRowAfter"] {
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
text-decoration: none !important;
|
||||
border: none 0px !important;
|
||||
width: 8px;
|
||||
height: 4px;
|
||||
background-image: url("resource:/res/table-add-row-after.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: none !important;
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddRowAfter"]:hover {
|
||||
background-image: url("resource:/res/table-add-row-after-hover.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableAddRowAfter"]:active {
|
||||
background-image: url("resource:/res/table-add-row-after-active.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableRemoveRow"] {
|
||||
position: absolute;
|
||||
z-index: 2147483647; /* max value for this property */
|
||||
text-decoration: none !important;
|
||||
border: none 0px !important;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-image: url("resource:/res/table-remove-row.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: none !important;
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableRemoveRow"]:hover {
|
||||
background-image: url("resource:/res/table-remove-row-hover.gif");
|
||||
}
|
||||
|
||||
a[\_moz_anonclass="mozTableRemoveRow"]:active {
|
||||
background-image: url("resource:/res/table-remove-row-active.gif");
|
||||
}
|
||||
|
|
После Ширина: | Высота: | Размер: 858 B |
После Ширина: | Высота: | Размер: 823 B |
После Ширина: | Высота: | Размер: 826 B |
После Ширина: | Высота: | Размер: 826 B |
После Ширина: | Высота: | Размер: 812 B |
После Ширина: | Высота: | Размер: 825 B |
После Ширина: | Высота: | Размер: 825 B |
После Ширина: | Высота: | Размер: 822 B |
После Ширина: | Высота: | Размер: 826 B |
После Ширина: | Высота: | Размер: 826 B |
После Ширина: | Высота: | Размер: 821 B |
После Ширина: | Высота: | Размер: 825 B |
После Ширина: | Высота: | Размер: 825 B |
После Ширина: | Высота: | Размер: 835 B |
После Ширина: | Высота: | Размер: 841 B |
После Ширина: | Высота: | Размер: 841 B |
После Ширина: | Высота: | Размер: 835 B |
После Ширина: | Высота: | Размер: 841 B |
После Ширина: | Высота: | Размер: 841 B |
|
@ -42,6 +42,9 @@ XPIDLSRCS = \
|
|||
nsIEditorStyleSheets.idl \
|
||||
nsIHTMLEditor.idl \
|
||||
nsIHTMLObjectResizer.idl \
|
||||
nsIHTMLAbsPosEditor.idl \
|
||||
nsIHTMLObjectResizeListener.idl \
|
||||
nsIHTMLInlineTableEditor.idl \
|
||||
nsIPlaintextEditor.idl \
|
||||
nsITableEditor.idl \
|
||||
nsIURIRefObject.idl \
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(91375f52-20e6-4757-9835-eb04fabe5498)]
|
||||
|
||||
interface nsIHTMLAbsPosEditor : nsISupports
|
||||
{
|
||||
/**
|
||||
* true if the selection container is absolutely positioned
|
||||
*/
|
||||
readonly attribute boolean selectionContainerAbsolutelyPositioned;
|
||||
|
||||
/**
|
||||
* this contains the absolutely positioned element currently edited
|
||||
* or null
|
||||
*/
|
||||
readonly attribute nsIDOMElement positionedElement;
|
||||
|
||||
/**
|
||||
* true if Absolute Positioning handling is enabled in the editor
|
||||
*/
|
||||
attribute boolean absolutePositioningEnabled;
|
||||
|
||||
|
||||
/* Utility methods */
|
||||
|
||||
/**
|
||||
* true if Snap To Grid is enabled in the editor.
|
||||
*/
|
||||
attribute boolean snapToGridEnabled;
|
||||
|
||||
/**
|
||||
* sets the grid size in pixels.
|
||||
* @param aSizeInPixels [IN] the size of the grid in pixels
|
||||
*/
|
||||
attribute unsigned long gridSize;
|
||||
|
||||
/* Selection-based methods */
|
||||
|
||||
/**
|
||||
* returns the deepest absolutely positioned container of the selection
|
||||
* if it exists or null.
|
||||
*/
|
||||
readonly attribute nsIDOMElement absolutelyPositionedSelectionContainer;
|
||||
|
||||
/**
|
||||
* extracts the selection from the normal flow of the document and
|
||||
* positions it.
|
||||
* @param aEnabled [IN] true to absolutely position the selection,
|
||||
* false to put it back in the normal flow
|
||||
*/
|
||||
void absolutePositionSelection(in boolean aEnabled);
|
||||
|
||||
/**
|
||||
* adds aChange to the z-index of the currently positioned element.
|
||||
* @param aChange [IN] relative change to apply to current z-index
|
||||
*/
|
||||
void relativeChangeZIndex(in long aChange);
|
||||
|
||||
/* Element-based methods */
|
||||
|
||||
/**
|
||||
* extracts an element from the normal flow of the document and
|
||||
* positions it, and puts it back in the normal flow.
|
||||
* @param aElement [IN] the element
|
||||
* @param aEnabled [IN] true to absolutely position the element,
|
||||
* false to put it back in the normal flow
|
||||
*/
|
||||
void absolutelyPositionElement(in nsIDOMElement aElement,
|
||||
in boolean aEnabled);
|
||||
|
||||
/**
|
||||
* sets the position of an element; warning it does NOT check if the
|
||||
* element is already positioned or not and that's on purpose.
|
||||
* @param aElement [IN] the element
|
||||
* @param aX [IN] the x position in pixels.
|
||||
* @param aY [IN] the y position in pixels.
|
||||
*/
|
||||
void setElementPosition(in nsIDOMElement aElement, in long aX, in long aY);
|
||||
|
||||
/**
|
||||
* returns the absolute z-index of a positioned element. Never returns 'auto'.
|
||||
* @return the z-index of the element
|
||||
* @param aElement [IN] the element.
|
||||
*/
|
||||
long getElementZIndex(in nsIDOMElement aElement);
|
||||
|
||||
/**
|
||||
* sets the z-index of an element.
|
||||
* @param aElement [IN] the element
|
||||
* @param aZorder [IN] the z-index
|
||||
*/
|
||||
void setElementZIndex(in nsIDOMElement aElement, in long aZorder);
|
||||
|
||||
/**
|
||||
* adds aChange to the z-index of an arbitrary element.
|
||||
* @return the new z-index of the element
|
||||
* @param aElement [IN] the element
|
||||
* @param aChange [IN] relative change to apply to current z-index of
|
||||
* the element
|
||||
*/
|
||||
long relativeChangeElementZIndex(in nsIDOMElement aElement, in long aChange);
|
||||
|
||||
/* Other */
|
||||
|
||||
/**
|
||||
* shows a grabber attached to an arbitrary element. The grabber is an image
|
||||
* positioned on the left hand side of the top border of the element. Dragging
|
||||
* and dropping it allows to change the element's absolute position in the
|
||||
* document. See chrome://editor/content/images/grabber.gif
|
||||
* @param aElement [IN] the element
|
||||
*/
|
||||
void showGrabberOnElement(in nsIDOMElement aElement);
|
||||
|
||||
/**
|
||||
* hide the grabber if it shown.
|
||||
*/
|
||||
void hideGrabber();
|
||||
|
||||
/**
|
||||
* refreshes the grabber if it shown, possibly updating its position or
|
||||
* even hiding it.
|
||||
*/
|
||||
void refreshGrabber();
|
||||
|
||||
};
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsIAtom.idl"
|
||||
|
||||
interface nsISupportsArray;
|
||||
interface nsISelection;
|
||||
interface nsIContentFilter;
|
||||
|
||||
%{C++
|
||||
|
@ -434,108 +435,108 @@ interface nsIHTMLEditor : nsISupports
|
|||
void align(in AString aAlign);
|
||||
|
||||
/**
|
||||
* Return the input node or a parent matching the given aTagName,
|
||||
* starting the search at the supplied node.
|
||||
* An example of use is for testing if a node is in a table cell
|
||||
* given a selection anchor node.
|
||||
*
|
||||
* @param aTagName The HTML tagname
|
||||
* Special input values:
|
||||
* Use "href" to get a link node
|
||||
* (an "A" tag with the "href" attribute set)
|
||||
* Use "anchor" or "namedanchor" to get a named anchor node
|
||||
* (an "A" tag with the "name" attribute set)
|
||||
* Use "list" to get an OL, UL, or DL list node
|
||||
* Use "td" to get either a TD or TH cell node
|
||||
*
|
||||
* @param aNode The node in the document to start the search.
|
||||
* If it is null, the anchor node of the current selection is used.
|
||||
* @return NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found
|
||||
* (passes NS_SUCCEEDED macro)
|
||||
*/
|
||||
* Return the input node or a parent matching the given aTagName,
|
||||
* starting the search at the supplied node.
|
||||
* An example of use is for testing if a node is in a table cell
|
||||
* given a selection anchor node.
|
||||
*
|
||||
* @param aTagName The HTML tagname
|
||||
* Special input values:
|
||||
* Use "href" to get a link node
|
||||
* (an "A" tag with the "href" attribute set)
|
||||
* Use "anchor" or "namedanchor" to get a named anchor node
|
||||
* (an "A" tag with the "name" attribute set)
|
||||
* Use "list" to get an OL, UL, or DL list node
|
||||
* Use "td" to get either a TD or TH cell node
|
||||
*
|
||||
* @param aNode The node in the document to start the search.
|
||||
* If it is null, the anchor node of the current selection is used.
|
||||
* @return NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found
|
||||
* (passes NS_SUCCEEDED macro)
|
||||
*/
|
||||
nsIDOMElement getElementOrParentByTagName(in AString aTagName,
|
||||
in nsIDOMNode aNode);
|
||||
|
||||
/**
|
||||
* Return an element only if it is the only node selected,
|
||||
* such as an image, horizontal rule, etc.
|
||||
* The exception is a link, which is more like a text attribute:
|
||||
* The Anchor tag is returned if the selection is within the textnode(s)
|
||||
* that are children of the "A" node.
|
||||
* This could be a collapsed selection, i.e., a caret
|
||||
* within the link text.
|
||||
*
|
||||
* @param aTagName The HTML tagname or and empty string
|
||||
* to get any element (but only if it is the only element selected)
|
||||
* Special input values for Links and Named anchors:
|
||||
* Use "href" to get a link node
|
||||
* (an "A" tag with the "href" attribute set)
|
||||
* Use "anchor" or "namedanchor" to get a named anchor node
|
||||
* (an "A" tag with the "name" attribute set)
|
||||
* @return NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found
|
||||
* (passes NS_SUCCEEDED macro)
|
||||
*/
|
||||
* Return an element only if it is the only node selected,
|
||||
* such as an image, horizontal rule, etc.
|
||||
* The exception is a link, which is more like a text attribute:
|
||||
* The Anchor tag is returned if the selection is within the textnode(s)
|
||||
* that are children of the "A" node.
|
||||
* This could be a collapsed selection, i.e., a caret
|
||||
* within the link text.
|
||||
*
|
||||
* @param aTagName The HTML tagname or and empty string
|
||||
* to get any element (but only if it is the only element selected)
|
||||
* Special input values for Links and Named anchors:
|
||||
* Use "href" to get a link node
|
||||
* (an "A" tag with the "href" attribute set)
|
||||
* Use "anchor" or "namedanchor" to get a named anchor node
|
||||
* (an "A" tag with the "name" attribute set)
|
||||
* @return NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found
|
||||
* (passes NS_SUCCEEDED macro)
|
||||
*/
|
||||
nsIDOMElement getSelectedElement(in AString aTagName);
|
||||
|
||||
/**
|
||||
* Output the contents of the <HEAD> section as text/HTML format
|
||||
*/
|
||||
* Output the contents of the <HEAD> section as text/HTML format
|
||||
*/
|
||||
AString getHeadContentsAsHTML();
|
||||
|
||||
/**
|
||||
* Replace all children of <HEAD> with string of HTML source
|
||||
*/
|
||||
* Replace all children of <HEAD> with string of HTML source
|
||||
*/
|
||||
void replaceHeadContentsWithHTML(in AString aSourceToInsert);
|
||||
|
||||
/**
|
||||
* Return a new element with default attribute values
|
||||
*
|
||||
* This does not rely on the selection, and is not sensitive to context.
|
||||
*
|
||||
* Used primarily to supply new element for various insert element dialogs
|
||||
* (Image, Link, NamedAnchor, Table, and HorizontalRule
|
||||
* are the only returned elements as of 7/25/99)
|
||||
*
|
||||
* @param aTagName The HTML tagname
|
||||
* Special input values for Links and Named anchors:
|
||||
* Use "href" to get a link node
|
||||
* (an "A" tag with the "href" attribute set)
|
||||
* Use "anchor" or "namedanchor" to get a named anchor node
|
||||
* (an "A" tag with the "name" attribute set)
|
||||
* @return The new element created.
|
||||
*/
|
||||
* Return a new element with default attribute values
|
||||
*
|
||||
* This does not rely on the selection, and is not sensitive to context.
|
||||
*
|
||||
* Used primarily to supply new element for various insert element dialogs
|
||||
* (Image, Link, NamedAnchor, Table, and HorizontalRule
|
||||
* are the only returned elements as of 7/25/99)
|
||||
*
|
||||
* @param aTagName The HTML tagname
|
||||
* Special input values for Links and Named anchors:
|
||||
* Use "href" to get a link node
|
||||
* (an "A" tag with the "href" attribute set)
|
||||
* Use "anchor" or "namedanchor" to get a named anchor node
|
||||
* (an "A" tag with the "name" attribute set)
|
||||
* @return The new element created.
|
||||
*/
|
||||
nsIDOMElement createElementWithDefaults(in AString aTagName);
|
||||
|
||||
/**
|
||||
* Insert an link element as the parent of the current selection
|
||||
*
|
||||
* @param aElement An "A" element with a non-empty "href" attribute
|
||||
*/
|
||||
* Insert an link element as the parent of the current selection
|
||||
*
|
||||
* @param aElement An "A" element with a non-empty "href" attribute
|
||||
*/
|
||||
void insertLinkAroundSelection(in nsIDOMElement aAnchorElement);
|
||||
|
||||
/**
|
||||
* Set the value of the "bgcolor" attribute on the document's <body> element
|
||||
*
|
||||
* @param aColor The HTML color string, such as "#ffccff" or "yellow"
|
||||
*/
|
||||
* Set the value of the "bgcolor" attribute on the document's <body> element
|
||||
*
|
||||
* @param aColor The HTML color string, such as "#ffccff" or "yellow"
|
||||
*/
|
||||
void setBackgroundColor(in AString aColor);
|
||||
|
||||
|
||||
/**
|
||||
* Set an attribute on the document's <body> element
|
||||
* such as text, link, background colors
|
||||
*
|
||||
* 8/31/00 THIS ISN'T BEING USED? SHOULD WE DROP IT?
|
||||
*
|
||||
* @param aAttr The attribute to be set
|
||||
* @param aValue The value of the attribute
|
||||
*/
|
||||
* Set an attribute on the document's <body> element
|
||||
* such as text, link, background colors
|
||||
*
|
||||
* 8/31/00 THIS ISN'T BEING USED? SHOULD WE DROP IT?
|
||||
*
|
||||
* @param aAttr The attribute to be set
|
||||
* @param aValue The value of the attribute
|
||||
*/
|
||||
void setBodyAttribute(in AString aAttr, in AString aValue);
|
||||
|
||||
/**
|
||||
* XXX Used to suppress spurious drag/drop events to workaround bug 50703
|
||||
* Don't use this method! It will go away after first release!
|
||||
*/
|
||||
* XXX Used to suppress spurious drag/drop events to workaround bug 50703
|
||||
* Don't use this method! It will go away after first release!
|
||||
*/
|
||||
void ignoreSpuriousDragEvent(in boolean aIgnoreSpuriousDragEvent);
|
||||
|
||||
/**
|
||||
|
@ -548,29 +549,63 @@ interface nsIHTMLEditor : nsISupports
|
|||
nsISupportsArray getLinkedObjects();
|
||||
|
||||
/**
|
||||
* A boolean which is true is the HTMLEditor has been instantiated
|
||||
* with CSS knowledge and if the CSS pref is currently checked
|
||||
*
|
||||
* @return true if CSS handled and enabled
|
||||
*/
|
||||
* A boolean which is true is the HTMLEditor has been instantiated
|
||||
* with CSS knowledge and if the CSS pref is currently checked
|
||||
*
|
||||
* @return true if CSS handled and enabled
|
||||
*/
|
||||
attribute boolean isCSSEnabled;
|
||||
|
||||
/**
|
||||
* Add listener for insertion override
|
||||
* @param inFilter function which callers want called during insertion
|
||||
*/
|
||||
|
||||
void addInsertionListener(in nsIContentFilter inFilter);
|
||||
|
||||
/**
|
||||
* Remove listener for insertion override
|
||||
* @param inFilter function which callers do not want called during insertion
|
||||
*/
|
||||
|
||||
void removeInsertionListener(in nsIContentFilter inFilter);
|
||||
|
||||
/**
|
||||
* parse a string containing CSS declarations and returns a DOM CSSStyleRule
|
||||
* @return a DOM CSSStyleRule
|
||||
* @param aString [IN] a string containing CSS declarations
|
||||
*/
|
||||
nsIDOMCSSStyleRule parseStyleAttrIntoCSSRule(in AString aString);
|
||||
|
||||
/**
|
||||
* Returns an anonymous nsDOMElement of type aTag,
|
||||
* child of aParentNode. If aIsCreatedHidden is true, the class
|
||||
* "hidden" is added to the created element. If aAnonClass is not
|
||||
* the empty string, it becomes the value of the attribute "_moz_anonclass"
|
||||
* @return a DOM Element
|
||||
* @param aTag [IN] a string representing the desired type of
|
||||
* the element to create
|
||||
* @param aParentNode [IN] the parent node of the created anonymous
|
||||
* element
|
||||
* @param aAnonClass [IN] contents of the _moz_anonclass attribute
|
||||
* @param aIsCreatedHidden [IN] a boolean specifying if the class "hidden"
|
||||
* is to be added to the created anonymous
|
||||
* element
|
||||
*/
|
||||
nsIDOMElement createAnonymousElement(in AString aTag, in nsIDOMNode aParentNode,
|
||||
in AString aAnonClass, in boolean aIsCreatedHidden);
|
||||
|
||||
/**
|
||||
* returns the deepest container of the selection
|
||||
* @return a DOM Element
|
||||
*/
|
||||
nsIDOMElement getSelectionContainer();
|
||||
|
||||
/**
|
||||
* Checks if the anonymous nodes created by the HTML editor have to be
|
||||
* refreshed or hidden depending on a possible new state of the selection
|
||||
* @param aSelection [IN] a selection
|
||||
*/
|
||||
void checkSelectionStateForAnonymousButtons(in nsISelection aSelection);
|
||||
|
||||
boolean isAnonymousElement(in nsIDOMElement aElement);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(eda2e65c-a758-451f-9b05-77cb8de74ed2)]
|
||||
|
||||
interface nsIHTMLInlineTableEditor : nsISupports
|
||||
{
|
||||
/**
|
||||
* boolean indicating if inline table editing is enabled in the editor.
|
||||
* When inline table editing is enabled, and when the selection is
|
||||
* contained in a table cell, special buttons allowing to add/remove
|
||||
* a line/column are available on the cell's border.
|
||||
*/
|
||||
attribute boolean inlineTableEditingEnabled;
|
||||
|
||||
/**
|
||||
* Shows inline table editing UI around a table cell
|
||||
* @param aCell [IN] a DOM Element being a table cell, td or th
|
||||
*/
|
||||
void showInlineTableEditingUI(in nsIDOMElement aCell);
|
||||
|
||||
/**
|
||||
* Hide all inline table editing UI
|
||||
*/
|
||||
void hideInlineTableEditingUI();
|
||||
|
||||
/**
|
||||
* Modifies the table containing the selection according to the
|
||||
* activation of an inline table editing UI element
|
||||
* @param aUIAnonymousElement [IN] the inline table editing UI element
|
||||
*/
|
||||
void doInlineTableEditingAction(in nsIDOMElement aUIAnonymousElement);
|
||||
|
||||
/**
|
||||
* Refresh already visible inline table editing UI
|
||||
*/
|
||||
void refreshInlineTableEditingUI();
|
||||
};
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(27b00295-349c-429f-ad0c-87b859e77130)]
|
||||
|
||||
interface nsIHTMLObjectResizeListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Listener's callback called by the editor when the user
|
||||
* starts resizing an element
|
||||
* @param aElement [IN] the element
|
||||
*/
|
||||
void onStartResizing(in nsIDOMElement aElement);
|
||||
|
||||
/**
|
||||
* Listener's callback called by the editor when the user
|
||||
* has finalized the resizing of an element
|
||||
* @param aElement [IN] the element that was resized
|
||||
* @param aOldWidth [IN] the width of the element before resizing
|
||||
* @param aOldHeight [IN] the height of the element before resizing
|
||||
* @param aNewWidth [IN] the width of the element after resizing
|
||||
* @param aNewHeight [IN] the height of the element after resizing
|
||||
*/
|
||||
void onEndResizing(in nsIDOMElement aElement,
|
||||
in long aOldWidth, in long aOldHeight,
|
||||
in long aNewWidth, in long aNewHeight);
|
||||
|
||||
};
|
|
@ -41,6 +41,8 @@
|
|||
#include "nsIAtom.idl"
|
||||
#include "nsISelection.idl"
|
||||
|
||||
interface nsIHTMLObjectResizeListener;
|
||||
|
||||
[scriptable, uuid(b0338f6c-ded3-4c39-a953-56e8bae494f5)]
|
||||
|
||||
interface nsIHTMLObjectResizer : nsISupports
|
||||
|
@ -57,18 +59,69 @@ interface nsIHTMLObjectResizer : nsISupports
|
|||
const short eBottom = 6;
|
||||
const short eBottomRight = 7;
|
||||
|
||||
/**
|
||||
* the element currently displaying resizers
|
||||
*/
|
||||
readonly attribute nsIDOMElement resizedObject;
|
||||
attribute boolean isImageResizingEnabled;
|
||||
|
||||
void getResizedObjectSize(out long aWidth, out long aHeight);
|
||||
/**
|
||||
* a boolean indicating if object resizing is enabled in the editor
|
||||
*/
|
||||
attribute boolean objectResizingEnabled;
|
||||
|
||||
/**
|
||||
* Shows active resizers around an element's frame
|
||||
* @param aResizedElement [IN] a DOM Element
|
||||
*/
|
||||
void showResizers(in nsIDOMElement aResizedElement);
|
||||
|
||||
/**
|
||||
* Hide resizers if they are visible
|
||||
*/
|
||||
void hideResizers();
|
||||
|
||||
/**
|
||||
* Refresh visible resizers
|
||||
*/
|
||||
void refreshResizers();
|
||||
|
||||
/**
|
||||
* event callback when a mouse button is pressed
|
||||
* @param aX [IN] horizontal position of the pointer
|
||||
* @param aY [IN] vertical position of the pointer
|
||||
* @param aTarget [IN] the element triggering the event
|
||||
*/
|
||||
void mouseDown(in long aX, in long aY,
|
||||
in nsIDOMElement aResizedObject);
|
||||
in nsIDOMElement aTarget);
|
||||
|
||||
/**
|
||||
* event callback when a mouse button is released
|
||||
* @param aX [IN] horizontal position of the pointer
|
||||
* @param aY [IN] vertical position of the pointer
|
||||
* @param aTarget [IN] the element triggering the event
|
||||
*/
|
||||
void mouseUp(in long aX, in long aY,
|
||||
in nsIDOMElement aResizedObject);
|
||||
in nsIDOMElement aTarget);
|
||||
|
||||
/**
|
||||
* event callback when the mouse pointer is moved
|
||||
* @param aMouseEvent [IN] the event
|
||||
*/
|
||||
void mouseMove(in nsIDOMEvent aMouseEvent);
|
||||
void checkResizingState(in nsISelection aSelection);
|
||||
|
||||
/* Event Listeners */
|
||||
|
||||
/**
|
||||
* Creates a resize listener that can be used to get notifications
|
||||
* that the user started to resize an object or finalized such an operation
|
||||
* @param aListener [IN] an instance of nsIHTMLObjectResizeListener
|
||||
*/
|
||||
void addObjectResizeEventListener(in nsIHTMLObjectResizeListener aListener);
|
||||
|
||||
/**
|
||||
* Deletes a resize listener
|
||||
* @param aListener [IN] an instance of nsIHTMLObjectResizeListener
|
||||
*/
|
||||
void removeObjectResizeEventListener(in nsIHTMLObjectResizeListener aListener);
|
||||
};
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ EDITOR_ATOM(size, "size")
|
|||
EDITOR_ATOM(cssBackgroundColor, "background-color")
|
||||
EDITOR_ATOM(cssBackgroundImage, "background-image")
|
||||
EDITOR_ATOM(cssBorder, "border")
|
||||
EDITOR_ATOM(cssBottom, "bottom")
|
||||
EDITOR_ATOM(cssCaptionSide, "caption-side")
|
||||
EDITOR_ATOM(cssColor, "color")
|
||||
EDITOR_ATOM(cssFloat, "float")
|
||||
|
@ -147,12 +148,15 @@ EDITOR_ATOM(cssListStyleType, "list-style-type")
|
|||
EDITOR_ATOM(cssLeft, "left")
|
||||
EDITOR_ATOM(cssMarginRight, "margin-right")
|
||||
EDITOR_ATOM(cssMarginLeft, "margin-left")
|
||||
EDITOR_ATOM(cssPosition, "position")
|
||||
EDITOR_ATOM(cssRight, "right")
|
||||
EDITOR_ATOM(cssTextAlign, "text-align")
|
||||
EDITOR_ATOM(cssTextDecoration, "text-decoration")
|
||||
EDITOR_ATOM(cssTop, "top")
|
||||
EDITOR_ATOM(cssVerticalAlign, "vertical-align")
|
||||
EDITOR_ATOM(cssWhitespace, "white-space")
|
||||
EDITOR_ATOM(cssWidth, "width")
|
||||
EDITOR_ATOM(cssZIndex, "z-index")
|
||||
|
||||
EDITOR_ATOM(cssMozUserSelect, "-moz-user-select")
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ REQUIRES = xpcom \
|
|||
|
||||
CPPSRCS = \
|
||||
nsEditProperty.cpp \
|
||||
nsHTMLAbsPosition.cpp \
|
||||
nsHTMLAnonymousUtils.cpp \
|
||||
nsHTMLDataTransfer.cpp \
|
||||
nsHTMLCSSUtils.cpp \
|
||||
nsHTMLEditor.cpp \
|
||||
|
@ -57,6 +59,7 @@ CPPSRCS = \
|
|||
nsHTMLEditUtils.cpp \
|
||||
nsHTMLObjectResizer.cpp \
|
||||
nsHTMLEditorMouseListener.cpp \
|
||||
nsHTMLInlineTableEditor.cpp \
|
||||
nsHTMLURIRefObject.cpp \
|
||||
nsTableEditor.cpp \
|
||||
nsWSRunObject.cpp \
|
||||
|
|
|
@ -0,0 +1,757 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "nsHTMLEditor.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
#include "nsISelection.h"
|
||||
|
||||
#include "nsTextEditUtils.h"
|
||||
#include "nsEditorUtils.h"
|
||||
#include "nsHTMLEditUtils.h"
|
||||
#include "nsTextEditRules.h"
|
||||
#include "nsIHTMLEditRules.h"
|
||||
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsIDOMCSSValue.h"
|
||||
#include "nsIDOMCSSPrimitiveValue.h"
|
||||
#include "nsIDOMRGBColor.h"
|
||||
|
||||
#define BLACK_BG_RGB_TRIGGER 0xd0
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::AbsolutePositionSelection(PRBool aEnabled)
|
||||
{
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
nsAutoRules beginRulesSniffing(this,
|
||||
aEnabled ? kOpSetAbsolutePosition :
|
||||
kOpRemoveAbsolutePosition,
|
||||
nsIEditor::eNext);
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(aEnabled ?
|
||||
nsTextEditRules::kSetAbsolutePosition :
|
||||
nsTextEditRules::kRemoveAbsolutePosition);
|
||||
PRBool cancel, handled;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(res) || cancel)
|
||||
return res;
|
||||
|
||||
return mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetAbsolutelyPositionedSelectionContainer(nsIDOMElement **_retval)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
nsresult res = GetSelectionContainer(getter_AddRefs(element));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString positionStr;
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(element);
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
|
||||
do {
|
||||
res = mHTMLCSSUtils->GetComputedProperty(node, nsEditProperty::cssPosition,
|
||||
positionStr);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (positionStr.Equals(NS_LITERAL_STRING("absolute")))
|
||||
resultNode = node;
|
||||
else {
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
res = node->GetParentNode(getter_AddRefs(parentNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node.swap(parentNode);
|
||||
}
|
||||
} while (!resultNode &&
|
||||
!nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("html")));
|
||||
|
||||
element = do_QueryInterface(resultNode );
|
||||
*_retval = element;
|
||||
NS_IF_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetSelectionContainerAbsolutelyPositioned(PRBool *aIsSelectionContainerAbsolutelyPositioned)
|
||||
{
|
||||
*aIsSelectionContainerAbsolutelyPositioned = (mAbsolutelyPositionedObject != nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetAbsolutePositioningEnabled(PRBool * aIsEnabled)
|
||||
{
|
||||
*aIsEnabled = mIsAbsolutelyPositioningEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetAbsolutePositioningEnabled(PRBool aIsEnabled)
|
||||
{
|
||||
mIsAbsolutelyPositioningEnabled = aIsEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RelativeChangeElementZIndex(nsIDOMElement * aElement,
|
||||
PRInt32 aChange,
|
||||
PRInt32 * aReturn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aElement);
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
if (!aChange) // early way out, no change
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 zIndex;
|
||||
nsresult res = GetElementZIndex(aElement, &zIndex);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
zIndex = PR_MAX(zIndex + aChange, 0);
|
||||
SetElementZIndex(aElement, zIndex);
|
||||
*aReturn = zIndex;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetElementZIndex(nsIDOMElement * aElement,
|
||||
PRInt32 aZindex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aElement);
|
||||
|
||||
nsAutoString zIndexStr;
|
||||
zIndexStr.AppendInt(aZindex);
|
||||
|
||||
mHTMLCSSUtils->SetCSSProperty(aElement,
|
||||
nsEditProperty::cssZIndex,
|
||||
zIndexStr,
|
||||
PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RelativeChangeZIndex(PRInt32 aChange)
|
||||
{
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
nsAutoRules beginRulesSniffing(this,
|
||||
(aChange < 0) ? kOpDecreaseZIndex :
|
||||
kOpIncreaseZIndex,
|
||||
nsIEditor::eNext);
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo((aChange < 0) ? nsTextEditRules::kDecreaseZIndex:
|
||||
nsTextEditRules::kIncreaseZIndex);
|
||||
PRBool cancel, handled;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(res))
|
||||
return res;
|
||||
|
||||
return mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetElementZIndex(nsIDOMElement * aElement,
|
||||
PRInt32 * aZindex)
|
||||
{
|
||||
nsAutoString zIndexStr;
|
||||
*aZindex = 0;
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
nsresult res = mHTMLCSSUtils->GetSpecifiedProperty(node,
|
||||
nsEditProperty::cssZIndex,
|
||||
zIndexStr);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (zIndexStr.Equals(NS_LITERAL_STRING("auto"))) {
|
||||
// we have to look at the positioned ancestors
|
||||
// cf. CSS 2 spec section 9.9.1
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
res = node->GetParentNode(getter_AddRefs(parentNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node = parentNode;
|
||||
nsAutoString positionStr;
|
||||
while (node &&
|
||||
zIndexStr.Equals(NS_LITERAL_STRING("auto")) &&
|
||||
!nsTextEditUtils::IsBody(node)) {
|
||||
res = mHTMLCSSUtils->GetComputedProperty(node,
|
||||
nsEditProperty::cssPosition,
|
||||
positionStr);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (positionStr.Equals(NS_LITERAL_STRING("absolute"))) {
|
||||
// ah, we found one, what's its z-index ? If its z-index is auto,
|
||||
// we have to continue climbing the document's tree
|
||||
res = mHTMLCSSUtils->GetComputedProperty(node,
|
||||
nsEditProperty::cssZIndex,
|
||||
zIndexStr);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
res = node->GetParentNode(getter_AddRefs(parentNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node = parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
if (!zIndexStr.Equals(NS_LITERAL_STRING("auto"))) {
|
||||
PRInt32 errorCode;
|
||||
*aZindex = zIndexStr.ToInteger(&errorCode);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::CreateGrabber(nsIDOMNode * aParentNode, nsIDOMElement ** aReturn)
|
||||
{
|
||||
// let's create a grabber through the element factory
|
||||
nsresult res = CreateAnonymousElement(NS_LITERAL_STRING("span"),
|
||||
aParentNode,
|
||||
NS_LITERAL_STRING("mozGrabber"),
|
||||
PR_FALSE,
|
||||
aReturn);
|
||||
|
||||
if (!*aReturn)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// add the mouse listener so we can detect a click on a resizer
|
||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(*aReturn));
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), mMouseListenerP, PR_FALSE);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RefreshGrabber()
|
||||
{
|
||||
NS_ENSURE_TRUE(mAbsolutelyPositionedObject, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsresult res = GetPositionAndDimensions(mAbsolutelyPositionedObject,
|
||||
mPositionedObjectX,
|
||||
mPositionedObjectY,
|
||||
mPositionedObjectWidth,
|
||||
mPositionedObjectHeight,
|
||||
mPositionedObjectBorderLeft,
|
||||
mPositionedObjectBorderTop,
|
||||
mPositionedObjectMarginLeft,
|
||||
mPositionedObjectMarginTop);
|
||||
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
SetAnonymousElementPosition(mPositionedObjectX+12,
|
||||
mPositionedObjectY-14,
|
||||
mGrabber);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::HideGrabber()
|
||||
{
|
||||
nsresult res =
|
||||
mAbsolutelyPositionedObject->RemoveAttribute(NS_LITERAL_STRING("_moz_abspos"));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
mAbsolutelyPositionedObject = nsnull;
|
||||
NS_ENSURE_TRUE(mGrabber, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// get the presshell's document observer interface.
|
||||
|
||||
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIDocumentObserver> docObserver(do_QueryInterface(ps));
|
||||
if (!docObserver) return NS_ERROR_FAILURE;
|
||||
|
||||
// get the root content node.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> bodyElement;
|
||||
res = GetRootElement(getter_AddRefs(bodyElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(bodyElement);
|
||||
if (!bodyContent) return res;
|
||||
|
||||
DeleteRefToAnonymousNode(mGrabber, bodyContent, docObserver);
|
||||
mGrabber = nsnull;
|
||||
DeleteRefToAnonymousNode(mPositioningShadow, bodyContent, docObserver);
|
||||
mPositioningShadow = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aElement);
|
||||
|
||||
nsAutoString classValue;
|
||||
nsresult res = CheckPositionedElementBGandFG(aElement, classValue);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = aElement->SetAttribute(NS_LITERAL_STRING("_moz_abspos"),
|
||||
classValue);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// first, let's keep track of that element...
|
||||
mAbsolutelyPositionedObject = aElement;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> bodyElement;
|
||||
res = GetRootElement(getter_AddRefs(bodyElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> bodyNode( do_QueryInterface(bodyElement) );
|
||||
|
||||
res = CreateGrabber(bodyNode, getter_AddRefs(mGrabber));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// and set its position
|
||||
return RefreshGrabber();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::StartMoving(nsIDOMElement *aHandle)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> bodyElement;
|
||||
nsresult result = GetRootElement(getter_AddRefs(bodyElement));
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> bodyNode( do_QueryInterface(bodyElement) );
|
||||
|
||||
// now, let's create the resizing shadow
|
||||
result = CreateShadow(getter_AddRefs(mPositioningShadow), bodyNode,
|
||||
mAbsolutelyPositionedObject);
|
||||
if (NS_FAILED(result)) return result;
|
||||
result = SetShadowPosition(mPositioningShadow, mAbsolutelyPositionedObject,
|
||||
mPositionedObjectX, mPositionedObjectY);
|
||||
if (NS_FAILED(result)) return result;
|
||||
|
||||
// make the shadow appear
|
||||
mPositioningShadow->RemoveAttribute(NS_LITERAL_STRING("class"));
|
||||
|
||||
// position it
|
||||
nsAutoString w, h;
|
||||
w.AppendInt(mPositionedObjectWidth);
|
||||
h.AppendInt(mPositionedObjectHeight);
|
||||
mHTMLCSSUtils->SetCSSProperty(mPositioningShadow,
|
||||
NS_LITERAL_STRING("width"),
|
||||
w + NS_LITERAL_STRING("px"));
|
||||
mHTMLCSSUtils->SetCSSProperty(mPositioningShadow,
|
||||
NS_LITERAL_STRING("height"),
|
||||
h + NS_LITERAL_STRING("px"));
|
||||
|
||||
mIsMoving = PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLEditor::SnapToGrid(PRInt32 & newX, PRInt32 & newY)
|
||||
{
|
||||
if (mSnapToGridEnabled && mGridSize) {
|
||||
newX = (PRInt32) floor( ((float)newX / (float)mGridSize) + 0.5f ) * mGridSize;
|
||||
newY = (PRInt32) floor( ((float)newY / (float)mGridSize) + 0.5f ) * mGridSize;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::GrabberClicked()
|
||||
{
|
||||
// add a mouse move listener to the editor
|
||||
nsresult res = NS_OK;
|
||||
if (!mMouseMotionListenerP) {
|
||||
mMouseMotionListenerP = new ResizerMouseMotionListener(this);
|
||||
if (!mMouseMotionListenerP) {return NS_ERROR_NULL_POINTER;}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||
res = GetDOMEventReceiver(getter_AddRefs(erP));
|
||||
if (NS_SUCCEEDED(res ))
|
||||
{
|
||||
res = erP->AddEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener));
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "failed to register mouse motion listener");
|
||||
}
|
||||
else
|
||||
HandleEventListenerError();
|
||||
}
|
||||
mGrabberClicked = PR_TRUE;
|
||||
return res;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::EndMoving()
|
||||
{
|
||||
if (mPositioningShadow) {
|
||||
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIDocumentObserver> docObserver(do_QueryInterface(ps));
|
||||
if (!docObserver) return NS_ERROR_FAILURE;
|
||||
|
||||
// get the root content node.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> bodyElement;
|
||||
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
|
||||
if (!bodyContent) return NS_ERROR_FAILURE;
|
||||
|
||||
DeleteRefToAnonymousNode(mPositioningShadow, bodyContent, docObserver);
|
||||
mPositioningShadow = nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||
nsresult res = GetDOMEventReceiver(getter_AddRefs(erP));
|
||||
|
||||
if (NS_SUCCEEDED(res) && erP && mMouseMotionListenerP) {
|
||||
res = erP->RemoveEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener));
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener");
|
||||
}
|
||||
mMouseMotionListenerP = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult
|
||||
nsHTMLEditor::SetFinalPosition(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
nsresult res = EndMoving();
|
||||
mGrabberClicked = PR_FALSE;
|
||||
mIsMoving = PR_FALSE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// we have now to set the new width and height of the resized object
|
||||
// we don't set the x and y position because we don't control that in
|
||||
// a normal HTML layout
|
||||
PRInt32 newX = mPositionedObjectX + aX - mOriginalX - (mPositionedObjectBorderLeft+mPositionedObjectMarginLeft);
|
||||
PRInt32 newY = mPositionedObjectY + aY - mOriginalY - (mPositionedObjectBorderTop+mPositionedObjectMarginTop);
|
||||
|
||||
SnapToGrid(newX, newY);
|
||||
|
||||
nsAutoString x, y;
|
||||
x.AppendInt(newX);
|
||||
y.AppendInt(newY);
|
||||
|
||||
// we want one transaction only from a user's point of view
|
||||
nsAutoEditBatch batchIt(this);
|
||||
|
||||
mHTMLCSSUtils->SetCSSProperty(mAbsolutelyPositionedObject,
|
||||
nsEditProperty::cssTop,
|
||||
y + NS_LITERAL_STRING("px"),
|
||||
PR_FALSE);
|
||||
mHTMLCSSUtils->SetCSSProperty(mAbsolutelyPositionedObject,
|
||||
nsEditProperty::cssLeft,
|
||||
x + NS_LITERAL_STRING("px"),
|
||||
PR_FALSE);
|
||||
// keep track of that size
|
||||
mPositionedObjectX = newX;
|
||||
mPositionedObjectY = newY;
|
||||
|
||||
return RefreshResizers();
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLEditor::AddPositioningOffet(PRInt32 & aX, PRInt32 & aY)
|
||||
{
|
||||
// Get the positioning offset
|
||||
nsresult res;
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &res);
|
||||
PRInt32 positioningOffset = 0;
|
||||
if (NS_SUCCEEDED(res) && prefBranch) {
|
||||
res = prefBranch->GetIntPref("editor.positioning.offset", &positioningOffset);
|
||||
if (NS_FAILED(res)) // paranoia
|
||||
positioningOffset = 0;
|
||||
}
|
||||
|
||||
aX += positioningOffset;
|
||||
aY += positioningOffset;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::AbsolutelyPositionElement(nsIDOMElement * aElement,
|
||||
PRBool aEnabled)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aElement);
|
||||
|
||||
nsAutoString positionStr;
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
mHTMLCSSUtils->GetComputedProperty(node, nsEditProperty::cssPosition,
|
||||
positionStr);
|
||||
PRBool isPositioned = (positionStr.Equals(NS_LITERAL_STRING("absolute")));
|
||||
|
||||
// nothing to do if the element is already in the state we want
|
||||
if (isPositioned == aEnabled)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoEditBatch batchIt(this);
|
||||
nsresult res;
|
||||
|
||||
if (aEnabled) {
|
||||
PRInt32 x, y;
|
||||
GetElementOrigin(aElement, x, y);
|
||||
|
||||
mHTMLCSSUtils->SetCSSProperty(aElement,
|
||||
nsEditProperty::cssPosition,
|
||||
NS_LITERAL_STRING("absolute"),
|
||||
PR_FALSE);
|
||||
|
||||
AddPositioningOffet(x, y);
|
||||
SnapToGrid(x, y);
|
||||
SetElementPosition(aElement, x, y);
|
||||
|
||||
// we may need to create a br if the positioned element is alone in its
|
||||
// container
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
res = node->GetParentNode(getter_AddRefs(parentNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
||||
res = parentNode->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!childNodes) return NS_ERROR_NULL_POINTER;
|
||||
PRUint32 childCount;
|
||||
res = childNodes->GetLength(&childCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (childCount == 1) {
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
res = CreateBR(parentNode, 0, address_of(brNode));
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsAutoString emptyStr;
|
||||
|
||||
mHTMLCSSUtils->RemoveCSSProperty(aElement,
|
||||
nsEditProperty::cssPosition,
|
||||
emptyStr, PR_FALSE);
|
||||
mHTMLCSSUtils->RemoveCSSProperty(aElement,
|
||||
nsEditProperty::cssTop,
|
||||
emptyStr, PR_FALSE);
|
||||
mHTMLCSSUtils->RemoveCSSProperty(aElement,
|
||||
nsEditProperty::cssLeft,
|
||||
emptyStr, PR_FALSE);
|
||||
mHTMLCSSUtils->RemoveCSSProperty(aElement,
|
||||
nsEditProperty::cssZIndex,
|
||||
emptyStr, PR_FALSE);
|
||||
|
||||
if (!nsHTMLEditUtils::IsImage(node)) {
|
||||
mHTMLCSSUtils->RemoveCSSProperty(aElement,
|
||||
nsEditProperty::cssWidth,
|
||||
emptyStr, PR_FALSE);
|
||||
mHTMLCSSUtils->RemoveCSSProperty(aElement,
|
||||
nsEditProperty::cssHeight,
|
||||
emptyStr, PR_FALSE);
|
||||
}
|
||||
|
||||
PRBool hasStyleOrIdOrClass;
|
||||
res = HasStyleOrIdOrClass(aElement, &hasStyleOrIdOrClass);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!hasStyleOrIdOrClass && NodeIsType(node, NS_LITERAL_STRING("div"))) {
|
||||
nsCOMPtr<nsIHTMLEditRules> htmlRules = do_QueryInterface(mRules);
|
||||
if (!htmlRules) return NS_ERROR_FAILURE;
|
||||
res = htmlRules->MakeSureElemStartsOrEndsOnCR(aElement);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = RemoveContainer(node);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetSnapToGridEnabled(PRBool aEnabled)
|
||||
{
|
||||
mSnapToGridEnabled = aEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetSnapToGridEnabled(PRBool * aIsEnabled)
|
||||
{
|
||||
*aIsEnabled = mSnapToGridEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetGridSize(PRUint32 aSize)
|
||||
{
|
||||
mGridSize = aSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetGridSize(PRUint32 * aSize)
|
||||
{
|
||||
*aSize = mGridSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// self-explanatory
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetElementPosition(nsIDOMElement *aElement, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
nsAutoString x, y;
|
||||
x.AppendInt(aX);
|
||||
y.AppendInt(aY);
|
||||
|
||||
nsAutoEditBatch batchIt(this);
|
||||
|
||||
mHTMLCSSUtils->SetCSSProperty(aElement,
|
||||
nsEditProperty::cssLeft,
|
||||
x + NS_LITERAL_STRING("px"),
|
||||
PR_FALSE);
|
||||
mHTMLCSSUtils->SetCSSProperty(aElement,
|
||||
nsEditProperty::cssTop,
|
||||
y + NS_LITERAL_STRING("px"),
|
||||
PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// self-explanatory
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetPositionedElement(nsIDOMElement ** aReturn)
|
||||
{
|
||||
*aReturn = mAbsolutelyPositionedObject;
|
||||
NS_IF_ADDREF(*aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::CheckPositionedElementBGandFG(nsIDOMElement * aElement,
|
||||
nsAString & aReturn)
|
||||
{
|
||||
// we are going to outline the positioned element and bring it to the
|
||||
// front to overlap any other element intersecting with it. But
|
||||
// first, let's see what's the background and foreground colors of the
|
||||
// positioned element.
|
||||
// if background-image computed value is 'none,
|
||||
// If the background color is 'auto' and R G B values of the foreground are
|
||||
// each above #d0, use a black background
|
||||
// If the background color is 'auto' and at least one of R G B values of
|
||||
// the foreground is below #d0, use a white background
|
||||
// Otherwise don't change background/foreground
|
||||
|
||||
aReturn.Truncate();
|
||||
|
||||
nsAutoString bgImageStr;
|
||||
nsresult res =
|
||||
mHTMLCSSUtils->GetComputedProperty(aElement,
|
||||
nsEditProperty::cssBackgroundImage,
|
||||
bgImageStr);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bgImageStr.Equals(NS_LITERAL_STRING("none"))) {
|
||||
nsAutoString bgColorStr;
|
||||
res =
|
||||
mHTMLCSSUtils->GetComputedProperty(aElement,
|
||||
nsEditProperty::cssBackgroundColor,
|
||||
bgColorStr);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bgColorStr.Equals(NS_LITERAL_STRING("transparent"))) {
|
||||
|
||||
nsCOMPtr<nsIDOMViewCSS> viewCSS;
|
||||
res = mHTMLCSSUtils->GetDefaultViewCSS(aElement, getter_AddRefs(viewCSS));
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
res = viewCSS->GetComputedStyle(aElement, nsString(), getter_AddRefs(cssDecl));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// from these declarations, get the one we want and that one only
|
||||
nsCOMPtr<nsIDOMCSSValue> colorCssValue;
|
||||
res = cssDecl->GetPropertyCSSValue(NS_LITERAL_STRING("color"), getter_AddRefs(colorCssValue));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
PRUint16 type;
|
||||
res = colorCssValue->GetCssValueType(&type);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (nsIDOMCSSValue::CSS_PRIMITIVE_VALUE == type) {
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> val = do_QueryInterface(colorCssValue);
|
||||
res = val->GetPrimitiveType(&type);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (nsIDOMCSSPrimitiveValue::CSS_RGBCOLOR == type) {
|
||||
nsCOMPtr<nsIDOMRGBColor> rgbColor;
|
||||
res = val->GetRGBColorValue(getter_AddRefs(rgbColor));
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> red, green, blue;
|
||||
float r, g, b;
|
||||
res = rgbColor->GetRed(getter_AddRefs(red));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = rgbColor->GetGreen(getter_AddRefs(green));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = rgbColor->GetBlue(getter_AddRefs(blue));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = red->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &r);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = green->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &g);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = blue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &b);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (r >= BLACK_BG_RGB_TRIGGER &&
|
||||
g >= BLACK_BG_RGB_TRIGGER &&
|
||||
b >= BLACK_BG_RGB_TRIGGER)
|
||||
aReturn = NS_LITERAL_STRING("black");
|
||||
else
|
||||
aReturn = NS_LITERAL_STRING("white");
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,395 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLEditor.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
#include "nsISelection.h"
|
||||
|
||||
#include "nsTextEditUtils.h"
|
||||
#include "nsEditorUtils.h"
|
||||
#include "nsHTMLEditUtils.h"
|
||||
#include "nsTextEditRules.h"
|
||||
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
|
||||
#include "nsIDOMCSSValue.h"
|
||||
#include "nsIDOMCSSPrimitiveValue.h"
|
||||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
|
||||
// retrieve an integer stored into a CSS computed float value
|
||||
static PRInt32 GetCSSFloatValue(nsIDOMCSSStyleDeclaration * aDecl,
|
||||
const nsAString & aProperty)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDecl);
|
||||
|
||||
nsCOMPtr<nsIDOMCSSValue> value;
|
||||
// get the computed CSSValue of the property
|
||||
nsresult res = aDecl->GetPropertyCSSValue(aProperty, getter_AddRefs(value));
|
||||
if (NS_FAILED(res) || !value) return 0;
|
||||
|
||||
// check the type of the returned CSSValue; we handle here only
|
||||
// pixel and enum types
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> val = do_QueryInterface(value);
|
||||
PRUint16 type;
|
||||
val->GetPrimitiveType(&type);
|
||||
|
||||
float f;
|
||||
switch (type) {
|
||||
case nsIDOMCSSPrimitiveValue::CSS_PX:
|
||||
// the value is in pixels, just get it
|
||||
res = val->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_PX, &f);
|
||||
if (NS_FAILED(res)) return 0;
|
||||
break;
|
||||
case nsIDOMCSSPrimitiveValue::CSS_IDENT: {
|
||||
// the value is keyword, we have to map these keywords into
|
||||
// numeric values
|
||||
nsAutoString str;
|
||||
res = val->GetStringValue(str);
|
||||
if (str.Equals(NS_LITERAL_STRING("thin")))
|
||||
f = 1;
|
||||
if (str.Equals(NS_LITERAL_STRING("medium")))
|
||||
f = 3;
|
||||
if (str.Equals(NS_LITERAL_STRING("thick")))
|
||||
f = 5;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
f = 0;
|
||||
}
|
||||
|
||||
return (PRInt32) f;
|
||||
}
|
||||
|
||||
// Returns in *aReturn an anonymous nsDOMElement of type aTag,
|
||||
// child of aParentNode. If aIsCreatedHidden is true, the class
|
||||
// "hidden" is added to the created element. If aAnonClass is not
|
||||
// the empty string, it becomes the value of the attribute "_moz_anonclass"
|
||||
nsresult
|
||||
nsHTMLEditor::CreateAnonymousElement(const nsAString & aTag, nsIDOMNode * aParentNode,
|
||||
const nsAString & aAnonClass, PRBool aIsCreatedHidden,
|
||||
nsIDOMElement ** aReturn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aParentNode);
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
|
||||
nsCOMPtr<nsIContent> parentContent( do_QueryInterface(aParentNode) );
|
||||
if (!parentContent)
|
||||
return NS_OK;
|
||||
|
||||
// Get the document
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
if (!doc) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Get the pres shell
|
||||
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Create a new node through the element factory
|
||||
nsCOMPtr<nsIContent> newContent;
|
||||
nsresult res = CreateHTMLContent(aTag, getter_AddRefs(newContent));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newContent);
|
||||
if (!newElement)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// add the "hidden" class if needed
|
||||
if (aIsCreatedHidden) {
|
||||
res = newElement->SetAttribute(NS_LITERAL_STRING("class"),
|
||||
NS_LITERAL_STRING("hidden"));
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// add an _moz_anonclass attribute if needed
|
||||
if (!aAnonClass.IsEmpty()) {
|
||||
res = newElement->SetAttribute(NS_LITERAL_STRING("_moz_anonclass"),
|
||||
aAnonClass);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// establish parenthood of the element
|
||||
newContent->SetNativeAnonymous(PR_TRUE);
|
||||
newContent->SetParent(parentContent);
|
||||
newContent->SetDocument(doc, PR_TRUE, PR_TRUE);
|
||||
newContent->SetBindingParent(newContent);
|
||||
// display the element
|
||||
ps->RecreateFramesFor(newContent);
|
||||
|
||||
*aReturn = newElement;
|
||||
NS_IF_ADDREF(*aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Deletes all references to an anonymous element
|
||||
void
|
||||
nsHTMLEditor::DeleteRefToAnonymousNode(nsIDOMElement* aElement,
|
||||
nsIContent * aParentContent,
|
||||
nsIDocumentObserver * aDocObserver)
|
||||
{
|
||||
// call ContentRemoved() for the anonymous content
|
||||
// node so its references get removed from the frame manager's
|
||||
// undisplay map, and its layout frames get destroyed!
|
||||
|
||||
if (aElement) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (content) {
|
||||
aDocObserver->ContentRemoved(nsnull, aParentContent, content, -1);
|
||||
content->SetParent(nsnull);
|
||||
content->SetBindingParent(nsnull);
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The following method is mostly called by a selection listener. When a
|
||||
// selection change is notified, the method is called to check if resizing
|
||||
// handles, a grabber and/or inline table editing UI need to be displayed
|
||||
// or refreshed
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSelection);
|
||||
|
||||
// early way out if all contextual UI extensions are disabled
|
||||
if (!mIsObjectResizingEnabled &&
|
||||
!mIsAbsolutelyPositioningEnabled &&
|
||||
!mIsInlineTableEditingEnabled)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> focusElement;
|
||||
// let's get the containing element of the selection
|
||||
nsresult res = GetSelectionContainer(getter_AddRefs(focusElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// what's its tag?
|
||||
nsAutoString focusTagName;
|
||||
res = focusElement->GetTagName(focusTagName);
|
||||
if (NS_FAILED(res)) return res;
|
||||
ToLowerCase(focusTagName);
|
||||
nsCOMPtr<nsIAtom> focusTagAtom = getter_AddRefs(NS_NewAtom(focusTagName));
|
||||
|
||||
nsCOMPtr<nsIDOMElement> absPosElement;
|
||||
if (mIsAbsolutelyPositioningEnabled) {
|
||||
// Absolute Positioning support is enabled, is the selection contained
|
||||
// in an absolutely positioned element ?
|
||||
res = GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(absPosElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> cellElement;
|
||||
if (mIsObjectResizingEnabled || mIsInlineTableEditingEnabled) {
|
||||
// Resizing or Inline Table Editing is enabled, we need to check if the
|
||||
// selection is contained in a table cell
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"),
|
||||
nsnull,
|
||||
getter_AddRefs(cellElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
if (mIsObjectResizingEnabled && cellElement) {
|
||||
// we are here because Resizing is enabled AND selection is contained in
|
||||
// a cell
|
||||
nsCOMPtr<nsIDOMNode> tableNode, cellNode = do_QueryInterface(cellElement);
|
||||
// get the enclosing table
|
||||
tableNode = GetEnclosingTable(cellNode);
|
||||
if (nsEditProperty::img != focusTagAtom) {
|
||||
// the element container of the selection is not an image, so we'll show
|
||||
// the resizers around the table
|
||||
focusElement = do_QueryInterface(tableNode);
|
||||
focusTagAtom = nsEditProperty::table;
|
||||
}
|
||||
}
|
||||
|
||||
// we allow resizers only around images, tables, and absolutely positioned
|
||||
// elements. If we don't have image/table, let's look at the latter case.
|
||||
if (nsEditProperty::img != focusTagAtom &&
|
||||
nsEditProperty::table != focusTagAtom)
|
||||
focusElement = absPosElement;
|
||||
|
||||
// at this point, focusElement contains the element for Resizing,
|
||||
// cellElement contains the element for InlineTableEditing
|
||||
// absPosElement contains the element for Positioning
|
||||
|
||||
// first let's cancel old settings if needed
|
||||
PRBool refreshResizing = (mResizedObject != nsnull);
|
||||
PRBool refreshPositioning = (mAbsolutelyPositionedObject != nsnull);
|
||||
PRBool refreshTableEditing = (mInlineEditedCell != nsnull);
|
||||
|
||||
if (mIsAbsolutelyPositioningEnabled && mAbsolutelyPositionedObject &&
|
||||
absPosElement != mAbsolutelyPositionedObject) {
|
||||
res = HideGrabber();
|
||||
if (NS_FAILED(res)) return res;
|
||||
refreshPositioning = PR_FALSE;
|
||||
}
|
||||
|
||||
if (mIsObjectResizingEnabled && mResizedObject &&
|
||||
mResizedObject != focusElement) {
|
||||
res = HideResizers();
|
||||
if (NS_FAILED(res)) return res;
|
||||
refreshResizing = PR_FALSE;
|
||||
}
|
||||
|
||||
if (mIsInlineTableEditingEnabled && mInlineEditedCell &&
|
||||
mInlineEditedCell != cellElement) {
|
||||
res = HideInlineTableEditingUI();
|
||||
if (NS_FAILED(res)) return res;
|
||||
refreshTableEditing = PR_FALSE;
|
||||
}
|
||||
|
||||
// now, let's display all contextual UI for good
|
||||
|
||||
if (mIsObjectResizingEnabled && focusElement) {
|
||||
if (nsEditProperty::img == focusTagAtom)
|
||||
mResizedObjectIsAnImage = PR_TRUE;
|
||||
if (refreshResizing)
|
||||
res = RefreshResizers();
|
||||
else
|
||||
res = ShowResizers(focusElement);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
if (mIsAbsolutelyPositioningEnabled && absPosElement) {
|
||||
if (refreshPositioning)
|
||||
res = RefreshGrabber();
|
||||
else
|
||||
res = ShowGrabberOnElement(absPosElement);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
if (mIsInlineTableEditingEnabled && cellElement) {
|
||||
if (refreshTableEditing)
|
||||
res = RefreshInlineTableEditingUI();
|
||||
else
|
||||
res = ShowInlineTableEditingUI(cellElement);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Resizing and Absolute Positioning need to know everything about the
|
||||
// containing box of the element: position, size, margins, borders
|
||||
nsresult
|
||||
nsHTMLEditor::GetPositionAndDimensions(nsIDOMElement * aElement,
|
||||
PRInt32 & aX, PRInt32 & aY,
|
||||
PRInt32 & aW, PRInt32 & aH,
|
||||
PRInt32 & aBorderLeft,
|
||||
PRInt32 & aBorderTop,
|
||||
PRInt32 & aMarginLeft,
|
||||
PRInt32 & aMarginTop)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aElement);
|
||||
|
||||
// Is the element positioned ? let's check the cheap way first...
|
||||
PRBool isPositioned = PR_FALSE;
|
||||
nsresult res = aElement->HasAttribute(NS_LITERAL_STRING("_moz_abspos"), &isPositioned);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!isPositioned) {
|
||||
// hmmm... the expensive way now...
|
||||
nsAutoString positionStr;
|
||||
mHTMLCSSUtils->GetComputedProperty(aElement, nsEditProperty::cssPosition,
|
||||
positionStr);
|
||||
isPositioned = positionStr.Equals(NS_LITERAL_STRING("absolute"));
|
||||
}
|
||||
|
||||
if (isPositioned) {
|
||||
// Yes, it is absolutely positioned
|
||||
mResizedObjectIsAbsolutelyPositioned = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMViewCSS> viewCSS;
|
||||
res = mHTMLCSSUtils->GetDefaultViewCSS(aElement, getter_AddRefs(viewCSS));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString empty;
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
// Get the all the computed css styles attached to the element node
|
||||
res = viewCSS->GetComputedStyle(aElement, empty, getter_AddRefs(cssDecl));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
aBorderLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-left-width"));
|
||||
aBorderTop = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-top-width"));
|
||||
aMarginLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-left"));
|
||||
aMarginTop = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-top"));
|
||||
|
||||
aX = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("left")) +
|
||||
aMarginLeft + aBorderLeft;
|
||||
aY = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("top")) +
|
||||
aMarginTop + aBorderTop;
|
||||
aW = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("width"));
|
||||
aH = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("height"));
|
||||
}
|
||||
else {
|
||||
mResizedObjectIsAbsolutelyPositioned = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> nsElement = do_QueryInterface(aElement);
|
||||
if (!nsElement) {return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
GetElementOrigin(aElement, aX, aY);
|
||||
|
||||
res = nsElement->GetOffsetWidth(&aW);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = nsElement->GetOffsetHeight(&aH);
|
||||
|
||||
aBorderLeft = 0;
|
||||
aBorderTop = 0;
|
||||
aMarginLeft = 0;
|
||||
aMarginTop = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// self-explanatory
|
||||
void
|
||||
nsHTMLEditor::SetAnonymousElementPosition(PRInt32 aX, PRInt32 aY, nsIDOMElement *aElement)
|
||||
{
|
||||
nsAutoString x, y;
|
||||
x.AppendInt(aX);
|
||||
y.AppendInt(aY);
|
||||
mHTMLCSSUtils->SetCSSProperty(aElement,
|
||||
NS_LITERAL_STRING("left"),
|
||||
x + NS_LITERAL_STRING("px"));
|
||||
mHTMLCSSUtils->SetCSSProperty(aElement,
|
||||
NS_LITERAL_STRING("top"),
|
||||
y + NS_LITERAL_STRING("px"));
|
||||
}
|
|
@ -1429,3 +1429,31 @@ nsHTMLCSSUtils::GetElementContainerOrSelf(nsIDOMNode * aNode, nsIDOMElement ** a
|
|||
NS_IF_ADDREF(*aElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLCSSUtils::SetCSSProperty(nsIDOMElement * aElement,
|
||||
const nsAString & aProperty,
|
||||
const nsAString & aValue)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
PRUint32 length = 0;
|
||||
nsresult res = GetInlineStyles(aElement, getter_AddRefs(cssDecl), &length);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
return cssDecl->SetProperty(aProperty,
|
||||
aValue,
|
||||
nsString());
|
||||
}
|
||||
nsresult
|
||||
nsHTMLCSSUtils::RemoveCSSProperty(nsIDOMElement * aElement,
|
||||
const nsAString & aProperty)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
PRUint32 length = 0;
|
||||
nsresult res = GetInlineStyles(aElement, getter_AddRefs(cssDecl), &length);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString returnString;
|
||||
return cssDecl->RemoveProperty(aProperty, returnString);
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,19 @@ public:
|
|||
nsresult RemoveCSSProperty(nsIDOMElement * aElement, nsIAtom * aProperty,
|
||||
const nsAString & aPropertyValue, PRBool aSuppressTransaction);
|
||||
|
||||
/** directly adds/remove a CSS declaration to the STYLE atrribute carried by
|
||||
* a given element without going through the txn manager
|
||||
*
|
||||
* @param aElement [IN] a DOM element
|
||||
* @param aProperty [IN] a string containing the CSS property to set/remove
|
||||
* @param aValue [IN] a string containing the new value of the CSS property
|
||||
*/
|
||||
nsresult SetCSSProperty(nsIDOMElement * aElement,
|
||||
const nsAString & aProperty,
|
||||
const nsAString & aValue);
|
||||
nsresult RemoveCSSProperty(nsIDOMElement * aElement,
|
||||
const nsAString & aProperty);
|
||||
|
||||
/** gets the specified/computed style value of a CSS property for a given node (or its element
|
||||
* ancestor if it is not an element)
|
||||
*
|
||||
|
@ -294,6 +307,14 @@ public:
|
|||
*/
|
||||
nsresult GetElementContainerOrSelf(nsIDOMNode * aNode, nsIDOMElement ** aElement);
|
||||
|
||||
/** Gets the default DOMView for a given node
|
||||
*
|
||||
* @param aNode the node we want the default DOMView for
|
||||
* @param aViewCSS [OUT] the default DOMViewCSS
|
||||
*/
|
||||
nsresult GetDefaultViewCSS(nsIDOMNode * aNode, nsIDOMViewCSS ** aViewCSS);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** retrieves the css property atom from an enum
|
||||
|
@ -342,13 +363,6 @@ private:
|
|||
nsStringArray & aValueArray,
|
||||
PRBool aGetOrRemoveRequest);
|
||||
|
||||
/** Gets the default DOMView for a given node
|
||||
*
|
||||
* @param aNode the node we want the default DOMView for
|
||||
* @param aViewCSS [OUT] the default DOMViewCSS
|
||||
*/
|
||||
nsresult GetDefaultViewCSS(nsIDOMNode * aNode, nsIDOMViewCSS ** aViewCSS);
|
||||
|
||||
/** creates a Transaction for setting or removing a css property
|
||||
*
|
||||
* @param aElement [IN] a DOM element
|
||||
|
|
|
@ -600,6 +600,10 @@ nsHTMLEditRules::WillDoAction(nsISelection *aSelection,
|
|||
return WillIndent(aSelection, aCancel, aHandled);
|
||||
case kOutdent:
|
||||
return WillOutdent(aSelection, aCancel, aHandled);
|
||||
case kSetAbsolutePosition:
|
||||
return WillAbsolutePosition(aSelection, aCancel, aHandled);
|
||||
case kRemoveAbsolutePosition:
|
||||
return WillRemoveAbsolutePosition(aSelection, aCancel, aHandled);
|
||||
case kAlign:
|
||||
return WillAlign(aSelection, info->alignType, aCancel, aHandled);
|
||||
case kMakeBasicBlock:
|
||||
|
@ -610,6 +614,10 @@ nsHTMLEditRules::WillDoAction(nsISelection *aSelection,
|
|||
return WillMakeDefListItem(aSelection, info->blockType, info->entireList, aCancel, aHandled);
|
||||
case kInsertElement:
|
||||
return WillInsert(aSelection, aCancel);
|
||||
case kDecreaseZIndex:
|
||||
return WillRelativeChangeZIndex(aSelection, -1, aCancel, aHandled);
|
||||
case kIncreaseZIndex:
|
||||
return WillRelativeChangeZIndex(aSelection, 1, aCancel, aHandled);
|
||||
}
|
||||
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel, aHandled);
|
||||
}
|
||||
|
@ -631,6 +639,11 @@ nsHTMLEditRules::DidDoAction(nsISelection *aSelection,
|
|||
case kOutdent:
|
||||
case kAlign:
|
||||
return DidMakeBasicBlock(aSelection, aInfo, aResult);
|
||||
case kSetAbsolutePosition: {
|
||||
nsresult rv = DidMakeBasicBlock(aSelection, aInfo, aResult);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return DidAbsolutePosition();
|
||||
}
|
||||
}
|
||||
|
||||
// default: pass thru to nsTextEditRules
|
||||
|
@ -809,7 +822,7 @@ nsHTMLEditRules::GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign)
|
|||
res = GetPromotedRanges(selection, arrayOfRanges, kAlign);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// use these ranges to contruct a list of nodes to act on.
|
||||
// use these ranges to construct a list of nodes to act on.
|
||||
nsCOMArray<nsIDOMNode> arrayOfNodes;
|
||||
res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, kAlign, PR_TRUE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -4176,7 +4189,7 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
|
|||
if (NS_FAILED(res)) return res;
|
||||
PropItem *item = nsnull;
|
||||
|
||||
// if we deleted selection then also apply cached styles
|
||||
// if we deleted selection then also for cached styles
|
||||
if (mDidDeleteSelection &&
|
||||
((mTheAction == nsEditor::kOpInsertText ) ||
|
||||
(mTheAction == nsEditor::kOpInsertIMEText) ||
|
||||
|
@ -5633,7 +5646,8 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
|||
// indent/outdent already do something special for list items, but
|
||||
// we still need to make sure we dont act on table elements
|
||||
else if ( (inOperationType == kOutdent) ||
|
||||
(inOperationType == kIndent) )
|
||||
(inOperationType == kIndent) ||
|
||||
(inOperationType == kSetAbsolutePosition))
|
||||
{
|
||||
PRInt32 listCount = outArrayOfNodes.Count();
|
||||
for (i=listCount-1; i>=0; i--)
|
||||
|
@ -5668,10 +5682,11 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
|||
|
||||
// post process the list to break up inline containers that contain br's.
|
||||
// but only for operations that might care, like making lists or para's...
|
||||
if ( (inOperationType == kMakeBasicBlock) ||
|
||||
(inOperationType == kMakeList) ||
|
||||
(inOperationType == kAlign) ||
|
||||
(inOperationType == kIndent) ||
|
||||
if ( (inOperationType == kMakeBasicBlock) ||
|
||||
(inOperationType == kMakeList) ||
|
||||
(inOperationType == kAlign) ||
|
||||
(inOperationType == kSetAbsolutePosition) ||
|
||||
(inOperationType == kIndent) ||
|
||||
(inOperationType == kOutdent) )
|
||||
{
|
||||
PRInt32 listCount = outArrayOfNodes.Count();
|
||||
|
@ -6274,7 +6289,6 @@ nsHTMLEditRules::ReturnInHeader(nsISelection *aSelection,
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ReturnInParagraph: do the right thing for returns pressed in paragraphs
|
||||
//
|
||||
|
@ -7440,7 +7454,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
|
|||
|
||||
// are we in a text node?
|
||||
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(selNode);
|
||||
if (textNode)
|
||||
if (textNode)
|
||||
return NS_OK; // we LIKE it when we are in a text node. that RULZ
|
||||
|
||||
// do we need to insert a special mozBR? We do if we are:
|
||||
|
@ -7701,7 +7715,6 @@ nsHTMLEditRules::RemoveEmptyNodes()
|
|||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("u")) ||
|
||||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("tt")) ||
|
||||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("s")) ||
|
||||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("span")) ||
|
||||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("strike")) ||
|
||||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("big")) ||
|
||||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("small")) ||
|
||||
|
@ -8541,7 +8554,7 @@ nsHTMLEditRules::MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, PRBool aStarts)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode)
|
||||
{
|
||||
nsresult res = MakeSureElemStartsOrEndsOnCR(aNode, PR_FALSE);
|
||||
|
@ -8665,3 +8678,274 @@ nsHTMLEditRules::RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, PRInt
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Support for Absolute Positioning
|
||||
//
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, PRBool *aCancel, PRBool * aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> focusElement;
|
||||
res = mHTMLEditor->GetSelectionContainer(getter_AddRefs(focusElement));
|
||||
if (focusElement) {
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(focusElement);
|
||||
if (mHTMLEditor->NodeIsType(node, nsEditProperty::img)) {
|
||||
mNewBlock = node;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
res = NormalizeSelection(aSelection);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
|
||||
|
||||
// convert the selection ranges into "promoted" selection ranges:
|
||||
// this basically just expands the range to include the immediate
|
||||
// block parent, and then further expands to include any ancestors
|
||||
// whose children are all in the range
|
||||
|
||||
nsCOMArray<nsIDOMRange> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, arrayOfRanges, kSetAbsolutePosition);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// use these ranges to contruct a list of nodes to act on.
|
||||
nsCOMArray<nsIDOMNode> arrayOfNodes;
|
||||
res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, kSetAbsolutePosition);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
NS_NAMED_LITERAL_STRING(divType, "div");
|
||||
|
||||
|
||||
// if nothing visible in list, make an empty block
|
||||
if (ListIsEmptyLine(arrayOfNodes))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> parent, thePositionedDiv;
|
||||
PRInt32 offset;
|
||||
|
||||
// get selection location
|
||||
res = mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(parent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// make sure we can put a block here
|
||||
res = SplitAsNeeded(&divType, address_of(parent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = mHTMLEditor->CreateNode(divType, parent, offset, getter_AddRefs(thePositionedDiv));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// remember our new block for postprocessing
|
||||
mNewBlock = thePositionedDiv;
|
||||
// delete anything that was in the list of nodes
|
||||
nsCOMPtr<nsIDOMNode> curNode = arrayOfNodes[0];
|
||||
while (curNode)
|
||||
{
|
||||
res = mHTMLEditor->DeleteNode(curNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = arrayOfNodes.RemoveObjectAt(0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
curNode = arrayOfNodes[0];
|
||||
}
|
||||
// put selection in new block
|
||||
res = aSelection->Collapse(thePositionedDiv,0);
|
||||
selectionResetter.Abort(); // to prevent selection reseter from overriding us.
|
||||
*aHandled = PR_TRUE;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Ok, now go through all the nodes and put them in a blockquote,
|
||||
// or whatever is appropriate. Wohoo!
|
||||
PRInt32 i;
|
||||
nsCOMPtr<nsIDOMNode> curParent, curPositionedDiv, curList, indentedLI, sibling;
|
||||
PRInt32 listCount = arrayOfNodes.Count();
|
||||
for (i=0; i<listCount; i++)
|
||||
{
|
||||
// here's where we actually figure out what to do
|
||||
nsCOMPtr<nsIDOMNode> curNode = arrayOfNodes[i];
|
||||
|
||||
// Ignore all non-editable nodes. Leave them be.
|
||||
if (!mHTMLEditor->IsEditable(curNode)) continue;
|
||||
|
||||
PRInt32 offset;
|
||||
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// some logic for putting list items into nested lists...
|
||||
if (nsHTMLEditUtils::IsList(curParent))
|
||||
{
|
||||
// check to see if curList is still appropriate. Which it is if
|
||||
// curNode is still right after it in the same list.
|
||||
if (curList)
|
||||
{
|
||||
sibling = nsnull;
|
||||
mHTMLEditor->GetPriorHTMLSibling(curNode, address_of(sibling));
|
||||
}
|
||||
|
||||
if (!curList || (sibling && sibling != curList) )
|
||||
{
|
||||
nsAutoString listTag;
|
||||
nsEditor::GetTagString(curParent,listTag);
|
||||
ToLowerCase(listTag);
|
||||
// create a new nested list of correct type
|
||||
res = SplitAsNeeded(&listTag, address_of(curParent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!curPositionedDiv) {
|
||||
PRInt32 parentOffset;
|
||||
nsCOMPtr<nsIDOMNode> curParentParent;
|
||||
res = nsEditor::GetNodeLocation(curParent, address_of(curParentParent), &parentOffset);
|
||||
res = mHTMLEditor->CreateNode(divType, curParentParent, parentOffset, getter_AddRefs(curPositionedDiv));
|
||||
mNewBlock = curPositionedDiv;
|
||||
}
|
||||
res = mHTMLEditor->CreateNode(listTag, curPositionedDiv, -1, getter_AddRefs(curList));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// curList is now the correct thing to put curNode in
|
||||
// remember our new block for postprocessing
|
||||
// mNewBlock = curList;
|
||||
}
|
||||
// tuck the node into the end of the active list
|
||||
res = mHTMLEditor->MoveNode(curNode, curList, -1);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// forget curPositionedDiv, if any
|
||||
// curPositionedDiv = nsnull;
|
||||
}
|
||||
|
||||
else // not a list item, use blockquote?
|
||||
{
|
||||
// if we are inside a list item, we dont want to blockquote, we want
|
||||
// to sublist the list item. We may have several nodes listed in the
|
||||
// array of nodes to act on, that are in the same list item. Since
|
||||
// we only want to indent that li once, we must keep track of the most
|
||||
// recent indented list item, and not indent it if we find another node
|
||||
// to act on that is still inside the same li.
|
||||
nsCOMPtr<nsIDOMNode> listitem=IsInListItem(curNode);
|
||||
if (listitem)
|
||||
{
|
||||
if (indentedLI == listitem) continue; // already indented this list item
|
||||
res = nsEditor::GetNodeLocation(listitem, address_of(curParent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// check to see if curList is still appropriate. Which it is if
|
||||
// curNode is still right after it in the same list.
|
||||
if (curList)
|
||||
{
|
||||
sibling = nsnull;
|
||||
mHTMLEditor->GetPriorHTMLSibling(curNode, address_of(sibling));
|
||||
}
|
||||
|
||||
if (!curList || (sibling && sibling != curList) )
|
||||
{
|
||||
nsAutoString listTag;
|
||||
nsEditor::GetTagString(curParent,listTag);
|
||||
ToLowerCase(listTag);
|
||||
// create a new nested list of correct type
|
||||
res = SplitAsNeeded(&listTag, address_of(curParent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!curPositionedDiv) {
|
||||
PRInt32 parentOffset;
|
||||
nsCOMPtr<nsIDOMNode> curParentParent;
|
||||
res = nsEditor::GetNodeLocation(curParent, address_of(curParentParent), &parentOffset);
|
||||
res = mHTMLEditor->CreateNode(divType, curParentParent, parentOffset, getter_AddRefs(curPositionedDiv));
|
||||
mNewBlock = curPositionedDiv;
|
||||
}
|
||||
res = mHTMLEditor->CreateNode(listTag, curPositionedDiv, -1, getter_AddRefs(curList));
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
res = mHTMLEditor->MoveNode(listitem, curList, -1);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// remember we indented this li
|
||||
indentedLI = listitem;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// need to make a div to put things in if we haven't already
|
||||
|
||||
if (!curPositionedDiv)
|
||||
{
|
||||
if (nsHTMLEditUtils::IsDiv(curNode))
|
||||
{
|
||||
curPositionedDiv = curNode;
|
||||
mNewBlock = curPositionedDiv;
|
||||
curList = nsnull;
|
||||
continue;
|
||||
}
|
||||
res = SplitAsNeeded(&divType, address_of(curParent), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = mHTMLEditor->CreateNode(divType, curParent, offset, getter_AddRefs(curPositionedDiv));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// remember our new block for postprocessing
|
||||
mNewBlock = curPositionedDiv;
|
||||
// curPositionedDiv is now the correct thing to put curNode in
|
||||
}
|
||||
|
||||
// tuck the node into the end of the active blockquote
|
||||
res = mHTMLEditor->MoveNode(curNode, curPositionedDiv, -1);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// forget curList, if any
|
||||
curList = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::DidAbsolutePosition()
|
||||
{
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> absPosHTMLEditor = mHTMLEditor;
|
||||
nsCOMPtr<nsIDOMElement> elt = do_QueryInterface(mNewBlock);
|
||||
return absPosHTMLEditor->AbsolutelyPositionElement(elt, PR_TRUE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillRemoveAbsolutePosition(nsISelection *aSelection, PRBool *aCancel, PRBool * aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// initialize out param
|
||||
// we want to ignore aCancel from WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elt;
|
||||
res = mHTMLEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
|
||||
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> absPosHTMLEditor = mHTMLEditor;
|
||||
return absPosHTMLEditor->AbsolutelyPositionElement(elt, PR_FALSE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillRelativeChangeZIndex(nsISelection *aSelection,
|
||||
PRInt32 aChange,
|
||||
PRBool *aCancel,
|
||||
PRBool * aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// initialize out param
|
||||
// we want to ignore aCancel from WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elt;
|
||||
res = mHTMLEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
|
||||
|
||||
nsCOMPtr<nsIHTMLAbsPosEditor> absPosHTMLEditor = mHTMLEditor;
|
||||
PRInt32 zIndex;
|
||||
return absPosHTMLEditor->RelativeChangeElementZIndex(elt, aChange, &zIndex);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ public:
|
|||
NS_IMETHOD GetIndentState(PRBool *aCanIndent, PRBool *aCanOutdent);
|
||||
NS_IMETHOD GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign);
|
||||
NS_IMETHOD GetParagraphState(PRBool *aMixed, nsAString &outFormat);
|
||||
NS_IMETHOD MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode);
|
||||
|
||||
// nsIEditActionListener methods
|
||||
|
||||
|
@ -164,9 +165,13 @@ protected:
|
|||
nsresult WillHTMLIndent(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillAlign(nsISelection *aSelection, const nsAString *alignType, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillAbsolutePosition(nsISelection *aSelection, PRBool *aCancel, PRBool * aHandled);
|
||||
nsresult WillRemoveAbsolutePosition(nsISelection *aSelection, PRBool *aCancel, PRBool * aHandled);
|
||||
nsresult WillRelativeChangeZIndex(nsISelection *aSelection, PRInt32 aChange, PRBool *aCancel, PRBool * aHandled);
|
||||
nsresult WillMakeDefListItem(nsISelection *aSelection, const nsAString *aBlockType, PRBool aEntireList, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillMakeBasicBlock(nsISelection *aSelection, const nsAString *aBlockType, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
nsresult DidAbsolutePosition();
|
||||
nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
|
||||
nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
|
||||
PRBool IsFormatNode(nsIDOMNode *aNode);
|
||||
|
@ -285,7 +290,6 @@ protected:
|
|||
PRBool ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes);
|
||||
nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, PRBool aChildrenOnly);
|
||||
nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, PRBool aStarts);
|
||||
nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode);
|
||||
nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, PRBool aContentsOnly);
|
||||
nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, PRInt8 aRelativeChange);
|
||||
|
||||
|
|
|
@ -170,10 +170,14 @@ nsHTMLEditor::nsHTMLEditor()
|
|||
, mTypeInState(nsnull)
|
||||
, mSelectedCellIndex(0)
|
||||
, mHTMLCSSUtils(nsnull)
|
||||
, mIsImageResizingEnabled(PR_TRUE) // this can be overriden
|
||||
, mIsShowingResizeHandles(PR_FALSE)
|
||||
, mIsObjectResizingEnabled(PR_TRUE)
|
||||
, mIsResizing(PR_FALSE)
|
||||
, mResizedObject(nsnull)
|
||||
, mIsAbsolutelyPositioningEnabled(PR_TRUE)
|
||||
, mIsMoving(PR_FALSE)
|
||||
, mResizedObjectIsAbsolutelyPositioned(PR_FALSE)
|
||||
, mIsInlineTableEditingEnabled(PR_TRUE)
|
||||
, mSnapToGridEnabled(PR_FALSE)
|
||||
, mGridSize(0)
|
||||
{
|
||||
mBoldAtom = getter_AddRefs(NS_NewAtom("b"));
|
||||
mItalicAtom = getter_AddRefs(NS_NewAtom("i"));
|
||||
|
@ -225,7 +229,21 @@ nsHTMLEditor::~nsHTMLEditor()
|
|||
NS_IMPL_ADDREF_INHERITED(nsHTMLEditor, nsEditor)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHTMLEditor, nsEditor)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsHTMLEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIHTMLEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPlaintextEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIHTMLObjectResizer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIHTMLAbsPosEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIHTMLInlineTableEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEditorMailSupport)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITableEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEditorStyleSheets)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTMLEditor)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
/*
|
||||
NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (!aInstancePtr)
|
||||
|
@ -248,6 +266,16 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIHTMLAbsPosEditor))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIHTMLAbsPosEditor*, this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIHTMLInlineTableEditor))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIHTMLInlineTableEditor*, this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIEditorMailSupport))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIEditorMailSupport*, this);
|
||||
NS_ADDREF_THIS();
|
||||
|
@ -271,7 +299,7 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
|
||||
return nsEditor::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
|
||||
nsIPresShell *aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags)
|
||||
|
@ -302,6 +330,13 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
|
|||
// the HTML Editor is CSS-aware only in the case of Composer
|
||||
mCSSAware = (0 == aFlags);
|
||||
|
||||
// disable Composer-only features
|
||||
if (aFlags & eEditorMailMask)
|
||||
{
|
||||
SetAbsolutePositioningEnabled(PR_FALSE);
|
||||
SetSnapToGridEnabled(PR_FALSE);
|
||||
}
|
||||
|
||||
// Init the HTML-CSS utils
|
||||
if (mHTMLCSSUtils)
|
||||
delete mHTMLCSSUtils;
|
||||
|
@ -6172,11 +6207,110 @@ nsHTMLEditor::EndUpdateViewBatch()
|
|||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NOT_INITIALIZED;
|
||||
res = CheckResizingState(selection);
|
||||
res = CheckSelectionStateForAnonymousButtons(selection);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent)
|
||||
{
|
||||
mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetSelectionContainer(nsIDOMElement ** aReturn)
|
||||
{
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
// if we don't get the selection, just skip this
|
||||
if (NS_FAILED(res) || !selection) return res;
|
||||
|
||||
PRBool bCollapsed;
|
||||
res = selection->GetIsCollapsed(&bCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> focusNode;
|
||||
|
||||
if (bCollapsed) {
|
||||
res = selection->GetFocusNode(getter_AddRefs(focusNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
else {
|
||||
|
||||
PRInt32 rangeCount;
|
||||
res = selection->GetRangeCount(&rangeCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (rangeCount == 1) {
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
res = selection->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!range) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startContainer, endContainer;
|
||||
res = range->GetStartContainer(getter_AddRefs(startContainer));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = range->GetEndContainer(getter_AddRefs(endContainer));
|
||||
if (NS_FAILED(res)) return res;
|
||||
PRInt32 startOffset, endOffset;
|
||||
res = range->GetStartOffset(&startOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = range->GetEndOffset(&endOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> focusElement;
|
||||
if (startContainer == endContainer && startOffset + 1 == endOffset) {
|
||||
res = GetSelectedElement(NS_LITERAL_STRING(""), getter_AddRefs(focusElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (focusElement)
|
||||
focusNode = do_QueryInterface(focusElement);
|
||||
}
|
||||
if (!focusNode) {
|
||||
res = range->GetCommonAncestorContainer(getter_AddRefs(focusNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRInt32 i;
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
for (i = 0; i < rangeCount; i++)
|
||||
{
|
||||
res = selection->GetRangeAt(i, getter_AddRefs(range));
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsCOMPtr<nsIDOMNode> startContainer;
|
||||
range->GetStartContainer(getter_AddRefs(startContainer));
|
||||
if (!focusNode)
|
||||
focusNode = startContainer;
|
||||
else if (focusNode != startContainer) {
|
||||
res = startContainer->GetParentNode(getter_AddRefs(focusNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (focusNode) {
|
||||
PRUint16 nodeType;
|
||||
focusNode->GetNodeType(&nodeType);
|
||||
if (nsIDOMNode::TEXT_NODE == nodeType) {
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
res = focusNode->GetParentNode(getter_AddRefs(parent));
|
||||
if (NS_FAILED(res)) return res;
|
||||
focusNode = parent;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> focusElement = do_QueryInterface(focusNode);
|
||||
*aReturn = focusElement;
|
||||
NS_IF_ADDREF(*aReturn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::IsAnonymousElement(nsIDOMElement * aElement, PRBool * aReturn)
|
||||
{
|
||||
|
@ -6185,3 +6319,4 @@ nsHTMLEditor::IsAnonymousElement(nsIDOMElement * aElement, PRBool * aReturn)
|
|||
*aReturn = content->IsNativeAnonymous();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "nsITableEditor.h"
|
||||
#include "nsIEditorMailSupport.h"
|
||||
#include "nsIEditorStyleSheets.h"
|
||||
#include "nsIDocumentObserver.h"
|
||||
|
||||
#include "nsEditor.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
@ -68,6 +67,11 @@
|
|||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsHTMLObjectResizer.h"
|
||||
#include "nsIHTMLAbsPosEditor.h"
|
||||
#include "nsIHTMLInlineTableEditor.h"
|
||||
#include "nsIHTMLObjectResizeListener.h"
|
||||
|
||||
#include "nsIDocumentObserver.h"
|
||||
|
||||
#include "nsPoint.h"
|
||||
|
||||
|
@ -87,7 +91,9 @@ class nsIContentFilter;
|
|||
class nsHTMLEditor : public nsPlaintextEditor,
|
||||
public nsIHTMLEditor,
|
||||
public nsIHTMLObjectResizer,
|
||||
public nsIHTMLAbsPosEditor,
|
||||
public nsITableEditor,
|
||||
public nsIHTMLInlineTableEditor,
|
||||
public nsIEditorStyleSheets,
|
||||
public nsICSSLoaderObserver
|
||||
{
|
||||
|
@ -111,7 +117,11 @@ public:
|
|||
kOpRemoveTextProperty = 3011,
|
||||
kOpHTMLPaste = 3012,
|
||||
kOpLoadHTML = 3013,
|
||||
kOpResetTextProperties = 3014
|
||||
kOpResetTextProperties = 3014,
|
||||
kOpSetAbsolutePosition = 3015,
|
||||
kOpRemoveAbsolutePosition = 3016,
|
||||
kOpDecreaseZIndex = 3017,
|
||||
kOpIncreaseZIndex = 3018
|
||||
};
|
||||
|
||||
enum ResizingRequestID
|
||||
|
@ -139,111 +149,37 @@ public:
|
|||
NS_IMETHOD GetIsDocumentEditable(PRBool *aIsDocumentEditable);
|
||||
NS_IMETHODIMP BeginningOfDocument();
|
||||
|
||||
/* ------------ nsIHTMLEditor methods -------------- */
|
||||
|
||||
NS_DECL_NSIHTMLEDITOR
|
||||
|
||||
/* ------------ nsIHTMLObjectResizer methods -------------- */
|
||||
/* -------- Implemented in nsHTMLObjectResizer.cpp -------- */
|
||||
NS_DECL_NSIHTMLOBJECTRESIZER
|
||||
|
||||
/* ------------ nsIHTMLEditor methods -------------- */
|
||||
NS_IMETHOD UpdateBaseURL();
|
||||
/* ------------ nsIHTMLAbsPosEditor methods -------------- */
|
||||
/* -------- Implemented in nsHTMLAbsPosition.cpp --------- */
|
||||
NS_DECL_NSIHTMLABSPOSEDITOR
|
||||
|
||||
/* ------------ nsIHTMLInlineTableEditor methods -------------- */
|
||||
/* ------- Implemented in nsHTMLInlineTableEditor.cpp --------- */
|
||||
NS_DECL_NSIHTMLINLINETABLEEDITOR
|
||||
|
||||
/* ------------ nsIHTMLEditor methods -------------- */
|
||||
NS_IMETHOD CopyLastEditableChildStyles(nsIDOMNode *aPreviousBlock, nsIDOMNode *aNewBlock,
|
||||
nsIDOMNode **aOutBrNode);
|
||||
|
||||
NS_IMETHOD ParseStyleAttrIntoCSSRule(const nsAString& aString,
|
||||
nsIDOMCSSStyleRule **_retval);
|
||||
|
||||
NS_IMETHOD AddDefaultProperty(nsIAtom *aProperty,
|
||||
const nsAString & aAttribute,
|
||||
const nsAString & aValue);
|
||||
|
||||
NS_IMETHOD RemoveDefaultProperty(nsIAtom *aProperty,
|
||||
const nsAString & aAttribute,
|
||||
const nsAString & aValue);
|
||||
|
||||
NS_IMETHOD RemoveAllDefaultProperties();
|
||||
|
||||
NS_IMETHOD SetCSSInlineProperty(nsIAtom *aProperty,
|
||||
const nsAString & aAttribute,
|
||||
const nsAString & aValue);
|
||||
|
||||
NS_IMETHOD SetInlineProperty(nsIAtom *aProperty,
|
||||
const nsAString & aAttribute,
|
||||
const nsAString & aValue);
|
||||
|
||||
NS_IMETHOD GetInlineProperty(nsIAtom *aProperty,
|
||||
const nsAString & aAttribute,
|
||||
const nsAString & aValue,
|
||||
PRBool *aFirst,
|
||||
PRBool *aAny,
|
||||
PRBool *aAll);
|
||||
NS_IMETHOD GetInlinePropertyWithAttrValue(nsIAtom *aProperty,
|
||||
const nsAString &aAttribute,
|
||||
const nsAString &aValue,
|
||||
PRBool *aFirst,
|
||||
PRBool *aAny,
|
||||
PRBool *aAll,
|
||||
nsAString &outValue);
|
||||
NS_IMETHOD RemoveAllInlineProperties();
|
||||
NS_IMETHOD RemoveInlineProperty(nsIAtom *aProperty, const nsAString & aAttribute);
|
||||
NS_IMETHOD IncreaseFontSize();
|
||||
NS_IMETHOD DecreaseFontSize();
|
||||
|
||||
NS_IMETHOD PasteNoFormatting(PRInt32 aSelectionType);
|
||||
NS_IMETHOD InsertHTML(const nsAString &aInputString);
|
||||
NS_IMETHOD InsertHTMLWithContext(const nsAString & aInputString,
|
||||
const nsAString & aContextStr,
|
||||
const nsAString & aInfoStr,
|
||||
const nsAString & aFlavor,
|
||||
nsIDOMDocument *aSourceDoc,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestinationOffset,
|
||||
PRBool aDeleteSelection);
|
||||
|
||||
NS_IMETHOD LoadHTML(const nsAString &aInputString);
|
||||
NS_IMETHOD RebuildDocumentFromSource(const nsAString& aSourceString);
|
||||
NS_IMETHOD InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSelection);
|
||||
|
||||
NS_IMETHOD SelectElement(nsIDOMElement* aElement);
|
||||
NS_IMETHOD SetCaretAfterElement(nsIDOMElement* aElement);
|
||||
|
||||
NS_IMETHOD SetParagraphFormat(const nsAString& aParagraphFormat);
|
||||
|
||||
NS_IMETHOD GetParentBlockTags(nsStringArray *aTagList, PRBool aGetLists);
|
||||
|
||||
NS_IMETHOD GetParagraphState(PRBool *aMixed, nsAString &outFormat);
|
||||
NS_IMETHOD GetFontFaceState(PRBool *aMixed, nsAString &outFace);
|
||||
NS_IMETHOD GetFontColorState(PRBool *aMixed, nsAString &outColor);
|
||||
NS_IMETHOD GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, PRBool aBlockLevel);
|
||||
nsresult GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor,
|
||||
PRBool aBlockLevel);
|
||||
NS_IMETHOD GetHTMLBackgroundColorState(PRBool *aMixed, nsAString &outColor);
|
||||
NS_IMETHOD GetBackgroundColorState(PRBool *aMixed, nsAString &outColor);
|
||||
NS_IMETHOD GetHighlightColorState(PRBool *aMixed, nsAString &outColor);
|
||||
NS_IMETHOD GetHighlightColor(PRBool *mixed, PRUnichar **_retval);
|
||||
NS_IMETHOD GetListState(PRBool *aMixed, PRBool *aOL, PRBool *aUL, PRBool *aDL);
|
||||
NS_IMETHOD GetListItemState(PRBool *aMixed, PRBool *aLI, PRBool *aDT, PRBool *aDD);
|
||||
NS_IMETHOD GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign);
|
||||
NS_IMETHOD GetIndentState(PRBool *aCanIndent, PRBool *aCanOutdent);
|
||||
|
||||
NS_IMETHOD MakeOrChangeList(const nsAString& aListType, PRBool entireList, const nsAString& aBulletType);
|
||||
NS_IMETHOD RemoveList(const nsAString& aListType);
|
||||
NS_IMETHOD Indent(const nsAString& aIndent);
|
||||
NS_IMETHOD Align(const nsAString& aAlign);
|
||||
|
||||
NS_IMETHOD GetElementOrParentByTagName(const nsAString& aTagName, nsIDOMNode *aNode, nsIDOMElement** aReturn);
|
||||
NS_IMETHOD GetSelectedElement(const nsAString& aTagName, nsIDOMElement** aReturn);
|
||||
NS_IMETHOD CreateElementWithDefaults(const nsAString& aTagName, nsIDOMElement** aReturn);
|
||||
NS_IMETHOD GetNextElementByTagName(nsIDOMElement *aCurrentElement, const nsAString *aTagName, nsIDOMElement **aReturn);
|
||||
|
||||
|
||||
NS_IMETHOD InsertLinkAroundSelection(nsIDOMElement* aAnchorElement);
|
||||
|
||||
NS_IMETHOD GetLinkedObjects(nsISupportsArray** aNodeList);
|
||||
|
||||
NS_IMETHOD SetIsCSSEnabled(PRBool aIsCSSPrefChecked);
|
||||
NS_IMETHOD GetIsCSSEnabled(PRBool *aIsCSSEnabled);
|
||||
NS_IMETHOD AddInsertionListener(nsIContentFilter *aFilter);
|
||||
NS_IMETHOD RemoveInsertionListener(nsIContentFilter *aFilter);
|
||||
|
||||
NS_IMETHOD IsAnonymousElement(nsIDOMElement * aElement, PRBool * aReturn);
|
||||
|
||||
/* ------------ nsIEditorIMESupport overrides -------------- */
|
||||
|
||||
NS_IMETHOD SetCompositionString(const nsAString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply);
|
||||
|
@ -340,11 +276,6 @@ public:
|
|||
// or calls into nsTextEditor to set the page background
|
||||
NS_IMETHOD SetCSSBackgroundColor(const nsAString& aColor);
|
||||
NS_IMETHOD SetHTMLBackgroundColor(const nsAString& aColor);
|
||||
NS_IMETHOD SetBackgroundColor(const nsAString& aColor);
|
||||
NS_IMETHOD SetBodyAttribute(const nsAString& aAttr, const nsAString& aValue);
|
||||
// aTitle may be null or empty string to remove child contents of <title>
|
||||
|
||||
NS_IMETHOD SetDocumentTitle(const nsAString &aTitle);
|
||||
|
||||
/* ------------ Block methods moved from nsEditor -------------- */
|
||||
static nsCOMPtr<nsIDOMNode> GetBlockNodeParent(nsIDOMNode *aNode);
|
||||
|
@ -406,8 +337,6 @@ public:
|
|||
/** Internal, static version */
|
||||
static nsresult NodeIsBlockStatic(nsIDOMNode *aNode, PRBool *aIsBlock);
|
||||
|
||||
/** This version is for exposure to JavaScript */
|
||||
NS_IMETHOD NodeIsBlock(nsIDOMNode *aNode, PRBool *aIsBlock);
|
||||
|
||||
/** we override this here to install event listeners */
|
||||
NS_IMETHOD PostCreate();
|
||||
|
@ -418,13 +347,6 @@ public:
|
|||
NS_IMETHOD Paste(PRInt32 aSelectionType);
|
||||
NS_IMETHOD CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste);
|
||||
|
||||
NS_IMETHOD CanDrag(nsIDOMEvent *aDragEvent, PRBool *aCanDrag);
|
||||
NS_IMETHOD DoDrag(nsIDOMEvent *aDragEvent);
|
||||
NS_IMETHOD InsertFromDrop(nsIDOMEvent* aDropEvent);
|
||||
|
||||
NS_IMETHOD GetHeadContentsAsHTML(nsAString& aOutputString);
|
||||
NS_IMETHOD ReplaceHeadContentsWithHTML(const nsAString &aSourceToInsert);
|
||||
|
||||
NS_IMETHOD DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed);
|
||||
|
||||
/** All editor operations which alter the doc should be prefaced
|
||||
|
@ -831,7 +753,6 @@ protected:
|
|||
|
||||
//XXX Kludge: Used to suppress spurious drag/drop events (bug 50703)
|
||||
PRBool mIgnoreSpuriousDragEvent;
|
||||
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;}
|
||||
|
||||
nsresult GetInlinePropertyBase(nsIAtom *aProperty,
|
||||
const nsAString *aAttribute,
|
||||
|
@ -892,12 +813,43 @@ protected:
|
|||
static PRInt32 sInstanceCount;
|
||||
|
||||
protected:
|
||||
PRPackedBool mIsImageResizingEnabled;
|
||||
PRPackedBool mIsShowingResizeHandles;
|
||||
|
||||
/* ANONYMOUS UTILS */
|
||||
void DeleteRefToAnonymousNode(nsIDOMElement* aElement,
|
||||
nsIContent * aParentContent,
|
||||
nsIDocumentObserver * aDocObserver);
|
||||
nsresult GetElementOrigin(nsIDOMElement * aElement, PRInt32 & aX, PRInt32 & aY);
|
||||
nsresult GetPositionAndDimensions(nsIDOMElement * aElement,
|
||||
PRInt32 & aX, PRInt32 & aY,
|
||||
PRInt32 & aW, PRInt32 & aH,
|
||||
PRInt32 & aBorderLeft,
|
||||
PRInt32 & aBorderTop,
|
||||
PRInt32 & aMarginLeft,
|
||||
PRInt32 & aMarginTop);
|
||||
|
||||
/* PACKED BOOLEANS FOR RESIZING, ABSOLUTE POSITIONING AND */
|
||||
/* INLINE TABLE EDITING */
|
||||
|
||||
// resizing
|
||||
PRPackedBool mIsObjectResizingEnabled;
|
||||
PRPackedBool mIsResizing;
|
||||
PRPackedBool mPreserveRatio;
|
||||
PRPackedBool mResizedObjectIsAnImage;
|
||||
|
||||
// absolute positioning
|
||||
PRPackedBool mIsAbsolutelyPositioningEnabled;
|
||||
PRPackedBool mResizedObjectIsAbsolutelyPositioned;
|
||||
|
||||
PRPackedBool mGrabberClicked;
|
||||
PRPackedBool mIsMoving;
|
||||
|
||||
PRPackedBool mSnapToGridEnabled;
|
||||
|
||||
// inline table editing
|
||||
PRPackedBool mIsInlineTableEditingEnabled;
|
||||
|
||||
/* RESIZING */
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mTopLeftHandle;
|
||||
nsCOMPtr<nsIDOMElement> mTopHandle;
|
||||
nsCOMPtr<nsIDOMElement> mTopRightHandle;
|
||||
|
@ -907,15 +859,20 @@ protected:
|
|||
nsCOMPtr<nsIDOMElement> mBottomHandle;
|
||||
nsCOMPtr<nsIDOMElement> mBottomRightHandle;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mActivatedHandle;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mResizingShadow;
|
||||
nsCOMPtr<nsIDOMElement> mResizingInfo;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mResizedObject;
|
||||
|
||||
nsCOMPtr<nsIDOMEventListener> mMouseMotionListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mMutationListenerP;
|
||||
nsCOMPtr<nsISelectionListener> mSelectionListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mResizeEventListenerP;
|
||||
|
||||
nsCOMArray<nsIHTMLObjectResizeListener> objectResizeEventListeners;
|
||||
|
||||
PRInt32 mOriginalX;
|
||||
PRInt32 mOriginalY;
|
||||
|
||||
|
@ -924,18 +881,32 @@ protected:
|
|||
PRInt32 mResizedObjectWidth;
|
||||
PRInt32 mResizedObjectHeight;
|
||||
|
||||
PRInt32 mResizedObjectMarginLeft;
|
||||
PRInt32 mResizedObjectMarginTop;
|
||||
PRInt32 mResizedObjectBorderLeft;
|
||||
PRInt32 mResizedObjectBorderTop;
|
||||
|
||||
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);
|
||||
PRInt8 mInfoXIncrement;
|
||||
PRInt8 mInfoYIncrement;
|
||||
|
||||
nsresult SetAllResizersPosition();
|
||||
|
||||
nsresult CreateResizer(nsIDOMElement ** aReturn, PRInt16 aLocation, nsIDOMNode * aParentNode);
|
||||
void SetAnonymousElementPosition(PRInt32 aX, PRInt32 aY, nsIDOMElement *aResizer);
|
||||
|
||||
nsresult CreateShadow(nsIDOMElement ** aReturn, nsIDOMNode * aParentNode,
|
||||
nsIDOMElement * aOriginalObject);
|
||||
nsresult SetShadowPosition(nsIDOMElement * aShadow,
|
||||
nsIDOMElement * aOriginalObject,
|
||||
PRInt32 aOriginalObjectX,
|
||||
PRInt32 aOriginalObjectY);
|
||||
|
||||
nsresult CreateResizingInfo(nsIDOMElement ** aReturn, nsIDOMNode * aParentNode);
|
||||
nsresult SetResizingInfoPosition(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aW, PRInt32 aH);
|
||||
|
||||
|
@ -947,11 +918,53 @@ protected:
|
|||
PRInt32 GetNewResizingHeight(PRInt32 aX, PRInt32 aY);
|
||||
void HideShadowAndInfo();
|
||||
void SetFinalSize(PRInt32 aX, PRInt32 aY);
|
||||
void DeleteRefToAnonymousNode(nsIDOMElement* aElement,
|
||||
nsIContent * aParentContent,
|
||||
nsIDocumentObserver * aDocObserver);
|
||||
void DeleteRefToAnonymousNode(nsIDOMNode * aNode);
|
||||
void SetResizeIncrements(PRInt32 aX, PRInt32 aY, PRInt32 aW, PRInt32 aH, PRBool aPreserveRatio);
|
||||
nsresult GetElementOrigin(nsIDOMElement * aElement, PRInt32 & aX, PRInt32 & aY);
|
||||
void SetInfoIncrements(PRInt8 aX, PRInt8 aY);
|
||||
|
||||
/* ABSOLUTE POSITIONING */
|
||||
|
||||
PRInt32 mPositionedObjectX;
|
||||
PRInt32 mPositionedObjectY;
|
||||
PRInt32 mPositionedObjectWidth;
|
||||
PRInt32 mPositionedObjectHeight;
|
||||
|
||||
PRInt32 mPositionedObjectMarginLeft;
|
||||
PRInt32 mPositionedObjectMarginTop;
|
||||
PRInt32 mPositionedObjectBorderLeft;
|
||||
PRInt32 mPositionedObjectBorderTop;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mAbsolutelyPositionedObject;
|
||||
nsCOMPtr<nsIDOMElement> mGrabber;
|
||||
nsCOMPtr<nsIDOMElement> mPositioningShadow;
|
||||
|
||||
PRInt32 mGridSize;
|
||||
|
||||
nsresult CreateGrabber(nsIDOMNode * aParentNode, nsIDOMElement ** aReturn);
|
||||
nsresult StartMoving(nsIDOMElement * aHandle);
|
||||
nsresult SetFinalPosition(PRInt32 aX, PRInt32 aY);
|
||||
void AddPositioningOffet(PRInt32 & aX, PRInt32 & aY);
|
||||
void SnapToGrid(PRInt32 & newX, PRInt32 & newY);
|
||||
nsresult GrabberClicked();
|
||||
nsresult EndMoving();
|
||||
nsresult CheckPositionedElementBGandFG(nsIDOMElement * aElement,
|
||||
nsAString & aReturn);
|
||||
|
||||
/* INLINE TABLE EDITING */
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mInlineEditedCell;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mAddColumnBeforeButton;
|
||||
nsCOMPtr<nsIDOMElement> mRemoveColumnButton;
|
||||
nsCOMPtr<nsIDOMElement> mAddColumnAfterButton;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> mAddRowBeforeButton;
|
||||
nsCOMPtr<nsIDOMElement> mRemoveRowButton;
|
||||
nsCOMPtr<nsIDOMElement> mAddRowAfterButton;
|
||||
|
||||
void AddMouseClickListener(nsIDOMElement * aElement);
|
||||
void RemoveMouseClickListener(nsIDOMElement * aElement);
|
||||
|
||||
public:
|
||||
|
||||
// friends
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "nsIHTMLObjectResizer.h"
|
||||
#include "nsEditProperty.h"
|
||||
#include "nsTextEditUtils.h"
|
||||
#include "nsIHTMLInlineTableEditor.h"
|
||||
|
||||
/*
|
||||
* nsHTMLEditorMouseListener implementation
|
||||
|
@ -116,7 +117,6 @@ nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
//non-ui event passed in. bad things.
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult res;
|
||||
|
||||
// Don't do anything special if not an HTML editor
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
||||
|
@ -126,7 +126,7 @@ nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
//XXX This should be easier to do!
|
||||
// But eDOMEvents_contextmenu and NS_CONTEXTMENU is not exposed in any event interface :-(
|
||||
PRUint16 buttonNumber;
|
||||
res = mouseEvent->GetButton(&buttonNumber);
|
||||
nsresult res = mouseEvent->GetButton(&buttonNumber);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
PRBool isContextClick;
|
||||
|
@ -270,8 +270,7 @@ 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<nsIHTMLObjectResizer> objectResizer = do_QueryInterface(htmlEditor);
|
||||
objectResizer->CheckResizingState(selection);
|
||||
htmlEditor->CheckSelectionStateForAnonymousButtons(selection);
|
||||
|
||||
// Prevent bubbling if we changed selection or
|
||||
// for all context clicks
|
||||
|
@ -295,6 +294,32 @@ nsHTMLEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
return nsTextEditorMouseListener::MouseDown(aMouseEvent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMouseEvent);
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
|
||||
if (!mouseEvent) {
|
||||
//non-ui event passed in. bad things.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't do anything special if not an HTML editor
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
||||
if (htmlEditor)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
nsresult res = aMouseEvent->GetTarget(getter_AddRefs(target));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!target) return NS_ERROR_NULL_POINTER;
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
|
||||
|
||||
nsCOMPtr<nsIHTMLInlineTableEditor> inlineTableEditing = do_QueryInterface(htmlEditor);
|
||||
inlineTableEditing->DoInlineTableEditingAction(element);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLEditorMouseListener(nsIDOMEventListener ** aInstancePtrResult,
|
||||
nsHTMLEditor *aHTMLEditor)
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
/*BEGIN implementations of mouseevent handler interface*/
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent);
|
||||
/*END implementations of mouseevent handler interface*/
|
||||
|
||||
protected:
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLEditor.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDocumentObserver.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsHTMLEditUtils.h"
|
||||
|
||||
// Uncomment the following line if you want to disable
|
||||
// table deletion when the only column/row is removed
|
||||
// #define DISABLE_TABLE_DELETION 1
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetInlineTableEditingEnabled(PRBool aIsEnabled)
|
||||
{
|
||||
mIsInlineTableEditingEnabled = aIsEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetInlineTableEditingEnabled(PRBool * aIsEnabled)
|
||||
{
|
||||
*aIsEnabled = mIsInlineTableEditingEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCell);
|
||||
|
||||
// do nothing if aCell is not a table cell...
|
||||
if (!nsHTMLEditUtils::IsTableCell(aCell))
|
||||
return NS_OK;
|
||||
|
||||
// the resizers and the shadow will be anonymous children of the body
|
||||
nsCOMPtr<nsIDOMElement> bodyElement;
|
||||
nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> bodyNode( do_QueryInterface(bodyElement) );
|
||||
|
||||
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyNode,
|
||||
NS_LITERAL_STRING("mozTableAddColumnBefore"),
|
||||
PR_FALSE, getter_AddRefs(mAddColumnBeforeButton));
|
||||
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyNode,
|
||||
NS_LITERAL_STRING("mozTableRemoveColumn"),
|
||||
PR_FALSE, getter_AddRefs(mRemoveColumnButton));
|
||||
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyNode,
|
||||
NS_LITERAL_STRING("mozTableAddColumnAfter"),
|
||||
PR_FALSE, getter_AddRefs(mAddColumnAfterButton));
|
||||
|
||||
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyNode,
|
||||
NS_LITERAL_STRING("mozTableAddRowBefore"),
|
||||
PR_FALSE, getter_AddRefs(mAddRowBeforeButton));
|
||||
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyNode,
|
||||
NS_LITERAL_STRING("mozTableRemoveRow"),
|
||||
PR_FALSE, getter_AddRefs(mRemoveRowButton));
|
||||
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyNode,
|
||||
NS_LITERAL_STRING("mozTableAddRowAfter"),
|
||||
PR_FALSE, getter_AddRefs(mAddRowAfterButton));
|
||||
|
||||
AddMouseClickListener(mAddColumnBeforeButton);
|
||||
AddMouseClickListener(mRemoveColumnButton);
|
||||
AddMouseClickListener(mAddColumnAfterButton);
|
||||
AddMouseClickListener(mAddRowBeforeButton);
|
||||
AddMouseClickListener(mRemoveRowButton);
|
||||
AddMouseClickListener(mAddRowAfterButton);
|
||||
|
||||
mInlineEditedCell = aCell;
|
||||
return RefreshInlineTableEditingUI();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::HideInlineTableEditingUI()
|
||||
{
|
||||
mInlineEditedCell = nsnull;
|
||||
|
||||
RemoveMouseClickListener(mAddColumnBeforeButton);
|
||||
RemoveMouseClickListener(mRemoveColumnButton);
|
||||
RemoveMouseClickListener(mAddColumnAfterButton);
|
||||
RemoveMouseClickListener(mAddRowBeforeButton);
|
||||
RemoveMouseClickListener(mRemoveRowButton);
|
||||
RemoveMouseClickListener(mAddRowAfterButton);
|
||||
|
||||
// get the presshell's document observer interface.
|
||||
|
||||
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIDocumentObserver> docObserver(do_QueryInterface(ps));
|
||||
if (!docObserver) return NS_ERROR_FAILURE;
|
||||
|
||||
// get the root content node.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> bodyElement;
|
||||
nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
|
||||
if (!bodyContent) return NS_ERROR_FAILURE;
|
||||
|
||||
DeleteRefToAnonymousNode(mAddColumnBeforeButton, bodyContent, docObserver);
|
||||
mAddColumnBeforeButton = nsnull;
|
||||
DeleteRefToAnonymousNode(mRemoveColumnButton, bodyContent, docObserver);
|
||||
mRemoveColumnButton = nsnull;
|
||||
DeleteRefToAnonymousNode(mAddColumnAfterButton, bodyContent, docObserver);
|
||||
mAddColumnAfterButton = nsnull;
|
||||
DeleteRefToAnonymousNode(mAddRowBeforeButton, bodyContent, docObserver);
|
||||
mAddRowBeforeButton = nsnull;
|
||||
DeleteRefToAnonymousNode(mRemoveRowButton, bodyContent, docObserver);
|
||||
mRemoveRowButton = nsnull;
|
||||
DeleteRefToAnonymousNode(mAddRowAfterButton, bodyContent, docObserver);
|
||||
mAddRowAfterButton = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::DoInlineTableEditingAction(nsIDOMElement * aElement)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aElement);
|
||||
PRBool anonElement = PR_FALSE;
|
||||
if (aElement &&
|
||||
NS_SUCCEEDED(aElement->HasAttribute(NS_LITERAL_STRING("_moz_anonclass"), &anonElement)) &&
|
||||
anonElement) {
|
||||
nsAutoString anonclass;
|
||||
nsresult res = aElement->GetAttribute(NS_LITERAL_STRING("_moz_anonclass"), anonclass);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (!Substring(anonclass, 0, 8).Equals(NS_LITERAL_STRING("mozTable")))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(mInlineEditedCell);
|
||||
nsCOMPtr<nsIDOMNode> tableNode = GetEnclosingTable(cellNode);
|
||||
nsCOMPtr<nsIDOMElement> tableElement = do_QueryInterface(tableNode);
|
||||
PRInt32 rowCount, colCount;
|
||||
res = GetTableSize(tableElement, &rowCount, &colCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
PRBool hideUI = PR_FALSE;
|
||||
PRBool hideResizersWithInlineTableUI = (mResizedObject == tableElement);
|
||||
|
||||
if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddColumnBefore")))
|
||||
InsertTableColumn(1, PR_FALSE);
|
||||
else if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddColumnAfter")))
|
||||
InsertTableColumn(1, PR_TRUE);
|
||||
else if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddRowBefore")))
|
||||
InsertTableRow(1, PR_FALSE);
|
||||
else if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddRowAfter")))
|
||||
InsertTableRow(1, PR_TRUE);
|
||||
else if (anonclass.Equals(NS_LITERAL_STRING("mozTableRemoveColumn"))) {
|
||||
DeleteTableColumn(1);
|
||||
#ifndef DISABLE_TABLE_DELETION
|
||||
hideUI = (colCount == 1);
|
||||
#endif
|
||||
}
|
||||
else if (anonclass.Equals(NS_LITERAL_STRING("mozTableRemoveRow"))) {
|
||||
DeleteTableRow(1);
|
||||
#ifndef DISABLE_TABLE_DELETION
|
||||
hideUI = (rowCount == 1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return NS_OK;
|
||||
|
||||
if (hideUI) {
|
||||
HideInlineTableEditingUI();
|
||||
if (hideResizersWithInlineTableUI)
|
||||
HideResizers();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLEditor::AddMouseClickListener(nsIDOMElement * aElement)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
|
||||
if (evtTarget)
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("click"), mMouseListenerP, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLEditor::RemoveMouseClickListener(nsIDOMElement * aElement)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
|
||||
if (evtTarget)
|
||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("click"), mMouseListenerP, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RefreshInlineTableEditingUI()
|
||||
{
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> nsElement = do_QueryInterface(mInlineEditedCell);
|
||||
if (!nsElement) {return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
PRInt32 xCell, yCell, wCell, hCell;
|
||||
GetElementOrigin(mInlineEditedCell, xCell, yCell);
|
||||
|
||||
nsresult res = nsElement->GetOffsetWidth(&wCell);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = nsElement->GetOffsetHeight(&hCell);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
PRInt32 xHoriz = xCell + wCell/2;
|
||||
PRInt32 yVert = yCell + hCell/2;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(mInlineEditedCell);
|
||||
nsCOMPtr<nsIDOMNode> tableNode = GetEnclosingTable(cellNode);
|
||||
nsCOMPtr<nsIDOMElement> tableElement = do_QueryInterface(tableNode);
|
||||
PRInt32 rowCount, colCount;
|
||||
res = GetTableSize(tableElement, &rowCount, &colCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
SetAnonymousElementPosition(xHoriz-10, yCell-7, mAddColumnBeforeButton);
|
||||
#ifdef DISABLE_TABLE_DELETION
|
||||
if (colCount== 1) {
|
||||
mRemoveColumnButton->SetAttribute(NS_LITERAL_STRING("class"),
|
||||
NS_LITERAL_STRING("hidden"));
|
||||
}
|
||||
else {
|
||||
PRBool hasClass = PR_FALSE;
|
||||
res = mRemoveColumnButton->HasAttribute(NS_LITERAL_STRING("class"), &hasClass);
|
||||
if (NS_SUCCEEDED(res) && hasClass)
|
||||
mRemoveColumnButton->RemoveAttribute(NS_LITERAL_STRING("class"));
|
||||
#endif
|
||||
SetAnonymousElementPosition(xHoriz-4, yCell-7, mRemoveColumnButton);
|
||||
#ifdef DISABLE_TABLE_DELETION
|
||||
}
|
||||
#endif
|
||||
SetAnonymousElementPosition(xHoriz+6, yCell-7, mAddColumnAfterButton);
|
||||
|
||||
SetAnonymousElementPosition(xCell-7, yVert-10, mAddRowBeforeButton);
|
||||
#ifdef DISABLE_TABLE_DELETION
|
||||
if (rowCount== 1) {
|
||||
mRemoveRowButton->SetAttribute(NS_LITERAL_STRING("class"),
|
||||
NS_LITERAL_STRING("hidden"));
|
||||
}
|
||||
else {
|
||||
PRBool hasClass = PR_FALSE;
|
||||
res = mRemoveRowButton->HasAttribute(NS_LITERAL_STRING("class"), &hasClass);
|
||||
if (NS_SUCCEEDED(res) && hasClass)
|
||||
mRemoveRowButton->RemoveAttribute(NS_LITERAL_STRING("class"));
|
||||
#endif
|
||||
SetAnonymousElementPosition(xCell-7, yVert-4, mRemoveRowButton);
|
||||
#ifdef DISABLE_TABLE_DELETION
|
||||
}
|
||||
#endif
|
||||
SetAnonymousElementPosition(xCell-7, yVert+6, mAddRowAfterButton);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -110,14 +110,14 @@ public:
|
|||
};
|
||||
|
||||
// ==================================================================
|
||||
// ResizeEventListener
|
||||
// DocumentResizeEventListener
|
||||
// ==================================================================
|
||||
|
||||
class ResizeEventListener: public nsIDOMEventListener
|
||||
class DocumentResizeEventListener: public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
ResizeEventListener(nsIHTMLEditor * aEditor);
|
||||
virtual ~ResizeEventListener();
|
||||
DocumentResizeEventListener(nsIHTMLEditor * aEditor);
|
||||
virtual ~DocumentResizeEventListener();
|
||||
|
||||
/*interfaces for addref and release and queryinterface*/
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -129,5 +129,4 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
#endif /* _nshtmlobjectresizer__h */
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
NS_IMETHOD GetIndentState(PRBool *aCanIndent, PRBool *aCanOutdent)=0;
|
||||
NS_IMETHOD GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign)=0;
|
||||
NS_IMETHOD GetParagraphState(PRBool *aMixed, nsAString &outFormat)=0;
|
||||
NS_IMETHOD MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode)=0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -99,7 +99,12 @@ public:
|
|||
kRemoveList = 3006,
|
||||
kMakeDefListItem = 3007,
|
||||
kInsertElement = 3008,
|
||||
kLoadHTML = 3013
|
||||
kLoadHTML = 3013,
|
||||
kSetAbsolutePosition = 3015,
|
||||
kRemoveAbsolutePosition = 3016,
|
||||
kDecreaseZIndex = 3017,
|
||||
kIncreaseZIndex = 3018
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -59,6 +59,8 @@ function SetupHTMLEditorCommands()
|
|||
|
||||
commandTable.registerCommand("cmd_renderedHTMLEnabler", nsDummyHTMLCommand);
|
||||
|
||||
commandTable.registerCommand("cmd_grid", nsGridCommand);
|
||||
|
||||
commandTable.registerCommand("cmd_listProperties", nsListPropertiesCommand);
|
||||
commandTable.registerCommand("cmd_pageProperties", nsPagePropertiesCommand);
|
||||
commandTable.registerCommand("cmd_colorProperties", nsColorPropertiesCommand);
|
||||
|
@ -286,9 +288,12 @@ function goUpdateCommandState(command)
|
|||
case "cmd_fontColor":
|
||||
case "cmd_fontFace":
|
||||
case "cmd_fontSize":
|
||||
case "cmd_absPos":
|
||||
pokeMultiStateUI(command, params);
|
||||
break;
|
||||
|
||||
case "cmd_decreaseZIndex":
|
||||
case "cmd_increaseZIndex":
|
||||
case "cmd_indent":
|
||||
case "cmd_outdent":
|
||||
case "cmd_increaseFont":
|
||||
|
@ -2884,6 +2889,25 @@ var nsInsertBreakAllCommand =
|
|||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
var nsGridCommand =
|
||||
{
|
||||
isCommandEnabled: function(aCommand, dummy)
|
||||
{
|
||||
return (IsDocumentEditable() && IsEditingRenderedHTML());
|
||||
},
|
||||
|
||||
getCommandStateParams: function(aCommand, aParams, aRefCon) {},
|
||||
doCommandParams: function(aCommand, aParams, aRefCon) {},
|
||||
|
||||
doCommand: function(aCommand)
|
||||
{
|
||||
window.openDialog("chrome://editor/content/EdSnapToGrid.xul","_blank", "chrome,close,titlebar,modal");
|
||||
window.content.focus();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
var nsListPropertiesCommand =
|
||||
{
|
||||
|
|
|
@ -143,6 +143,8 @@
|
|||
|
||||
<menu id="formatMenu" label="&formatMenu.label;" accesskey="&formatmenu.accesskey;">
|
||||
<menupopup id="formatMenuPopup">
|
||||
<menuitem id="snapToGrid"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="objectProperties"/>
|
||||
<menuitem id="colorsAndBackground"/>
|
||||
<menuitem id="pageProperties"/>
|
||||
|
@ -230,6 +232,10 @@
|
|||
<toolbarbutton id="align-right-button"/>
|
||||
<toolbarbutton id="align-justify-button"/>
|
||||
|
||||
<toolbarbutton id="absolutePositionButton"/>
|
||||
<toolbarbutton id="decreaseZIndexButton"/>
|
||||
<toolbarbutton id="increaseZIndexButton"/>
|
||||
|
||||
<!-- TODO: Change to a menulist? -->
|
||||
<!-- menu>
|
||||
<button id="AlignPopupButton"/>
|
||||
|
|
|
@ -225,7 +225,11 @@
|
|||
|
||||
<command id="cmd_fontSize" oncommand="goDoCommand('cmd_fontSize')"/>
|
||||
<command id="cmd_align" state=""/>
|
||||
|
||||
|
||||
<command id="cmd_absPos" state="" oncommand="goDoCommand('cmd_absPos')"/>
|
||||
<command id="cmd_increaseZIndex" state="" oncommand="goDoCommand('cmd_increaseZIndex')"/>
|
||||
<command id="cmd_decreaseZIndex" state="" oncommand="goDoCommand('cmd_decreaseZIndex')"/>
|
||||
|
||||
<command id="cmd_advancedProperties" oncommand="goDoCommand('cmd_advancedProperties')"/>
|
||||
|
||||
<command id="cmd_increaseFont" oncommand="goDoCommand('cmd_increaseFont')"/>
|
||||
|
@ -584,6 +588,9 @@
|
|||
<!-- Merge property items here -->
|
||||
</menupopup>
|
||||
|
||||
<menuitem id="snapToGrid" label="&grid.label;" accesskey="&grid.accesskey;"
|
||||
oncommand="goDoCommand('cmd_grid')" observes="cmd_renderedHTMLEnabler"/>
|
||||
|
||||
<!-- Next 3 are items to append at the bottom of the formatMenuPopup -->
|
||||
<!-- label and accesskey filled in during menu creation -->
|
||||
<menuitem id="objectProperties" oncommand="goDoCommand('cmd_objectProperties')" observes="cmd_renderedHTMLEnabler"/>
|
||||
|
@ -852,6 +859,12 @@
|
|||
onbroadcast="onStateButtonUpdate(this.parentNode, 'cmd_align', 'justify')"/>
|
||||
</toolbarbutton>
|
||||
|
||||
<toolbarbutton id="absolutePositionButton" type="checkbox" observes="cmd_absPos">
|
||||
<observes element="cmd_absPos" attribute="state" onbroadcast="onStateButtonUpdate(this.parentNode, 'cmd_absPos', 'absolute')"/>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="decreaseZIndexButton" observes="cmd_decreaseZIndex"/>
|
||||
<toolbarbutton id="increaseZIndexButton" observes="cmd_increaseZIndex"/>
|
||||
|
||||
<!-- Edit Mode toolbar -->
|
||||
<tab id="NormalModeButton" class="tab-bottom edit-mode _plain" type="text" selected="1" label="&NormalModeTab.label;" oncommand="goDoCommand('cmd_NormalMode');"
|
||||
tooltiptext="&NormalMode.tooltip;"/>
|
||||
|
|
|
@ -48,7 +48,8 @@
|
|||
var _elementIDs = [
|
||||
"showNew", "showOpen", "showSave", "showPublish", "showPreview", "showSmaller", "showLarger", "showBold",
|
||||
"showCut", "showCopy", "showPaste", "showPrint", "showFind", "showBullets", "showNumbers", "showItalic",
|
||||
"showImage", "showHline", "showTable", "showLink", "showAnchor", "showOutdent", "showIndent", "showUnderline"];
|
||||
"showImage", "showHline", "showTable", "showLink", "showAnchor", "showOutdent", "showIndent", "showUnderline",
|
||||
"showAbsolutePosition", "showDecreaseZIndex", "showIncreaseZIndex" ];
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
@ -101,6 +102,8 @@
|
|||
prefstring="editor.toolbars.showbutton.IncreaseFontSize"/>
|
||||
<checkbox label="&bold.label;" id="showBold"
|
||||
prefstring="editor.toolbars.showbutton.bold"/>
|
||||
<checkbox label="&absolutePosition.label;" id="showAbsolutePosition"
|
||||
prefstring="editor.toolbars.showbutton.absolutePosition"/>
|
||||
</vbox>
|
||||
<vbox flex="1">
|
||||
<checkbox label="&bullets.label;" id="showBullets"
|
||||
|
@ -109,6 +112,8 @@
|
|||
prefstring="editor.toolbars.showbutton.ol"/>
|
||||
<checkbox label="&italic.label;" id="showItalic"
|
||||
prefstring="editor.toolbars.showbutton.italic"/>
|
||||
<checkbox label="&decreaseZIndex.label;" id="showDecreaseZIndex"
|
||||
prefstring="editor.toolbars.showbutton.decreaseZIndex"/>
|
||||
</vbox>
|
||||
<vbox flex="1">
|
||||
<checkbox label="&outdent.label;" id="showOutdent"
|
||||
|
@ -117,6 +122,8 @@
|
|||
prefstring="editor.toolbars.showbutton.indent"/>
|
||||
<checkbox label="&underline.label;" id="showUnderline"
|
||||
prefstring="editor.toolbars.showbutton.underline"/>
|
||||
<checkbox label="&increaseZIndex.label;" id="showIncreaseZIndex"
|
||||
prefstring="editor.toolbars.showbutton.increaseZIndex"/>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
</page>
|
||||
|
|
|
@ -395,6 +395,9 @@
|
|||
<!ENTITY decreaseindent.accesskey "D">
|
||||
<!ENTITY decreaseindentkb "-">
|
||||
|
||||
<!ENTITY grid.label "Positioning grid">
|
||||
<!ENTITY grid.accesskey "t">
|
||||
|
||||
<!ENTITY pageProperties.label "Page Title and Properties...">
|
||||
<!ENTITY pageproperties.accesskey "g">
|
||||
<!ENTITY colorsAndBackground.label "Page Colors and Background...">
|
||||
|
|
|
@ -65,3 +65,7 @@
|
|||
<!ENTITY outdent.label "Outdent">
|
||||
<!ENTITY indent.label "Indent">
|
||||
<!ENTITY underline.label "Underline">
|
||||
|
||||
<!ENTITY absolutePosition.label "Absolute positioning">
|
||||
<!ENTITY decreaseZIndex.label "Sent to back">
|
||||
<!ENTITY increaseZIndex.label "Bring to front">
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
var gPrefs = GetPrefs();
|
||||
var gEditor;
|
||||
|
||||
// dialog initialization code
|
||||
function Startup()
|
||||
{
|
||||
gEditor = GetCurrentEditor();
|
||||
if (!gEditor)
|
||||
{
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
gEditor instanceof Components.interfaces.nsIHTMLAbsPosEditor;
|
||||
|
||||
gDialog.enableSnapToGrid = document.getElementById("enableSnapToGrid");
|
||||
gDialog.sizeInput = document.getElementById("size");
|
||||
gDialog.sizeLabel = document.getElementById("sizeLabel");
|
||||
gDialog.unitLabel = document.getElementById("unitLabel");
|
||||
|
||||
// Initialize control values based on existing attributes
|
||||
InitDialog()
|
||||
|
||||
// SET FOCUS TO FIRST CONTROL
|
||||
SetTextboxFocus(gDialog.sizeInput);
|
||||
|
||||
// Resize window
|
||||
window.sizeToContent();
|
||||
|
||||
SetWindowLocation();
|
||||
}
|
||||
|
||||
// Set dialog widgets with attribute data
|
||||
// We get them from globalElement copy so this can be used
|
||||
// by AdvancedEdit(), which is shared by all property dialogs
|
||||
function InitDialog()
|
||||
{
|
||||
gDialog.enableSnapToGrid.checked = gEditor.snapToGridEnabled;
|
||||
toggleSnapToGrid();
|
||||
|
||||
gDialog.sizeInput.value = gEditor.gridSize;
|
||||
}
|
||||
|
||||
function onAccept()
|
||||
{
|
||||
gEditor.snapToGridEnabled = gDialog.enableSnapToGrid.checked;
|
||||
gEditor.gridSize = gDialog.sizeInput.value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function toggleSnapToGrid()
|
||||
{
|
||||
SetElementEnabledById("size", gDialog.enableSnapToGrid.checked)
|
||||
SetElementEnabledById("sizeLabel", gDialog.enableSnapToGrid.checked)
|
||||
SetElementEnabledById("unitLabel", gDialog.enableSnapToGrid.checked)
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Mozilla.org.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2003
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Daniel Glazman (glazman@netscape.com) (Original author)
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://editor/skin/editor.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://editor/skin/EditorDialog.css" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://editor/content/EdDialogOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://editor/locale/EditorSnapToGrid.dtd">
|
||||
|
||||
<dialog title="&windowTitle.label;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="Startup()"
|
||||
ondialogaccept="return onAccept();"
|
||||
ondialogcancel="return onCancel();">
|
||||
|
||||
<!-- Methods common to all editor dialogs -->
|
||||
<script type="application/x-javascript" src="chrome://editor/content/editorUtilities.js"/>
|
||||
<script type="application/x-javascript" src="chrome://editor/content/EdDialogCommon.js"/>
|
||||
<!--- Element-specific methods -->
|
||||
<script type="application/x-javascript" src="chrome://editor/content/EdSnapToGrid.js"/>
|
||||
|
||||
<spacer id="location" offsetY="50" persist="offsetX offsetY"/>
|
||||
|
||||
<checkbox id="enableSnapToGrid"
|
||||
label="&enableSnapToGrid.label;"
|
||||
accesskey="&enableSnapToGrid.accessKey;"
|
||||
oncommand="toggleSnapToGrid();"/>
|
||||
|
||||
<spacer class="spacer"/>
|
||||
|
||||
<grid>
|
||||
<columns><column/><column/><column /></columns>
|
||||
<rows>
|
||||
<row align="center">
|
||||
<label value="&sizeEditField.label;"
|
||||
id="sizeLabel"
|
||||
control="size"
|
||||
accesskey="&sizeEditField.accessKey;"/>
|
||||
<textbox class="narrow" id="size" oninput="forceInteger('size')"/>
|
||||
<label id="unitLabel"
|
||||
value="&pixelsLabel.value;" />
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
||||
<spacer class="spacer"/>
|
||||
<separator class="groove"/>
|
||||
</dialog>
|
|
@ -31,6 +31,10 @@ comm.jar:
|
|||
content/editor/editorTasksOverlay.xul (composer/content/editorTasksOverlay.xul)
|
||||
content/editor/editorApplicationOverlay.js (composer/content/editorApplicationOverlay.js)
|
||||
content/editor/StructBarContextMenu.js (composer/content/StructBarContextMenu.js)
|
||||
content/editor/images/sendtoback.gif (composer/content/images/sendtoback.gif)
|
||||
content/editor/images/sendtoback-disabled.gif (composer/content/images/sendtoback-disabled.gif)
|
||||
content/editor/images/bringtofront.gif (composer/content/images/bringtofront.gif)
|
||||
content/editor/images/bringtofront-disabled.gif (composer/content/images/bringtofront-disabled.gif)
|
||||
content/editor/images/tag-anchor.gif (composer/content/images/tag-anchor.gif)
|
||||
content/editor/images/tag-abr.gif (composer/content/images/tag-abr.gif)
|
||||
content/editor/images/tag-acr.gif (composer/content/images/tag-acr.gif)
|
||||
|
@ -167,6 +171,8 @@ comm.jar:
|
|||
content/editor/EdHLineProps.js (dialogs/content/EdHLineProps.js)
|
||||
content/editor/EdReplace.xul (dialogs/content/EdReplace.xul)
|
||||
content/editor/EdReplace.js (dialogs/content/EdReplace.js)
|
||||
content/editor/EdSnapToGrid.xul (dialogs/content/EdSnapToGrid.xul)
|
||||
content/editor/EdSnapToGrid.js (dialogs/content/EdSnapToGrid.js)
|
||||
content/editor/EdSpellCheck.xul (dialogs/content/EdSpellCheck.xul)
|
||||
content/editor/EdSpellCheck.js (dialogs/content/EdSpellCheck.js)
|
||||
content/editor/EdDictionary.xul (dialogs/content/EdDictionary.xul)
|
||||
|
@ -260,6 +266,7 @@ en-US.jar:
|
|||
locale/en-US/editor/EdColorPicker.dtd (dialogs/locale/en-US/EdColorPicker.dtd)
|
||||
locale/en-US/editor/EditorPersonalDictionary.dtd (dialogs/locale/en-US/EditorPersonalDictionary.dtd)
|
||||
locale/en-US/editor/EditorReplace.dtd (dialogs/locale/en-US/EditorReplace.dtd)
|
||||
locale/en-US/editor/EditorSnapToGrid.dtd (dialogs/locale/en-US/EditorSnapToGrid.dtd)
|
||||
locale/en-US/editor/EditorSpellCheck.dtd (dialogs/locale/en-US/EditorSpellCheck.dtd)
|
||||
locale/en-US/editor/EditorTableProperties.dtd (dialogs/locale/en-US/EditorTableProperties.dtd)
|
||||
locale/en-US/editor/EditorFormProperties.dtd (dialogs/locale/en-US/EditorFormProperties.dtd)
|
||||
|
|