2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2016-07-09 05:42:33 +03:00
|
|
|
#include "mozilla/HTMLEditor.h"
|
|
|
|
|
2016-07-07 08:01:12 +03:00
|
|
|
#include "HTMLEditUtils.h"
|
2012-07-13 10:33:42 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
|
|
|
#include "nsAString.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsDebug.h"
|
|
|
|
#include "nsError.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIDOMElement.h"
|
2003-06-25 12:50:48 +04:00
|
|
|
#include "nsIDOMEventTarget.h"
|
2012-07-13 10:33:42 +04:00
|
|
|
#include "nsIDOMHTMLElement.h"
|
|
|
|
#include "nsIDOMNode.h"
|
|
|
|
#include "nsIHTMLObjectResizer.h"
|
2003-06-25 12:50:48 +04:00
|
|
|
#include "nsIPresShell.h"
|
2012-07-13 10:33:42 +04:00
|
|
|
#include "nsLiteralString.h"
|
2003-07-14 11:37:39 +04:00
|
|
|
#include "nsReadableUtils.h"
|
2012-07-13 10:33:42 +04:00
|
|
|
#include "nsString.h"
|
|
|
|
#include "nscore.h"
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2016-07-09 05:42:33 +03:00
|
|
|
namespace mozilla {
|
2016-07-07 08:01:12 +03:00
|
|
|
|
2003-06-25 12:50:48 +04:00
|
|
|
// 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
|
2016-07-09 05:42:33 +03:00
|
|
|
HTMLEditor::SetInlineTableEditingEnabled(bool aIsEnabled)
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
|
|
|
mIsInlineTableEditingEnabled = aIsEnabled;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-07-09 05:42:33 +03:00
|
|
|
HTMLEditor::GetInlineTableEditingEnabled(bool* aIsEnabled)
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
|
|
|
*aIsEnabled = mIsInlineTableEditingEnabled;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-12-15 19:14:54 +03:00
|
|
|
nsresult
|
|
|
|
HTMLEditor::ShowInlineTableEditingUI(Element* aCell)
|
|
|
|
{
|
2003-06-25 12:50:48 +04:00
|
|
|
// do nothing if aCell is not a table cell...
|
2017-12-15 19:14:54 +03:00
|
|
|
if (!aCell || !HTMLEditUtils::IsTableCell(aCell)) {
|
2003-06-25 12:50:48 +04:00
|
|
|
return NS_OK;
|
2016-07-07 08:01:12 +03:00
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2017-12-15 19:14:54 +03:00
|
|
|
if (NS_WARN_IF(!IsDescendantOfEditorRoot(aCell))) {
|
2017-09-09 17:49:02 +03:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2008-04-14 00:22:31 +04:00
|
|
|
if (mInlineEditedCell) {
|
|
|
|
NS_ERROR("call HideInlineTableEditingUI first");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2003-06-25 12:50:48 +04:00
|
|
|
// the resizers and the shadow will be anonymous children of the body
|
2017-08-07 08:09:51 +03:00
|
|
|
RefPtr<Element> bodyElement = GetRoot();
|
2010-06-17 23:41:16 +04:00
|
|
|
NS_ENSURE_TRUE(bodyElement, NS_ERROR_NULL_POINTER);
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2016-11-24 09:58:01 +03:00
|
|
|
mAddColumnBeforeButton =
|
2017-08-07 08:09:51 +03:00
|
|
|
CreateAnonymousElement(nsGkAtoms::a, *bodyElement,
|
2016-11-24 09:58:01 +03:00
|
|
|
NS_LITERAL_STRING("mozTableAddColumnBefore"), false);
|
|
|
|
mRemoveColumnButton =
|
2017-08-07 08:09:51 +03:00
|
|
|
CreateAnonymousElement(nsGkAtoms::a, *bodyElement,
|
2016-11-24 09:58:01 +03:00
|
|
|
NS_LITERAL_STRING("mozTableRemoveColumn"), false);
|
|
|
|
mAddColumnAfterButton =
|
2017-08-07 08:09:51 +03:00
|
|
|
CreateAnonymousElement(nsGkAtoms::a, *bodyElement,
|
2016-11-24 09:58:01 +03:00
|
|
|
NS_LITERAL_STRING("mozTableAddColumnAfter"), false);
|
|
|
|
|
|
|
|
mAddRowBeforeButton =
|
2017-08-07 08:09:51 +03:00
|
|
|
CreateAnonymousElement(nsGkAtoms::a, *bodyElement,
|
2016-11-24 09:58:01 +03:00
|
|
|
NS_LITERAL_STRING("mozTableAddRowBefore"), false);
|
|
|
|
mRemoveRowButton =
|
2017-08-07 08:09:51 +03:00
|
|
|
CreateAnonymousElement(nsGkAtoms::a, *bodyElement,
|
2016-11-24 09:58:01 +03:00
|
|
|
NS_LITERAL_STRING("mozTableRemoveRow"), false);
|
|
|
|
mAddRowAfterButton =
|
2017-08-07 08:09:51 +03:00
|
|
|
CreateAnonymousElement(nsGkAtoms::a, *bodyElement,
|
2016-11-24 09:58:01 +03:00
|
|
|
NS_LITERAL_STRING("mozTableAddRowAfter"), false);
|
2003-06-25 12:50:48 +04:00
|
|
|
|
|
|
|
AddMouseClickListener(mAddColumnBeforeButton);
|
|
|
|
AddMouseClickListener(mRemoveColumnButton);
|
|
|
|
AddMouseClickListener(mAddColumnAfterButton);
|
|
|
|
AddMouseClickListener(mAddRowBeforeButton);
|
|
|
|
AddMouseClickListener(mRemoveRowButton);
|
|
|
|
AddMouseClickListener(mAddRowAfterButton);
|
|
|
|
|
|
|
|
mInlineEditedCell = aCell;
|
|
|
|
return RefreshInlineTableEditingUI();
|
|
|
|
}
|
|
|
|
|
2018-01-19 10:41:41 +03:00
|
|
|
nsresult
|
2016-07-09 05:42:33 +03:00
|
|
|
HTMLEditor::HideInlineTableEditingUI()
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
mInlineEditedCell = nullptr;
|
2003-06-25 12:50:48 +04:00
|
|
|
|
|
|
|
RemoveMouseClickListener(mAddColumnBeforeButton);
|
|
|
|
RemoveMouseClickListener(mRemoveColumnButton);
|
|
|
|
RemoveMouseClickListener(mAddColumnAfterButton);
|
|
|
|
RemoveMouseClickListener(mAddRowBeforeButton);
|
|
|
|
RemoveMouseClickListener(mRemoveRowButton);
|
|
|
|
RemoveMouseClickListener(mAddRowAfterButton);
|
|
|
|
|
|
|
|
// get the presshell's document observer interface.
|
2011-05-22 16:43:13 +04:00
|
|
|
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
2010-05-06 05:20:43 +04:00
|
|
|
// We allow the pres shell to be null; when it is, we presume there
|
|
|
|
// are no document observers to notify, but we still want to
|
|
|
|
// UnbindFromTree.
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2017-08-02 22:37:44 +03:00
|
|
|
DeleteRefToAnonymousNode(Move(mAddColumnBeforeButton), ps);
|
|
|
|
DeleteRefToAnonymousNode(Move(mRemoveColumnButton), ps);
|
|
|
|
DeleteRefToAnonymousNode(Move(mAddColumnAfterButton), ps);
|
|
|
|
DeleteRefToAnonymousNode(Move(mAddRowBeforeButton), ps);
|
|
|
|
DeleteRefToAnonymousNode(Move(mRemoveRowButton), ps);
|
|
|
|
DeleteRefToAnonymousNode(Move(mAddRowAfterButton), ps);
|
2003-06-25 12:50:48 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-01-19 10:41:41 +03:00
|
|
|
nsresult
|
|
|
|
HTMLEditor::DoInlineTableEditingAction(Element& aElement)
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
2018-01-19 10:41:41 +03:00
|
|
|
nsAutoString anonclass;
|
|
|
|
aElement.GetAttr(kNameSpaceID_None, nsGkAtoms::_moz_anonclass, anonclass);
|
|
|
|
|
|
|
|
if (!StringBeginsWith(anonclass, NS_LITERAL_STRING("mozTable"))) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<Element> tableElement = GetEnclosingTable(mInlineEditedCell);
|
|
|
|
int32_t rowCount, colCount;
|
|
|
|
nsresult rv = GetTableSize(tableElement, &rowCount, &colCount);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
bool hideUI = false;
|
|
|
|
bool hideResizersWithInlineTableUI = (mResizedObject == tableElement);
|
|
|
|
|
|
|
|
if (anonclass.EqualsLiteral("mozTableAddColumnBefore")) {
|
|
|
|
InsertTableColumn(1, false);
|
|
|
|
} else if (anonclass.EqualsLiteral("mozTableAddColumnAfter")) {
|
|
|
|
InsertTableColumn(1, true);
|
|
|
|
} else if (anonclass.EqualsLiteral("mozTableAddRowBefore")) {
|
|
|
|
InsertTableRow(1, false);
|
|
|
|
} else if (anonclass.EqualsLiteral("mozTableAddRowAfter")) {
|
|
|
|
InsertTableRow(1, true);
|
|
|
|
} else if (anonclass.EqualsLiteral("mozTableRemoveColumn")) {
|
|
|
|
DeleteTableColumn(1);
|
2003-06-25 12:50:48 +04:00
|
|
|
#ifndef DISABLE_TABLE_DELETION
|
2018-01-19 10:41:41 +03:00
|
|
|
hideUI = (colCount == 1);
|
2003-06-25 12:50:48 +04:00
|
|
|
#endif
|
2018-01-19 10:41:41 +03:00
|
|
|
} else if (anonclass.EqualsLiteral("mozTableRemoveRow")) {
|
|
|
|
DeleteTableRow(1);
|
2003-06-25 12:50:48 +04:00
|
|
|
#ifndef DISABLE_TABLE_DELETION
|
2018-01-19 10:41:41 +03:00
|
|
|
hideUI = (rowCount == 1);
|
2003-06-25 12:50:48 +04:00
|
|
|
#endif
|
2018-01-19 10:41:41 +03:00
|
|
|
} else {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2018-01-19 10:41:41 +03:00
|
|
|
// InsertTableRow might causes reframe
|
|
|
|
if (Destroyed()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2017-07-14 09:48:40 +03:00
|
|
|
|
2018-01-19 10:41:41 +03:00
|
|
|
if (hideUI) {
|
|
|
|
HideInlineTableEditingUI();
|
|
|
|
if (hideResizersWithInlineTableUI) {
|
|
|
|
HideResizers();
|
2003-06-25 12:50:48 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-11-24 09:58:01 +03:00
|
|
|
HTMLEditor::AddMouseClickListener(Element* aElement)
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
|
2010-03-06 07:01:28 +03:00
|
|
|
if (evtTarget) {
|
|
|
|
evtTarget->AddEventListener(NS_LITERAL_STRING("click"),
|
2011-10-17 18:59:28 +04:00
|
|
|
mEventListener, true);
|
2010-03-06 07:01:28 +03:00
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-11-24 09:58:01 +03:00
|
|
|
HTMLEditor::RemoveMouseClickListener(Element* aElement)
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
|
2010-03-06 07:01:28 +03:00
|
|
|
if (evtTarget) {
|
|
|
|
evtTarget->RemoveEventListener(NS_LITERAL_STRING("click"),
|
2011-10-17 18:59:28 +04:00
|
|
|
mEventListener, true);
|
2010-03-06 07:01:28 +03:00
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-07-09 05:42:33 +03:00
|
|
|
HTMLEditor::RefreshInlineTableEditingUI()
|
2003-06-25 12:50:48 +04:00
|
|
|
{
|
2017-12-15 19:14:54 +03:00
|
|
|
if (!mInlineEditedCell) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-10-30 00:03:55 +04:00
|
|
|
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mInlineEditedCell);
|
|
|
|
if (!htmlElement) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t xCell, yCell, wCell, hCell;
|
2017-12-15 19:14:54 +03:00
|
|
|
GetElementOrigin(*mInlineEditedCell, xCell, yCell);
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2016-10-19 12:09:33 +03:00
|
|
|
nsresult rv = htmlElement->GetOffsetWidth(&wCell);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = htmlElement->GetOffsetHeight(&hCell);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t xHoriz = xCell + wCell/2;
|
|
|
|
int32_t yVert = yCell + hCell/2;
|
2003-06-25 12:50:48 +04:00
|
|
|
|
2017-12-15 19:14:54 +03:00
|
|
|
RefPtr<Element> tableElement = GetEnclosingTable(mInlineEditedCell);
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t rowCount, colCount;
|
2016-10-19 12:09:33 +03:00
|
|
|
rv = GetTableSize(tableElement, &rowCount, &colCount);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2003-06-25 12:50:48 +04:00
|
|
|
|
|
|
|
SetAnonymousElementPosition(xHoriz-10, yCell-7, mAddColumnBeforeButton);
|
|
|
|
#ifdef DISABLE_TABLE_DELETION
|
|
|
|
if (colCount== 1) {
|
2016-11-24 09:58:01 +03:00
|
|
|
mRemoveColumnButton->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
|
|
|
NS_LITERAL_STRING("hidden"), true);
|
|
|
|
} else {
|
|
|
|
if (mRemoveColumnButton->HasAttr(kNameSpaceID_None, nsGkAtoms::_class)) {
|
|
|
|
mRemoveColumnButton->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class);
|
2016-10-19 12:09:33 +03:00
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
#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) {
|
2016-11-24 09:58:01 +03:00
|
|
|
mRemoveRowButton->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
|
|
|
NS_LITERAL_STRING("hidden"), true);
|
|
|
|
} else {
|
|
|
|
if (mRemoveRowButton->HasAttr(kNameSpaceID_None, nsGkAtoms::_class)) {
|
|
|
|
mRemoveRowButton->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class, true);
|
2016-10-19 12:09:33 +03:00
|
|
|
}
|
2003-06-25 12:50:48 +04:00
|
|
|
#endif
|
|
|
|
SetAnonymousElementPosition(xCell-7, yVert-4, mRemoveRowButton);
|
|
|
|
#ifdef DISABLE_TABLE_DELETION
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
SetAnonymousElementPosition(xCell-7, yVert+6, mAddRowAfterButton);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-07-09 05:42:33 +03:00
|
|
|
} // namespace mozilla
|