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

📄 kwqkhtmlpart.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    // Parallel arrays that we use to cache regExps.  In practice the number of expressions
    // that the app will use is equal to the number of locales is used in searching.
    static const unsigned int regExpCacheSize = 4;
    static NSMutableArray *regExpLabels = nil;
    static QPtrList <QRegExp> regExps;
    static QRegExp wordRegExp = QRegExp("\\w");

    QRegExp *result;
    if (!regExpLabels) {
        regExpLabels = [[NSMutableArray alloc] initWithCapacity:regExpCacheSize];
    }
    unsigned int cacheHit = [regExpLabels indexOfObject:labels];
    if (cacheHit != NSNotFound) {
        result = regExps.at(cacheHit);
    } else {
        QString pattern("(");
        unsigned int numLabels = [labels count];
        unsigned int i;
        for (i = 0; i < numLabels; i++) {
            QString label = QString::fromNSString([labels objectAtIndex:i]);

            bool startsWithWordChar = false;
            bool endsWithWordChar = false;
            if (label.length() != 0) {
                startsWithWordChar = wordRegExp.search(label.at(0)) >= 0;
                endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0;
            }

            if (i != 0) {
                pattern.append("|");
            }
            // Search for word boundaries only if label starts/ends with "word characters".
            // If we always searched for word boundaries, this wouldn't work for languages
            // such as Japanese.
            if (startsWithWordChar) {
                pattern.append("\\b");
            }
            pattern.append(label);
            if (endsWithWordChar) {
                pattern.append("\\b");
            }
        }
        pattern.append(")");
        result = new QRegExp(pattern, false);
    }

    // add regexp to the cache, making sure it is at the front for LRU ordering
    if (cacheHit != 0) {
        if (cacheHit != NSNotFound) {
            // remove from old spot
            [regExpLabels removeObjectAtIndex:cacheHit];
            regExps.remove(cacheHit);
        }
        // add to start
        [regExpLabels insertObject:labels atIndex:0];
        regExps.insert(0, result);
        // trim if too big
        if ([regExpLabels count] > regExpCacheSize) {
            [regExpLabels removeObjectAtIndex:regExpCacheSize];
            QRegExp *last = regExps.last();
            regExps.removeLast();
            delete last;
        }
    }
    return result;
}

NSString *KWQKHTMLPart::searchForLabelsAboveCell(QRegExp *regExp, HTMLTableCellElementImpl *cell)
{
    RenderTableCell *cellRenderer = static_cast<RenderTableCell *>(cell->renderer());
    RenderTableCell *cellAboveRenderer = cellRenderer->table()->cellAbove(cellRenderer);

    if (cellAboveRenderer) {
        HTMLTableCellElementImpl *aboveCell =
            static_cast<HTMLTableCellElementImpl *>(cellAboveRenderer->element());

        if (aboveCell) {
            // search within the above cell we found for a match
            for (NodeImpl *n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) {
                if (idFromNode(n) == ID_TEXT
                    && n->renderer() && n->renderer()->style()->visibility() == VISIBLE)
                {
                    // For each text chunk, run the regexp
                    QString nodeString = n->nodeValue().string();
                    int pos = regExp->searchRev(nodeString);
                    if (pos >= 0) {
                        return nodeString.mid(pos, regExp->matchedLength()).getNSString();
                    }
                }
            }
        }
    }
    // Any reason in practice to search all cells in that are above cell?
    return nil;
}

