already_AddRefed<nsAtom> CharacterData::GetCurrentValueAtom() { nsAutoString val; GetData(val); return NS_Atomize(val); }
nsresult XULPersist::ApplyPersistentAttributesToElements( const nsAString& aID, nsCOMArray<Element>& aElements) { nsAutoCString utf8uri; nsresult rv = mDocument->GetDocumentURI()->GetSpec(utf8uri); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } NS_ConvertUTF8toUTF16 uri(utf8uri); // Get a list of attributes for which persisted values are available nsCOMPtr<nsIStringEnumerator> attrs; rv = mLocalStore->GetAttributeEnumerator(uri, aID, getter_AddRefs(attrs)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } while (1) { bool hasmore = PR_FALSE; attrs->HasMore(&hasmore); if (!hasmore) { break; } nsAutoString attrstr; attrs->GetNext(attrstr); nsAutoString value; rv = mLocalStore->GetValue(uri, aID, attrstr, value); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } RefPtr<nsAtom> attr = NS_Atomize(attrstr); if (NS_WARN_IF(!attr)) { return NS_ERROR_OUT_OF_MEMORY; } uint32_t cnt = aElements.Length(); for (int32_t i = int32_t(cnt) - 1; i >= 0; --i) { Element* element = aElements.SafeElementAt(i); if (!element) { continue; } // Applying persistent attributes to top level windows is handled // by nsXULWindow. if (element->IsXULElement(nsGkAtoms::window)) { if (nsCOMPtr<nsIXULWindow> win = mDocument->GetXULWindowIfToplevelChrome()) { continue; } } Unused << element->SetAttr(kNameSpaceID_None, attr, value, true); } } return NS_OK; }
/* * txIdPattern * * txIdPattern matches if the given node has a ID attribute with one * of the space delimited values. * This looks like the id() function, but may only have LITERALs as * argument. */ txIdPattern::txIdPattern(const nsAString& aString) { nsWhitespaceTokenizer tokenizer(aString); while (tokenizer.hasMoreTokens()) { // this can fail, XXX move to a Init(aString) method RefPtr<nsAtom> atom = NS_Atomize(tokenizer.nextToken()); mIds.AppendElement(atom); } }
int32_t txNamespaceMap::lookupNamespaceWithDefault(const nsAString& aPrefix) { RefPtr<nsAtom> prefix = NS_Atomize(aPrefix); if (prefix != nsGkAtoms::_poundDefault) { return lookupNamespace(prefix); } return lookupNamespace(nullptr); }
void EventTarget::SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler, ErrorResult& aRv) { if (!StringBeginsWith(aType, NS_LITERAL_STRING("on"))) { aRv.Throw(NS_ERROR_INVALID_ARG); return; } RefPtr<nsAtom> type = NS_Atomize(aType); SetEventHandler(type, aHandler); }
Element* AnonymousContent::GetElementById(const nsAString& aElementId) { // This can be made faster in the future if needed. RefPtr<nsAtom> elementId = NS_Atomize(aElementId); for (nsIContent* node = mContentNode; node; node = node->GetNextNode(mContentNode)) { if (!node->IsElement()) { continue; } nsAtom* id = node->AsElement()->GetID(); if (id && id == elementId) { return node->AsElement(); } } return nullptr; }
Element* AnonymousContent::GetElementById(const nsAString& aElementId) { // This can be made faster in the future if needed. nsCOMPtr<nsIAtom> elementId = NS_Atomize(aElementId); for (nsIContent* kid = mContentNode->GetFirstChild(); kid; kid = kid->GetNextNode(mContentNode)) { if (!kid->IsElement()) { continue; } nsIAtom* id = kid->AsElement()->GetID(); if (id && id == elementId) { return kid->AsElement(); } } return nullptr; }
explicit PropertyAtomHolder(const nsAString& aProperty) { nsCSSPropertyID propID = nsCSSProps::LookupProperty(aProperty, CSSEnabledState::eForAllContent); if (propID == eCSSPropertyExtra_variable) { mIsCustomProperty = true; mAtom = NS_Atomize( Substring(aProperty, CSS_CUSTOM_NAME_PREFIX_LENGTH)).take(); } else { mIsCustomProperty = false; if (propID != eCSSProperty_UNKNOWN) { mAtom = nsCSSProps::AtomForProperty(propID); } else { mAtom = nullptr; } } }
NS_IMETHODIMP nsThebesFontEnumerator::EnumerateFonts(const char *aLangGroup, const char *aGeneric, uint32_t *aCount, char16_t ***aResult) { NS_ENSURE_ARG_POINTER(aCount); NS_ENSURE_ARG_POINTER(aResult); nsTArray<nsString> fontList; nsAutoCString generic; if (aGeneric) generic.Assign(aGeneric); else generic.SetIsVoid(true); nsCOMPtr<nsIAtom> langGroupAtom; if (aLangGroup) { nsAutoCString lowered; lowered.Assign(aLangGroup); ToLowerCase(lowered); langGroupAtom = NS_Atomize(lowered); } nsresult rv = gfxPlatform::GetPlatform()->GetFontList(langGroupAtom, generic, fontList); if (NS_FAILED(rv)) { *aCount = 0; *aResult = nullptr; /* XXX in this case, do we want to return the CSS generics? */ return NS_OK; } char16_t **fs = static_cast<char16_t **> (moz_xmalloc(fontList.Length() * sizeof(char16_t*))); for (uint32_t i = 0; i < fontList.Length(); i++) { fs[i] = ToNewUnicode(fontList[i]); } *aResult = fs; *aCount = fontList.Length(); return NS_OK; }
void EventTarget::SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler, ErrorResult& aRv) { if (!StringBeginsWith(aType, NS_LITERAL_STRING("on"))) { aRv.Throw(NS_ERROR_INVALID_ARG); return; } if (NS_IsMainThread()) { nsCOMPtr<nsIAtom> type = NS_Atomize(aType); SetEventHandler(type, EmptyString(), aHandler); return; } SetEventHandler(nullptr, Substring(aType, 2), // Remove "on" aHandler); }
already_AddRefed<DataTransfer> DataTransfer::MozCloneForEvent(const nsAString& aEvent, ErrorResult& aRv) { RefPtr<nsAtom> atomEvt = NS_Atomize(aEvent); if (!atomEvt) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } EventMessage eventMessage = nsContentUtils::GetEventMessage(atomEvt); RefPtr<DataTransfer> dt; nsresult rv = Clone(mParent, eventMessage, false, false, getter_AddRefs(dt)); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return dt.forget(); }
void nsReferencedElement::ResetWithID(nsIContent* aFromContent, const nsString& aID, bool aWatch) { nsIDocument *doc = aFromContent->OwnerDoc(); if (!doc) return; // XXX Need to take care of XBL/XBL2 if (aWatch) { nsCOMPtr<nsIAtom> atom = NS_Atomize(aID); if (!atom) return; atom.swap(mWatchID); } mReferencingImage = false; HaveNewDocument(doc, aWatch, aID); }
// XXX currently you can not add the same adjacency (i.e. you can't have multiple // XXX stream converters registering to handle the same from-to combination. It's // XXX not programatically prohibited, it's just that results are un-predictable // XXX right now. nsresult nsStreamConverterService::AddAdjacency(const char *aContractID) { nsresult rv; // first parse out the FROM and TO MIME-types. nsAutoCString fromStr, toStr; rv = ParseFromTo(aContractID, fromStr, toStr); if (NS_FAILED(rv)) return rv; // Each MIME-type is a vertex in the graph, so first lets make sure // each MIME-type is represented as a key in our hashtable. nsCOMArray<nsIAtom> *fromEdges = mAdjacencyList.Get(fromStr); if (!fromEdges) { // There is no fromStr vertex, create one. fromEdges = new nsCOMArray<nsIAtom>(); mAdjacencyList.Put(fromStr, fromEdges); } if (!mAdjacencyList.Get(toStr)) { // There is no toStr vertex, create one. mAdjacencyList.Put(toStr, new nsCOMArray<nsIAtom>()); } // Now we know the FROM and TO types are represented as keys in the hashtable. // Let's "connect" the verticies, making an edge. nsCOMPtr<nsIAtom> vertex = NS_Atomize(toStr); if (!vertex) return NS_ERROR_OUT_OF_MEMORY; NS_ASSERTION(fromEdges, "something wrong in adjacency list construction"); if (!fromEdges) return NS_ERROR_FAILURE; return fromEdges->AppendObject(vertex) ? NS_OK : NS_ERROR_FAILURE; }
int main(int argc, char** argv) { ScopedXPCOM xpcom("TestStaticAtoms"); if (xpcom.failed()) { return 1; } TestingAtoms::AddRefAtoms(); NS_SealStaticAtomTable(); nsCOMPtr<nsIAtom> atom = NS_Atomize("foo"); if (!atom) { fail("Didn't get an atom for foo."); return 1; } if (atom->IsStaticAtom()) { passed("foo is a static atom"); } else { fail("foo is not a static atom."); return 1; } if (atom == TestingAtoms::foo) { passed("foo is the right pointer"); } else { fail("foo was not the right pointer"); return 1; } nsIAtom* staticAtom = NS_GetStaticAtom(NS_LITERAL_STRING("foo")); if (!staticAtom) { fail("Did not get a static atom for foo"); return 1; } if (atom == staticAtom) { passed("NS_Atomize and NS_GetStaticAtom returned the same atom."); } else { fail("NS_Atomize and NS_GetStaticAtom returned different atoms."); return 1; } MoreTestingAtoms::AddRefAtoms(); atom = NS_Atomize("qux"); if (!atom) { fail("Didn't get an atom for qux."); return 1; } if (atom->IsStaticAtom()) { passed("qux is a static atom"); } else { fail("qux is not a static atom."); return 1; } if (atom == MoreTestingAtoms::qux) { passed("qux is the right pointer"); } else { fail("qux was not the right pointer"); return 1; } staticAtom = NS_GetStaticAtom(NS_LITERAL_STRING("qux")); if (staticAtom) { fail("Got an atom for qux. The static atom table was not sealed properly."); return 1; } return 0; }
void nsReferencedElement::Reset(nsIContent* aFromContent, nsIURI* aURI, bool aWatch, bool aReferenceImage) { MOZ_ASSERT(aFromContent, "Reset() expects non-null content pointer"); Unlink(); if (!aURI) return; nsAutoCString refPart; aURI->GetRef(refPart); // Unescape %-escapes in the reference. The result will be in the // origin charset of the URL, hopefully... NS_UnescapeURL(refPart); nsAutoCString charset; aURI->GetOriginCharset(charset); nsAutoString ref; nsresult rv = nsContentUtils::ConvertStringFromEncoding(charset, refPart, ref); if (NS_FAILED(rv)) { // XXX Eww. If fallible malloc failed, using a conversion method that // assumes UTF-8 and doesn't handle UTF-8 errors. // https://bugzilla.mozilla.org/show_bug.cgi?id=951082 CopyUTF8toUTF16(refPart, ref); } if (ref.IsEmpty()) return; // Get the current document nsIDocument *doc = aFromContent->OwnerDoc(); if (!doc) return; nsIContent* bindingParent = aFromContent->GetBindingParent(); if (bindingParent) { nsXBLBinding* binding = bindingParent->GetXBLBinding(); if (binding) { bool isEqualExceptRef; rv = aURI->EqualsExceptRef(binding->PrototypeBinding()->DocURI(), &isEqualExceptRef); if (NS_SUCCEEDED(rv) && isEqualExceptRef) { // XXX sXBL/XBL2 issue // Our content is an anonymous XBL element from a binding inside the // same document that the referenced URI points to. In order to avoid // the risk of ID collisions we restrict ourselves to anonymous // elements from this binding; specifically, URIs that are relative to // the binding document should resolve to the copy of the target // element that has been inserted into the bound document. // If the URI points to a different document we don't need this // restriction. nsINodeList* anonymousChildren = doc->BindingManager()->GetAnonymousNodesFor(bindingParent); if (anonymousChildren) { uint32_t length; anonymousChildren->GetLength(&length); for (uint32_t i = 0; i < length && !mElement; ++i) { mElement = nsContentUtils::MatchElementId(anonymousChildren->Item(i), ref); } } // We don't have watching working yet for XBL, so bail out here. return; } } } bool isEqualExceptRef; rv = aURI->EqualsExceptRef(doc->GetDocumentURI(), &isEqualExceptRef); if (NS_FAILED(rv) || !isEqualExceptRef) { RefPtr<nsIDocument::ExternalResourceLoad> load; doc = doc->RequestExternalResource(aURI, aFromContent, getter_AddRefs(load)); if (!doc) { if (!load || !aWatch) { // Nothing will ever happen here return; } DocumentLoadNotification* observer = new DocumentLoadNotification(this, ref); mPendingNotification = observer; if (observer) { load->AddObserver(observer); } // Keep going so we set up our watching stuff a bit } } if (aWatch) { nsCOMPtr<nsIAtom> atom = NS_Atomize(ref); if (!atom) return; atom.swap(mWatchID); } mReferencingImage = aReferenceImage; HaveNewDocument(doc, aWatch, ref); }
nsresult txPatternParser::createLocPathPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; bool isChild = true; bool isAbsolute = false; txPattern* stepPattern = 0; txLocPathPattern* pathPattern = 0; Token::Type type = aLexer.peek()->mType; switch (type) { case Token::ANCESTOR_OP: isChild = false; isAbsolute = true; aLexer.nextToken(); break; case Token::PARENT_OP: aLexer.nextToken(); isAbsolute = true; if (aLexer.peek()->mType == Token::END || aLexer.peek()->mType == Token::UNION_OP) { aPattern = new txRootPattern(); return NS_OK; } break; case Token::FUNCTION_NAME_AND_PAREN: // id(Literal) or key(Literal, Literal) { RefPtr<nsAtom> nameAtom = NS_Atomize(aLexer.nextToken()->Value()); if (nameAtom == nsGkAtoms::id) { rv = createIdPattern(aLexer, stepPattern); } else if (nameAtom == nsGkAtoms::key) { rv = createKeyPattern(aLexer, aContext, stepPattern); } if (NS_FAILED(rv)) return rv; } break; default: break; } if (!stepPattern) { rv = createStepPattern(aLexer, aContext, stepPattern); if (NS_FAILED(rv)) return rv; } type = aLexer.peek()->mType; if (!isAbsolute && type != Token::PARENT_OP && type != Token::ANCESTOR_OP) { aPattern = stepPattern; return NS_OK; } pathPattern = new txLocPathPattern(); if (isAbsolute) { txRootPattern* root = new txRootPattern(); #ifdef TX_TO_STRING root->setSerialize(false); #endif rv = pathPattern->addStep(root, isChild); if (NS_FAILED(rv)) { delete stepPattern; delete pathPattern; delete root; return NS_ERROR_OUT_OF_MEMORY; } } rv = pathPattern->addStep(stepPattern, isChild); if (NS_FAILED(rv)) { delete stepPattern; delete pathPattern; return NS_ERROR_OUT_OF_MEMORY; } stepPattern = 0; // stepPattern is part of pathPattern now while (type == Token::PARENT_OP || type == Token::ANCESTOR_OP) { isChild = type == Token::PARENT_OP; aLexer.nextToken(); rv = createStepPattern(aLexer, aContext, stepPattern); if (NS_FAILED(rv)) { delete pathPattern; return rv; } rv = pathPattern->addStep(stepPattern, isChild); if (NS_FAILED(rv)) { delete stepPattern; delete pathPattern; return NS_ERROR_OUT_OF_MEMORY; } stepPattern = 0; // stepPattern is part of pathPattern now type = aLexer.peek()->mType; } aPattern = pathPattern; return rv; }
nsresult CharacterData::SetTextInternal( uint32_t aOffset, uint32_t aCount, const char16_t* aBuffer, uint32_t aLength, bool aNotify, CharacterDataChangeInfo::Details* aDetails) { MOZ_ASSERT(aBuffer || !aLength, "Null buffer passed to SetTextInternal!"); // sanitize arguments uint32_t textLength = mText.GetLength(); if (aOffset > textLength) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } if (aCount > textLength - aOffset) { aCount = textLength - aOffset; } uint32_t endOffset = aOffset + aCount; // Make sure the text fragment can hold the new data. if (aLength > aCount && !mText.CanGrowBy(aLength - aCount)) { return NS_ERROR_OUT_OF_MEMORY; } Document* document = GetComposedDoc(); mozAutoDocUpdate updateBatch(document, aNotify); bool haveMutationListeners = aNotify && nsContentUtils::HasMutationListeners( this, NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED, this); RefPtr<nsAtom> oldValue; if (haveMutationListeners) { oldValue = GetCurrentValueAtom(); } if (aNotify) { CharacterDataChangeInfo info = {aOffset == textLength, aOffset, endOffset, aLength, aDetails}; nsNodeUtils::CharacterDataWillChange(this, info); } Directionality oldDir = eDir_NotSet; bool dirAffectsAncestor = (NodeType() == TEXT_NODE && TextNodeWillChangeDirection(static_cast<nsTextNode*>(this), &oldDir, aOffset)); if (aOffset == 0 && endOffset == textLength) { // Replacing whole text or old text was empty. Don't bother to check for // bidi in this string if the document already has bidi enabled. // If this is marked as "maybe modified frequently", the text should be // stored as char16_t since converting char* to char16_t* is expensive. bool ok = mText.SetTo(aBuffer, aLength, !document || !document->GetBidiEnabled(), HasFlag(NS_MAYBE_MODIFIED_FREQUENTLY)); NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); } else if (aOffset == textLength) { // Appending to existing bool ok = mText.Append(aBuffer, aLength, !document || !document->GetBidiEnabled(), HasFlag(NS_MAYBE_MODIFIED_FREQUENTLY)); NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); } else { // Merging old and new bool bidi = mText.IsBidi(); // Allocate new buffer int32_t newLength = textLength - aCount + aLength; // Use nsString and not nsAutoString so that we get a nsStringBuffer which // can be just AddRefed in nsTextFragment. nsString to; to.SetCapacity(newLength); // Copy over appropriate data if (aOffset) { mText.AppendTo(to, 0, aOffset); } if (aLength) { to.Append(aBuffer, aLength); if (!bidi && (!document || !document->GetBidiEnabled())) { bidi = HasRTLChars(MakeSpan(aBuffer, aLength)); } } if (endOffset != textLength) { mText.AppendTo(to, endOffset, textLength - endOffset); } // If this is marked as "maybe modified frequently", the text should be // stored as char16_t since converting char* to char16_t* is expensive. // Use char16_t also when we have bidi characters. bool use2b = HasFlag(NS_MAYBE_MODIFIED_FREQUENTLY) || bidi; bool ok = mText.SetTo(to, false, use2b); mText.SetBidi(bidi); NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); } UnsetFlags(NS_CACHED_TEXT_IS_ONLY_WHITESPACE); if (document && mText.IsBidi()) { // If we found bidi characters in mText.SetTo() above, indicate that the // document contains bidi characters. document->SetBidiEnabled(); } if (dirAffectsAncestor) { // dirAffectsAncestor being true implies that we have a text node, see // above. MOZ_ASSERT(NodeType() == TEXT_NODE); TextNodeChangedDirection(static_cast<nsTextNode*>(this), oldDir, aNotify); } // Notify observers if (aNotify) { CharacterDataChangeInfo info = {aOffset == textLength, aOffset, endOffset, aLength, aDetails}; nsNodeUtils::CharacterDataChanged(this, info); if (haveMutationListeners) { InternalMutationEvent mutation(true, eLegacyCharacterDataModified); mutation.mPrevAttrValue = oldValue; if (aLength > 0) { nsAutoString val; mText.AppendTo(val); mutation.mNewAttrValue = NS_Atomize(val); } mozAutoSubtreeModified subtree(OwnerDoc(), this); (new AsyncEventDispatcher(this, mutation))->RunDOMEventWhenSafe(); } } return NS_OK; }
nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength) { return NS_Atomize(nsDependentCSubstring(aString, aLength)).take(); }
nsresult XULSortServiceImpl::InitializeSortState(nsIContent* aRootElement, nsIContent* aContainer, const nsAString& aSortKey, const nsAString& aSortHints, nsSortState* aSortState) { // used as an optimization for the content builder if (aContainer != aSortState->lastContainer.get()) { aSortState->lastContainer = aContainer; aSortState->lastWasFirst = false; aSortState->lastWasLast = false; } // The attributes allowed are either: // sort="key1 key2 ..." // or sortResource="key1" sortResource2="key2" // The latter is for backwards compatibility, and is equivalent to concatenating // both values in the sort attribute nsAutoString sort(aSortKey); aSortState->sortKeys.Clear(); if (sort.IsEmpty()) { nsAutoString sortResource, sortResource2; aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource, sortResource); if (!sortResource.IsEmpty()) { nsCOMPtr<nsIAtom> sortkeyatom = NS_Atomize(sortResource); aSortState->sortKeys.AppendObject(sortkeyatom); sort.Append(sortResource); aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource2, sortResource2); if (!sortResource2.IsEmpty()) { nsCOMPtr<nsIAtom> sortkeyatom2 = NS_Atomize(sortResource2); aSortState->sortKeys.AppendObject(sortkeyatom2); sort.Append(' '); sort.Append(sortResource2); } } } else { nsWhitespaceTokenizer tokenizer(sort); while (tokenizer.hasMoreTokens()) { nsCOMPtr<nsIAtom> keyatom = NS_Atomize(tokenizer.nextToken()); NS_ENSURE_TRUE(keyatom, NS_ERROR_OUT_OF_MEMORY); aSortState->sortKeys.AppendObject(keyatom); } } aSortState->sort.Assign(sort); aSortState->direction = nsSortState_natural; bool noNaturalState = false; nsWhitespaceTokenizer tokenizer(aSortHints); while (tokenizer.hasMoreTokens()) { const nsDependentSubstring& token(tokenizer.nextToken()); if (token.EqualsLiteral("comparecase")) aSortState->sortHints |= nsIXULSortService::SORT_COMPARECASE; else if (token.EqualsLiteral("integer")) aSortState->sortHints |= nsIXULSortService::SORT_INTEGER; else if (token.EqualsLiteral("descending")) aSortState->direction = nsSortState_descending; else if (token.EqualsLiteral("ascending")) aSortState->direction = nsSortState_ascending; else if (token.EqualsLiteral("twostate")) noNaturalState = true; } // if the twostate flag was set, the natural order is skipped and only // ascending and descending are allowed if (aSortState->direction == nsSortState_natural && noNaturalState) { aSortState->direction = nsSortState_ascending; } // set up sort order info aSortState->invertSort = false; nsAutoString existingsort; aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sort, existingsort); nsAutoString existingsortDirection; aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection, existingsortDirection); // if just switching direction, set the invertSort flag if (sort.Equals(existingsort)) { if (aSortState->direction == nsSortState_descending) { if (existingsortDirection.EqualsLiteral("ascending")) aSortState->invertSort = true; } else if (aSortState->direction == nsSortState_ascending && existingsortDirection.EqualsLiteral("descending")) { aSortState->invertSort = true; } } // sort items between separators independently aSortState->inbetweenSeparatorSort = aRootElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::sortSeparators, nsGkAtoms::_true, eCaseMatters); // sort static content (non template generated nodes) after generated content aSortState->sortStaticsLast = aRootElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::sortStaticsLast, nsGkAtoms::_true, eCaseMatters); aSortState->initialized = true; return NS_OK; }