⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmltokenizer.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {
        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 );
#ifdef TOKEN_DEBUG
            qDebug("tab pending, prePos: %d, toadd: %d", prePos, p);
#endif

            for ( int x = 0; x < p; x++ )
                *dest++ = QChar(' ');
            prePos += p;
            break;

        case NonePending:
            assert(0);
            break;
        }
    }

    pending = NonePending;
}

void HTMLTokenizer::write(const TokenizerString &str, bool appendData)
{
#ifdef TOKEN_DEBUG
    kdDebug( 6036 ) << this << " Tokenizer::write(\"" << str << "\"," << appendData << ")" << endl;
#endif

    // don't do parsing if there is not enough memory
    OOM_PRE_CHECK( ( src.length() + str.length() ) * 16, 0, "HTMLTokenizer::write" )

    if (!buffer)
        return;

    if (loadStopped)
        return;

    if ( ( m_executingScript && appendData ) || (!cachedScript.isEmpty()
#if NOKIA_CHANGES
        && !parser->doc()->fastDisplayMode()
#endif
        ) ) {
        // don't parse; we will do this later
	if (currentPrependingSrc) {
	    currentPrependingSrc->append(str);
	} else {
	    pendingSrc.append(str);
	}
        return;
    }

    if ( onHold ) {
        src.append(str);
        return;
    }

    if (!src.isEmpty())
        src.append(str);
    else
        setSrc(str);

    // Once a timer is set, it has control of when the tokenizer continues.
    if (timerId)
        return;

    bool wasInWrite = inWrite;
    inWrite = true;

#ifdef INSTRUMENT_LAYOUT_SCHEDULING
    if (!parser->doc()->ownerElement())
        printf("Beginning write at time %d\n", parser->doc()->elapsedTime());
#endif

//     if (Entity)
//         parseEntity(src, dest);

    int processedCount = 0;
    QTime startTime;
    startTime.start();
    KWQUIEventTime eventTime;

    while (!src.isEmpty() && (!parser->doc()->part() || !parser->doc()->part()->isScheduledLocationChangePending())) {
        if (!continueProcessing(processedCount, startTime, eventTime))
            break;

        // do we need to enlarge the buffer?
        RETURN_IF_OOM( 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;
        }
    }

#ifdef INSTRUMENT_LAYOUT_SCHEDULING
    if (!parser->doc()->ownerElement())
        printf("Ending write at time %d\n", parser->doc()->elapsedTime());
#endif

    inWrite = wasInWrite;

    if (noMoreData && !inWrite && !loadingExtScript && !m_executingScript && !timerId)
        end(); // this actually causes us to be deleted

    OOM_POST_CHECK_FAILED( 
        end();
    )
}

void HTMLTokenizer::stopped()
{
    if (timerId) {
        killTimer(timerId);
        timerId = 0;
    }
}

bool HTMLTokenizer::processingData() const
{
    return timerId != 0;
}

bool HTMLTokenizer::continueProcessing(int& processedCount, const QTime& startTime, const KWQUIEventTime& eventTime)
{
    // We don't want to be checking elapsed time with every character, so we only check after we've
    // processed a certain number of characters.
    bool allowedYield = allowYield;
    allowYield = false;
    if (!loadingExtScript && !forceSynchronous && !m_executingScript && (processedCount > TOKENIZER_CHUNK_SIZE || allowedYield)) {
        processedCount = 0;
        if (startTime.elapsed() > TOKENIZER_TIME_DELAY) {
            /* FIXME: We'd like to yield aggressively to give stylesheets the opportunity to
               load, but this hurts overall performance on slower machines.  For now turn this
               off.
            || (!parser->doc()->haveStylesheetsLoaded() &&
                (parser->doc()->documentElement()->id() != ID_HTML || parser->doc()->body()))) {*/
            // Schedule the timer to keep processing as soon as possible.
            if (!timerId)
                timerId = startTimer(0);
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
            if (eventTime.uiEventPending())
                printf("Deferring processing of data because of UI event.\n");
            else if (startTime.elapsed() > TOKENIZER_TIME_DELAY)
                printf("Deferring processing of data because 200ms elapsed away from event loop.\n");
#endif
            return false;
        }
    }

    processedCount++;
    return true;
}

void HTMLTokenizer::timerEvent(QTimerEvent* e)
{
    if (e->timerId() == timerId) {
        // Kill the timer.
        killTimer(timerId);
        timerId = 0;

#ifdef INSTRUMENT_LAYOUT_SCHEDULING
        if (!parser->doc()->ownerElement())
            printf("Beginning timer write at time %d\n", parser->doc()->elapsedTime());
#endif

        if (parser->doc()->view() && parser->doc()->view()-

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -