michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: // vim:cindent:ts=2:et:sw=2: michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* implementation of quotes for the CSS 'content' property */ michael@0: michael@0: #include "nsQuoteList.h" michael@0: #include "nsReadableUtils.h" michael@0: #include "nsIContent.h" michael@0: michael@0: bool michael@0: nsQuoteNode::InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame, michael@0: nsIFrame* aTextFrame) michael@0: { michael@0: nsGenConNode::InitTextFrame(aList, aPseudoFrame, aTextFrame); michael@0: michael@0: nsQuoteList* quoteList = static_cast(aList); michael@0: bool dirty = false; michael@0: quoteList->Insert(this); michael@0: if (quoteList->IsLast(this)) michael@0: quoteList->Calc(this); michael@0: else michael@0: dirty = true; michael@0: michael@0: // Don't set up text for 'no-open-quote' and 'no-close-quote'. michael@0: if (IsRealQuote()) { michael@0: aTextFrame->GetContent()->SetText(*Text(), false); michael@0: } michael@0: return dirty; michael@0: } michael@0: michael@0: const nsString* michael@0: nsQuoteNode::Text() michael@0: { michael@0: NS_ASSERTION(mType == eStyleContentType_OpenQuote || michael@0: mType == eStyleContentType_CloseQuote, michael@0: "should only be called when mText should be non-null"); michael@0: const nsStyleQuotes* styleQuotes = mPseudoFrame->StyleQuotes(); michael@0: int32_t quotesCount = styleQuotes->QuotesCount(); // 0 if 'quotes:none' michael@0: int32_t quoteDepth = Depth(); michael@0: michael@0: // Reuse the last pair when the depth is greater than the number of michael@0: // pairs of quotes. (Also make 'quotes: none' and close-quote from michael@0: // a depth of 0 equivalent for the next test.) michael@0: if (quoteDepth >= quotesCount) michael@0: quoteDepth = quotesCount - 1; michael@0: michael@0: const nsString *result; michael@0: if (quoteDepth == -1) { michael@0: // close-quote from a depth of 0 or 'quotes: none' (we want a node michael@0: // with the empty string so dynamic changes are easier to handle) michael@0: result = & EmptyString(); michael@0: } else { michael@0: result = eStyleContentType_OpenQuote == mType michael@0: ? styleQuotes->OpenQuoteAt(quoteDepth) michael@0: : styleQuotes->CloseQuoteAt(quoteDepth); michael@0: } michael@0: return result; michael@0: } michael@0: michael@0: void michael@0: nsQuoteList::Calc(nsQuoteNode* aNode) michael@0: { michael@0: if (aNode == FirstNode()) { michael@0: aNode->mDepthBefore = 0; michael@0: } else { michael@0: aNode->mDepthBefore = Prev(aNode)->DepthAfter(); michael@0: } michael@0: } michael@0: michael@0: void michael@0: nsQuoteList::RecalcAll() michael@0: { michael@0: nsQuoteNode *node = FirstNode(); michael@0: if (!node) michael@0: return; michael@0: michael@0: do { michael@0: int32_t oldDepth = node->mDepthBefore; michael@0: Calc(node); michael@0: michael@0: if (node->mDepthBefore != oldDepth && node->mText && node->IsRealQuote()) michael@0: node->mText->SetData(*node->Text()); michael@0: michael@0: // Next node michael@0: node = Next(node); michael@0: } while (node != FirstNode()); michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: void michael@0: nsQuoteList::PrintChain() michael@0: { michael@0: printf("Chain: \n"); michael@0: if (!FirstNode()) { michael@0: return; michael@0: } michael@0: nsQuoteNode* node = FirstNode(); michael@0: do { michael@0: printf(" %p %d - ", static_cast(node), node->mDepthBefore); michael@0: switch(node->mType) { michael@0: case (eStyleContentType_OpenQuote): michael@0: printf("open"); michael@0: break; michael@0: case (eStyleContentType_NoOpenQuote): michael@0: printf("noOpen"); michael@0: break; michael@0: case (eStyleContentType_CloseQuote): michael@0: printf("close"); michael@0: break; michael@0: case (eStyleContentType_NoCloseQuote): michael@0: printf("noClose"); michael@0: break; michael@0: default: michael@0: printf("unknown!!!"); michael@0: } michael@0: printf(" %d - %d,", node->Depth(), node->DepthAfter()); michael@0: if (node->mText) { michael@0: nsAutoString data; michael@0: node->mText->GetData(data); michael@0: printf(" \"%s\",", NS_ConvertUTF16toUTF8(data).get()); michael@0: } michael@0: printf("\n"); michael@0: node = Next(node); michael@0: } while (node != FirstNode()); michael@0: } michael@0: #endif