/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #include #include "COtherDelegate.h" #include "nsScanner.h" #include "nsParserTypes.h" #include "CNavDTD.h" // Note: We already handle the following special case conditions: // 1) If you see , simply treat it as a bad tag. // 2) If you see , treat it like a comment. // 3) If you see <> or <_ (< space) simply treat it as text. // 4) If you see <~ (< followed by non-alpha), treat it as text. static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; /** * Default constructor * * @updated gess 3/25/98 * @param * @return */ COtherDelegate::COtherDelegate() : ITokenizerDelegate(), mTokenDeque() { } /** * Default constructor * * @updated gess 3/25/98 * @param * @return */ COtherDelegate::COtherDelegate(COtherDelegate& aDelegate) : ITokenizerDelegate(), mTokenDeque() { } /** * * @update gess4/11/98 * @param * @return */ eParseMode COtherDelegate::GetParseMode(void) const { return eParseMode_unknown; } /** * Cause delegate to create and return a new DTD. * * @update gess4/22/98 * @return new DTD or null */ nsIDTD* COtherDelegate::GetDTD(void) const{ return new CNavDTD(); } /** * This method is called just after a "<" has been consumed * and we know we're at the start of some kind of tagged * element. We don't know yet if it's a tag or a comment. * * @update gess 3/25/98 * @param * @return */ PRInt32 COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken) { nsAutoString empty(""); PRInt32 result=aScanner.GetChar(aChar); switch(aChar) { case kForwardSlash: PRUnichar ch; result=aScanner.Peek(ch); if(nsString::IsAlpha(ch)) aToken=new CEndToken(empty); else aToken=new CCommentToken(empty); //Special case: is treated as a comment break; case kExclamation: aToken=new CCommentToken(empty); break; default: if(nsString::IsAlpha(aChar)) return ConsumeStartTag(aChar,aScanner,aToken); else if(kEOF!=aChar) { nsAutoString temp("<"); return ConsumeText(temp,aScanner,aToken); } } //switch if(0!=aToken) { result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text... if(result) { delete aToken; aToken=0; } } return result; } /** * This method is called just after we've consumed a start * tag, and we now have to consume its attributes. * * @update gess 3/25/98 * @param aChar: last char read * @param aScanner: see nsScanner.h * @return */ PRInt32 COtherDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,CToken*& aToken) { PRBool done=PR_FALSE; nsAutoString as(""); PRInt32 result=kNoError; while((!done) && (result==kNoError)) { CToken* theToken= new CAttributeToken(as); if(theToken){ result= theToken->Consume(aChar,aScanner); //tell new token to finish consuming text... mTokenDeque.Push(theToken); } aScanner.Peek(aChar); if(aChar==kGreaterThan) { //you just ate the '>' aScanner.GetChar(aChar); //skip the '>' done=PR_TRUE; } } return result; } /** * This is a special case method. It's job is to consume * all of the given tag up to an including the end tag. * * @param aChar: last char read * @param aScanner: see nsScanner.h * @param anErrorCode: arg that will hold error condition * @return new token or null */ PRInt32 COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ //In the case that we just read the given tag, we should go and //consume all the input until we find a matching end tag. nsAutoString endTag(""); aToken=new CSkippedContentToken(endTag); PRInt32 result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text... return result; } /** * This method is called just after a "<" has been consumed * and we know we're at the start of a tag. * * @update gess 3/25/98 * @param aChar: last char read * @param aScanner: see nsScanner.h * @param anErrorCode: arg that will hold error condition * @return new token or null */ PRInt32 COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken) { aToken=new CStartToken(nsAutoString("")); PRInt32 result=kNoError; if(aToken) { result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text... if(((CStartToken*)aToken)->IsAttributed()) { result=ConsumeAttributes(aChar,aScanner,aToken); } //now that that's over with, we have one more problem to solve. //In the case that we just read a