~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is Mozilla.org.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * Netscape Communications Corp.
 
18
 * Portions created by the Initial Developer are Copyright (C) 2003
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *   Daniel Glazman (glazman@netscape.com) (Original author)
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the MPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the MPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#include "nsHTMLEditor.h"
 
39
#include "nsIDOMNSHTMLElement.h"
 
40
#include "nsIDOMEventTarget.h"
 
41
#include "nsIPresShell.h"
 
42
#include "nsIDocumentObserver.h"
 
43
#include "nsIContent.h"
 
44
#include "nsHTMLEditUtils.h"
 
45
#include "nsReadableUtils.h"
 
46
 
 
47
// Uncomment the following line if you want to disable
 
48
// table deletion when the only column/row is removed
 
49
// #define DISABLE_TABLE_DELETION 1
 
50
 
 
51
NS_IMETHODIMP
 
52
nsHTMLEditor::SetInlineTableEditingEnabled(PRBool aIsEnabled)
 
53
{
 
54
  mIsInlineTableEditingEnabled = aIsEnabled;
 
55
  return NS_OK;
 
56
}
 
57
 
 
58
NS_IMETHODIMP
 
59
nsHTMLEditor::GetInlineTableEditingEnabled(PRBool * aIsEnabled)
 
60
{
 
61
  *aIsEnabled = mIsInlineTableEditingEnabled;
 
62
  return NS_OK;
 
63
}
 
64
 
 
65
NS_IMETHODIMP
 
66
nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell)
 
67
{
 
68
  NS_ENSURE_ARG_POINTER(aCell);
 
69
 
 
70
  // do nothing if aCell is not a table cell...
 
71
  if (!nsHTMLEditUtils::IsTableCell(aCell))
 
72
    return NS_OK;
 
73
 
 
74
  // the resizers and the shadow will be anonymous children of the body
 
75
  nsCOMPtr<nsIDOMElement> bodyElement;
 
76
  nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
 
77
  if (NS_FAILED(res)) return res;
 
78
  if (!bodyElement)   return NS_ERROR_NULL_POINTER;
 
79
 
 
80
  CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
 
81
                         NS_LITERAL_STRING("mozTableAddColumnBefore"),
 
82
                         PR_FALSE, getter_AddRefs(mAddColumnBeforeButton));
 
83
  CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
 
84
                         NS_LITERAL_STRING("mozTableRemoveColumn"),
 
85
                         PR_FALSE, getter_AddRefs(mRemoveColumnButton));
 
86
  CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
 
87
                         NS_LITERAL_STRING("mozTableAddColumnAfter"),
 
88
                         PR_FALSE, getter_AddRefs(mAddColumnAfterButton));
 
89
 
 
90
  CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
 
91
                         NS_LITERAL_STRING("mozTableAddRowBefore"),
 
92
                         PR_FALSE, getter_AddRefs(mAddRowBeforeButton));
 
93
  CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
 
94
                         NS_LITERAL_STRING("mozTableRemoveRow"),
 
95
                         PR_FALSE, getter_AddRefs(mRemoveRowButton));
 
96
  CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
 
97
                         NS_LITERAL_STRING("mozTableAddRowAfter"),
 
98
                         PR_FALSE, getter_AddRefs(mAddRowAfterButton));
 
99
 
 
100
  AddMouseClickListener(mAddColumnBeforeButton);
 
101
  AddMouseClickListener(mRemoveColumnButton);
 
102
  AddMouseClickListener(mAddColumnAfterButton);
 
103
  AddMouseClickListener(mAddRowBeforeButton);
 
104
  AddMouseClickListener(mRemoveRowButton);
 
105
  AddMouseClickListener(mAddRowAfterButton);
 
106
 
 
107
  mInlineEditedCell = aCell;
 
108
  return RefreshInlineTableEditingUI();
 
109
}
 
110
 
 
111
NS_IMETHODIMP
 
112
nsHTMLEditor::HideInlineTableEditingUI()
 