NSString *KWQKHTMLPart::searchForLabelsBeforeElement(NSArray *labels, ElementImpl *element)
{
    QRegExp *regExp = regExpForLabels(labels);
    // We stop searching after we've seen this many chars
    const unsigned int charsSearchedThreshold = 500;
    // This is the absolute max we search.  We allow a little more slop than
    // charsSearchedThreshold, to make it more likely that we'll search whole nodes.
    const unsigned int maxCharsSearched = 600;
    // If the starting element is within a table, the cell that contains it
    HTMLTableCellElementImpl *startingTableCell = 0;
    bool searchedCellAbove = false;

    // walk backwards in the node tree, until another element, or form, or end of tree
    int unsigned lengthSearched = 0;
    NodeImpl *n;
    for (n = element->traversePreviousNode();
         n && lengthSearched < charsSearchedThreshold;
         n = n->traversePreviousNode())
    {
        NodeImpl::Id nodeID = idFromNode(n);
        if (nodeID == ID_FORM
            || (n->isHTMLElement()
                && static_cast<HTMLElementImpl *>(n)->isGenericFormElement()))
        {
            // We hit another form element or the start of the form - bail out
            break;
        } else if (nodeID == ID_TD && !startingTableCell) {
            startingTableCell = static_cast<HTMLTableCellElementImpl *>(n);
        } else if (nodeID == ID_TR && startingTableCell) {
            NSString *result = searchForLabelsAboveCell(regExp, startingTableCell);
            if (result) {
                return result;
            }
            searchedCellAbove = true;
        } else if (nodeID == ID_TEXT
                   && n->renderer() && n->renderer()->style()->visibility() == VISIBLE)
        {
            // For each text chunk, run the regexp
            QString nodeString = n->nodeValue().string();
            // add 100 for slop, to make it more likely that we'll search whole nodes
            if (lengthSearched + nodeString.length() > maxCharsSearched) {
                nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
            }
            int pos = regExp->searchRev(nodeString);
            if (pos >= 0) {
                return nodeString.mid(pos, regExp->matchedLength()).getNSString();
            } else {
                lengthSearched += nodeString.length();
            }
        }
    }

    // If we started in a cell, but bailed because we found the start of the form or the
    // previous element, we still might need to search the row above us for a label.
    if (startingTableCell && !searchedCellAbove) {
         return searchForLabelsAboveCell(regExp, startingTableCell);
    } else {
        return nil;
    }
}

NSString *KWQKHTMLPart::matchLabelsAgainstElement(NSArray *labels, ElementImpl *element)
{
    QString name = element->getAttribute(ATTR_NAME).string();
    // Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
    name.replace(QRegExp("[[:digit:]]"), " ");
    name.replace('_', ' ');

    QRegExp *regExp = regExpForLabels(labels);
    // Use the largest match we can find in the whole name string
    int pos;
    int length;
    int bestPos = -1;
    int bestLength = -1;
    int start = 0;
    do {
        pos = regExp->search(name, start);
        if (pos != -1) {
            length = regExp->matchedLength();
            if (length >= bestLength) {
                bestPos = pos;
                bestLength = length;
            }
            start = pos+1;
        }
    } while (pos != -1);

    if (bestPos != -1) {
        return name.mid(bestPos, bestLength).getNSString();
    } else {
        return nil;
    }
}

#endif


void KWQKHTMLPart::ClearFind()
{
    // need implementation
    //view()->calcContentPosition(0, 0, INT_MAX, true, true, bool foundInOrigView, QPoint &aToPoint)
    const khtml::Selection noSelection;
    setSelection(noSelection, false);
    d->m_firstFound = noSelection;

}

TInt KWQKHTMLPart::FindStringAgain(const TDesC& str, TBool forward, TBool caseSensitive, TBool wrap)
{
    // update the the first found selection when user issue a findagain.
    // the first found selection is cleared whenever user is changing the
    // keyword.
    if (d->m_firstFound.toRange().collapsed())
    {
        d->m_firstFound = d->m_selection;
    }
    return FindString(str, forward, caseSensitive, wrap, true);
}

// Search from the end of the currently selected location if we are first responder, or from
// the beginning of the document if nothing is selected or we're not first responder.
TInt KWQKHTMLPart::FindString(const TDesC& str, TBool forward, TBool caseSensitive, TBool wrap, TBool sameStr)
{
    TInt result = TBrCtlDefs::EFindNoMatches;
    QString target = QString::FromDes(str);
    if (target.isEmpty())
    {
        ClearFind();
        return result;
    }

    if (!sameStr )
    {
        // clear the first found when keyword changes, set it when a findAgain is invoked
        d->m_firstFound = khtml::Selection();
    }

    // Start on the correct edge of the selection, search to edge of document.
    Range searchRange(xmlDocImpl());
    searchRange.selectNodeContents(xmlDocImpl());

    if (d->m_lastFound.start().node()) {

        NodeImpl * lastStartNode = d->m_lastFound.start().node();
        NodeImpl * lastEndNode = d->m_lastFound.end().node();
        int lastStartOffset = d->m_lastFound.start().offset();
        int lastEndOffset = d->m_lastFound.end().offset();

        if (forward)
            if (sameStr)
                searchRange.setStart(lastEndNode, lastEndOffset);
            else
                searchRange.setStart(lastStartNode, lastStartOffset);
        else
            if (sameStr)
                searchRange.setEnd(lastStartNode, lastStartOffset);
            else
                searchRange.setEnd(lastEndNode, lastEndOffset);
    }

    // Do the search once, then do it a second time to handle wrapped search.
    // Searches some or all of document twice in the failure case, but that's probably OK.
    Range resultRange = khtml::findPlainText(searchRange, target, forward, caseSensitive);
    if (resultRange.collapsed() && wrap) {
        result = TBrCtlDefs::EFindWrapAround;
        searchRange.selectNodeContents(xmlDocImpl());
        resultRange = khtml::findPlainText(searchRange, target, forward, caseSensitive);
    }

    if (resultRange.collapsed()) {
        ClearFind();
        return TBrCtlDefs::EFindNoMatches;
    }
    else
    {
        if (result != TBrCtlDefs::EFindWrapAround)
            result = TBrCtlDefs::EFindMatch;
        // If we got back to the same place we started, that means we found all matches.
        if (resultRange == d->m_firstFound.toRange())
        {
            result = TBrCtlDefs::EFindAllMatches;
            // if the selection is the only occurance in the search range, no need to update.
            if (resultRange == selection().toRange()) {
                return result;
            }
        }
    }

    setSelection(khtml::Selection(resultRange, khtml::DOWNSTREAM, khtml::SEL_PREFER_UPSTREAM_AFFINITY), false);
    d->m_lastFound = d->m_selection;
    //jumpToSelection();

    return result;
}

