Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLEditUtils.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsHTMLEditUtils.h"
00039 #include "nsTextEditUtils.h"
00040 
00041 #include "nsString.h"
00042 #include "nsUnicharUtils.h"
00043 #include "nsEditor.h"
00044 #include "nsEditProperty.h"
00045 #include "nsIAtom.h"
00046 #include "nsIDOMNode.h"
00047 #include "nsIContent.h"
00048 #include "nsIDOMNodeList.h"
00049 #include "nsIDOMHTMLAnchorElement.h"
00050 
00052 //                  
00053 PRBool 
00054 nsHTMLEditUtils::IsBig(nsIDOMNode *node)
00055 {
00056   return nsEditor::NodeIsType(node, nsEditProperty::big);
00057 }
00058 
00059 
00061 // IsInlineStyle true if node is an inline style
00062 //                  
00063 PRBool 
00064 nsHTMLEditUtils::IsInlineStyle(nsIDOMNode *node)
00065 {
00066   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsInlineStyle");
00067   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00068   return (nodeAtom == nsEditProperty::b)
00069       || (nodeAtom == nsEditProperty::i)
00070       || (nodeAtom == nsEditProperty::u)
00071       || (nodeAtom == nsEditProperty::tt)
00072       || (nodeAtom == nsEditProperty::s)
00073       || (nodeAtom == nsEditProperty::strike)
00074       || (nodeAtom == nsEditProperty::big)
00075       || (nodeAtom == nsEditProperty::small)
00076       || (nodeAtom == nsEditProperty::blink)
00077       || (nodeAtom == nsEditProperty::sub)
00078       || (nodeAtom == nsEditProperty::sup)
00079       || (nodeAtom == nsEditProperty::font);
00080 }
00081 
00083 // IsFormatNode true if node is a format node
00084 // 
00085 PRBool
00086 nsHTMLEditUtils::IsFormatNode(nsIDOMNode *node)
00087 {
00088   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsFormatNode");
00089   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00090   return (nodeAtom == nsEditProperty::p)
00091       || (nodeAtom == nsEditProperty::pre)
00092       || (nodeAtom == nsEditProperty::h1)
00093       || (nodeAtom == nsEditProperty::h2)
00094       || (nodeAtom == nsEditProperty::h3)
00095       || (nodeAtom == nsEditProperty::h4)
00096       || (nodeAtom == nsEditProperty::h5)
00097       || (nodeAtom == nsEditProperty::h6)
00098       || (nodeAtom == nsEditProperty::address);
00099 }
00100 
00102 // IsNodeThatCanOutdent true if node is a list, list item, or blockquote      
00103 //
00104 PRBool
00105 nsHTMLEditUtils::IsNodeThatCanOutdent(nsIDOMNode *node)
00106 {
00107   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsNodeThatCanOutdent");
00108   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00109   return (nodeAtom == nsEditProperty::ul)
00110       || (nodeAtom == nsEditProperty::ol)
00111       || (nodeAtom == nsEditProperty::dl)
00112       || (nodeAtom == nsEditProperty::li)
00113       || (nodeAtom == nsEditProperty::dd)
00114       || (nodeAtom == nsEditProperty::dt)
00115       || (nodeAtom == nsEditProperty::blockquote);
00116 }
00117 
00119 //                  
00120 PRBool 
00121 nsHTMLEditUtils::IsSmall(nsIDOMNode *node)
00122 {
00123   return nsEditor::NodeIsType(node, nsEditProperty::small);
00124 }
00125 
00126 
00127 /********************************************************
00128  *  helper methods from nsHTMLEditRules
00129  ********************************************************/
00130  
00132 // IsHeader: true if node an html header
00133 //                  
00134 PRBool 
00135 nsHTMLEditUtils::IsHeader(nsIDOMNode *node)
00136 {
00137   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsHeader");
00138   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00139   return (nodeAtom == nsEditProperty::h1)
00140       || (nodeAtom == nsEditProperty::h2)
00141       || (nodeAtom == nsEditProperty::h3)
00142       || (nodeAtom == nsEditProperty::h4)
00143       || (nodeAtom == nsEditProperty::h5)
00144       || (nodeAtom == nsEditProperty::h6);
00145 }
00146 
00147 
00149 // IsParagraph: true if node an html paragraph
00150 //                  
00151 PRBool 
00152 nsHTMLEditUtils::IsParagraph(nsIDOMNode *node)
00153 {
00154   return nsEditor::NodeIsType(node, nsEditProperty::p);
00155 }
00156 
00157 
00159 // IsHR: true if node an horizontal rule
00160 //                  
00161 PRBool 
00162 nsHTMLEditUtils::IsHR(nsIDOMNode *node)
00163 {
00164   return nsEditor::NodeIsType(node, nsEditProperty::hr);
00165 }
00166 
00167 
00169 // IsListItem: true if node an html list item
00170 //                  
00171 PRBool 
00172 nsHTMLEditUtils::IsListItem(nsIDOMNode *node)
00173 {
00174   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsListItem");
00175   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00176   return (nodeAtom == nsEditProperty::li)
00177       || (nodeAtom == nsEditProperty::dd)
00178       || (nodeAtom == nsEditProperty::dt);
00179 }
00180 
00181 
00183 // IsTableElement: true if node an html table, td, tr, ...
00184 //                  
00185 PRBool 
00186 nsHTMLEditUtils::IsTableElement(nsIDOMNode *node)
00187 {
00188   NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableElement");
00189   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00190   return (nodeAtom == nsEditProperty::table)
00191       || (nodeAtom == nsEditProperty::tr)
00192       || (nodeAtom == nsEditProperty::td)
00193       || (nodeAtom == nsEditProperty::th)
00194       || (nodeAtom == nsEditProperty::thead)
00195       || (nodeAtom == nsEditProperty::tfoot)
00196       || (nodeAtom == nsEditProperty::tbody)
00197       || (nodeAtom == nsEditProperty::caption);
00198 }
00199 
00201 // IsTableElementButNotTable: true if node an html td, tr, ... (doesn't include table)
00202 //                  
00203 PRBool 
00204 nsHTMLEditUtils::IsTableElementButNotTable(nsIDOMNode *node)
00205 {
00206   NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableElementButNotTable");
00207   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00208   return (nodeAtom == nsEditProperty::tr)
00209       || (nodeAtom == nsEditProperty::td)
00210       || (nodeAtom == nsEditProperty::th)
00211       || (nodeAtom == nsEditProperty::thead)
00212       || (nodeAtom == nsEditProperty::tfoot)
00213       || (nodeAtom == nsEditProperty::tbody)
00214       || (nodeAtom == nsEditProperty::caption);
00215 }
00216 
00218 // IsTable: true if node an html table
00219 //                  
00220 PRBool 
00221 nsHTMLEditUtils::IsTable(nsIDOMNode *node)
00222 {
00223   return nsEditor::NodeIsType(node, nsEditProperty::table);
00224 }
00225 
00227 // IsTableRow: true if node an html tr
00228 //                  
00229 PRBool 
00230 nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
00231 {
00232   return nsEditor::NodeIsType(node, nsEditProperty::tr);
00233 }
00234 
00235 
00237 // IsTableCell: true if node an html td or th
00238 //                  
00239 PRBool 
00240 nsHTMLEditUtils::IsTableCell(nsIDOMNode *node)
00241 {
00242   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsTableCell");
00243   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00244   return (nodeAtom == nsEditProperty::td)
00245       || (nodeAtom == nsEditProperty::th);
00246 }
00247 
00248 
00250 // IsTableCell: true if node an html td or th
00251 //                  
00252 PRBool 
00253 nsHTMLEditUtils::IsTableCellOrCaption(nsIDOMNode *node)
00254 {
00255   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsTableCell");
00256   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00257   return (nodeAtom == nsEditProperty::td)
00258       || (nodeAtom == nsEditProperty::th)
00259       || (nodeAtom == nsEditProperty::caption);
00260 }
00261 
00262 
00264 // IsList: true if node an html list
00265 //                  
00266 PRBool 
00267 nsHTMLEditUtils::IsList(nsIDOMNode *node)
00268 {
00269   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsList");
00270   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00271   return (nodeAtom == nsEditProperty::ul)
00272       || (nodeAtom == nsEditProperty::ol)
00273       || (nodeAtom == nsEditProperty::dl);
00274 }
00275 
00276 
00278 // IsOrderedList: true if node an html ordered list
00279 //                  
00280 PRBool 
00281 nsHTMLEditUtils::IsOrderedList(nsIDOMNode *node)
00282 {
00283   return nsEditor::NodeIsType(node, nsEditProperty::ol);
00284 }
00285 
00286 
00288 // IsUnorderedList: true if node an html unordered list
00289 //                  
00290 PRBool 
00291 nsHTMLEditUtils::IsUnorderedList(nsIDOMNode *node)
00292 {
00293   return nsEditor::NodeIsType(node, nsEditProperty::ul);
00294 }
00295 
00296 
00298 // IsBlockquote: true if node an html blockquote node
00299 //                  
00300 PRBool 
00301 nsHTMLEditUtils::IsBlockquote(nsIDOMNode *node)
00302 {
00303   return nsEditor::NodeIsType(node, nsEditProperty::blockquote);
00304 }
00305 
00306 
00308 // IsPre: true if node an html pre node
00309 //                  
00310 PRBool 
00311 nsHTMLEditUtils::IsPre(nsIDOMNode *node)
00312 {
00313   return nsEditor::NodeIsType(node, nsEditProperty::pre);
00314 }
00315 
00316 
00318 // IsAddress: true if node an html address node
00319 //                  
00320 PRBool 
00321 nsHTMLEditUtils::IsAddress(nsIDOMNode *node)
00322 {
00323   return nsEditor::NodeIsType(node, nsEditProperty::address);
00324 }
00325 
00326 
00328 // IsImage: true if node an html image node
00329 //                  
00330 PRBool 
00331 nsHTMLEditUtils::IsImage(nsIDOMNode *node)
00332 {
00333   return nsEditor::NodeIsType(node, nsEditProperty::img);
00334 }
00335 
00336 PRBool 
00337 nsHTMLEditUtils::IsLink(nsIDOMNode *aNode)
00338 {
00339   if (!aNode) return PR_FALSE;
00340   nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aNode);
00341   if (anchor)
00342   {
00343     nsAutoString tmpText;
00344     if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && !tmpText.IsEmpty())
00345       return PR_TRUE;
00346   }
00347   return PR_FALSE;
00348 }
00349 
00350 PRBool 
00351 nsHTMLEditUtils::IsNamedAnchor(nsIDOMNode *aNode)
00352 {
00353   if (!aNode) return PR_FALSE;
00354   nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aNode);
00355   if (anchor)
00356   {
00357     nsAutoString tmpText;
00358     if (NS_SUCCEEDED(anchor->GetName(tmpText)) && !tmpText.IsEmpty())
00359       return PR_TRUE;
00360   }
00361   return PR_FALSE;
00362 }
00363 
00364 
00366 // IsDiv: true if node an html div node
00367 //                  
00368 PRBool 
00369 nsHTMLEditUtils::IsDiv(nsIDOMNode *node)
00370 {
00371   return nsEditor::NodeIsType(node, nsEditProperty::div);
00372 }
00373 
00374 
00376 // IsMozDiv: true if node an html div node with type = _moz
00377 //                  
00378 PRBool 
00379 nsHTMLEditUtils::IsMozDiv(nsIDOMNode *node)
00380 {
00381   if (IsDiv(node) && nsTextEditUtils::HasMozAttr(node)) return PR_TRUE;
00382   return PR_FALSE;
00383 }
00384 
00385 
00386 
00388 // IsMailCite: true if node an html blockquote with type=cite
00389 //                  
00390 PRBool 
00391 nsHTMLEditUtils::IsMailCite(nsIDOMNode *node)
00392 {
00393   NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsMailCite");
00394   nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(node);
00395   if (!elem) return PR_FALSE;
00396   nsAutoString attrName (NS_LITERAL_STRING("type")); 
00397   
00398   // don't ask me why, but our html mailcites are id'd by "type=cite"...
00399   nsAutoString attrVal;
00400   nsresult res = elem->GetAttribute(attrName, attrVal);
00401   ToLowerCase(attrVal);
00402   if (NS_SUCCEEDED(res))
00403   {
00404     if (attrVal.EqualsLiteral("cite"))
00405       return PR_TRUE;
00406   }
00407 
00408   // ... but our plaintext mailcites by "_moz_quote=true".  go figure.
00409   attrName.AssignLiteral("_moz_quote");
00410   res = elem->GetAttribute(attrName, attrVal);
00411   if (NS_SUCCEEDED(res))
00412   {
00413     ToLowerCase(attrVal);
00414     if (attrVal.EqualsLiteral("true"))
00415       return PR_TRUE;
00416   }
00417 
00418   return PR_FALSE;
00419 }
00420 
00421 
00423 // IsFormWidget: true if node is a form widget of some kind
00424 //                  
00425 PRBool 
00426 nsHTMLEditUtils::IsFormWidget(nsIDOMNode *node)
00427 {
00428   NS_PRECONDITION(node, "null node passed to nsHTMLEditUtils::IsFormWidget");
00429   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(node);
00430   return (nodeAtom == nsEditProperty::textarea)
00431       || (nodeAtom == nsEditProperty::select)
00432       || (nodeAtom == nsEditProperty::button)
00433       || (nodeAtom == nsEditProperty::input);
00434 }
00435 
00436 PRBool
00437 nsHTMLEditUtils::SupportsAlignAttr(nsIDOMNode * aNode)
00438 {
00439   NS_PRECONDITION(aNode, "null node passed to nsHTMLEditUtils::SupportsAlignAttr");
00440   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(aNode);
00441   return (nodeAtom == nsEditProperty::hr)
00442       || (nodeAtom == nsEditProperty::table)
00443       || (nodeAtom == nsEditProperty::tbody)
00444       || (nodeAtom == nsEditProperty::tfoot)
00445       || (nodeAtom == nsEditProperty::thead)
00446       || (nodeAtom == nsEditProperty::tr)
00447       || (nodeAtom == nsEditProperty::td)
00448       || (nodeAtom == nsEditProperty::th)
00449       || (nodeAtom == nsEditProperty::div)
00450       || (nodeAtom == nsEditProperty::p)
00451       || (nodeAtom == nsEditProperty::h1)
00452       || (nodeAtom == nsEditProperty::h2)
00453       || (nodeAtom == nsEditProperty::h3)
00454       || (nodeAtom == nsEditProperty::h4)
00455       || (nodeAtom == nsEditProperty::h5)
00456       || (nodeAtom == nsEditProperty::h6);
00457 }