113
{
 
114
  mInlineEditedCell = nsnull;
 
115
 
 
116
  RemoveMouseClickListener(mAddColumnBeforeButton);
 
117
  RemoveMouseClickListener(mRemoveColumnButton);
 
118
  RemoveMouseClickListener(mAddColumnAfterButton);
 
119
  RemoveMouseClickListener(mAddRowBeforeButton);
 
120
  RemoveMouseClickListener(mRemoveRowButton);
 
121
  RemoveMouseClickListener(mAddRowAfterButton);
 
122
 
 
123
  // get the presshell's document observer interface.
 
124
  nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
 
125
  if (!ps) return NS_ERROR_NOT_INITIALIZED;
 
126
 
 
127
  nsCOMPtr<nsIDocumentObserver> docObserver(do_QueryInterface(ps));
 
128
  if (!docObserver) return NS_ERROR_FAILURE;
 
129
 
 
130
  // get the root content node.
 
131
 
 
132
  nsCOMPtr<nsIDOMElement> bodyElement;
 
133
  nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
 
134
  if (NS_FAILED(res)) return res;
 
135
 
 
136
  nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
 
137
  if (!bodyContent) return NS_ERROR_FAILURE;
 
138
 
 
139
  DeleteRefToAnonymousNode(mAddColumnBeforeButton, bodyContent, docObserver);
 
140
  mAddColumnBeforeButton = nsnull;
 
141
  DeleteRefToAnonymousNode(mRemoveColumnButton, bodyContent, docObserver);
 
142
  mRemoveColumnButton = nsnull;
 
143
  DeleteRefToAnonymousNode(mAddColumnAfterButton, bodyContent, docObserver);
 
144
  mAddColumnAfterButton = nsnull;
 
145
  DeleteRefToAnonymousNode(mAddRowBeforeButton, bodyContent, docObserver);
 
146
  mAddRowBeforeButton = nsnull;
 
147
  DeleteRefToAnonymousNode(mRemoveRowButton, bodyContent, docObserver);
 
148
  mRemoveRowButton = nsnull;
 
149
  DeleteRefToAnonymousNode(mAddRowAfterButton, bodyContent, docObserver);
 
150
  mAddRowAfterButton = nsnull;
 
151
 
 
152
  return NS_OK;
 
153
}
 
154
 
 
155
NS_IMETHODIMP
 
156
nsHTMLEditor::DoInlineTableEditingAction(nsIDOMElement * aElement)
 
157
{
 
158
  NS_ENSURE_ARG_POINTER(aElement);
 
159
  PRBool anonElement = PR_FALSE;
 
160
  if (aElement &&
 
161
      NS_SUCCEEDED(aElement->HasAttribute(NS_LITERAL_STRING("_moz_anonclass"), &anonElement)) &&
 
162
      anonElement) {
 
163
    nsAutoString anonclass;
 
164
    nsresult res = aElement->GetAttribute(NS_LITERAL_STRING("_moz_anonclass"), anonclass);
 
165
    if (NS_FAILED(res)) return res;
 
166
 
 
167
    if (!StringBeginsWith(anonclass, NS_LITERAL_STRING("mozTable")))
 
168
      return NS_OK;
 
169
 
 
170
    nsCOMPtr<nsIDOMNode> tableNode = GetEnclosingTable(mInlineEditedCell);
 
171
    nsCOMPtr<nsIDOMElement> tableElement = do_QueryInterface(tableNode);
 
172
    PRInt32 rowCount, colCount;
 
173
    res = GetTableSize(tableElement, &rowCount, &colCount);
 
174
    if (NS_FAILED(res)) return res;
 
175
 
 
176
    PRBool hideUI = PR_FALSE;
 
177
    PRBool hideResizersWithInlineTableUI = (mResizedObject == tableElement);
 
178
 
 
179
    if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddColumnBefore")))
 
180
      InsertTableColumn(1, PR_FALSE);
 
181
    else if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddColumnAfter")))
 
182
      InsertTableColumn(1, PR_TRUE);
 
183
    else if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddRowBefore")))
 
184
      InsertTableRow(1, PR_FALSE);
 
185
    else if (anonclass.Equals(NS_LITERAL_STRING("mozTableAddRowAfter")))
 
186
      InsertTableRow(1, PR_TRUE);
 
187
    else if (anonclass.Equals(NS_LITERAL_STRING("mozTableRemoveColumn"))) {
 
188
      DeleteTableColumn(1);
 
189
#ifndef DISABLE_TABLE_DELETION
 
190
      hideUI = (colCount == 1);
 
191
#endif
 
192
    }
 
193
    else if (anonclass.Equals(NS_LITERAL_STRING("mozTableRemoveRow"))) {
 
194
      DeleteTableRow(1);
 
195
#ifndef DISABLE_TABLE_DELETION
 
196
      hideUI = (rowCount == 1);
 
197
#endif
 
198
    }
 
199
    else
 
200
      return NS_OK;
 
201
 
 
202
    if (hideUI) {
 
203
      HideInlineTableEditingUI();
 
204
      if (hideResizersWithInlineTableUI)
 
205
        HideResizers();
 
206
    }
 
207
  }
 
208
 
 
209
  return NS_OK;
 
210
}
 