void KWQKHTMLPart::clearRecordedFormValues()
{

// ### NOT IMPLEMENTED forms
/*
    // It's safe to assume that our own classes and Foundation data
    // structures won't raise exceptions in dealloc

    KWQRelease(_formValuesAboutToBeSubmitted);
    _formValuesAboutToBeSubmitted = nil;
    KWQRelease(_formAboutToBeSubmitted);
    _formAboutToBeSubmitted = nil;
*/
}

void KWQKHTMLPart::recordFormValue(const QString &name, const QString &value, HTMLFormElementImpl *element)
{
// ### NOT IMPLEMENTED forms
/*
    // It's safe to assume that our own classes and basic Foundation
    // data structures won't raise exceptions

    if (!_formValuesAboutToBeSubmitted) {
        _formValuesAboutToBeSubmitted = KWQRetainNSRelease([[NSMutableDictionary alloc] init]);
        ASSERT(!_formAboutToBeSubmitted);
        _formAboutToBeSubmitted = KWQRetain([DOMElement _elementWithImpl:element]);
    } else {
        ASSERT([_formAboutToBeSubmitted _elementImpl] == element);
    }
    [_formValuesAboutToBeSubmitted setObject:value.getNSString() forKey:name.getNSString()];
*/
}

void KWQKHTMLPart::submitForm(const KURL &url, const URLArgs &args)
{
// ### NOT IMPLEMENTED forms
/*
    KWQ_BLOCK_EXCEPTIONS;

    // The form multi-submit logic here is only right when we are submitting a form that affects this frame.
    // Eventually when we find a better fix we can remove this altogether.
    WebCoreBridge *target = args.frameName.isEmpty() ? _bridge : [_bridge findFrameNamed:args.frameName.getNSString()];
    KHTMLPart *targetPart = [target part];
    bool willReplaceThisFrame = false;
    for (KHTMLPart *p = this; p; p = p->parentPart()) {
        if (p == targetPart) {
            willReplaceThisFrame = true;
            break;
        }
    }
    if (willReplaceThisFrame) {
        if (_submittedFormURL == url) {
            return;
        }
        _submittedFormURL = url;
    }*/

    if (!args.doPost()) {
        TEventCode code = EEventNull;
        _bridge->Client().LoadUrl(url.Des(),
                    _bridge->Referrer(), // referrer
                      args.reload, // reload
                      ETrue, //userGesture
                      args.frameName.Des(), //target
     		          code //triggeringEvent
                      );
    } else {
        TEventCode code( EEventNull );
        ASSERT(args.contentType().startsWith("Content-Type: "));

        RArray<TWebCoreFormDataItem> formData;

        WebCoreFromFormData(args.postData, formData);
        _bridge->Client().PostWithURL( url.Des(),
	            _bridge->Referrer(), // referrer
                 args.frameName.Des(), //target
                  formData, // post data
                  args.contentType().mid(14).Des(),
                  code );

		formData.Close();
    }
//    clearRecordedFormValues();

//    KWQ_UNBLOCK_EXCEPTIONS;
}

void KWQKHTMLPart::setEncoding(const QString &name, bool userChosen)
{
    if (!d->m_workingURL.isEmpty()) {
        receivedFirstData();
    }
    d->m_encoding = name;
    d->m_haveEncoding = userChosen;
}

void KWQKHTMLPart::addData(const char *bytes, int length)
{
    ASSERT(d->m_workingURL.isEmpty());
    ASSERT(d->m_doc);
    ASSERT(d->m_doc->parsing());
    write(bytes, length);
}

⌨️ 快捷键说明

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