static inline void getDecorationRootAndDecoratedRoot(HTMLInputElement* input, ShadowRoot*& decorationRoot, ShadowRoot*& decoratedRoot)
{
    ShadowRoot* existingRoot = input->youngestShadowRoot();
    ShadowRoot* newRoot = 0;
    while (existingRoot->childNodeCount() == 1 && existingRoot->firstChild()->hasTagName(shadowTag)) {
        newRoot = existingRoot;
        existingRoot = existingRoot->olderShadowRoot();
        ASSERT(existingRoot);
    }
    if (newRoot)
        newRoot->removeChild(newRoot->firstChild());
    else
        newRoot = ShadowRoot::create(input, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION).get();
    decorationRoot = newRoot;
    decoratedRoot = existingRoot;
}
void TextFieldDecorationElement::decorate(HTMLInputElement* input, bool visible)
{
    ASSERT(input);
    ShadowRoot* existingRoot;
    ShadowRoot* decorationRoot;
    getDecorationRootAndDecoratedRoot(input, decorationRoot, existingRoot);
    ASSERT(decorationRoot);
    ASSERT(existingRoot);
    RefPtr<HTMLDivElement> box = HTMLDivElement::create(input->document());
    decorationRoot->appendChild(box);
    box->setInlineStyleProperty(CSSPropertyDisplay, CSSValueWebkitBox);
    box->setInlineStyleProperty(CSSPropertyWebkitBoxAlign, CSSValueCenter);
    ASSERT(existingRoot->childNodeCount() == 1);
    toHTMLElement(existingRoot->firstChild())->setInlineStyleProperty(CSSPropertyWebkitBoxFlex, 1.0, CSSPrimitiveValue::CSS_NUMBER);
    box->appendChild(HTMLShadowElement::create(HTMLNames::shadowTag, input->document()));

    setInlineStyleProperty(CSSPropertyDisplay, visible ? CSSValueBlock : CSSValueNone);
    box->appendChild(this);
}
예제 #3
0
static inline void getDecorationRootAndDecoratedRoot(HTMLInputElement* input, ShadowRoot*& decorationRoot, ShadowRoot*& decoratedRoot)
{
    ShadowRoot* existingRoot = input->youngestShadowRoot();
    ShadowRoot* newRoot = 0;
    while (existingRoot->childNodeCount() == 1 && existingRoot->firstChild()->hasTagName(shadowTag)) {
        newRoot = existingRoot;
        existingRoot = existingRoot->olderShadowRoot();
        ASSERT(existingRoot);
    }
    if (newRoot)
        newRoot->removeChild(newRoot->firstChild());
    else {
        // FIXME: This interacts really badly with author shadow roots because now
        // we can interleave user agent and author shadow roots on the element meaning
        // input.shadowRoot may be inaccessible if the browser has decided to decorate
        // the input.
        newRoot = input->ensureShadow()->addShadowRoot(input, ShadowRoot::UserAgentShadowRoot);
    }
    decorationRoot = newRoot;
    decoratedRoot = existingRoot;
}
예제 #4
0
void InPageSearchManager::scopeStringMatches(const String& text, bool reset, bool locateActiveMatchOnly, Frame* scopingFrame)
{
    if (reset) {
        if (!locateActiveMatchOnly) {
            m_activeMatchCount = 0;
            m_scopingComplete = false;
        }
        m_resumeScopingFromRange = 0;
        m_locatingActiveMatch = true;
        m_activeMatchIndex = 0;
        // New search should always start from mainFrame.
        scopeStringMatchesSoon(m_webPage->mainFrame(), text, false /* reset */, locateActiveMatchOnly);
        return;
    }

    if (m_resumeScopingFromRange && scopingFrame != m_resumeScopingFromRange->ownerDocument().frame())
        m_resumeScopingFromRange = 0;

    RefPtr<Range> searchRange(rangeOfContents(scopingFrame->document()));
    Node* originalEndContainer = searchRange->endContainer();
    int originalEndOffset = searchRange->endOffset();
    ExceptionCode ec = 0, ec2 = 0;
    if (m_resumeScopingFromRange) {
        searchRange->setStart(m_resumeScopingFromRange->startContainer(), m_resumeScopingFromRange->startOffset(ec2) + 1, ec);
        if (ec || ec2) {
            m_scopingComplete = true; // We should stop scoping because of some stale data.
            return;
        }
    }

    int matchCount = 0;
    bool timeout = false;
    double startTime = currentTime();
    do {
        RefPtr<Range> resultRange(findPlainText(searchRange.get(), text, m_scopingCaseInsensitive ? CaseInsensitive : 0));
        if (resultRange->collapsed(ec)) {
            if (!resultRange->startContainer()->isInShadowTree())
                break;
            searchRange->setStartAfter(resultRange->startContainer()->deprecatedShadowAncestorNode(), ec);
            searchRange->setEnd(originalEndContainer, originalEndOffset, ec);
            continue;
        }

        ++matchCount;
        bool foundActiveMatch = false;
        if (m_locatingActiveMatch && areRangesEqual(resultRange.get(), m_activeMatch.get())) {
            foundActiveMatch = true;
            m_locatingActiveMatch = false;
            if (locateActiveMatchOnly) {
                m_activeMatchIndex += matchCount;
                m_webPage->m_client->updateFindStringResult(m_activeMatchCount, m_activeMatchIndex);
                return;
            }
            m_activeMatchIndex = m_activeMatchCount + matchCount;
        }
        if (!locateActiveMatchOnly && m_highlightAllMatches)
            resultRange->ownerDocument().markers().addTextMatchMarker(resultRange.get(), foundActiveMatch);

        searchRange->setStart(resultRange->endContainer(ec), resultRange->endOffset(ec), ec);
        ShadowRoot* shadowTreeRoot = searchRange->shadowRoot();
        if (searchRange->collapsed(ec) && shadowTreeRoot)
            searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
        m_resumeScopingFromRange = resultRange;
        timeout = (currentTime() - startTime) >= MaxScopingDuration;
    } while (!timeout);

    if (matchCount > 0) {
        if (locateActiveMatchOnly) {
            // We have not found it yet.
            // m_activeMatchIndex now temporarily remember where we left over in this time slot.
            m_activeMatchIndex += matchCount;
        } else {
            if (m_highlightAllMatches)
                scopingFrame->editor().setMarkedTextMatchesAreHighlighted(true /* highlight */);
            m_activeMatchCount += matchCount;
            m_webPage->m_client->updateFindStringResult(m_activeMatchCount, m_activeMatchIndex);
        }
    }

    if (timeout)
        scopeStringMatchesSoon(scopingFrame, text, false /* reset */, locateActiveMatchOnly);
    else {
        // Scoping is done for this frame.
        Frame* nextFrame = DOMSupport::incrementFrame(scopingFrame, true /* forward */, false /* wrapFlag */);
        if (!nextFrame) {
            m_scopingComplete = true;
            return; // Scoping is done for all frames;
        }
        scopeStringMatchesSoon(nextFrame, text, false /* reset */, locateActiveMatchOnly);
    }
}