211
 
 
212
void
 
213
nsHTMLEditor::AddMouseClickListener(nsIDOMElement * aElement)
 
214
{
 
215
  nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
 
216
  if (evtTarget)
 
217
    evtTarget->AddEventListener(NS_LITERAL_STRING("click"), mMouseListenerP, PR_TRUE);
 
218
}
 
219
 
 
220
void
 
221
nsHTMLEditor::RemoveMouseClickListener(nsIDOMElement * aElement)
 
222
{
 
223
  nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aElement));
 
224
  if (evtTarget)
 
225
    evtTarget->RemoveEventListener(NS_LITERAL_STRING("click"), mMouseListenerP, PR_TRUE);
 
226
}
 
227
 
 
228
NS_IMETHODIMP
 
229
nsHTMLEditor::RefreshInlineTableEditingUI()
 
230
{
 
231
  nsCOMPtr<nsIDOMNSHTMLElement> nsElement = do_QueryInterface(mInlineEditedCell);
 
232
  if (!nsElement) {return NS_ERROR_NULL_POINTER; }
 
233
 
 
234
  PRInt32 xCell, yCell, wCell, hCell;
 
235
  GetElementOrigin(mInlineEditedCell, xCell, yCell);
 
236
 
 
237
  nsresult res = nsElement->GetOffsetWidth(&wCell);
 
238
  if (NS_FAILED(res)) return res;
 
239
  res = nsElement->GetOffsetHeight(&hCell);
 
240
  if (NS_FAILED(res)) return res;
 
241
 
 
242
  PRInt32 xHoriz = xCell + wCell/2;
 
243
  PRInt32 yVert  = yCell + hCell/2;
 
244
 
 
245
  nsCOMPtr<nsIDOMNode> tableNode = GetEnclosingTable(mInlineEditedCell);
 
246
  nsCOMPtr<nsIDOMElement> tableElement = do_QueryInterface(tableNode);
 
247
  PRInt32 rowCount, colCount;
 
248
  res = GetTableSize(tableElement, &rowCount, &colCount);
 
249
  if (NS_FAILED(res)) return res;
 
250
 
 
251
  SetAnonymousElementPosition(xHoriz-10, yCell-7,  mAddColumnBeforeButton);
 
252
#ifdef DISABLE_TABLE_DELETION
 
253
  NS_NAMED_LITERAL_STRING(classStr, "class");
 
254
 
 
255
  if (colCount== 1) {
 
256
    mRemoveColumnButton->SetAttribute(classStr,
 
257
                                      NS_LITERAL_STRING("hidden"));
 
258
  }
 
259
  else {
 
260
    PRBool hasClass = PR_FALSE;
 
261
    res = mRemoveColumnButton->HasAttribute(classStr, &hasClass);
 
262
    if (NS_SUCCEEDED(res) && hasClass)
 
263
      mRemoveColumnButton->RemoveAttribute(classStr);
 
264
#endif
 
265
    SetAnonymousElementPosition(xHoriz-4, yCell-7,  mRemoveColumnButton);
 
266
#ifdef DISABLE_TABLE_DELETION
 
267
  }
 
268
#endif
 
269
  SetAnonymousElementPosition(xHoriz+6, yCell-7,  mAddColumnAfterButton);
 
270
 
 
271
  SetAnonymousElementPosition(xCell-7, yVert-10,  mAddRowBeforeButton);
 
272
#ifdef DISABLE_TABLE_DELETION
 
273
  if (rowCount== 1) {
 
274
    mRemoveRowButton->SetAttribute(classStr,
 
275
                                   NS_LITERAL_STRING("hidden"));
 
276
  }
 
277
  else {
 
278
    PRBool hasClass = PR_FALSE;
 
279
    res = mRemoveRowButton->HasAttribute(classStr, &hasClass);
 
280
    if (NS_SUCCEEDED(res) && hasClass)
 
281
      mRemoveRowButton->RemoveAttribute(classStr);
 
282
#endif
 
283
    SetAnonymousElementPosition(xCell-7, yVert-4,  mRemoveRowButton);
 
284
#ifdef DISABLE_TABLE_DELETION
 
285
  }
 
286
#endif
 
287
  SetAnonymousElementPosition(xCell-7, yVert+6,  mAddRowAfterButton);
 
288
 
 
289
  return NS_OK;
 
290
}
 
291