void nsXBLPrototypeHandler::ConstructPrototype(nsIContent* aKeyElement, const PRUnichar* aEvent, const PRUnichar* aPhase, const PRUnichar* aAction, const PRUnichar* aCommand, const PRUnichar* aKeyCode, const PRUnichar* aCharCode, const PRUnichar* aModifiers, const PRUnichar* aButton, const PRUnichar* aClickCount, const PRUnichar* aGroup, const PRUnichar* aPreventDefault, const PRUnichar* aAllowUntrusted) { mType = 0; if (aKeyElement) { mType |= NS_HANDLER_TYPE_XUL; nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(aKeyElement); if (!weak) { return; } weak.swap(mHandlerElement); } else { mType |= aCommand ? NS_HANDLER_TYPE_XBL_COMMAND : NS_HANDLER_TYPE_XBL_JS; mHandlerText = nsnull; } mDetail = -1; mMisc = 0; mKeyMask = 0; mPhase = NS_PHASE_BUBBLING; if (aAction) mHandlerText = ToNewUnicode(nsDependentString(aAction)); else if (aCommand) mHandlerText = ToNewUnicode(nsDependentString(aCommand)); nsAutoString event(aEvent); if (event.IsEmpty()) { if (mType & NS_HANDLER_TYPE_XUL) GetEventType(event); if (event.IsEmpty()) return; } mEventName = do_GetAtom(event); if (aPhase) { const nsDependentString phase(aPhase); if (phase.EqualsLiteral("capturing")) mPhase = NS_PHASE_CAPTURING; else if (phase.EqualsLiteral("target")) mPhase = NS_PHASE_TARGET; } // Button and clickcount apply only to XBL handlers and don't apply to XUL key // handlers. if (aButton && *aButton) mDetail = *aButton - '0'; if (aClickCount && *aClickCount) mMisc = *aClickCount - '0'; // Modifiers are supported by both types of handlers (XUL and XBL). nsAutoString modifiers(aModifiers); if (mType & NS_HANDLER_TYPE_XUL) aKeyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers, modifiers); if (!modifiers.IsEmpty()) { mKeyMask = cAllModifiers; char* str = ToNewCString(modifiers); char* newStr; char* token = nsCRT::strtok( str, ", \t", &newStr ); while( token != NULL ) { if (PL_strcmp(token, "shift") == 0) mKeyMask |= cShift | cShiftMask; else if (PL_strcmp(token, "alt") == 0) mKeyMask |= cAlt | cAltMask; else if (PL_strcmp(token, "meta") == 0) mKeyMask |= cMeta | cMetaMask; else if (PL_strcmp(token, "control") == 0) mKeyMask |= cControl | cControlMask; else if (PL_strcmp(token, "accel") == 0) mKeyMask |= KeyToMask(kAccelKey); else if (PL_strcmp(token, "access") == 0) mKeyMask |= KeyToMask(kMenuAccessKey); else if (PL_strcmp(token, "any") == 0) mKeyMask &= ~(mKeyMask << 4); token = nsCRT::strtok( newStr, ", \t", &newStr ); } nsMemory::Free(str); } nsAutoString key(aCharCode); if (key.IsEmpty()) { if (mType & NS_HANDLER_TYPE_XUL) { aKeyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::key, key); if (key.IsEmpty()) aKeyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::charcode, key); } } if (!key.IsEmpty()) { if (mKeyMask == 0) mKeyMask = cAllModifiers; ToLowerCase(key); // We have a charcode. mMisc = 1; mDetail = key[0]; const PRUint8 GTK2Modifiers = cShift | cControl | cShiftMask | cControlMask; if ((mKeyMask & GTK2Modifiers) == GTK2Modifiers && modifiers.First() != PRUnichar(',') && (mDetail == 'u' || mDetail == 'U')) ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "GTK2Conflict"); const PRUint8 WinModifiers = cControl | cAlt | cControlMask | cAltMask; if ((mKeyMask & WinModifiers) == WinModifiers && modifiers.First() != PRUnichar(',') && (('A' <= mDetail && mDetail <= 'Z') || ('a' <= mDetail && mDetail <= 'z'))) ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "WinConflict"); } else { key.Assign(aKeyCode); if (mType & NS_HANDLER_TYPE_XUL) aKeyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, key); if (!key.IsEmpty()) { if (mKeyMask == 0) mKeyMask = cAllModifiers; mDetail = GetMatchingKeyCode(key); } } if (aGroup && nsDependentString(aGroup).EqualsLiteral("system")) mType |= NS_HANDLER_TYPE_SYSTEM; if (aPreventDefault && nsDependentString(aPreventDefault).EqualsLiteral("true")) mType |= NS_HANDLER_TYPE_PREVENTDEFAULT; if (aAllowUntrusted) { mType |= NS_HANDLER_HAS_ALLOW_UNTRUSTED_ATTR; if (nsDependentString(aAllowUntrusted).EqualsLiteral("true")) { mType |= NS_HANDLER_ALLOW_UNTRUSTED; } else { mType &= ~NS_HANDLER_ALLOW_UNTRUSTED; } } }
NS_IMETHODIMP XULContentSinkImpl::HandleStartElement(const PRUnichar *aName, const PRUnichar **aAtts, PRUint32 aAttsCount, PRInt32 aIndex, PRUint32 aLineNumber) { // XXX Hopefully the parser will flag this before we get here. If // we're in the epilog, there should be no new elements NS_PRECONDITION(mState != eInEpilog, "tag in XUL doc epilog"); NS_PRECONDITION(aIndex >= -1, "Bogus aIndex"); NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount"); // Adjust aAttsCount so it's the actual number of attributes aAttsCount /= 2; if (mState == eInEpilog) return NS_ERROR_UNEXPECTED; if (mState != eInScript) { FlushText(); } PRInt32 nameSpaceID; nsCOMPtr<nsIAtom> prefix, localName; nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix), getter_AddRefs(localName), &nameSpaceID); nsCOMPtr<nsINodeInfo> nodeInfo; nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID); NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); nsresult rv = NS_OK; switch (mState) { case eInProlog: // We're the root document element rv = OpenRoot(aAtts, aAttsCount, nodeInfo); break; case eInDocumentElement: rv = OpenTag(aAtts, aAttsCount, aLineNumber, nodeInfo); break; case eInEpilog: case eInScript: PR_LOG(gLog, PR_LOG_WARNING, ("xul: warning: unexpected tags in epilog at line %d", aLineNumber)); rv = NS_ERROR_UNEXPECTED; // XXX break; } // Set the ID attribute atom on the node info object for this node if (aIndex != -1 && NS_SUCCEEDED(rv)) { nsCOMPtr<nsIAtom> IDAttr = do_GetAtom(aAtts[aIndex]); if (IDAttr) { nodeInfo->SetIDAttributeAtom(IDAttr); } } return rv; }
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; }
nsresult nsXBLPrototypeHandler::ExecuteHandler(nsPIDOMEventTarget* aTarget, nsIDOMEvent* aEvent) { nsresult rv = NS_ERROR_FAILURE; // Prevent default action? if (mType & NS_HANDLER_TYPE_PREVENTDEFAULT) { aEvent->PreventDefault(); // If we prevent default, then it's okay for // mHandlerElement and mHandlerText to be null rv = NS_OK; } if (!mHandlerElement) // This works for both types of handlers. In both cases, the union's var should be defined. return rv; // See if our event receiver is a content node (and not us). PRBool isXULKey = !!(mType & NS_HANDLER_TYPE_XUL); PRBool isXBLCommand = !!(mType & NS_HANDLER_TYPE_XBL_COMMAND); NS_ASSERTION(!(isXULKey && isXBLCommand), "can't be both a key and xbl command handler"); // XUL handlers and commands shouldn't be triggered by non-trusted // events. if (isXULKey || isXBLCommand) { nsCOMPtr<nsIDOMNSEvent> domNSEvent = do_QueryInterface(aEvent); PRBool trustedEvent = PR_FALSE; if (domNSEvent) { domNSEvent->GetIsTrusted(&trustedEvent); } if (!trustedEvent) return NS_OK; } if (isXBLCommand) { return DispatchXBLCommand(aTarget, aEvent); } // If we're executing on a XUL key element, just dispatch a command // event at the element. It will take care of retargeting it to its // command element, if applicable, and executing the event handler. if (isXULKey) { return DispatchXULKeyCommand(aEvent); } // Look for a compiled handler on the element. // Should be compiled and bound with "on" in front of the name. nsAutoString onEvent(NS_LITERAL_STRING("onxbl")); nsAutoString str; mEventName->ToString(str); onEvent += str; nsCOMPtr<nsIAtom> onEventAtom = do_GetAtom(onEvent); // Compile the event handler. PRUint32 stID = nsIProgrammingLanguage::JAVASCRIPT; // Compile the handler and bind it to the element. nsCOMPtr<nsIScriptGlobalObject> boundGlobal; nsCOMPtr<nsPIWindowRoot> winRoot(do_QueryInterface(aTarget)); nsCOMPtr<nsIDOMWindow> window; if (winRoot) { window = winRoot->GetWindow(); } if (window) { nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(window)); if (piWin) { piWin = piWin->GetCurrentInnerWindow(); NS_ENSURE_TRUE(piWin, NS_ERROR_UNEXPECTED); } boundGlobal = do_QueryInterface(piWin->GetPrivateRoot()); } else boundGlobal = do_QueryInterface(aTarget); if (!boundGlobal) { nsCOMPtr<nsIDocument> boundDocument(do_QueryInterface(aTarget)); if (!boundDocument) { // We must be an element. nsCOMPtr<nsIContent> content(do_QueryInterface(aTarget)); if (!content) return NS_OK; boundDocument = content->GetOwnerDoc(); if (!boundDocument) return NS_OK; } boundGlobal = boundDocument->GetScriptGlobalObject(); } // If we still don't have a 'boundGlobal', we're doomed. bug 95465. NS_ASSERTION(boundGlobal, "failed to get the nsIScriptGlobalObject. bug 95465?"); if (!boundGlobal) return NS_OK; nsIScriptContext *boundContext = boundGlobal->GetScriptContext(stID); if (!boundContext) return NS_OK; nsScriptObjectHolder handler(boundContext); nsISupports *scriptTarget; if (winRoot) { scriptTarget = boundGlobal; } else { scriptTarget = aTarget; } rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler); NS_ENSURE_SUCCESS(rv, rv); // Temporarily bind it to the bound element void *scope = boundGlobal->GetScriptGlobal(stID); rv = boundContext->BindCompiledEventHandler(scriptTarget, scope, onEventAtom, handler); NS_ENSURE_SUCCESS(rv, rv); // Execute it. nsCOMPtr<nsIDOMEventListener> eventListener; NS_NewJSEventListener(boundContext, scope, scriptTarget, getter_AddRefs(eventListener)); nsCOMPtr<nsIJSEventListener> jsListener(do_QueryInterface(eventListener)); jsListener->SetEventName(onEventAtom); // Handle the event. eventListener->HandleEvent(aEvent); return NS_OK; }
void nsReferencedElement::Reset(nsIContent* aFromContent, nsIURI* aURI, bool aWatch, bool aReferenceImage) { NS_ABORT_IF_FALSE(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->GetCurrentDoc(); 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) { nsRefPtr<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 = do_GetAtom(ref); if (!atom) return; atom.swap(mWatchID); } mReferencingImage = aReferenceImage; HaveNewDocument(doc, aWatch, ref); }
nsresult XULSortServiceImpl::InitializeSortState(nsIContent* aRootElement, nsIContent* aContainer, const nsAString& aSortKey, const nsAString& aSortDirection, nsSortState* aSortState) { // used as an optimization for the content builder if (aContainer != aSortState->lastContainer.get()) { aSortState->lastContainer = aContainer; aSortState->lastWasFirst = PR_FALSE; aSortState->lastWasLast = PR_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 = do_GetAtom(sortResource); aSortState->sortKeys.AppendObject(sortkeyatom); sort.Append(sortResource); aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource2, sortResource2); if (!sortResource2.IsEmpty()) { nsCOMPtr<nsIAtom> sortkeyatom2 = do_GetAtom(sortResource2); aSortState->sortKeys.AppendObject(sortkeyatom2); sort.AppendLiteral(" "); sort.Append(sortResource2); } } } else { PRInt32 start = 0, end = 0; while ((end = sort.FindChar(' ',start)) >= 0) { if (end > start) { nsCOMPtr<nsIAtom> keyatom = do_GetAtom(Substring(sort, start, end - start)); if (!keyatom) return NS_ERROR_OUT_OF_MEMORY; aSortState->sortKeys.AppendObject(keyatom); } start = end + 1; } if (start < (PRInt32)sort.Length()) { nsCOMPtr<nsIAtom> keyatom = do_GetAtom(Substring(sort, start)); if (!keyatom) return NS_ERROR_OUT_OF_MEMORY; aSortState->sortKeys.AppendObject(keyatom); } } aSortState->sort.Assign(sort); // set up sort order info if (aSortDirection.EqualsLiteral("descending")) aSortState->direction = nsSortState_descending; else if (aSortDirection.EqualsLiteral("ascending")) aSortState->direction = nsSortState_ascending; else aSortState->direction = nsSortState_natural; aSortState->invertSort = PR_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 = PR_TRUE; } else if (aSortState->direction == nsSortState_ascending && existingsortDirection.EqualsLiteral("descending")) { aSortState->invertSort = PR_TRUE; } } // sort items between separatore 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 = PR_TRUE; return NS_OK; }
void nsAttrValue::ParseAtomArray(const nsAString& aValue) { nsAString::const_iterator iter, end; aValue.BeginReading(iter); aValue.EndReading(end); // skip initial whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) { ++iter; } if (iter == end) { ResetIfSet(); return; } nsAString::const_iterator start(iter); // get first - and often only - atom do { ++iter; } while (iter != end && !nsCRT::IsAsciiSpace(*iter)); nsCOMPtr<nsIAtom> classAtom = do_GetAtom(Substring(start, iter)); if (!classAtom) { Reset(); return; } // skip whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) { ++iter; } if (iter == end) { // we only found one classname so don't bother storing a list ResetIfSet(); nsIAtom* atom = nsnull; classAtom.swap(atom); SetPtrValueAndType(atom, eAtomBase); return; } if (!EnsureEmptyAtomArray()) { return; } nsCOMArray<nsIAtom>* array = GetAtomArrayValue(); if (!array->AppendObject(classAtom)) { Reset(); return; } // parse the rest of the classnames do { start = iter; do { ++iter; } while (iter != end && !nsCRT::IsAsciiSpace(*iter)); classAtom = do_GetAtom(Substring(start, iter)); if (!array->AppendObject(classAtom)) { Reset(); return; } // skip whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) { ++iter; } } while (iter != end); return; }
nsresult txMozillaXMLOutput::createResultDocument(const nsSubstring& aName, PRInt32 aNsID, nsIDOMDocument* aSourceDocument, nsIDOMDocument* aResultDocument) { nsresult rv; if (!aResultDocument) { // Create the document if (mOutputFormat.mMethod == eHTMLOutput) { rv = NS_NewHTMLDocument(getter_AddRefs(mDocument)); NS_ENSURE_SUCCESS(rv, rv); } else { // We should check the root name/namespace here and create the // appropriate document rv = NS_NewXMLDocument(getter_AddRefs(mDocument)); NS_ENSURE_SUCCESS(rv, rv); } // This should really be handled by nsIDocument::BeginLoad mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_LOADING); nsCOMPtr<nsIDocument> source = do_QueryInterface(aSourceDocument); NS_ENSURE_STATE(source); PRBool hasHadScriptObject = PR_FALSE; nsIScriptGlobalObject* sgo = source->GetScriptHandlingObject(hasHadScriptObject); NS_ENSURE_STATE(sgo || !hasHadScriptObject); mDocument->SetScriptHandlingObject(sgo); } else { mDocument = do_QueryInterface(aResultDocument); } mCurrentNode = mDocument; mNodeInfoManager = mDocument->NodeInfoManager(); // Reset and set up the document URIUtils::ResetWithSource(mDocument, aSourceDocument); // Set the charset if (!mOutputFormat.mEncoding.IsEmpty()) { NS_LossyConvertUTF16toASCII charset(mOutputFormat.mEncoding); nsCAutoString canonicalCharset; nsCOMPtr<nsICharsetAlias> calias = do_GetService("@mozilla.org/intl/charsetalias;1"); if (calias && NS_SUCCEEDED(calias->GetPreferred(charset, canonicalCharset))) { mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent); mDocument->SetDocumentCharacterSet(canonicalCharset); } } // Set the mime-type if (!mOutputFormat.mMediaType.IsEmpty()) { mDocument->SetContentType(mOutputFormat.mMediaType); } else if (mOutputFormat.mMethod == eHTMLOutput) { mDocument->SetContentType(NS_LITERAL_STRING("text/html")); } else { mDocument->SetContentType(NS_LITERAL_STRING("application/xml")); } if (mOutputFormat.mMethod == eXMLOutput && mOutputFormat.mOmitXMLDeclaration != eTrue) { PRInt32 standalone; if (mOutputFormat.mStandalone == eNotSet) { standalone = -1; } else if (mOutputFormat.mStandalone == eFalse) { standalone = 0; } else { standalone = 1; } // Could use mOutputFormat.mVersion.get() when we support // versions > 1.0. static const PRUnichar kOneDotZero[] = { '1', '.', '0', '\0' }; mDocument->SetXMLDeclaration(kOneDotZero, mOutputFormat.mEncoding.get(), standalone); } // Set up script loader of the result document. nsScriptLoader *loader = mDocument->ScriptLoader(); if (mNotifier) { loader->AddObserver(mNotifier); } else { // Don't load scripts, we can't notify the caller when they're loaded. loader->SetEnabled(PR_FALSE); } if (mNotifier) { rv = mNotifier->SetOutputDocument(mDocument); NS_ENSURE_SUCCESS(rv, rv); } // Do this after calling OnDocumentCreated to ensure that the // PresShell/PresContext has been hooked up and get notified. nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument); if (htmlDoc) { htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards); } // Add a doc-type if requested if (!mOutputFormat.mSystemId.IsEmpty()) { nsAutoString qName; if (mOutputFormat.mMethod == eHTMLOutput) { qName.AssignLiteral("html"); } else { qName.Assign(aName); } nsCOMPtr<nsIDOMDocumentType> documentType; nsresult rv = nsContentUtils::CheckQName(qName); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIAtom> doctypeName = do_GetAtom(qName); if (!doctypeName) { return NS_ERROR_OUT_OF_MEMORY; } // Indicate that there is no internal subset (not just an empty one) nsAutoString voidString; voidString.SetIsVoid(PR_TRUE); rv = NS_NewDOMDocumentType(getter_AddRefs(documentType), mNodeInfoManager, nsnull, doctypeName, nsnull, nsnull, mOutputFormat.mPublicId, mOutputFormat.mSystemId, voidString); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIContent> docType = do_QueryInterface(documentType); rv = mDocument->AppendChildTo(docType, PR_TRUE); NS_ENSURE_SUCCESS(rv, rv); } } return NS_OK; }
nsresult txStartElement::execute(txExecutionState& aEs) { nsAutoString name; nsresult rv = mName->evaluateToString(aEs.getEvalContext(), name); NS_ENSURE_SUCCESS(rv, rv); PRInt32 nsId = kNameSpaceID_None; nsCOMPtr<nsIAtom> prefix; PRUint32 lnameStart = 0; const PRUnichar* colon; if (XMLUtils::isValidQName(name, &colon)) { if (colon) { prefix = do_GetAtom(Substring(name.get(), colon)); lnameStart = colon - name.get() + 1; } if (mNamespace) { nsAutoString nspace; rv = mNamespace->evaluateToString(aEs.getEvalContext(), nspace); NS_ENSURE_SUCCESS(rv, rv); if (!nspace.IsEmpty()) { nsId = txNamespaceManager::getNamespaceID(nspace); } } else { nsId = mMappings->lookupNamespace(prefix); } } else { nsId = kNameSpaceID_Unknown; } bool success = true; if (nsId != kNameSpaceID_Unknown) { rv = aEs.mResultHandler->startElement(prefix, Substring(name, lnameStart), nsId); } else { rv = NS_ERROR_XSLT_BAD_NODE_NAME; } if (rv == NS_ERROR_XSLT_BAD_NODE_NAME) { success = false; // we call characters with an empty string to "close" any element to // make sure that no attributes are added rv = aEs.mResultHandler->characters(EmptyString(), false); } NS_ENSURE_SUCCESS(rv, rv); rv = aEs.pushBool(success); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
nsresult txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext, Expr** aExpr) { *aExpr = nsnull; //-- child axis is default LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS; nsAutoPtr<txNodeTest> nodeTest; //-- get Axis Identifier or AbbreviatedStep, if present Token* tok = lexer.peek(); switch (tok->mType) { case Token::AXIS_IDENTIFIER: { //-- eat token lexer.nextToken(); nsCOMPtr<nsIAtom> axis = do_GetAtom(tok->Value()); if (axis == txXPathAtoms::ancestor) { axisIdentifier = LocationStep::ANCESTOR_AXIS; } else if (axis == txXPathAtoms::ancestorOrSelf) { axisIdentifier = LocationStep::ANCESTOR_OR_SELF_AXIS; } else if (axis == txXPathAtoms::attribute) { axisIdentifier = LocationStep::ATTRIBUTE_AXIS; } else if (axis == txXPathAtoms::child) { axisIdentifier = LocationStep::CHILD_AXIS; } else if (axis == txXPathAtoms::descendant) { axisIdentifier = LocationStep::DESCENDANT_AXIS; } else if (axis == txXPathAtoms::descendantOrSelf) { axisIdentifier = LocationStep::DESCENDANT_OR_SELF_AXIS; } else if (axis == txXPathAtoms::following) { axisIdentifier = LocationStep::FOLLOWING_AXIS; } else if (axis == txXPathAtoms::followingSibling) { axisIdentifier = LocationStep::FOLLOWING_SIBLING_AXIS; } else if (axis == txXPathAtoms::_namespace) { axisIdentifier = LocationStep::NAMESPACE_AXIS; } else if (axis == txXPathAtoms::parent) { axisIdentifier = LocationStep::PARENT_AXIS; } else if (axis == txXPathAtoms::preceding) { axisIdentifier = LocationStep::PRECEDING_AXIS; } else if (axis == txXPathAtoms::precedingSibling) { axisIdentifier = LocationStep::PRECEDING_SIBLING_AXIS; } else if (axis == txXPathAtoms::self) { axisIdentifier = LocationStep::SELF_AXIS; } else { return NS_ERROR_XPATH_INVALID_AXIS; } break; } case Token::AT_SIGN: //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::ATTRIBUTE_AXIS; break; case Token::PARENT_NODE : //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::PARENT_AXIS; nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); break; case Token::SELF_NODE : //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::SELF_AXIS; nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); break; default: break; } //-- get NodeTest unless an AbbreviatedStep was found nsresult rv = NS_OK; if (!nodeTest) { tok = lexer.nextToken(); if (tok->mType == Token::CNAME) { // resolve QName nsCOMPtr<nsIAtom> prefix, lName; PRInt32 nspace; rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, PR_TRUE); NS_ENSURE_SUCCESS(rv, rv); nodeTest = new txNameTest(prefix, lName, nspace, axisIdentifier == LocationStep::ATTRIBUTE_AXIS ? txXPathNodeType::ATTRIBUTE_NODE : txXPathNodeType::ELEMENT_NODE); NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); } else { lexer.pushBack(); rv = createNodeTypeTest(lexer, getter_Transfers(nodeTest)); NS_ENSURE_SUCCESS(rv, rv); } } nsAutoPtr<LocationStep> lstep(new LocationStep(nodeTest, axisIdentifier)); NS_ENSURE_TRUE(lstep, NS_ERROR_OUT_OF_MEMORY); nodeTest.forget(); //-- handle predicates rv = parsePredicates(lstep, lexer, aContext); NS_ENSURE_SUCCESS(rv, rv); *aExpr = lstep.forget(); return NS_OK; }
bool EventListenerManager::HasListenersFor(const nsAString& aEventName) { nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventName); return HasListenersFor(atom); }
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 = PR_FALSE; aSortState->lastWasLast = PR_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 = do_GetAtom(sortResource); aSortState->sortKeys.AppendObject(sortkeyatom); sort.Append(sortResource); aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource2, sortResource2); if (!sortResource2.IsEmpty()) { nsCOMPtr<nsIAtom> sortkeyatom2 = do_GetAtom(sortResource2); aSortState->sortKeys.AppendObject(sortkeyatom2); sort.AppendLiteral(" "); sort.Append(sortResource2); } } } else { nsWhitespaceTokenizer tokenizer(sort); while (tokenizer.hasMoreTokens()) { nsCOMPtr<nsIAtom> keyatom = do_GetAtom(tokenizer.nextToken()); NS_ENSURE_TRUE(keyatom, NS_ERROR_OUT_OF_MEMORY); aSortState->sortKeys.AppendObject(keyatom); } } aSortState->sort.Assign(sort); aSortState->direction = nsSortState_natural; PRBool noNaturalState = PR_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 = PR_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 = PR_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 = PR_TRUE; } else if (aSortState->direction == nsSortState_ascending && existingsortDirection.EqualsLiteral("descending")) { aSortState->invertSort = PR_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 = PR_TRUE; return NS_OK; }
// 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. nsCStringKey fromKey(fromStr); SCTableData *fromEdges = (SCTableData*)mAdjacencyList->Get(&fromKey); if (!fromEdges) { // There is no fromStr vertex, create one. nsCStringKey *newFromKey = new nsCStringKey(ToNewCString(fromStr), fromStr.Length(), nsCStringKey::OWN); if (!newFromKey) return NS_ERROR_OUT_OF_MEMORY; SCTableData *data = new SCTableData(newFromKey); if (!data) { delete newFromKey; return NS_ERROR_OUT_OF_MEMORY; } nsCOMArray<nsIAtom>* edgeArray = new nsCOMArray<nsIAtom>; if (!edgeArray) { delete newFromKey; data->key = nullptr; delete data; return NS_ERROR_OUT_OF_MEMORY; } data->data.edges = edgeArray; mAdjacencyList->Put(newFromKey, data); fromEdges = data; } nsCStringKey toKey(toStr); if (!mAdjacencyList->Get(&toKey)) { // There is no toStr vertex, create one. nsCStringKey *newToKey = new nsCStringKey(ToNewCString(toStr), toStr.Length(), nsCStringKey::OWN); if (!newToKey) return NS_ERROR_OUT_OF_MEMORY; SCTableData *data = new SCTableData(newToKey); if (!data) { delete newToKey; return NS_ERROR_OUT_OF_MEMORY; } nsCOMArray<nsIAtom>* edgeArray = new nsCOMArray<nsIAtom>; if (!edgeArray) { delete newToKey; data->key = nullptr; delete data; return NS_ERROR_OUT_OF_MEMORY; } data->data.edges = edgeArray; mAdjacencyList->Put(newToKey, data); } // 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 = do_GetAtom(toStr); if (!vertex) return NS_ERROR_OUT_OF_MEMORY; NS_ASSERTION(fromEdges, "something wrong in adjacency list construction"); if (!fromEdges) return NS_ERROR_FAILURE; nsCOMArray<nsIAtom> *adjacencyList = fromEdges->data.edges; return adjacencyList->AppendObject(vertex) ? NS_OK : NS_ERROR_FAILURE; }
void nsTypeAheadFind::RangeStartsInsideLink(nsIDOMRange *aRange, nsIPresShell *aPresShell, bool *aIsInsideLink, bool *aIsStartingLink) { *aIsInsideLink = false; *aIsStartingLink = true; // ------- Get nsIContent to test ------- nsCOMPtr<nsIDOMNode> startNode; nsCOMPtr<nsIContent> startContent, origContent; aRange->GetStartContainer(getter_AddRefs(startNode)); int32_t startOffset; aRange->GetStartOffset(&startOffset); startContent = do_QueryInterface(startNode); if (!startContent) { NS_NOTREACHED("startContent should never be null"); return; } origContent = startContent; if (startContent->IsElement()) { nsIContent *childContent = startContent->GetChildAt(startOffset); if (childContent) { startContent = childContent; } } else if (startOffset > 0) { const nsTextFragment *textFrag = startContent->GetText(); if (textFrag) { // look for non whitespace character before start offset for (int32_t index = 0; index < startOffset; index++) { // FIXME: take content language into account when deciding whitespace. if (!mozilla::dom::IsSpaceCharacter(textFrag->CharAt(index))) { *aIsStartingLink = false; // not at start of a node break; } } } } // ------- Check to see if inside link --------- // We now have the correct start node for the range // Search for links, starting with startNode, and going up parent chain nsCOMPtr<nsIAtom> tag, hrefAtom(do_GetAtom("href")); nsCOMPtr<nsIAtom> typeAtom(do_GetAtom("type")); while (true) { // Keep testing while startContent is equal to something, // eventually we'll run out of ancestors if (startContent->IsHTMLElement()) { nsCOMPtr<mozilla::dom::Link> link(do_QueryInterface(startContent)); if (link) { // Check to see if inside HTML link *aIsInsideLink = startContent->HasAttr(kNameSpaceID_None, hrefAtom); return; } } else { // Any xml element can be an xlink *aIsInsideLink = startContent->HasAttr(kNameSpaceID_XLink, hrefAtom); if (*aIsInsideLink) { if (!startContent->AttrValueIs(kNameSpaceID_XLink, typeAtom, NS_LITERAL_STRING("simple"), eCaseMatters)) { *aIsInsideLink = false; // Xlink must be type="simple" } return; } } // Get the parent nsCOMPtr<nsIContent> parent = startContent->GetParent(); if (!parent) break; nsIContent* parentsFirstChild = parent->GetFirstChild(); // We don't want to look at a whitespace-only first child if (parentsFirstChild && parentsFirstChild->TextIsOnlyWhitespace()) { parentsFirstChild = parentsFirstChild->GetNextSibling(); } if (parentsFirstChild != startContent) { // startContent wasn't a first child, so we conclude that // if this is inside a link, it's not at the beginning of it *aIsStartingLink = false; } startContent = parent; } *aIsStartingLink = false; }
nsresult txPatternParser::createLocPathPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; MBool isChild = MB_TRUE; MBool isAbsolute = MB_FALSE; txPattern* stepPattern = 0; txLocPathPattern* pathPattern = 0; Token::Type type = aLexer.peek()->mType; switch (type) { case Token::ANCESTOR_OP: isChild = MB_FALSE; isAbsolute = MB_TRUE; aLexer.nextToken(); break; case Token::PARENT_OP: aLexer.nextToken(); isAbsolute = MB_TRUE; if (aLexer.peek()->mType == Token::END || aLexer.peek()->mType == Token::UNION_OP) { aPattern = new txRootPattern(); return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } break; case Token::FUNCTION_NAME_AND_PAREN: // id(Literal) or key(Literal, Literal) { nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(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 (!pathPattern) { delete stepPattern; return NS_ERROR_OUT_OF_MEMORY; } if (isAbsolute) { txRootPattern* root = new txRootPattern(); if (!root) { delete stepPattern; delete pathPattern; return NS_ERROR_OUT_OF_MEMORY; } #ifdef TX_TO_STRING root->setSerialize(PR_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; }