📄 htmltokenizer.cpp
字号:
assert(0); break; } } pending = NonePending;}void HTMLTokenizer::write(const TokenizerString &str, bool appendData){#ifdef TOKEN_DEBUG kdDebug( 6036 ) << this << " Tokenizer::write(\"" << str.toString() << "\"," << appendData << ")" << endl;#endif if ( !buffer ) return; if ( ( m_executingScript && appendData ) || ( !m_executingScript && loadingExtScript ) ) { // don't parse; we will do this later pendingSrc.append(str); return; } if ( onHold ) { src.append(str); return; } setSrc(str);#ifndef NDEBUG inWrite = true;#endif // if (Entity)// parseEntity(src, dest); while (!src.isEmpty()) { // do we need to enlarge the buffer? checkBuffer(); ushort cc = src->unicode(); if (skipLF && (cc != '\n')) skipLF = false; if (skipLF) { skipLF = false; ++src; } else if ( Entity ) parseEntity( src, dest ); else if ( plaintext ) parseText( src ); else if (script) parseSpecial(src); else if (style) parseSpecial(src); else if (xmp) parseSpecial(src); else if (textarea) parseSpecial(src); else if (title) parseSpecial(src); else if (comment) parseComment(src); else if (server) parseServer(src); else if (processingInstruction) parseProcessingInstruction(src); else if (tag) parseTag(src); else if ( startTag ) { startTag = false; switch(cc) { case '/': break; case '!': { // <!-- comment --> searchCount = 1; // Look for '<!--' sequence to start comment break; } case '?': { // xml processing instruction processingInstruction = true; tquote = NoQuote; parseProcessingInstruction(src); continue; break; } case '%': if (!brokenServer) { // <% server stuff, handle as comment %> server = true; tquote = NoQuote; parseServer(src); continue; } // else fall through default: { if( ((cc >= 'a') && (cc <= 'z')) || ((cc >= 'A') && (cc <= 'Z'))) { // Start of a Start-Tag } else { // Invalid tag // Add as is if (pending) addPending(); *dest = '<'; dest++; continue; } } }; // end case if ( pending ) { // pre context always gets its spaces/linefeeds if ( pre || script || (!parser->selectMode() && (!parser->noSpaces() || dest > buffer ))) { addPending(); discard = AllDiscard; // So we discard the first LF after the open tag. } // just forget it else pending = NonePending; } if (cc == '/' && discard == AllDiscard) discard = NoneDiscard; // A close tag. No need to discard LF. processToken(); cBufferPos = 0; tag = TagName; parseTag(src); } else if ( cc == '&' && !src.escaped()) { ++src; if ( pending ) addPending(); parseEntity(src, dest, true); } else if ( cc == '<' && !src.escaped()) { tagStartLineno = lineno+src.lineCount(); ++src; startTag = true; } else if (( cc == '\n' ) || ( cc == '\r' )) { if (select && !script) { if (discard == LFDiscard) { // Ignore this LF discard = NoneDiscard; // We have discarded 1 LF } else if(discard == AllDiscard) { } else { // Process this LF if (pending == NonePending) pending = LFPending; } } else { if (discard == LFDiscard || discard == AllDiscard) { // Ignore this LF discard = NoneDiscard; // We have discarded 1 LF } else { // Process this LF if (pending) addPending(); pending = LFPending; } } /* Check for MS-DOS CRLF sequence */ if (cc == '\r') { skipLF = true; } ++src; } else if (( cc == ' ' ) || ( cc == '\t' )) { if (select && !script) { if(discard == SpaceDiscard) discard = NoneDiscard; else if(discard == AllDiscard) { } else pending = SpacePending; } else { if (discard == AllDiscard) discard = NoneDiscard; if (pending) addPending(); if (cc == ' ') pending = SpacePending; else pending = TabPending; } ++src; } else { if (pending) addPending(); discard = NoneDiscard; if ( pre ) { prePos++; }#if QT_VERSION < 300 unsigned char row = src->row(); if ( row > 0x05 && row < 0x10 || row > 0xfd ) currToken.complexText = true;#endif *dest = *src; fixUpChar( *dest ); ++dest; ++src; } } #ifndef NDEBUG inWrite = false;#endif if (noMoreData && !loadingExtScript && !m_executingScript ) end(); // this actually causes us to be deleted}void HTMLTokenizer::end(){ if ( buffer == 0 ) { parser->finished(); emit finishedParsing(); return; } // parseTag is using the buffer for different matters if ( !tag ) processToken(); if(buffer) KHTML_DELETE_QCHAR_VEC(buffer); if(scriptCode) KHTML_DELETE_QCHAR_VEC(scriptCode); scriptCode = 0; scriptCodeSize = scriptCodeMaxSize = scriptCodeResync = 0; buffer = 0; parser->finished(); emit finishedParsing();}void HTMLTokenizer::finish(){ // do this as long as we don't find matching comment ends while((comment || server) && scriptCode && scriptCodeSize) { // we've found an unmatched comment start if (comment) brokenComments = true; else brokenServer = true; checkScriptBuffer(); scriptCode[ scriptCodeSize ] = 0; scriptCode[ scriptCodeSize + 1 ] = 0; int pos; QString food; if (script || style) { food.setUnicode(scriptCode, scriptCodeSize); } else if (server) { food = "<"; food += QString(scriptCode, scriptCodeSize); } else { pos = QConstString(scriptCode, scriptCodeSize).string().find('>'); food.setUnicode(scriptCode+pos+1, scriptCodeSize-pos-1); // deep copy } KHTML_DELETE_QCHAR_VEC(scriptCode); scriptCode = 0; scriptCodeSize = scriptCodeMaxSize = scriptCodeResync = 0; comment = server = false; if ( !food.isEmpty() ) write(food, true); } // this indicates we will not recieve any more data... but if we are waiting on // an external script to load, we can't finish parsing until that is done noMoreData = true; if (!loadingExtScript && !m_executingScript && !onHold) end(); // this actually causes us to be deleted}void HTMLTokenizer::processToken(){ KJSProxy *jsProxy = (view && view->part()) ? view->part()->jScript() : 0L; if (jsProxy) jsProxy->setEventHandlerLineno(tagStartLineno); if ( dest > buffer ) {#ifdef TOKEN_DEBUG if(currToken.id) { qDebug( "unexpected token id: %d, str: *%s*", currToken.id,QConstString( buffer,dest-buffer ).string().latin1() ); assert(0); }#endif currToken.text = new DOMStringImpl( buffer, dest - buffer ); currToken.text->ref(); currToken.id = ID_TEXT; } else if(!currToken.id) { currToken.reset(); if (jsProxy) jsProxy->setEventHandlerLineno(lineno+src.lineCount()); return; } dest = buffer;#ifdef TOKEN_DEBUG QString name = getTagName(currToken.id).string(); QString text; if(currToken.text) text = QConstString(currToken.text->s, currToken.text->l).string(); kdDebug( 6036 ) << "Token --> " << name << " id = " << currToken.id << endl; if (currToken.flat) kdDebug( 6036 ) << "Token is FLAT!" << endl; if(!text.isNull()) kdDebug( 6036 ) << "text: \"" << text << "\"" << endl; unsigned long l = currToken.attrs ? currToken.attrs->length() : 0; if(l) { kdDebug( 6036 ) << "Attributes: " << static_cast<int>(l) << endl; for (unsigned long i = 0; i < l; ++i) { AttributeImpl* c = currToken.attrs->attributeItem(i); kdDebug( 6036 ) << " " << c->id() << " " << parser->doc()->getDocument()->attrName(c->id()).string() << "=\"" << c->value().string() << "\"" << endl; } } kdDebug( 6036 ) << endl;#endif // pass the token over to the parser, the parser DOES NOT delete the token parser->parseToken(&currToken); currToken.reset(); if (jsProxy) jsProxy->setEventHandlerLineno(0);}HTMLTokenizer::~HTMLTokenizer(){ assert(!inWrite); reset(); delete parser;}void HTMLTokenizer::enlargeBuffer(int len){ int newsize = kMax(size*2, size+len); int oldoffs = (dest - buffer); buffer = (QChar*)realloc(buffer, newsize*sizeof(QChar)); dest = buffer + oldoffs; size = newsize;}void HTMLTokenizer::enlargeScriptBuffer(int len){ int newsize = kMax(scriptCodeMaxSize*2, scriptCodeMaxSize+len); scriptCode = (QChar*)realloc(scriptCode, newsize*sizeof(QChar)); scriptCodeMaxSize = newsize;}void HTMLTokenizer::notifyFinished(CachedObject */*finishedObj*/){ assert(!cachedScript.isEmpty()); bool finished = false; while (!finished && cachedScript.head()->isLoaded()) {#ifdef TOKEN_DEBUG kdDebug( 6036 ) << "Finished loading an external script" << endl;#endif CachedScript* cs = cachedScript.dequeue(); DOMString scriptSource = cs->script();#ifdef TOKEN_DEBUG kdDebug( 6036 ) << "External script is:" << endl << scriptSource.string() << endl;#endif setSrc(TokenizerString()); // make sure we forget about the script before we execute the new one // infinite recursion might happen otherwise QString cachedScriptUrl( cs->url().string() ); cs->deref(this); scriptExecution( scriptSource.string(), cachedScriptUrl ); // cachedScript.isEmpty() can change inside the scriptExecution() call above, // so don't test it until afterwards. finished = cachedScript.isEmpty(); if (finished) loadingExtScript = false; // 'script' is true when we are called synchronously from // parseScript(). In that case parseScript() will take care // of 'scriptOutput'. if ( !script ) { TokenizerString rest = pendingSrc; pendingSrc.clear(); write(rest, false); // we might be deleted at this point, do not // access any members. } }}bool HTMLTokenizer::isWaitingForScripts(){ return loadingExtScript;}void HTMLTokenizer::setSrc(const TokenizerString &source){ lineno += src.lineCount(); src = source; src.resetLineCount();}void HTMLTokenizer::setOnHold(bool _onHold){ if (onHold == _onHold) return; onHold = _onHold;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -