LCOV - app.info - content/base/src/nsDOMTokenList.cpp

LCOV - code coverage report
| Current view: | directory - content/base/src - nsDOMTokenList.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 142 | 2 | 1.4 %
| Date: | 2012-04-21 | Functions: | 23 | 2 | 8.7 %

           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 code.
          15                 :  *
          16                 :  * The Initial Developer of the Original Code is
          17                 :  * Sylvain Pasche <sylvain.pasche@gmail.com>
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2009
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *
          23                 :  * Alternatively, the contents of this file may be used under the terms of
          24                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          25                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          27                 :  * of those above. If you wish to allow use of your version of this file only
          28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          29                 :  * use your version of this file under the terms of the MPL, indicate your
          30                 :  * decision by deleting the provisions above and replace them with the notice
          31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          32                 :  * the provisions above, a recipient may use your version of this file under
          33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          34                 :  *
          35                 :  * ***** END LICENSE BLOCK ***** */
          36                 :
          37                 : /*
          38                 :  * Implementation of nsIDOMDOMTokenList specified by HTML5.
          39                 :  */
          40                 :
          41                 : #include "nsDOMTokenList.h"
          42                 :
          43                 : #include "nsAttrValue.h"
          44                 : #include "nsContentUtils.h"
          45                 : #include "nsDOMError.h"
          46                 : #include "nsGenericElement.h"
          47                 : #include "dombindings.h"
          48                 :
          49                 :
          50               0 : nsDOMTokenList::nsDOMTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
          51                 :   : mElement(aElement),
          52               0 :     mAttrAtom(aAttrAtom)
          53                 : {
          54                 :   // We don't add a reference to our element. If it goes away,
          55                 :   // we'll be told to drop our reference
          56               0 :   SetIsProxy();
          57               0 : }
          58                 :
          59               0 : nsDOMTokenList::~nsDOMTokenList() { }
          60                 :
          61            1396 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTokenList)
          62               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMTokenList)
          63               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
          64               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
          65               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMTokenList)
          66               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
          67               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
          68               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMTokenList)
          69               0 :   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
          70               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
          71                 :
          72                 : DOMCI_DATA(DOMTokenList, nsDOMTokenList)
          73                 :
          74               0 : NS_INTERFACE_TABLE_HEAD(nsDOMTokenList)
          75               0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
          76               0 :   NS_INTERFACE_TABLE1(nsDOMTokenList,
          77                 :                       nsIDOMDOMTokenList)
          78               0 :   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsDOMTokenList)
          79               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMTokenList)
          80               0 : NS_INTERFACE_MAP_END
          81                 :
          82               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTokenList)
          83               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTokenList)
          84                 :
          85                 : void
          86               0 : nsDOMTokenList::DropReference()
          87                 : {
          88               0 :   mElement = nsnull;
          89               0 : }
          90                 :
          91                 : NS_IMETHODIMP
          92               0 : nsDOMTokenList::GetLength(PRUint32 *aLength)
          93                 : {
          94               0 :   const nsAttrValue* attr = GetParsedAttr();
          95               0 :   if (!attr) {
          96               0 :     *aLength = 0;
          97               0 :     return NS_OK;
          98                 :   }
          99                 :
         100               0 :   *aLength = attr->GetAtomCount();
         101                 :
         102               0 :   return NS_OK;
         103                 : }
         104                 :
         105                 : NS_IMETHODIMP
         106               0 : nsDOMTokenList::Item(PRUint32 aIndex, nsAString& aResult)
         107                 : {
         108               0 :   const nsAttrValue* attr = GetParsedAttr();
         109                 :
         110               0 :   if (!attr || aIndex >= static_cast<PRUint32>(attr->GetAtomCount())) {
         111               0 :     SetDOMStringToNull(aResult);
         112               0 :     return NS_OK;
         113                 :   }
         114               0 :   attr->AtomAt(aIndex)->ToString(aResult);
         115                 :
         116               0 :   return NS_OK;
         117                 : }
         118                 :
         119                 : nsresult
         120               0 : nsDOMTokenList::CheckToken(const nsAString& aStr)
         121                 : {
         122               0 :   if (aStr.IsEmpty()) {
         123               0 :     return NS_ERROR_DOM_SYNTAX_ERR;
         124                 :   }
         125                 :
         126               0 :   nsAString::const_iterator iter, end;
         127               0 :   aStr.BeginReading(iter);
         128               0 :   aStr.EndReading(end);
         129                 :
         130               0 :   while (iter != end) {
         131               0 :     if (nsContentUtils::IsHTMLWhitespace(*iter))
         132               0 :       return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
         133               0 :     ++iter;
         134                 :   }
         135                 :
         136               0 :   return NS_OK;
         137                 : }
         138                 :
         139                 : NS_IMETHODIMP
         140               0 : nsDOMTokenList::Contains(const nsAString& aToken, bool* aResult)
         141                 : {
         142               0 :   nsresult rv = CheckToken(aToken);
         143               0 :   NS_ENSURE_SUCCESS(rv, rv);
         144                 :
         145               0 :   const nsAttrValue* attr = GetParsedAttr();
         146               0 :   if (!attr) {
         147               0 :     *aResult = false;
         148               0 :     return NS_OK;
         149                 :   }
         150                 :
         151               0 :   *aResult = attr->Contains(aToken);
         152                 :
         153               0 :   return NS_OK;
         154                 : }
         155                 :
         156                 : void
         157               0 : nsDOMTokenList::AddInternal(const nsAttrValue* aAttr,
         158                 :                             const nsAString& aToken)
         159                 : {
         160               0 :   if (!mElement) {
         161               0 :     return;
         162                 :   }
         163                 :
         164               0 :   nsAutoString resultStr;
         165                 :
         166               0 :   if (aAttr) {
         167               0 :     aAttr->ToString(resultStr);
         168                 :   }
         169                 :
         170               0 :   if (!resultStr.IsEmpty() &&
         171                 :       !nsContentUtils::IsHTMLWhitespace(
         172               0 :           resultStr.CharAt(resultStr.Length() - 1))) {
         173               0 :     resultStr.Append(NS_LITERAL_STRING(" ") + aToken);
         174                 :   } else {
         175               0 :     resultStr.Append(aToken);
         176                 :   }
         177               0 :   mElement->SetAttr(kNameSpaceID_None, mAttrAtom, resultStr, true);
         178                 : }
         179                 :
         180                 : NS_IMETHODIMP
         181               0 : nsDOMTokenList::Add(const nsAString& aToken)
         182                 : {
         183               0 :   nsresult rv = CheckToken(aToken);
         184               0 :   NS_ENSURE_SUCCESS(rv, rv);
         185                 :
         186               0 :   const nsAttrValue* attr = GetParsedAttr();
         187                 :
         188               0 :   if (attr && attr->Contains(aToken)) {
         189               0 :     return NS_OK;
         190                 :   }
         191                 :
         192               0 :   AddInternal(attr, aToken);
         193                 :
         194               0 :   return NS_OK;
         195                 : }
         196                 :
         197                 : void
         198               0 : nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
         199                 :                                const nsAString& aToken)
         200                 : {
         201               0 :   NS_ABORT_IF_FALSE(aAttr, "Need an attribute");
         202                 :
         203               0 :   nsAutoString input;
         204               0 :   aAttr->ToString(input);
         205                 :
         206               0 :   nsAString::const_iterator copyStart, tokenStart, iter, end;
         207               0 :   input.BeginReading(iter);
         208               0 :   input.EndReading(end);
         209               0 :   copyStart = iter;
         210                 :
         211               0 :   nsAutoString output;
         212               0 :   bool lastTokenRemoved = false;
         213                 :
         214               0 :   while (iter != end) {
         215                 :     // skip whitespace.
         216               0 :     while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
         217               0 :       ++iter;
         218                 :     }
         219                 :
         220               0 :     if (iter == end) {
         221                 :       // At this point we're sure the last seen token (if any) wasn't to be
         222                 :       // removed. So the trailing spaces will need to be kept.
         223               0 :       NS_ABORT_IF_FALSE(!lastTokenRemoved, "How did this happen?");
         224                 :
         225               0 :       output.Append(Substring(copyStart, end));
         226               0 :       break;
         227                 :     }
         228                 :
         229               0 :     tokenStart = iter;
         230               0 :     do {
         231               0 :       ++iter;
         232               0 :     } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
         233                 :
         234               0 :     if (Substring(tokenStart, iter).Equals(aToken)) {
         235                 :
         236                 :       // Skip whitespace after the token, it will be collapsed.
         237               0 :       while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
         238               0 :         ++iter;
         239                 :       }
         240               0 :       copyStart = iter;
         241               0 :       lastTokenRemoved = true;
         242                 :
         243                 :     } else {
         244                 :
         245               0 :       if (lastTokenRemoved && !output.IsEmpty()) {
         246               0 :         NS_ABORT_IF_FALSE(!nsContentUtils::IsHTMLWhitespace(
         247                 :           output.CharAt(output.Length() - 1)), "Invalid last output token");
         248               0 :         output.Append(PRUnichar(' '));
         249                 :       }
         250               0 :       lastTokenRemoved = false;
         251               0 :       output.Append(Substring(copyStart, iter));
         252               0 :       copyStart = iter;
         253                 :     }
         254                 :   }
         255                 :
         256               0 :   mElement->SetAttr(kNameSpaceID_None, mAttrAtom, output, true);
         257               0 : }
         258                 :
         259                 : NS_IMETHODIMP
         260               0 : nsDOMTokenList::Remove(const nsAString& aToken)
         261                 : {
         262               0 :   nsresult rv = CheckToken(aToken);
         263               0 :   NS_ENSURE_SUCCESS(rv, rv);
         264                 :
         265               0 :   const nsAttrValue* attr = GetParsedAttr();
         266               0 :   if (!attr) {
         267               0 :     return NS_OK;
         268                 :   }
         269                 :
         270               0 :   if (!attr->Contains(aToken)) {
         271               0 :     return NS_OK;
         272                 :   }
         273                 :
         274               0 :   RemoveInternal(attr, aToken);
         275                 :
         276               0 :   return NS_OK;
         277                 : }
         278                 :
         279                 : NS_IMETHODIMP
         280               0 : nsDOMTokenList::Toggle(const nsAString& aToken, bool* aResult)
         281                 : {
         282               0 :   nsresult rv = CheckToken(aToken);
         283               0 :   NS_ENSURE_SUCCESS(rv, rv);
         284                 :
         285               0 :   const nsAttrValue* attr = GetParsedAttr();
         286                 :
         287               0 :   if (attr && attr->Contains(aToken)) {
         288               0 :     RemoveInternal(attr, aToken);
         289               0 :     *aResult = false;
         290                 :   } else {
         291               0 :     AddInternal(attr, aToken);
         292               0 :     *aResult = true;
         293                 :   }
         294                 :
         295               0 :   return NS_OK;
         296                 : }
         297                 :
         298                 : NS_IMETHODIMP
         299               0 : nsDOMTokenList::ToString(nsAString& aResult)
         300                 : {
         301               0 :   if (!mElement) {
         302               0 :     aResult.Truncate();
         303               0 :     return NS_OK;
         304                 :   }
         305                 :
         306               0 :   mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
         307                 :
         308               0 :   return NS_OK;
         309                 : }
         310                 :
         311                 : JSObject*
         312               0 : nsDOMTokenList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
         313                 :                            bool *triedToWrap)
         314                 : {
         315                 :   return mozilla::dom::binding::DOMTokenList::create(cx, scope, this,
         316               0 :                                                      triedToWrap);
         317            4188 : }
         318                 :

Generated by: LCOV version 1.7