📄 htmltokenizer.cpp
字号:
int ll = kMin(src.length(), CBUFLEN-cBufferPos); while(ll--) { curchar = *src; if(curchar <= '>') { if(curchar <= ' ' || curchar == '=' || curchar == '>') { unsigned int a; cBuffer[cBufferPos] = '\0'; a = khtml::getAttrID(cBuffer, cBufferPos); if ( !a ) attrName = QString::fromLatin1(QCString(cBuffer, cBufferPos+1).data()); dest = buffer; *dest++ = a;#ifdef TOKEN_DEBUG if (!a || (cBufferPos && *cBuffer == '!')) kdDebug( 6036 ) << "Unknown attribute: *" << QCString(cBuffer, cBufferPos+1).data() << "*" << endl; else kdDebug( 6036 ) << "Known attribute: " << QCString(cBuffer, cBufferPos+1).data() << endl;#endif tag = SearchEqual; break; } } cBuffer[cBufferPos++] = (char) curchar | 0x20; ++src; } if ( cBufferPos == CBUFLEN ) { cBuffer[cBufferPos] = '\0'; attrName = QString::fromLatin1(QCString(cBuffer, cBufferPos+1).data()); dest = buffer; *dest++ = 0; tag = SearchEqual; } break; } case SearchEqual: {#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1 qDebug("SearchEqual");#endif ushort curchar; bool atespace = false; while(src.length()) { curchar = src->unicode(); if(curchar > ' ') { if(curchar == '=') {#ifdef TOKEN_DEBUG kdDebug(6036) << "found equal" << endl;#endif tag = SearchValue; ++src; } else if(atespace && (curchar == '\'' || curchar == '"')) { tag = SearchValue; *dest++ = 0; attrName = QString::null; } else { AttrImpl* a = 0; if(*buffer) a = new AttrImpl(parser->docPtr(), (int)*buffer); else if ( !attrName.isEmpty() && attrName != "/" ) a = new AttrImpl(parser->docPtr(), attrName); if ( a ) { a->setValue(""); currToken.insertAttr(a); } dest = buffer; tag = SearchAttribute; } break; } atespace = true; ++src; } break; } case SearchValue: { ushort curchar; while(src.length()) { curchar = src->unicode(); if(curchar > ' ') { if(( curchar == '\'' || curchar == '\"' )) { tquote = curchar == '\"' ? DoubleQuote : SingleQuote; tag = QuotedValue; ++src; } else tag = Value; break; } ++src; } break; } case QuotedValue: {#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1 qDebug("QuotedValue");#endif ushort curchar; while(src.length()) { checkBuffer(); curchar = src->unicode(); if(curchar <= '\'' && !src.escaped()) { // ### attributes like '&{blaa....};' are supposed to be treated as jscript. if ( curchar == '&' ) { ++src; parseEntity(src, dest, true); break; } else if ( (tquote == SingleQuote && curchar == '\'') || (tquote == DoubleQuote && curchar == '\"') ) { // end of attribute AttrImpl* a; if(*buffer) a = new AttrImpl(parser->docPtr(), (int)*buffer); else a = new AttrImpl(parser->docPtr(), DOMString(attrName)); if(a->attrId || !attrName.isNull()) { // some <input type=hidden> rely on trailing spaces. argh while(dest > buffer+1 && (*(dest-1) == '\n' || *(dest-1) == '\r')) dest--; // remove trailing newlines a->setValue(DOMString(buffer+1, dest-buffer-1)); currToken.insertAttr(a); } else { // hmm, suboptimal, but happens seldom delete a; a = 0; } dest = buffer; tag = SearchAttribute; tquote = NoQuote; ++src; break; } } *dest++ = *src; ++src; } break; } case Value: {#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1 qDebug("Value");#endif ushort curchar; while(src.length()) { checkBuffer(); curchar = src->unicode(); if(curchar <= '>' && !src.escaped()) { // parse Entities if ( curchar == '&' ) { ++src; parseEntity(src, dest, true); break; } // '/' does not delimit in IE! if ( curchar <= ' ' || curchar == '>' ) { // no quotes. Every space means end of value AttrImpl* a; if(*buffer) a = new AttrImpl(parser->docPtr(), (int)*buffer); else a = new AttrImpl(parser->docPtr(), DOMString(attrName)); a->setValue(DOMString(buffer+1, dest-buffer-1)); currToken.insertAttr(a); dest = buffer; tag = SearchAttribute; break; } } *dest++ = *src; ++src; } break; } case SearchEnd: {#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1 qDebug("SearchEnd");#endif while(src.length()) { if(*src == '>') break; ++src; } if(!src.length() && *src != '>') break; searchCount = 0; // Stop looking for '<!--' sequence tag = NoTag; tquote = NoQuote; ++src; if ( !currToken.id ) //stop if tag is unknown return; uint tagID = currToken.id;#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 0 kdDebug( 6036 ) << "appending Tag: " << tagID << endl;#endif bool beginTag = tagID < ID_CLOSE_TAG; if(!beginTag) tagID -= ID_CLOSE_TAG; else if ( beginTag && tagID == ID_SCRIPT ) { AttrImpl* a = 0; scriptSrc = scriptSrcCharset = ""; if ( currToken.attrs && !parser->doc()->view()->part()->onlyLocalReferences()) { if ( ( a = currToken.attrs->getIdItem( ATTR_SRC ) ) ) scriptSrc = parser->doc()->view()->part()->completeURL(khtml::parseURL( a->value() ).string() ).url(); if ( ( a = currToken.attrs->getIdItem( ATTR_CHARSET ) ) ) scriptSrcCharset = a->value().string().stripWhiteSpace(); if ( scriptSrcCharset.isEmpty() ) scriptSrcCharset = parser->doc()->view()->part()->encoding(); a = currToken.attrs->getIdItem( ATTR_LANGUAGE ); } javascript = true; if( a ) { QString lang = a->value().string(); lang = lang.lower(); if( !lang.contains("javascript") && !lang.contains("ecmascript") && !lang.contains("livescript") && !lang.contains("jscript") ) javascript = false; } else { if( currToken.attrs ) a = currToken.attrs->getIdItem(ATTR_TYPE); if( a ) { QString lang = a->value().string(); lang = lang.lower(); if( !lang.contains("javascript") && !lang.contains("ecmascript") && !lang.contains("livescript") && !lang.contains("jscript") ) javascript = false; } } } processToken(); // we have to take care to close the pre block in // case we encounter an unallowed element.... if(pre && beginTag && !DOM::checkChild(ID_PRE, tagID)) { kdDebug(6036) << " not allowed in <pre> " << (int)tagID << endl; pre = false; } switch( tagID ) { case ID_PRE: prePos = 0; pre = beginTag; break; case ID_TEXTAREA: if(beginTag) parseSpecial(src, textarea = true ); break; case ID_SCRIPT: if (beginTag) parseSpecial(src, script = true); break; case ID_STYLE: if (beginTag) parseSpecial(src, style = true); break; case ID_LISTING: if (beginTag) parseSpecial(src, listing = true); break; case ID_SELECT: select = beginTag; break; case ID_PLAINTEXT: plaintext = beginTag; break; } return; // Finished parsing tag! } } // end switch } return;}void HTMLTokenizer::addPending(){ if ( select) { *dest++ = ' '; } else if ( textarea ) { if (pending == LFPending) *dest++ = '\n'; else *dest++ = ' '; } else if ( pre ) { int p; switch (pending) { case SpacePending: // Insert a breaking space *dest++ = QChar(' '); prePos++; break; case LFPending: *dest = '\n'; dest++; prePos = 0; break; case TabPending: p = TAB_SIZE - ( prePos % TAB_SIZE ); for ( int x = 0; x < p; x++ ) { *dest = QChar(' '); dest++; } prePos += p; break; default:#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1 kdDebug( 6036 ) << "Assertion failed: pending = " << (int) pending << endl;#endif break; } } else { *dest++ = ' '; } pending = NonePending;}void HTMLTokenizer::write( const QString &str, bool appendData ){#ifdef TOKEN_DEBUG kdDebug( 6036 ) << "Tokenizer::write(\"" << str << "\"," << appendData << ")" << endl;#endif if ( !buffer ) return; if ( ( m_executingScript && appendData ) || ( !m_executingScript && loadingExtScript ) ) { // don't parse; we will do this later pendingSrc += str; return; } if ( onHold ) { QString rest = QString( src.current(), src.length() ); rest += str; _src = rest; return; } else _src = str; src = DOMStringIt(_src); if (Entity) parseEntity(src, dest); if ( src.length() ) { if (plaintext) parseText(src); else if (script) parseSpecial(src, false); else if (style)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -