PRBool nsAttrValue::Contains(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const { switch (BaseType()) { case eAtomBase: { nsIAtom* atom = GetAtomValue(); if (aCaseSensitive == eCaseMatters) { return aValue == atom; } // For performance reasons, don't do a full on unicode case insensitive // string comparison. This is only used for quirks mode anyway. return nsContentUtils::EqualsIgnoreASCIICase(nsDependentAtomString(aValue), nsDependentAtomString(atom)); } default: { if (Type() == eAtomArray) { AtomArray* array = GetAtomArrayValue(); if (aCaseSensitive == eCaseMatters) { return array->IndexOf(aValue) != AtomArray::NoIndex; } nsDependentAtomString val1(aValue); for (nsCOMPtr<nsIAtom> *cur = array->Elements(), *end = cur + array->Length(); cur != end; ++cur) { // For performance reasons, don't do a full on unicode case // insensitive string comparison. This is only used for quirks mode // anyway. if (nsContentUtils::EqualsIgnoreASCIICase(val1, nsDependentAtomString(*cur))) { return PR_TRUE; } } } } } return PR_FALSE; }
bool nsAttrValue::Contains(const nsAString& aValue) const { switch (BaseType()) { case eAtomBase: { nsIAtom* atom = GetAtomValue(); return atom->Equals(aValue); } default: { if (Type() == eAtomArray) { AtomArray* array = GetAtomArrayValue(); return array->Contains(aValue, AtomArrayStringComparator()); } } } return false; }
nsresult nsTreeUtils::TokenizeProperties(const nsAString& aProperties, AtomArray & aPropertiesArray) { nsAString::const_iterator end; aProperties.EndReading(end); nsAString::const_iterator iter; aProperties.BeginReading(iter); do { // Skip whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) ++iter; // If only whitespace, we're done if (iter == end) break; // Note the first non-whitespace character nsAString::const_iterator first = iter; // Advance to the next whitespace character while (iter != end && ! nsCRT::IsAsciiSpace(*iter)) ++iter; // XXX this would be nonsensical NS_ASSERTION(iter != first, "eh? something's wrong here"); if (iter == first) break; nsCOMPtr<nsIAtom> atom = do_GetAtom(Substring(first, iter)); aPropertiesArray.AppendElement(atom); } while (iter != end); return NS_OK; }
void nsAttrValue::ParseAtomArray(const nsAString& aValue) { nsAString::const_iterator iter, end; aValue.BeginReading(iter); aValue.EndReading(end); PRBool hasSpace = PR_FALSE; // skip initial whitespace while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) { hasSpace = PR_TRUE; ++iter; } if (iter == end) { SetTo(aValue); return; } nsAString::const_iterator start(iter); // get first - and often only - atom do { ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); nsCOMPtr<nsIAtom> classAtom = do_GetAtom(Substring(start, iter)); if (!classAtom) { Reset(); return; } // skip whitespace while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) { hasSpace = PR_TRUE; ++iter; } if (iter == end && !hasSpace) { // we only found one classname and there was no whitespace so // don't bother storing a list ResetIfSet(); nsIAtom* atom = nsnull; classAtom.swap(atom); SetPtrValueAndType(atom, eAtomBase); return; } if (!EnsureEmptyAtomArray()) { return; } AtomArray* array = GetAtomArrayValue(); if (!array->AppendElement(classAtom)) { Reset(); return; } // parse the rest of the classnames while (iter != end) { start = iter; do { ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); classAtom = do_GetAtom(Substring(start, iter)); if (!array->AppendElement(classAtom)) { Reset(); return; } // skip whitespace while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) { ++iter; } } SetMiscAtomOrString(&aValue); return; }
ArrayClass::ArrayClass(VTable* cvtable) : ClassClosure(cvtable), kComma(core()->internConstantStringLatin1(",")) { AvmCore* core = this->core(); Toplevel* toplevel = this->toplevel(); toplevel->arrayClass = this; AvmAssert(traits()->getSizeOfInstance() == sizeof(ArrayClass)); VTable* ivtable = this->ivtable(); ScriptObject* objectPrototype = toplevel->objectClass->prototype; prototype = new (core->GetGC(), ivtable->getExtraSize()) ArrayObject(ivtable, objectPrototype, 0); // According to ECMAscript spec (ECMA-262.pdf) // generic support: concat, join, pop, push, reverse, shift, slice, sort, splice, unshift // NOT generic: toString, toLocaleString // unknown: sortOn (our own extension) #if defined(_DEBUG) // AtomArray DRC unit tests, put here b/c this always runs once, has a GC * and // this class has to do with arrays. this is more convienent that trying to test // through actionscript // create an atom Stringp s = core->newConstantStringLatin1("foo"); Atom a = s->atom(); AvmAssert(s->RefCount()==0); AtomArray *ar = new (gc()) AtomArray(); // test push/pop ar->push(a); AvmAssert(s->RefCount()==1); ar->push(a); AvmAssert(s->RefCount()==2); ar->pop(); AvmAssert(s->RefCount()==1); // reverse ar->push(a); AvmAssert(s->RefCount()==2); ar->reverse(); AvmAssert(s->RefCount()==2); // shift ar->shift(); AvmAssert(s->RefCount()==1); // splice AtomArray *ar2 = new (gc()) AtomArray(); ar->push(a); ar2->push(ar); AvmAssert(s->RefCount()==4); ar->splice(1, 2, 1, ar2, 0); // [a,a,a] AvmAssert(s->RefCount()==5); // unshift Atom as[4] = {a,a,a,a}; ar->unshift(as, 4); AvmAssert(s->RefCount()==9); // removeAt ar->removeAt(1); AvmAssert(s->RefCount()==8); // setAt ar->setAt(2, a); AvmAssert(s->RefCount()==8); // insert ar->insert(2, a); AvmAssert(s->RefCount()==9); // clear ar->clear(); AvmAssert(s->RefCount() == 2); ar2->clear(); AvmAssert(s->RefCount() == 0); gc()->Free(ar); gc()->Free(ar2); #endif }