PRBool nsCounterManager::AddResetOrIncrement(nsIFrame *aFrame, PRInt32 aIndex, const nsStyleCounterData *aCounterData, nsCounterNode::Type aType) { nsCounterChangeNode *node = new nsCounterChangeNode(aFrame, aType, aCounterData->mValue, aIndex); if (!node) return PR_FALSE; nsCounterList *counterList = CounterListFor(aCounterData->mCounter); if (!counterList) { NS_NOTREACHED("CounterListFor failed (should only happen on OOM)"); return PR_FALSE; } counterList->Insert(node); if (!counterList->IsLast(node)) { // Tell the caller it's responsible for recalculating the entire // list. counterList->SetDirty(); return PR_TRUE; } // Don't call Calc() if the list is already dirty -- it'll be recalculated // anyway, and trying to calculate with a dirty list doesn't work. if (NS_LIKELY(!counterList->IsDirty())) { node->Calc(counterList); } return PR_FALSE; }
nsHtml5OtherDocUpdate(nsIDocument* aCurrentDoc, nsIDocument* aExecutorDoc) { NS_PRECONDITION(aCurrentDoc, "Node has no doc?"); NS_PRECONDITION(aExecutorDoc, "Executor has no doc?"); if (NS_LIKELY(aCurrentDoc == aExecutorDoc)) { mDocument = nsnull; } else { mDocument = aCurrentDoc; aCurrentDoc->BeginUpdate(UPDATE_CONTENT_MODEL); } }
void nsLineBox::NoteFramesMovedFrom(nsLineBox* aFromLine) { PRUint32 fromCount = aFromLine->GetChildCount(); PRUint32 toCount = GetChildCount(); MOZ_ASSERT(toCount <= fromCount, "moved more frames than aFromLine has"); PRUint32 fromNewCount = fromCount - toCount; if (NS_LIKELY(!aFromLine->mFlags.mHasHashedFrames)) { aFromLine->mChildCount = fromNewCount; MOZ_ASSERT(toCount < kMinChildCountForHashtable); } else if (fromNewCount < kMinChildCountForHashtable) { // aFromLine has a hash table but will not have it after moving the frames // so this line can steal the hash table if it needs it. if (toCount >= kMinChildCountForHashtable) { StealHashTableFrom(aFromLine, fromNewCount); } else { delete aFromLine->mFrames; aFromLine->mFlags.mHasHashedFrames = 0; aFromLine->mChildCount = fromNewCount; } } else { // aFromLine still needs a hash table. if (toCount < kMinChildCountForHashtable) { // remove the moved frames from it nsIFrame* f = mFirstChild; for (PRUint32 i = 0; i < toCount; f = f->GetNextSibling(), ++i) { aFromLine->mFrames->RemoveEntry(f); } } else if (toCount <= fromNewCount) { // This line needs a hash table, allocate a hash table for it since that // means fewer hash ops. nsIFrame* f = mFirstChild; for (PRUint32 i = 0; i < toCount; f = f->GetNextSibling(), ++i) { aFromLine->mFrames->RemoveEntry(f); // toCount RemoveEntry } SwitchToHashtable(); // toCount PutEntry } else { // This line needs a hash table, but it's fewer hash ops to steal // aFromLine's hash table and allocate a new hash table for that line. StealHashTableFrom(aFromLine, fromNewCount); // fromNewCount RemoveEntry aFromLine->SwitchToHashtable(); // fromNewCount PutEntry } } }
nscoord nsComboboxControlFrame::GetIntrinsicWidth(nsIRenderingContext* aRenderingContext, nsLayoutUtils::IntrinsicWidthType aType) { // get the scrollbar width, we'll use this later nscoord scrollbarWidth = 0; nsPresContext* presContext = PresContext(); if (mListControlFrame) { nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame); NS_ASSERTION(scrollable, "List must be a scrollable frame"); scrollbarWidth = scrollable->GetDesiredScrollbarSizes(presContext, aRenderingContext).LeftRight(); } nscoord displayWidth = 0; if (NS_LIKELY(mDisplayFrame)) { displayWidth = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, mDisplayFrame, aType); } if (mDropdownFrame) { nscoord dropdownContentWidth; if (aType == nsLayoutUtils::MIN_WIDTH) { dropdownContentWidth = mDropdownFrame->GetMinWidth(aRenderingContext); } else { NS_ASSERTION(aType == nsLayoutUtils::PREF_WIDTH, "Unexpected type"); dropdownContentWidth = mDropdownFrame->GetPrefWidth(aRenderingContext); } dropdownContentWidth = NSCoordSaturatingSubtract(dropdownContentWidth, scrollbarWidth, nscoord_MAX); displayWidth = PR_MAX(dropdownContentWidth, displayWidth); } // add room for the dropmarker button if there is one if (!IsThemed() || presContext->GetTheme()->ThemeNeedsComboboxDropmarker()) displayWidth += scrollbarWidth; return displayWidth; }
// static nsStringBuffer* nsCSSValue::BufferFromString(const nsString& aValue) { nsStringBuffer* buffer = nsStringBuffer::FromString(aValue); if (buffer) { buffer->AddRef(); return buffer; } PRUnichar length = aValue.Length(); buffer = nsStringBuffer::Alloc((length + 1) * sizeof(PRUnichar)); if (NS_LIKELY(buffer != 0)) { PRUnichar* data = static_cast<PRUnichar*>(buffer->Data()); nsCharTraits<PRUnichar>::copy(data, aValue.get(), length); // Null-terminate. data[length] = 0; } return buffer; }
// static already_AddRefed<nsStringBuffer> nsCSSValue::BufferFromString(const nsString& aValue) { nsStringBuffer* buffer = nsStringBuffer::FromString(aValue); if (buffer) { buffer->AddRef(); return buffer; } PRUnichar length = aValue.Length(); // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer. buffer = nsStringBuffer::Alloc((length + 1) * sizeof(PRUnichar)); if (NS_LIKELY(buffer != 0)) { PRUnichar* data = static_cast<PRUnichar*>(buffer->Data()); nsCharTraits<PRUnichar>::copy(data, aValue.get(), length); // Null-terminate. data[length] = 0; } return buffer; }
/** * This method consumes a start tag and all of its attributes. * * @param aChar The last character read from the scanner. * @param aToken The OUT parameter that holds our resulting token. (allocated * by the function using mTokenAllocator * @param aScanner Our source of data * @param aFlushTokens is an OUT parameter use to tell consumers to flush * the current tokens after processing the current one. * @return Error result. */ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar, CToken*& aToken, nsScanner& aScanner, bool& aFlushTokens) { // Remember this for later in case you have to unwind... PRInt32 theDequeSize = mTokenDeque.GetSize(); nsresult result = NS_OK; nsTokenAllocator* theAllocator = this->GetTokenAllocator(); aToken = theAllocator->CreateTokenOfType(eToken_start, eHTMLTag_unknown); NS_ENSURE_TRUE(aToken, NS_ERROR_OUT_OF_MEMORY); // Tell the new token to finish consuming text... result = aToken->Consume(aChar, aScanner, mFlags); if (NS_SUCCEEDED(result)) { AddToken(aToken, result, &mTokenDeque, theAllocator); eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID(); // Good. Now, let's see if the next char is ">". // If so, we have a complete tag, otherwise, we have attributes. result = aScanner.Peek(aChar); if (NS_FAILED(result)) { aToken->SetInError(true); // Don't return early here so we can create a text and end token for // the special <iframe>, <script> and similar tags down below. result = NS_OK; } else { if (kGreaterThan != aChar) { // Look for a '>' result = ConsumeAttributes(aChar, aToken, aScanner); } else { aScanner.GetChar(aChar); } } /* Now that that's over with, we have one more problem to solve. In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and consume all the content itself. But XML doesn't treat these tags differently, so we shouldn't if the document is XML. */ if (NS_SUCCEEDED(result) && !(mFlags & NS_IPARSER_FLAG_XML)) { bool isCDATA = gHTMLElements[theTag].CanContainType(kCDATA); bool isPCDATA = eHTMLTag_textarea == theTag || eHTMLTag_title == theTag; // XXX This is an evil hack, we should be able to handle these properly // in the DTD. if ((eHTMLTag_iframe == theTag && (mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) || (eHTMLTag_noframes == theTag && (mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) || (eHTMLTag_noscript == theTag && (mFlags & NS_IPARSER_FLAG_SCRIPT_ENABLED)) || (eHTMLTag_noembed == theTag)) { isCDATA = true; } // Plaintext contains CDATA, but it's special, so we handle it // differently than the other CDATA elements if (eHTMLTag_plaintext == theTag) { isCDATA = false; // Note: We check in ConsumeToken() for this flag, and if we see it // we only construct text tokens (which is what we want). mFlags |= NS_IPARSER_FLAG_PLAIN_TEXT; } if (isCDATA || isPCDATA) { bool done = false; nsDependentString endTagName(nsHTMLTags::GetStringValue(theTag)); CToken* text = theAllocator->CreateTokenOfType(eToken_text, eHTMLTag_text); NS_ENSURE_TRUE(text, NS_ERROR_OUT_OF_MEMORY); CTextToken* textToken = static_cast<CTextToken*>(text); if (isCDATA) { result = textToken->ConsumeCharacterData(theTag != eHTMLTag_script, aScanner, endTagName, mFlags, done); // Only flush tokens for <script>, to give ourselves more of a // chance of allowing inlines to contain blocks. aFlushTokens = done && theTag == eHTMLTag_script; } else if (isPCDATA) { // Title is consumed conservatively in order to not regress // bug 42945 result = textToken->ConsumeParsedCharacterData( theTag == eHTMLTag_textarea, theTag == eHTMLTag_title, aScanner, endTagName, mFlags, done); // Note: we *don't* set aFlushTokens here. } // We want to do this unless result is kEOF, in which case we will // simply unwind our stack and wait for more data anyway. if (kEOF != result) { AddToken(text, NS_OK, &mTokenDeque, theAllocator); CToken* endToken = nullptr; if (NS_SUCCEEDED(result) && done) { PRUnichar theChar; // Get the < result = aScanner.GetChar(theChar); NS_ASSERTION(NS_SUCCEEDED(result) && theChar == kLessThan, "CTextToken::Consume*Data is broken!"); #ifdef DEBUG // Ensure we have a / PRUnichar tempChar; // Don't change non-debug vars in debug-only code result = aScanner.Peek(tempChar); NS_ASSERTION(NS_SUCCEEDED(result) && tempChar == kForwardSlash, "CTextToken::Consume*Data is broken!"); #endif result = ConsumeEndTag(PRUnichar('/'), endToken, aScanner); if (!(mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) && NS_SUCCEEDED(result)) { // If ConsumeCharacterData returned a success result (and // we're not in view source), then we want to make sure that // we're going to execute this script (since the result means // that we've found an end tag that satisfies all of the right // conditions). endToken->SetInError(false); } } else if (result == kFakeEndTag && !(mFlags & NS_IPARSER_FLAG_VIEW_SOURCE)) { result = NS_OK; endToken = theAllocator->CreateTokenOfType(eToken_end, theTag, endTagName); AddToken(endToken, result, &mTokenDeque, theAllocator); if (NS_LIKELY(endToken != nullptr)) { endToken->SetInError(true); } else { result = NS_ERROR_OUT_OF_MEMORY; } } else if (result == kFakeEndTag) { // If we are here, we are both faking having seen the end tag // and are in view-source. result = NS_OK; } } else { IF_FREE(text, mTokenAllocator); } } } // This code is confusing, so pay attention. // If you're here, it's because we were in the midst of consuming a start // tag but ran out of data (not in the stream, but in this *part* of the // stream. For simplicity, we have to unwind our input. Therefore, we pop // and discard any new tokens we've queued this round. Later we can get // smarter about this. if (NS_FAILED(result)) { while (mTokenDeque.GetSize()>theDequeSize) { CToken* theToken = (CToken*)mTokenDeque.Pop(); IF_FREE(theToken, mTokenAllocator); } } } else { IF_FREE(aToken, mTokenAllocator); } return result; }
/** * This method is called just after we've consumed a start or end * tag, and we now have to consume its attributes. * * @param aChar is the last char read * @param aToken is the start or end tag that "owns" these attributes. * @param aScanner represents our input source * @return Error result. */ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar, CToken* aToken, nsScanner& aScanner) { bool done = false; nsresult result = NS_OK; PRInt16 theAttrCount = 0; nsTokenAllocator* theAllocator = this->GetTokenAllocator(); while (!done && result == NS_OK) { CAttributeToken* theToken = static_cast<CAttributeToken*> (theAllocator->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown)); if (NS_LIKELY(theToken != nullptr)) { // Tell the new token to finish consuming text... result = theToken->Consume(aChar, aScanner, mFlags); if (NS_SUCCEEDED(result)) { ++theAttrCount; AddToken((CToken*&)theToken, result, &mTokenDeque, theAllocator); } else { IF_FREE(theToken, mTokenAllocator); // Bad attribute returns shouldn't propagate out. if (NS_ERROR_HTMLPARSER_BADATTRIBUTE == result) { result = NS_OK; } } } else { result = NS_ERROR_OUT_OF_MEMORY; } #ifdef DEBUG if (NS_SUCCEEDED(result)) { PRInt32 newline = 0; aScanner.SkipWhitespace(newline); NS_ASSERTION(newline == 0, "CAttribute::Consume() failed to collect all the newlines!"); } #endif if (NS_SUCCEEDED(result)) { result = aScanner.Peek(aChar); if (NS_SUCCEEDED(result)) { if (aChar == kGreaterThan) { // You just ate the '>' aScanner.GetChar(aChar); // Skip the '>' done = true; } else if (aChar == kLessThan) { aToken->SetInError(true); done = true; } } } } if (NS_FAILED(result)) { aToken->SetInError(true); if (!aScanner.IsIncremental()) { result = NS_OK; } } aToken->SetAttributeCount(theAttrCount); return result; }
PRBool nsCSSScanner::NextURL(nsCSSToken& aToken) { EatWhiteSpace(); PRInt32 ch = Read(); if (ch < 0) { return PR_FALSE; } // STRING if ((ch == '"') || (ch == '\'')) { #ifdef DEBUG PRBool ok = #endif ParseString(ch, aToken); NS_ABORT_IF_FALSE(ok, "ParseString should never fail, " "since there's always something read"); NS_ABORT_IF_FALSE(aToken.mType == eCSSToken_String || aToken.mType == eCSSToken_Bad_String, "unexpected token type"); if (NS_LIKELY(aToken.mType == eCSSToken_String)) { EatWhiteSpace(); if (LookAheadOrEOF(')')) { aToken.mType = eCSSToken_URL; } else { aToken.mType = eCSSToken_Bad_URL; } } else { aToken.mType = eCSSToken_Bad_URL; } return PR_TRUE; } // Process a url lexical token. A CSS1 url token can contain // characters beyond identifier characters (e.g. '/', ':', etc.) // Because of this the normal rules for tokenizing the input don't // apply very well. To simplify the parser and relax some of the // requirements on the scanner we parse url's here. If we find a // malformed URL then we emit a token of type "Bad_URL" so that // the CSS1 parser can ignore the invalid input. The parser must // treat a Bad_URL token like a Function token, and process // tokens until a matching parenthesis. aToken.mType = eCSSToken_Bad_URL; aToken.mSymbol = PRUnichar(0); nsString& ident = aToken.mIdent; ident.SetLength(0); Pushback(ch); // start of a non-quoted url (which may be empty) PRBool ok = PR_TRUE; for (;;) { ch = Read(); if (ch < 0) break; if (ch == CSS_ESCAPE) { ParseAndAppendEscape(ident); } else if (IsWhitespace(ch)) { // Whitespace is allowed at the end of the URL EatWhiteSpace(); // Consume the close paren if we have it; if not we're an invalid URL. ok = LookAheadOrEOF(')'); break; } else if (ch == '"' || ch == '\'' || ch == '(' || ch < PRUnichar(' ')) { // This is an invalid URL spec ok = PR_FALSE; Pushback(ch); // push it back so the parser can match tokens and // then closing parenthesis break; } else if (ch == ')') { // All done break; } else { // A regular url character. ident.Append(PRUnichar(ch)); } } // If the result of the above scanning is ok then change the token // type to a useful one. if (ok) { aToken.mType = eCSSToken_URL; } return PR_TRUE; }
JSBool WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn) { NS_ASSERTION(XPCPerThreadData::IsMainThread(cx), "Can't do this off the main thread!"); // Our argument should be a wrapped native object, but the caller may have // passed it in as an optimization. JSObject *wrappedObj; if (JSVAL_IS_PRIMITIVE(*vp) || !(wrappedObj = JSVAL_TO_OBJECT(*vp)) || wrappedObj->getClass() == &XOWClass) { return JS_TRUE; } if (!wn && !(wn = XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, wrappedObj))) { return JS_TRUE; } CheckWindow(wn); // The parent must be the inner global object for its scope. parent = JS_GetGlobalForObject(cx, parent); OBJ_TO_INNER_OBJECT(cx, parent); if (!parent) { return JS_FALSE; } XPCWrappedNativeWithXOW *wnxow = nsnull; if (wn->NeedsXOW()) { JSObject *innerWrappedObj = wrappedObj; OBJ_TO_INNER_OBJECT(cx, innerWrappedObj); if (!innerWrappedObj) { return JS_FALSE; } if (innerWrappedObj == parent) { wnxow = static_cast<XPCWrappedNativeWithXOW *>(wn); JSObject *xow = wnxow->GetXOW(); if (xow) { *vp = OBJECT_TO_JSVAL(xow); return JS_TRUE; } } } XPCWrappedNative *parentwn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, parent); XPCWrappedNativeScope *parentScope; if (NS_LIKELY(parentwn)) { parentScope = parentwn->GetScope(); } else { parentScope = XPCWrappedNativeScope::FindInJSObjectScope(cx, parent); } JSObject *outerObj = nsnull; WrappedNative2WrapperMap *map = parentScope->GetWrapperMap(); outerObj = map->Find(wrappedObj); if (outerObj) { NS_ASSERTION(outerObj->getClass() == &XOWClass, "What crazy object are we getting here?"); *vp = OBJECT_TO_JSVAL(outerObj); if (wnxow) { // NB: wnxow->GetXOW() must have returned false. SetFlags(cx, outerObj, AddFlags(GetFlags(cx, outerObj), FLAG_IS_CACHED)); wnxow->SetXOW(outerObj); } return JS_TRUE; } outerObj = JS_NewObjectWithGivenProto(cx, js::Jsvalify(&XOWClass), nsnull, parent); if (!outerObj) { return JS_FALSE; } jsval flags = INT_TO_JSVAL(wnxow ? FLAG_IS_CACHED : 0); if (!JS_SetReservedSlot(cx, outerObj, sWrappedObjSlot, *vp) || !JS_SetReservedSlot(cx, outerObj, sFlagsSlot, flags) || !JS_SetReservedSlot(cx, outerObj, XPC_XOW_ScopeSlot, PRIVATE_TO_JSVAL(parentScope))) { return JS_FALSE; } *vp = OBJECT_TO_JSVAL(outerObj); map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj); if(wnxow) { wnxow->SetXOW(outerObj); } return JS_TRUE; }
// Calculates the codepoint of the UTF8 sequence starting at aStr. Sets aNext // to the byte following the end of the sequence. // // If the sequence is invalid, or if computing the codepoint would take us off // the end of the string (as marked by aEnd), returns -1 and does not set // aNext. Note that this function doesn't check that aStr < aEnd -- it assumes // you've done that already. static NS_ALWAYS_INLINE PRUint32 GetLowerUTF8Codepoint(const char* aStr, const char* aEnd, const char **aNext) { // Convert to unsigned char so that stuffing chars into PRUint32s doesn't // sign extend. const unsigned char *str = (unsigned char*)aStr; if (UTF8traits::isASCII(str[0])) { // It's ASCII; just convert to lower-case and return it. *aNext = aStr + 1; return gASCIIToLower[*str]; } if (UTF8traits::is2byte(str[0]) && NS_LIKELY(aStr + 1 < aEnd)) { // It's a two-byte sequence, so it looks like // 110XXXXX 10XXXXXX. // This is definitely in the BMP, so we can store straightaway into a // PRUint16. PRUint16 c; c = (str[0] & 0x1F) << 6; c += (str[1] & 0x3F); // we don't go through ToLowerCase here, because we know this isn't // an ASCII character so the ASCII fast-path there is useless c = mozilla::unicode::GetLowercase(c); *aNext = aStr + 2; return c; } if (UTF8traits::is3byte(str[0]) && NS_LIKELY(aStr + 2 < aEnd)) { // It's a three-byte sequence, so it looks like // 1110XXXX 10XXXXXX 10XXXXXX. // This will just barely fit into 16-bits, so store into a PRUint16. PRUint16 c; c = (str[0] & 0x0F) << 12; c += (str[1] & 0x3F) << 6; c += (str[2] & 0x3F); c = mozilla::unicode::GetLowercase(c); *aNext = aStr + 3; return c; } if (UTF8traits::is4byte(str[0]) && NS_LIKELY(aStr + 3 < aEnd)) { // It's a four-byte sequence, so it looks like // 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX. PRUint32 c; c = (str[0] & 0x07) << 18; c += (str[1] & 0x3F) << 12; c += (str[2] & 0x3F) << 6; c += (str[3] & 0x3F); c = mozilla::unicode::GetLowercase(c); *aNext = aStr + 4; return c; } // Hm, we don't understand this sequence. return -1; }