void HTMLLabelElement::defaultEventHandler(Event* evt)
{
    if (evt->type() == EventTypeNames::click && !m_processingClick) {
        RefPtrWillBeRawPtr<HTMLElement> element = control();

        // If we can't find a control or if the control received the click
        // event, then there's no need for us to do anything.
        if (!element || (evt->target() && element->containsIncludingShadowDOM(evt->target()->toNode())))
            return;

        if (evt->target() && isInInteractiveContent(evt->target()->toNode()))
            return;

        //   Behaviour of label element is as follows:
        //     - If there is double click, two clicks will be passed to control
        //       element. Control element will *not* be focused.
        //     - If there is selection of label element by dragging, no click
        //       event is passed. Also, no focus on control element.
        //     - If there is already a selection on label element and then label
        //       is clicked, then click event is passed to control element and
        //       control element is focused.

        bool isLabelTextSelected = false;

        // If the click is not simulated and the text of the label element
        // is selected by dragging over it, then return without passing the
        // click event to control element.
        // Note: check if it is a MouseEvent because a click event may
        // not be an instance of a MouseEvent if created by document.createEvent().
        if (evt->isMouseEvent() && toMouseEvent(evt)->hasPosition()) {
            if (LocalFrame* frame = document().frame()) {
                // Check if there is a selection and click is not on the
                // selection.
                if (layoutObject() && layoutObject()->isSelectable() && frame->selection().isRange() && !frame->eventHandler().selectionController().mouseDownWasSingleClickInSelection())
                    isLabelTextSelected = true;
                // If selection is there and is single click i.e. text is
                // selected by dragging over label text, then return.
                // Click count >=2, meaning double click or triple click,
                // should pass click event to control element.
                // Only in case of drag, *neither* we pass the click event,
                // *nor* we focus the control element.
                if (isLabelTextSelected && frame->eventHandler().clickCount() == 1)
                    return;
            }
        }

        m_processingClick = true;

        document().updateLayoutIgnorePendingStylesheets();
        if (element->isMouseFocusable()) {
            // If the label is *not* selected, or if the click happened on
            // selection of label, only then focus the control element.
            // In case of double click or triple click, selection will be there,
            // so do not focus the control element.
            if (!isLabelTextSelected)
                element->focus(FocusParams(SelectionBehaviorOnFocus::Restore, WebFocusTypeMouse, nullptr));
        }

        // Click the corresponding control.
        element->dispatchSimulatedClick(evt);

        m_processingClick = false;

        evt->setDefaultHandled();
    }

    HTMLElement::defaultEventHandler(evt);
}
PassRefPtrWillBeRawPtr<HTMLLabelElement> HTMLLabelElement::create(Document& document, HTMLFormElement* form)
{
    RefPtrWillBeRawPtr<HTMLLabelElement> labelElement = adoptRefWillBeNoop(new HTMLLabelElement(document, form));
    return labelElement.release();
}
Example #3
0
static PassRefPtrWillBeRawPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> value, v8::Isolate* isolate, bool& succeeded)
{
    succeeded = true;

    // Create default options.
    RefPtrWillBeRawPtr<PositionOptions> options = PositionOptions::create();

    // Argument is optional (hence undefined is allowed), and null is allowed.
    if (isUndefinedOrNull(value)) {
        // Use default options.
        return options.release();
    }

    // Given the above test, this will always yield an object.
    v8::Local<v8::Object> object = value->ToObject();

    // For all three properties, we apply the following ...
    // - If the getter or the property's valueOf method throws an exception, we
    //   quit so as not to risk overwriting the exception.
    // - If the value is absent or undefined, we don't override the default.
    v8::Local<v8::Value> enableHighAccuracyValue = object->Get(v8AtomicString(isolate, "enableHighAccuracy"));
    if (enableHighAccuracyValue.IsEmpty()) {
        succeeded = false;
        return nullptr;
    }
    if (!enableHighAccuracyValue->IsUndefined()) {
        v8::Local<v8::Boolean> enableHighAccuracyBoolean = enableHighAccuracyValue->ToBoolean();
        if (enableHighAccuracyBoolean.IsEmpty()) {
            succeeded = false;
            return nullptr;
        }
        options->setEnableHighAccuracy(enableHighAccuracyBoolean->Value());
    }

    v8::Local<v8::Value> timeoutValue = object->Get(v8AtomicString(isolate, "timeout"));
    if (timeoutValue.IsEmpty()) {
        succeeded = false;
        return nullptr;
    }
    if (!timeoutValue->IsUndefined()) {
        v8::Local<v8::Number> timeoutNumber = timeoutValue->ToNumber();
        if (timeoutNumber.IsEmpty()) {
            succeeded = false;
            return nullptr;
        }
        double timeoutDouble = timeoutNumber->Value();
        // If the value is positive infinity, there's nothing to do.
        if (!(std::isinf(timeoutDouble) && timeoutDouble > 0)) {
            v8::Local<v8::Int32> timeoutInt32 = timeoutValue->ToInt32();
            if (timeoutInt32.IsEmpty()) {
                succeeded = false;
                return nullptr;
            }
            // Wrap to int32 and force non-negative to match behavior of window.setTimeout.
            options->setTimeout(max(0, timeoutInt32->Value()));
        }
    }

    v8::Local<v8::Value> maximumAgeValue = object->Get(v8AtomicString(isolate, "maximumAge"));
    if (maximumAgeValue.IsEmpty()) {
        succeeded = false;
        return nullptr;
    }
    if (!maximumAgeValue->IsUndefined()) {
        v8::Local<v8::Number> maximumAgeNumber = maximumAgeValue->ToNumber();
        if (maximumAgeNumber.IsEmpty()) {
            succeeded = false;
            return nullptr;
        }
        double maximumAgeDouble = maximumAgeNumber->Value();
        if (std::isinf(maximumAgeDouble) && maximumAgeDouble > 0) {
            // If the value is positive infinity, clear maximumAge.
            options->clearMaximumAge();
        } else {
            v8::Local<v8::Int32> maximumAgeInt32 = maximumAgeValue->ToInt32();
            if (maximumAgeInt32.IsEmpty()) {
                succeeded = false;
                return nullptr;
            }
            // Wrap to int32 and force non-negative to match behavior of window.setTimeout.
            options->setMaximumAge(max(0, maximumAgeInt32->Value()));
        }
    }

    return options.release();
}
Example #4
0
PassRefPtrWillBeRawPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
{
    CSSValuePool& pool = cssValuePool();

    RefPtrWillBeRawPtr<CSSBasicShape> basicShapeValue;
    switch (basicShape->type()) {
    case BasicShape::BasicShapeRectangleType: {
        const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
        RefPtrWillBeRawPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();

        rectangleValue->setX(pool.createValue(rectangle->x(), style));
        rectangleValue->setY(pool.createValue(rectangle->y(), style));
        rectangleValue->setWidth(pool.createValue(rectangle->width(), style));
        rectangleValue->setHeight(pool.createValue(rectangle->height(), style));
        rectangleValue->setRadiusX(pool.createValue(rectangle->cornerRadiusX(), style));
        rectangleValue->setRadiusY(pool.createValue(rectangle->cornerRadiusY(), style));

        basicShapeValue = rectangleValue.release();
        break;
    }
    case BasicShape::DeprecatedBasicShapeCircleType: {
        const DeprecatedBasicShapeCircle* circle = static_cast<const DeprecatedBasicShapeCircle*>(basicShape);
        RefPtrWillBeRawPtr<CSSDeprecatedBasicShapeCircle> circleValue = CSSDeprecatedBasicShapeCircle::create();

        circleValue->setCenterX(pool.createValue(circle->centerX(), style));
        circleValue->setCenterY(pool.createValue(circle->centerY(), style));
        circleValue->setRadius(pool.createValue(circle->radius(), style));

        basicShapeValue = circleValue.release();
        break;
    }
    case BasicShape::BasicShapeCircleType: {
        const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
        RefPtrWillBeRawPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();

        circleValue->setCenterX(valueForCenterCoordinate(pool, style, circle->centerX()));
        circleValue->setCenterY(valueForCenterCoordinate(pool, style, circle->centerY()));
        circleValue->setRadius(basicShapeRadiusToCSSValue(pool, style, circle->radius()));
        basicShapeValue = circleValue.release();
        break;
    }
    case BasicShape::DeprecatedBasicShapeEllipseType: {
        const DeprecatedBasicShapeEllipse* ellipse = static_cast<const DeprecatedBasicShapeEllipse*>(basicShape);
        RefPtrWillBeRawPtr<CSSDeprecatedBasicShapeEllipse> ellipseValue = CSSDeprecatedBasicShapeEllipse::create();

        ellipseValue->setCenterX(pool.createValue(ellipse->centerX(), style));
        ellipseValue->setCenterY(pool.createValue(ellipse->centerY(), style));
        ellipseValue->setRadiusX(pool.createValue(ellipse->radiusX(), style));
        ellipseValue->setRadiusY(pool.createValue(ellipse->radiusY(), style));

        basicShapeValue = ellipseValue.release();
        break;
    }
    case BasicShape::BasicShapeEllipseType: {
        const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
        RefPtrWillBeRawPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();

        ellipseValue->setCenterX(valueForCenterCoordinate(pool, style, ellipse->centerX()));
        ellipseValue->setCenterY(valueForCenterCoordinate(pool, style, ellipse->centerY()));
        ellipseValue->setRadiusX(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusX()));
        ellipseValue->setRadiusY(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusY()));
        basicShapeValue = ellipseValue.release();
        break;
    }
    case BasicShape::BasicShapePolygonType: {
        const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape);
        RefPtrWillBeRawPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();

        polygonValue->setWindRule(polygon->windRule());
        const Vector<Length>& values = polygon->values();
        for (unsigned i = 0; i < values.size(); i += 2)
            polygonValue->appendPoint(pool.createValue(values.at(i), style), pool.createValue(values.at(i + 1), style));

        basicShapeValue = polygonValue.release();
        break;
    }
    case BasicShape::BasicShapeInsetRectangleType: {
        const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
        RefPtrWillBeRawPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();

        rectangleValue->setTop(cssValuePool().createValue(rectangle->top()));
        rectangleValue->setRight(cssValuePool().createValue(rectangle->right()));
        rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom()));
        rectangleValue->setLeft(cssValuePool().createValue(rectangle->left()));
        rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
        rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));

        basicShapeValue = rectangleValue.release();
        break;
    }
    case BasicShape::BasicShapeInsetType: {
        const BasicShapeInset* inset = static_cast<const BasicShapeInset*>(basicShape);
        RefPtrWillBeRawPtr<CSSBasicShapeInset> insetValue = CSSBasicShapeInset::create();

        insetValue->setTop(CSSPrimitiveValue::create(inset->top()));
        insetValue->setRight(CSSPrimitiveValue::create(inset->right()));
        insetValue->setBottom(CSSPrimitiveValue::create(inset->bottom()));
        insetValue->setLeft(CSSPrimitiveValue::create(inset->left()));

        insetValue->setTopLeftRadius(CSSPrimitiveValue::create(inset->topLeftRadius()));
        insetValue->setTopRightRadius(CSSPrimitiveValue::create(inset->topRightRadius()));
        insetValue->setBottomRightRadius(CSSPrimitiveValue::create(inset->bottomRightRadius()));
        insetValue->setBottomLeftRadius(CSSPrimitiveValue::create(inset->bottomLeftRadius()));

        basicShapeValue = insetValue.release();
        break;
    }
    default:
        break;
    }

    if (basicShape->layoutBox() != BoxMissing)
        basicShapeValue->setLayoutBox(pool.createValue(basicShape->layoutBox()));

    return pool.createValue(basicShapeValue.release());
}
Example #5
0
TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles)
{
    const RefPtrWillBeRawPtr<Document> document = Document::create();
    const RefPtrWillBeRawPtr<HTMLInputElement> input =
        HTMLInputElement::create(*document, nullptr, false);
    const RefPtrWillBeRawPtr<InputType> fileInput = FileInputType::create(*input);

    const RefPtrWillBeRawPtr<DataObject> nativeFileRawDragData = DataObject::create();
    const DragData nativeFileDragData(nativeFileRawDragData.get(), IntPoint(), IntPoint(), DragOperationCopy);
    nativeFileDragData.platformData()->add(File::create("/native/path"));
    nativeFileDragData.platformData()->setFilesystemId("fileSystemId");
    fileInput->receiveDroppedFiles(&nativeFileDragData);
    EXPECT_EQ("fileSystemId", fileInput->droppedFileSystemId());
    ASSERT_EQ(1u, fileInput->files()->length());
    EXPECT_EQ(String("/native/path"), fileInput->files()->item(0)->path());

    const RefPtrWillBeRawPtr<DataObject> nonNativeFileRawDragData = DataObject::create();
    const DragData nonNativeFileDragData(nonNativeFileRawDragData.get(), IntPoint(), IntPoint(), DragOperationCopy);
    FileMetadata metadata;
    metadata.length = 1234;
    const KURL url(ParsedURLStringTag(), "filesystem:http://example.com/isolated/hash/non-native-file");
    nonNativeFileDragData.platformData()->add(File::createForFileSystemFile(url, metadata, File::IsUserVisible));
    nonNativeFileDragData.platformData()->setFilesystemId("fileSystemId");
    fileInput->receiveDroppedFiles(&nonNativeFileDragData);
    // Dropping non-native files should not change the existing files.
    EXPECT_EQ("fileSystemId", fileInput->droppedFileSystemId());
    ASSERT_EQ(1u, fileInput->files()->length());
    EXPECT_EQ(String("/native/path"), fileInput->files()->item(0)->path());
}
Example #6
0
bool WebFrame::swap(WebFrame* frame)
{
    using std::swap;
    RefPtrWillBeRawPtr<Frame> oldFrame = toCoreFrame(this);

    // All child frames must be detached first.
    oldFrame->detachChildren();

    // If the frame has been detached during detaching its children, return
    // immediately.
    // FIXME: There is no unit test for this condition, so one needs to be
    // written.
    if (!oldFrame->host())
        return false;

    if (m_parent) {
        if (m_parent->m_firstChild == this)
            m_parent->m_firstChild = frame;
        if (m_parent->m_lastChild == this)
            m_parent->m_lastChild = frame;
        swap(m_parent, frame->m_parent);
    }

    if (m_previousSibling) {
        m_previousSibling->m_nextSibling = frame;
        swap(m_previousSibling, frame->m_previousSibling);
    }
    if (m_nextSibling) {
        m_nextSibling->m_previousSibling = frame;
        swap(m_nextSibling, frame->m_nextSibling);
    }

    if (m_opener) {
        m_opener->m_openedFrameTracker->remove(this);
        m_opener->m_openedFrameTracker->add(frame);
        swap(m_opener, frame->m_opener);
    }
    if (!m_openedFrameTracker->isEmpty()) {
        m_openedFrameTracker->updateOpener(frame);
        frame->m_openedFrameTracker.reset(m_openedFrameTracker.release());
    }

    // Finally, clone the state of the current Frame into one matching
    // the type of the passed in WebFrame.
    // FIXME: This is a bit clunky; this results in pointless decrements and
    // increments of connected subframes.
    FrameOwner* owner = oldFrame->owner();
    oldFrame->disconnectOwnerElement();
    if (Frame* newFrame = toCoreFrame(frame)) {
        ASSERT(owner == newFrame->owner());
        if (owner->isLocal()) {
            HTMLFrameOwnerElement* ownerElement = toHTMLFrameOwnerElement(owner);
            ownerElement->setContentFrame(*newFrame);
            if (newFrame->isLocalFrame())
                ownerElement->setWidget(toLocalFrame(newFrame)->view());
        }
    } else if (frame->isWebLocalFrame()) {
        toWebLocalFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name(), nullAtom);
    } else {
        toWebRemoteFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name());
    }

    return true;
}
Example #7
0
void ImageDocument::createDocumentStructure(bool loadingMultipartContent)
{
    RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
    appendChild(rootElement);
    rootElement->insertedByParser();

    if (frame())
        frame()->loader().dispatchDocumentElementAvailable();
    // Normally, ImageDocument creates an HTMLImageElement that doesn't actually load
    // anything, and the ImageDocument routes the main resource data into the HTMLImageElement's
    // ImageResource. However, the main resource pipeline doesn't know how to handle multipart content.
    // For multipart content, we instead stop streaming data through the main resource and re-request
    // the data directly.
    if (loadingMultipartContent)
        loader()->stopLoading();

    RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
    RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
    meta->setAttribute(nameAttr, "viewport");
    meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1");
    head->appendChild(meta);

    RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
    body->setAttribute(styleAttr, "margin: 0px;");

    if (frame())
        frame()->loader().client()->dispatchWillInsertBody();

    m_imageElement = HTMLImageElement::create(*this);
    m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none");
    // If the image is multipart, we neglect to mention to the HTMLImageElement that it's in an
    // ImageDocument, so that it requests the image normally.
    if (!loadingMultipartContent)
        m_imageElement->setLoadingImageDocument();
    m_imageElement->setSrc(url().string());
    body->appendChild(m_imageElement.get());

    if (shouldShrinkToFit()) {
        // Add event listeners
        RefPtrWillBeRawPtr<EventListener> listener = ImageEventListener::create(this);
        if (LocalDOMWindow* domWindow = this->domWindow())
            domWindow->addEventListener("resize", listener, false);
        if (m_shrinkToFitMode == Desktop)
            m_imageElement->addEventListener("click", listener.release(), false);
    }

    rootElement->appendChild(head);
    rootElement->appendChild(body);
    if (loadingMultipartContent)
        finishedParsing();
}
Example #8
0
SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
{
    SMILTime earliestFireTime = SMILTime::unresolved();

#if ENABLE(ASSERT)
    // This boolean will catch any attempts to schedule/unschedule scheduledAnimations during this critical section.
    // Similarly, any elements removed will unschedule themselves, so this will catch modification of animationsToApply.
    m_preventScheduledAnimationsChanges = true;
#endif

    if (m_documentOrderIndexesDirty)
        updateDocumentOrderIndexes();

    WillBeHeapHashSet<ElementAttributePair> invalidKeys;
    using AnimationsVector = WillBeHeapVector<RefPtrWillBeMember<SVGSMILElement>>;
    AnimationsVector animationsToApply;
    for (const auto& entry : m_scheduledAnimations) {
        if (!entry.key.first || entry.value->isEmpty()) {
            invalidKeys.add(entry.key);
            continue;
        }

        AnimationsLinkedHashSet* scheduled = entry.value.get();

        // Sort according to priority. Elements with later begin time have higher priority.
        // In case of a tie, document order decides.
        // FIXME: This should also consider timing relationships between the elements. Dependents
        // have higher priority.
        AnimationsVector scheduledAnimations;
        copyToVector(*scheduled, scheduledAnimations);
        std::sort(scheduledAnimations.begin(), scheduledAnimations.end(), PriorityCompare(elapsed));

        SVGSMILElement* resultElement = nullptr;
        for (const auto& itAnimation : scheduledAnimations) {
            SVGSMILElement* animation = itAnimation.get();
            ASSERT(animation->timeContainer() == this);
            ASSERT(animation->targetElement());
            ASSERT(animation->hasValidAttributeName());

            // Results are accumulated to the first animation that animates and contributes to a particular element/attribute pair.
            // FIXME: we should ensure that resultElement is of an appropriate type.
            if (!resultElement) {
                if (!animation->hasValidAttributeType())
                    continue;
                resultElement = animation;
            }

            // This will calculate the contribution from the animation and add it to the resultsElement.
            if (!animation->progress(elapsed, resultElement, seekToTime) && resultElement == animation)
                resultElement = nullptr;

            SMILTime nextFireTime = animation->nextProgressTime();
            if (nextFireTime.isFinite())
                earliestFireTime = std::min(nextFireTime, earliestFireTime);
        }

        if (resultElement)
            animationsToApply.append(resultElement);
    }
    m_scheduledAnimations.removeAll(invalidKeys);

    std::sort(animationsToApply.begin(), animationsToApply.end(), PriorityCompare(elapsed));

    unsigned animationsToApplySize = animationsToApply.size();
    if (!animationsToApplySize) {
#if ENABLE(ASSERT)
        m_preventScheduledAnimationsChanges = false;
#endif
        return earliestFireTime;
    }

    // Apply results to target elements.
    for (unsigned i = 0; i < animationsToApplySize; ++i)
        animationsToApply[i]->applyResultsToTarget();

#if ENABLE(ASSERT)
    m_preventScheduledAnimationsChanges = false;
#endif

    for (unsigned i = 0; i < animationsToApplySize; ++i) {
        if (animationsToApply[i]->inDocument() && animationsToApply[i]->isSVGDiscardElement()) {
            RefPtrWillBeRawPtr<SVGSMILElement> animDiscard = animationsToApply[i];
            RefPtrWillBeRawPtr<SVGElement> targetElement = animDiscard->targetElement();
            if (targetElement && targetElement->inDocument()) {
                targetElement->remove(IGNORE_EXCEPTION);
                ASSERT(!targetElement->inDocument());
            }

            if (animDiscard->inDocument()) {
                animDiscard->remove(IGNORE_EXCEPTION);
                ASSERT(!animDiscard->inDocument());
            }
        }
    }
    return earliestFireTime;
}
PassRefPtrWillBeRawPtr<Text> GranularityStrategyTest::appendTextNode(const String& data)
{
    RefPtrWillBeRawPtr<Text> text = document().createTextNode(data);
    document().body()->appendChild(text);
    return text.release();
}
Example #10
0
bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode, double* compilationFinishTime)
{
    ASSERT(m_alreadyStarted);

    if (sourceCode.isEmpty())
        return true;

    RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
    RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
    if (!contextDocument)
        return true;

    LocalFrame* frame = contextDocument->frame();

    const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy();
    bool shouldBypassMainWorldCSP = (frame && frame->script().shouldBypassMainWorldCSP())
        || csp->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr))
        || csp->allowScriptWithHash(sourceCode.source());

    if (!m_isExternalScript && (!shouldBypassMainWorldCSP && !csp->allowInlineScript(elementDocument->url(), m_startLineNumber, sourceCode.source()))) {
        return false;
    }

    if (m_isExternalScript) {
        ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.resource();
        if (resource && !resource->mimeTypeAllowedByNosniff()) {
            contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->url().elidedString() + "' because its MIME type ('" + resource->mimeType() + "') is not executable, and strict MIME type checking is enabled."));
            return false;
        }

        if (resource && resource->mimeType().lower().startsWith("image/")) {
            contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->url().elidedString() + "' because its MIME type ('" + resource->mimeType() + "') is not executable."));
            UseCounter::count(frame, UseCounter::BlockedSniffingImageToScript);
            return false;
        }
    }

    // FIXME: Can this be moved earlier in the function?
    // Why are we ever attempting to execute scripts without a frame?
    if (!frame)
        return true;

    AccessControlStatus corsCheck = NotSharableCrossOrigin;
    if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin())))
        corsCheck = SharableCrossOrigin;

    if (m_isExternalScript) {
        const KURL resourceUrl = sourceCode.resource()->resourceRequest().url();
        if (!SubresourceIntegrity::CheckSubresourceIntegrity(*m_element, sourceCode.source(), sourceCode.resource()->url(), *sourceCode.resource())) {
            return false;
        }
    }

    const bool isImportedScript = contextDocument != elementDocument;
    // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block step 2.3
    // with additional support for HTML imports.
    IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_isExternalScript || isImportedScript ? contextDocument.get() : 0);

    if (isHTMLScriptLoader(m_element))
        contextDocument->pushCurrentScript(toHTMLScriptElement(m_element));

    // Create a script from the script element node, using the script
    // block's source and the script block's type.
    // Note: This is where the script is compiled and actually executed.
    frame->script().executeScriptInMainWorld(sourceCode, corsCheck, compilationFinishTime);

    if (isHTMLScriptLoader(m_element)) {
        ASSERT(contextDocument->currentScript() == m_element);
        contextDocument->popCurrentScript();
    }

    return true;
}
bool MediaControls::initializeControls()
{
    TrackExceptionState exceptionState;

    if (document().settings() && document().settings()->mediaControlsOverlayPlayButtonEnabled()) {
        RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(*this);
        RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(*this);
        m_overlayPlayButton = overlayPlayButton.get();
        overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
        if (exceptionState.hadException())
            return false;

        m_overlayEnclosure = overlayEnclosure.get();
        appendChild(overlayEnclosure.release(), exceptionState);
        if (exceptionState.hadException())
            return false;
    }

    // Create an enclosing element for the panel so we can visually offset the controls correctly.
    RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(*this);

    RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(*this);

    RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(*this);
    m_playButton = playButton.get();
    panel->appendChild(playButton.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(*this);
    m_timeline = timeline.get();
    panel->appendChild(timeline.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
    m_currentTimeDisplay = currentTimeDisplay.get();
    m_currentTimeDisplay->hide();
    panel->appendChild(currentTimeDisplay.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
    m_durationDisplay = durationDisplay.get();
    panel->appendChild(durationDisplay.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlMuteButtonElement::create(*this);
    m_muteButton = muteButton.get();
    panel->appendChild(muteButton.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(*this);
    m_volumeSlider = slider.get();
    panel->appendChild(slider.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
    m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
    panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(*this);
    m_fullScreenButton = fullscreenButton.get();
    panel->appendChild(fullscreenButton.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    m_panel = panel.get();
    enclosure->appendChild(panel.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    m_enclosure = enclosure.get();
    appendChild(enclosure.release(), exceptionState);
    if (exceptionState.hadException())
        return false;

    return true;
}
PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::createPropertyForAnimation(const String& value)
{
    if (isAnimatingSVGDom()) {
        // SVG DOM animVal animation code-path.

        if (m_type == AnimatedTransformList) {
            // TransformList must be animated via <animateTransform>,
            // and its {from,by,to} attribute values needs to be parsed w.r.t. its "type" attribute.
            // Spec: http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement
            ASSERT(m_animationElement);
            SVGTransformType transformType = toSVGAnimateTransformElement(m_animationElement)->transformType();
            return SVGTransformList::create(transformType, value);
        }

        ASSERT(m_animatedProperty);
        return m_animatedProperty->currentValueBase()->cloneForAnimation(value);
    }

    ASSERT(isAnimatingCSSProperty());

    // CSS properties animation code-path.
    // Create a basic instance of the corresponding SVG property.
    // The instance will not have full context info. (e.g. SVGLengthMode)

    switch (m_type) {
    case AnimatedColor:
        return SVGColorProperty::create(value.isEmpty() ? StyleColor::currentColor() : CSSParser::colorFromRGBColorString(value));
    case AnimatedNumber: {
        RefPtrWillBeRawPtr<SVGNumber> property = SVGNumber::create();
        property->setValueAsString(value, IGNORE_EXCEPTION);
        return property.release();
    }
    case AnimatedLength: {
        RefPtrWillBeRawPtr<SVGLength> property = SVGLength::create(LengthModeOther);
        property->setValueAsString(value, IGNORE_EXCEPTION);
        return property.release();
    }
    case AnimatedLengthList: {
        RefPtrWillBeRawPtr<SVGLengthList> property = SVGLengthList::create(LengthModeOther);
        property->setValueAsString(value, IGNORE_EXCEPTION);
        return property.release();
    }
    case AnimatedString: {
        RefPtrWillBeRawPtr<SVGString> property = SVGString::create();
        property->setValueAsString(value, IGNORE_EXCEPTION);
        return property.release();
    }

    // These types don't appear in the table in SVGElement::animatedPropertyTypeForCSSAttribute() and thus don't need support.
    case AnimatedAngle:
    case AnimatedBoolean:
    case AnimatedEnumeration:
    case AnimatedInteger:
    case AnimatedIntegerOptionalInteger:
    case AnimatedNumberList:
    case AnimatedNumberOptionalNumber:
    case AnimatedPath:
    case AnimatedPoint:
    case AnimatedPoints:
    case AnimatedPreserveAspectRatio:
    case AnimatedRect:
    case AnimatedStringList:
    case AnimatedTransform:
    case AnimatedTransformList:
        ASSERT_NOT_REACHED();

    case AnimatedUnknown:
        ASSERT_NOT_REACHED();
    };

    ASSERT_NOT_REACHED();
    return nullptr;
}
PassRefPtrWillBeRawPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
{
    RefPtrWillBeRawPtr<HTMLSummaryElement> summary = adoptRefWillBeNoop(new HTMLSummaryElement(document));
    summary->ensureUserAgentShadowRoot();
    return summary.release();
}
TEST_F(AnimationInterpolationEffectTest, MultipleInterpolations)
{
    RefPtrWillBeRawPtr<InterpolationEffect> interpolationEffect = InterpolationEffect::create();
    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(10), InterpolableNumber::create(15)),
        RefPtr<TimingFunction>(), 1, 2, 1, 3);
    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(0), InterpolableNumber::create(1)),
        LinearTimingFunction::shared(), 0, 1, 0, 1);
    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(1), InterpolableNumber::create(6)),
        CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), 0.5, 1.5, 0.5, 1.5);

    OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > activeInterpolations = nullptr;
    interpolationEffect->getActiveInterpolations(-0.5, duration, activeInterpolations);
    EXPECT_EQ(0ul, activeInterpolations->size());

    interpolationEffect->getActiveInterpolations(0, duration, activeInterpolations);
    EXPECT_EQ(1ul, activeInterpolations->size());
    EXPECT_FLOAT_EQ(0, getInterpolableNumber(activeInterpolations->at(0)));

    interpolationEffect->getActiveInterpolations(0.5, duration, activeInterpolations);
    EXPECT_EQ(2ul, activeInterpolations->size());
    EXPECT_FLOAT_EQ(0.5f, getInterpolableNumber(activeInterpolations->at(0)));
    EXPECT_FLOAT_EQ(1, getInterpolableNumber(activeInterpolations->at(1)));

    interpolationEffect->getActiveInterpolations(1, duration, activeInterpolations);
    EXPECT_EQ(2ul, activeInterpolations->size());
    EXPECT_FLOAT_EQ(10, getInterpolableNumber(activeInterpolations->at(0)));
    EXPECT_FLOAT_EQ(5.0282884f, getInterpolableNumber(activeInterpolations->at(1)));

    interpolationEffect->getActiveInterpolations(1, duration * 1000, activeInterpolations);
    EXPECT_EQ(2ul, activeInterpolations->size());
    EXPECT_FLOAT_EQ(10, getInterpolableNumber(activeInterpolations->at(0)));
    EXPECT_FLOAT_EQ(5.0120168f, getInterpolableNumber(activeInterpolations->at(1)));

    interpolationEffect->getActiveInterpolations(1.5, duration, activeInterpolations);
    EXPECT_EQ(1ul, activeInterpolations->size());
    EXPECT_FLOAT_EQ(12.5f, getInterpolableNumber(activeInterpolations->at(0)));

    interpolationEffect->getActiveInterpolations(2, duration, activeInterpolations);
    EXPECT_EQ(1ul, activeInterpolations->size());
    EXPECT_FLOAT_EQ(15, getInterpolableNumber(activeInterpolations->at(0)));
}
Example #15
0
PassRefPtrWillBeRawPtr<StyleRuleKeyframe> CSSParser::parseKeyframeRule(const CSSParserContext& context, const String& rule)
{
    RefPtrWillBeRawPtr<StyleRuleBase> keyframe = CSSParserImpl::parseRule(rule, context, nullptr, CSSParserImpl::KeyframeRules);
    return toStyleRuleKeyframe(keyframe.get());
}
Example #16
0
// This test checks that Documunt::linkManifest() returns a value conform to the specification.
TEST_F(DocumentTest, LinkManifest)
{
    // Test the default result.
    EXPECT_EQ(0, document().linkManifest());

    // Check that we use the first manifest with <link rel=manifest>
    RefPtrWillBeRawPtr<HTMLLinkElement> link = HTMLLinkElement::create(document(), false);
    link->setAttribute(blink::HTMLNames::relAttr, "manifest");
    link->setAttribute(blink::HTMLNames::hrefAttr, "foo.json");
    document().head()->appendChild(link);
    EXPECT_EQ(link, document().linkManifest());

    RefPtrWillBeRawPtr<HTMLLinkElement> link2 = HTMLLinkElement::create(document(), false);
    link2->setAttribute(blink::HTMLNames::relAttr, "manifest");
    link2->setAttribute(blink::HTMLNames::hrefAttr, "bar.json");
    document().head()->insertBefore(link2, link.get());
    EXPECT_EQ(link2, document().linkManifest());
    document().head()->appendChild(link2);
    EXPECT_EQ(link, document().linkManifest());

    // Check that crazy URLs are accepted.
    link->setAttribute(blink::HTMLNames::hrefAttr, "http:foo.json");
    EXPECT_EQ(link, document().linkManifest());

    // Check that empty URLs are accepted.
    link->setAttribute(blink::HTMLNames::hrefAttr, "");
    EXPECT_EQ(link, document().linkManifest());

    // Check that URLs from different origins are accepted.
    link->setAttribute(blink::HTMLNames::hrefAttr, "http://example.org/manifest.json");
    EXPECT_EQ(link, document().linkManifest());
    link->setAttribute(blink::HTMLNames::hrefAttr, "http://foo.example.org/manifest.json");
    EXPECT_EQ(link, document().linkManifest());
    link->setAttribute(blink::HTMLNames::hrefAttr, "http://foo.bar/manifest.json");
    EXPECT_EQ(link, document().linkManifest());

    // More than one token in @rel is accepted.
    link->setAttribute(blink::HTMLNames::relAttr, "foo bar manifest");
    EXPECT_EQ(link, document().linkManifest());

    // Such as spaces around the token.
    link->setAttribute(blink::HTMLNames::relAttr, " manifest ");
    EXPECT_EQ(link, document().linkManifest());

    // Check that rel=manifest actually matters.
    link->setAttribute(blink::HTMLNames::relAttr, "");
    EXPECT_EQ(link2, document().linkManifest());
    link->setAttribute(blink::HTMLNames::relAttr, "manifest");

    // Check that link outside of the <head> are ignored.
    document().head()->removeChild(link.get(), ASSERT_NO_EXCEPTION);
    document().head()->removeChild(link2.get(), ASSERT_NO_EXCEPTION);
    EXPECT_EQ(0, document().linkManifest());
    document().body()->appendChild(link);
    EXPECT_EQ(0, document().linkManifest());
    document().head()->appendChild(link);
    document().head()->appendChild(link2);

    // Check that some attribute values do not have an effect.
    link->setAttribute(blink::HTMLNames::crossoriginAttr, "use-credentials");
    EXPECT_EQ(link, document().linkManifest());
    link->setAttribute(blink::HTMLNames::hreflangAttr, "klingon");
    EXPECT_EQ(link, document().linkManifest());
    link->setAttribute(blink::HTMLNames::typeAttr, "image/gif");
    EXPECT_EQ(link, document().linkManifest());
    link->setAttribute(blink::HTMLNames::sizesAttr, "16x16");
    EXPECT_EQ(link, document().linkManifest());
    link->setAttribute(blink::HTMLNames::mediaAttr, "print");
    EXPECT_EQ(link, document().linkManifest());
}
Example #17
0
void XMLErrors::insertErrorMessageBlock()
{
    // One or more errors occurred during parsing of the code. Display an error block to the user above
    // the normal content (the DOM tree is created manually and includes line/col info regarding
    // where the errors are located)

    // Create elements for display
    RefPtrWillBeRawPtr<Element> documentElement = m_document->documentElement();
    if (!documentElement) {
        RefPtrWillBeRawPtr<Element> rootElement = m_document->createElement(htmlTag, true);
        RefPtrWillBeRawPtr<Element> body = m_document->createElement(bodyTag, true);
        rootElement->parserAppendChild(body);
        m_document->parserAppendChild(rootElement);
        documentElement = body.get();
    } else if (documentElement->namespaceURI() == SVGNames::svgNamespaceURI) {
        RefPtrWillBeRawPtr<Element> rootElement = m_document->createElement(htmlTag, true);
        RefPtrWillBeRawPtr<Element> head = m_document->createElement(headTag, true);
        RefPtrWillBeRawPtr<Element> style = m_document->createElement(styleTag, true);
        head->parserAppendChild(style);
        style->parserAppendChild(m_document->createTextNode("html, body { height: 100% } parsererror + svg { width: 100%; height: 100% }"));
        style->finishParsingChildren();
        rootElement->parserAppendChild(head);
        RefPtrWillBeRawPtr<Element> body = m_document->createElement(bodyTag, true);
        rootElement->parserAppendChild(body);

        m_document->parserRemoveChild(*documentElement);

        body->parserAppendChild(documentElement);
        m_document->parserAppendChild(rootElement);

        documentElement = body.get();
    }

    String errorMessages = m_errorMessages.toString();
    RefPtrWillBeRawPtr<Element> reportElement = createXHTMLParserErrorHeader(m_document, errorMessages);

    if (DocumentXSLT::hasTransformSourceDocument(*m_document)) {
        Vector<Attribute> attributes;
        attributes.append(Attribute(styleAttr, "white-space: normal"));
        RefPtrWillBeRawPtr<Element> paragraph = m_document->createElement(pTag, true);
        paragraph->parserSetAttributes(attributes);
        paragraph->parserAppendChild(m_document->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."));
        reportElement->parserAppendChild(paragraph.release());
    }

    Node* firstChild = documentElement->firstChild();
    if (firstChild)
        documentElement->parserInsertBefore(reportElement, *firstChild);
    else
        documentElement->parserAppendChild(reportElement);

    // FIXME: Why do we need to call this manually?
    m_document->updateRenderTreeIfNeeded();
}
PassRefPtrWillBeRawPtr<HTMLObjectElement> HTMLObjectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
    RefPtrWillBeRawPtr<HTMLObjectElement> element = adoptRefWillBeNoop(new HTMLObjectElement(document, form, createdByParser));
    element->ensureUserAgentShadowRoot();
    return element.release();
}
Example #19
0
void TextFinder::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset)
{
    if (reset) {
        // This is a brand new search, so we need to reset everything.
        // Scoping is just about to begin.
        m_scopingInProgress = true;

        // Need to keep the current identifier locally in order to finish the
        // request in case the frame is detached during the process.
        m_findRequestIdentifier = identifier;

        // Clear highlighting for this frame.
        LocalFrame* frame = ownerFrame().frame();
        if (frame && frame->page() && frame->editor().markedTextMatchesAreHighlighted())
            frame->page()->unmarkAllTextMatches();

        // Clear the tickmarks and results cache.
        clearFindMatchesCache();

        // Clear the counters from last operation.
        m_lastMatchCount = 0;
        m_nextInvalidateAfter = 0;
        m_resumeScopingFromRange = nullptr;

        // The view might be null on detached frames.
        if (frame && frame->page())
            ownerFrame().viewImpl()->mainFrameImpl()->ensureTextFinder().m_framesScopingCount++;

        // Now, defer scoping until later to allow find operation to finish quickly.
        scopeStringMatchesSoon(identifier, searchText, options, false); // false means just reset, so don't do it again.
        return;
    }

    if (!shouldScopeMatches(searchText)) {
        // Note that we want to defer the final update when resetting even if shouldScopeMatches returns false.
        // This is done in order to prevent sending a final message based only on the results of the first frame
        // since m_framesScopingCount would be 0 as other frames have yet to reset.
        finishCurrentScopingEffort(identifier);
        return;
    }

    WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
    Position searchStart = firstPositionInNode(ownerFrame().frame()->document());
    Position searchEnd = lastPositionInNode(ownerFrame().frame()->document());
    ASSERT(searchStart.document() == searchEnd.document());

    if (m_resumeScopingFromRange) {
        // This is a continuation of a scoping operation that timed out and didn't
        // complete last time around, so we should start from where we left off.
        ASSERT(m_resumeScopingFromRange->collapsed());
        searchStart = m_resumeScopingFromRange->endPosition();
        if (searchStart.document() != searchEnd.document())
            return;
    }

    // This timeout controls how long we scope before releasing control. This
    // value does not prevent us from running for longer than this, but it is
    // periodically checked to see if we have exceeded our allocated time.
    const double maxScopingDuration = 0.1; // seconds

    int matchCount = 0;
    bool timedOut = false;
    double startTime = currentTime();
    do {
        // Find next occurrence of the search string.
        // FIXME: (http://crbug.com/6818) This WebKit operation may run for longer
        // than the timeout value, and is not interruptible as it is currently
        // written. We may need to rewrite it with interruptibility in mind, or
        // find an alternative.
        Position resultStart;
        Position resultEnd;
        findPlainText(searchStart, searchEnd, searchText, options.matchCase ? 0 : CaseInsensitive, resultStart, resultEnd);
        if (resultStart == resultEnd) {
            // Not found.
            break;
        }

        RefPtrWillBeRawPtr<Range> resultRange = Range::create(*resultStart.document(), resultStart, resultEnd);
        if (resultRange->collapsed()) {
            // resultRange will be collapsed if the matched text spans over multiple TreeScopes.
            // FIXME: Show such matches to users.
            searchStart = resultEnd;
            continue;
        }

        ++matchCount;

        // Catch a special case where Find found something but doesn't know what
        // the bounding box for it is. In this case we set the first match we find
        // as the active rect.
        IntRect resultBounds = resultRange->boundingBox();
        IntRect activeSelectionRect;
        if (m_locatingActiveRect) {
            activeSelectionRect = m_activeMatch.get() ?
                m_activeMatch->boundingBox() : resultBounds;
        }

        // If the Find function found a match it will have stored where the
        // match was found in m_activeSelectionRect on the current frame. If we
        // find this rect during scoping it means we have found the active
        // tickmark.
        bool foundActiveMatch = false;
        if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) {
            // We have found the active tickmark frame.
            mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &ownerFrame();
            foundActiveMatch = true;
            // We also know which tickmark is active now.
            m_activeMatchIndexInCurrentFrame = matchCount - 1;
            // To stop looking for the active tickmark, we set this flag.
            m_locatingActiveRect = false;

            // Notify browser of new location for the selected rectangle.
            reportFindInPageSelection(
                ownerFrame().frameView()->contentsToWindow(resultBounds),
                m_activeMatchIndexInCurrentFrame + 1,
                identifier);
        }

        addMarker(resultRange.get(), foundActiveMatch);

        m_findMatchesCache.append(FindMatch(resultRange.get(), m_lastMatchCount + matchCount));

        // Set the new start for the search range to be the end of the previous
        // result range. There is no need to use a VisiblePosition here,
        // since findPlainText will use a TextIterator to go over the visible
        // text nodes.
        searchStart = resultEnd;

        m_resumeScopingFromRange = Range::create(*resultStart.document(), resultEnd, resultEnd);
        timedOut = (currentTime() - startTime) >= maxScopingDuration;
    } while (!timedOut);

    // Remember what we search for last time, so we can skip searching if more
    // letters are added to the search string (and last outcome was 0).
    m_lastSearchString = searchText;

    if (matchCount > 0) {
        ownerFrame().frame()->editor().setMarkedTextMatchesAreHighlighted(true);

        m_lastMatchCount += matchCount;

        // Let the mainframe know how much we found during this pass.
        mainFrameImpl->increaseMatchCount(matchCount, identifier);
    }

    if (timedOut) {
        // If we found anything during this pass, we should redraw. However, we
        // don't want to spam too much if the page is extremely long, so if we
        // reach a certain point we start throttling the redraw requests.
        if (matchCount > 0)
            invalidateIfNecessary();

        // Scoping effort ran out of time, lets ask for another time-slice.
        scopeStringMatchesSoon(
            identifier,
            searchText,
            options,
            false); // don't reset.
        return; // Done for now, resume work later.
    }

    finishCurrentScopingEffort(identifier);
}
Example #20
0
PassRefPtrWillBeRawPtr<HTMLOptionElement> HTMLOptionElement::create(Document& document)
{
    RefPtrWillBeRawPtr<HTMLOptionElement> option = adoptRefWillBeNoop(new HTMLOptionElement(document));
    option->ensureUserAgentShadowRoot();
    return option.release();
}
Example #21
0
PassRefPtrWillBeRawPtr<Text> Text::replaceWholeText(const String& newText)
{
    // Remove all adjacent text nodes, and replace the contents of this one.

    // Protect startText and endText against mutation event handlers removing the last ref
    RefPtrWillBeRawPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
    RefPtrWillBeRawPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));

    RefPtrWillBeRawPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
    RefPtrWillBeRawPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal
    for (RefPtrWillBeRawPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
        RefPtrWillBeRawPtr<Node> nodeToRemove(n.release());
        n = nodeToRemove->nextSibling();
        parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
    }

    if (this != endText) {
        Node* onePastEndText = endText->nextSibling();
        for (RefPtrWillBeRawPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
            RefPtrWillBeRawPtr<Node> nodeToRemove(n.release());
            n = nodeToRemove->nextSibling();
            parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
        }
    }

    if (newText.isEmpty()) {
        if (parent && parentNode() == parent)
            parent->removeChild(this, IGNORE_EXCEPTION);
        return nullptr;
    }

    setData(newText);
    return protectedThis.release();
}