void V8Clipboard::setDragImageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& args)
{
    Clipboard* clipboard = V8Clipboard::toNative(args.Holder());

    if (!clipboard->isForDragAndDrop())
        return;

    if (args.Length() != 3) {
        throwError(v8SyntaxError, "setDragImage: Invalid number of arguments", args.GetIsolate());
        return;
    }

    int x = toInt32(args[1]);
    int y = toInt32(args[2]);

    Node* node = 0;
    if (V8Node::HasInstance(args[0], args.GetIsolate(), worldType(args.GetIsolate())))
        node = V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0]));

    if (!node || !node->isElementNode()) {
        throwTypeError("setDragImageFromElement: Invalid first argument", args.GetIsolate());
        return;
    }

    if (toElement(node)->hasTagName(HTMLNames::imgTag) && !node->inDocument())
        clipboard->setDragImage(toHTMLImageElement(node)->cachedImage(), IntPoint(x, y));
    else
        clipboard->setDragImageElement(node, IntPoint(x, y));
}
Beispiel #2
0
static void appendServerMapMousePosition(StringBuilder& url, Event* event)
{
    if (!event->isMouseEvent())
        return;

    ASSERT(event->target());
    Node* target = event->target()->toNode();
    ASSERT(target);
    if (!isHTMLImageElement(target))
        return;

    HTMLImageElement* imageElement = toHTMLImageElement(target);
    if (!imageElement || !imageElement->isServerMap())
        return;

    if (!imageElement->renderer() || !imageElement->renderer()->isRenderImage())
        return;
    RenderImage* renderer = toRenderImage(imageElement->renderer());

    // FIXME: This should probably pass true for useTransforms.
    FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(toMouseEvent(event)->pageX(), toMouseEvent(event)->pageY()));
    int x = absolutePosition.x();
    int y = absolutePosition.y();
    url.append('?');
    url.appendNumber(x);
    url.append(',');
    url.appendNumber(y);
}
Beispiel #3
0
void PageSerializer::serializeFrame(Frame* frame)
{
    Document* document = frame->document();
    URL url = document->url();
    if (!url.isValid() || url.isBlankURL()) {
        // For blank frames we generate a fake URL so they can be referenced by their containing frame.
        url = urlForBlankFrame(frame);
    }

    if (m_resourceURLs.contains(url)) {
        // FIXME: We could have 2 frame with the same URL but which were dynamically changed and have now
        // different content. So we should serialize both and somehow rename the frame src in the containing
        // frame. Arg!
        return;
    }

    Vector<Node*> nodes;
    SerializerMarkupAccumulator accumulator(*this, *document, &nodes);
    TextEncoding textEncoding(document->charset());
    CString data;
    if (!textEncoding.isValid()) {
        // FIXME: iframes used as images trigger this. We should deal with them correctly.
        return;
    }
    String text = accumulator.serializeNodes(*document->documentElement(), 0, IncludeNode);
    CString frameHTML = textEncoding.encode(text, EntitiesForUnencodables);
    m_resources->append(Resource(url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length())));
    m_resourceURLs.add(url);

    for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
        Node* node = *iter;
        if (!node->isElementNode())
            continue;

        Element* element = toElement(node);
        // We have to process in-line style as it might contain some resources (typically background images).
        if (element->isStyledElement())
            retrieveResourcesForProperties(toStyledElement(element)->inlineStyle(), document);

        if (isHTMLImageElement(element)) {
            HTMLImageElement* imageElement = toHTMLImageElement(element);
            URL url = document->completeURL(imageElement->getAttribute(HTMLNames::srcAttr));
            CachedImage* cachedImage = imageElement->cachedImage();
            addImageToResources(cachedImage, imageElement->renderer(), url);
        } else if (element->hasTagName(HTMLNames::linkTag)) {
            HTMLLinkElement* linkElement = toHTMLLinkElement(element);
            if (CSSStyleSheet* sheet = linkElement->sheet()) {
                URL url = document->completeURL(linkElement->getAttribute(HTMLNames::hrefAttr));
                serializeCSSStyleSheet(sheet, url);
                ASSERT(m_resourceURLs.contains(url));
            }
        } else if (isHTMLStyleElement(element)) {
            if (CSSStyleSheet* sheet = toHTMLStyleElement(element)->sheet())
                serializeCSSStyleSheet(sheet, URL());
        }
    }

    for (Frame* childFrame = frame->tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling())
        serializeFrame(childFrame);
}
Node* V8GCController::opaqueRootForGC(v8::Isolate*, Node* node)
{
    ASSERT(node);
    // FIXME: Remove the special handling for image elements.
    // Maybe should image elements be active DOM nodes?
    // See https://code.google.com/p/chromium/issues/detail?id=164882
    if (node->inDocument() || (isHTMLImageElement(*node) && toHTMLImageElement(*node).hasPendingActivity())) {
        Document& document = node->document();
        if (HTMLImportsController* controller = document.importsController())
            return controller->master();
        return &document;
    }

    if (node->isAttributeNode()) {
        Node* ownerElement = toAttr(node)->ownerElement();
        if (!ownerElement)
            return node;
        node = ownerElement;
    }

    while (Node* parent = node->parentOrShadowHostOrTemplateHostNode())
        node = parent;

    return node;
}
Beispiel #5
0
void DataTransfer::setDragImage(Element* element, int x, int y)
{
    if (!canSetDragImage())
        return;

    CachedImage* image;
    if (element && isHTMLImageElement(element) && !element->inDocument())
        image = toHTMLImageElement(element)->cachedImage();
    else
        image = 0;

    m_dragLocation = IntPoint(x, y);

    if (m_dragImageLoader && m_dragImage)
        m_dragImageLoader->stopLoading(m_dragImage);
    m_dragImage = image;
    if (m_dragImage) {
        if (!m_dragImageLoader)
            m_dragImageLoader = std::make_unique<DragImageLoader>(this);
        m_dragImageLoader->startLoading(m_dragImage);
    }

    m_dragImageElement = image ? 0 : element;

    updateDragImage();
}
Beispiel #6
0
void DataTransfer::setDragImage(Element* image, int x, int y) {
  ASSERT(image);

  if (!isForDragAndDrop())
    return;

  IntPoint location(x, y);
  if (isHTMLImageElement(*image) && !image->isConnected())
    setDragImageResource(toHTMLImageElement(*image).cachedImage(), location);
  else
    setDragImageElement(image, location);
}
static void configureRequest(FetchRequest& request, ImageLoader::BypassMainWorldBehavior bypassBehavior, Element& element, const ClientHintsPreferences& clientHintsPreferences)
{
    if (bypassBehavior == ImageLoader::BypassMainWorldCSP)
        request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);

    AtomicString crossOriginMode = element.fastGetAttribute(HTMLNames::crossoriginAttr);
    if (!crossOriginMode.isNull())
        request.setCrossOriginAccessControl(element.document().securityOrigin(), crossOriginMode);

    if (clientHintsPreferences.shouldSendResourceWidth() && isHTMLImageElement(element))
        request.setResourceWidth(toHTMLImageElement(element).resourceWidth());
}
void DataTransfer::setDragImage(Element* image, int x, int y, ExceptionState& exceptionState)
{
    if (!isForDragAndDrop())
        return;

    if (!image) {
        exceptionState.throwTypeError("setDragImage: Invalid first argument");
        return;
    }
    IntPoint location(x, y);
    if (isHTMLImageElement(*image) && !image->inDocument())
        setDragImageResource(toHTMLImageElement(*image).cachedImage(), location);
    else
        setDragImageElement(image, location);
}
Beispiel #9
0
    virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_t classId) override
    {
        // A minor DOM GC can collect only Nodes.
        if (classId != WrapperTypeInfo::NodeClassId)
            return;

        // To make minor GC cycle time bounded, we limit the number of wrappers handled
        // by each minor GC cycle to 10000. This value was selected so that the minor
        // GC cycle time is bounded to 20 ms in a case where the new space size
        // is 16 MB and it is full of wrappers (which is almost the worst case).
        // Practically speaking, as far as I crawled real web applications,
        // the number of wrappers handled by each minor GC cycle is at most 3000.
        // So this limit is mainly for pathological micro benchmarks.
        const unsigned wrappersHandledByEachMinorGC = 10000;
        if (m_nodesInNewSpace.size() >= wrappersHandledByEachMinorGC)
            return;

        // Casting to a Handle is safe here, since the Persistent doesn't get GCd
        // during the GC prologue.
        ASSERT((*reinterpret_cast<v8::Handle<v8::Value>*>(value))->IsObject());
        v8::Handle<v8::Object>* wrapper = reinterpret_cast<v8::Handle<v8::Object>*>(value);
        ASSERT(V8DOMWrapper::isDOMWrapper(*wrapper));
        ASSERT(V8Node::hasInstance(*wrapper, m_isolate));
        Node* node = V8Node::toImpl(*wrapper);
        // A minor DOM GC can handle only node wrappers in the main world.
        // Note that node->wrapper().IsEmpty() returns true for nodes that
        // do not have wrappers in the main world.
        if (node->containsWrapper()) {
            const WrapperTypeInfo* type = toWrapperTypeInfo(*wrapper);
            ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(*wrapper);
            if (activeDOMObject && activeDOMObject->hasPendingActivity())
                return;
            // FIXME: Remove the special handling for image elements.
            // The same special handling is in V8GCController::opaqueRootForGC().
            // Maybe should image elements be active DOM nodes?
            // See https://code.google.com/p/chromium/issues/detail?id=164882
            if (isHTMLImageElement(*node) && toHTMLImageElement(*node).hasPendingActivity())
                return;
            // FIXME: Remove the special handling for SVG elements.
            // We currently can't collect SVG Elements from minor gc, as we have
            // strong references from SVG property tear-offs keeping context SVG element alive.
            if (node->isSVGElement())
                return;

            m_nodesInNewSpace.append(node);
            node->markV8CollectableDuringMinorGC();
        }
    }
Beispiel #10
0
HTMLImageElement* HTMLMapElement::imageElement()
{
    RefPtrWillBeRawPtr<HTMLCollection> images = document().images();
    for (unsigned i = 0; Element* curr = images->item(i); ++i) {
        ASSERT(isHTMLImageElement(curr));

        // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
        // which has to be stripped off.
        HTMLImageElement& imageElement = toHTMLImageElement(*curr);
        String useMapName = imageElement.getAttribute(usemapAttr).string().substring(1);
        if (equalIgnoringCase(useMapName, m_name))
            return &imageElement;
    }

    return nullptr;
}
    void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_t classId) override
    {

        if (classId != WrapperTypeInfo::NodeClassId && classId != WrapperTypeInfo::ObjectClassId) {
            return;
        }

        // MinorGC does not collect objects because it may be expensive to
        // update references during minorGC
        if (classId == WrapperTypeInfo::ObjectClassId) {
            v8::Persistent<v8::Object>::Cast(*value).MarkActive();
            return;
        }

        v8::Local<v8::Object> wrapper = v8::Local<v8::Object>::New(m_isolate, v8::Persistent<v8::Object>::Cast(*value));
        ASSERT(V8DOMWrapper::hasInternalFieldsSet(wrapper));
        const WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);
        if (type != npObjectTypeInfo() && toScriptWrappable(wrapper)->hasPendingActivity()) {
            v8::Persistent<v8::Object>::Cast(*value).MarkActive();
            return;
        }

        if (classId == WrapperTypeInfo::NodeClassId) {
            ASSERT(V8Node::hasInstance(wrapper, m_isolate));
            Node* node = V8Node::toImpl(wrapper);
            if (node->hasEventListeners()) {
                v8::Persistent<v8::Object>::Cast(*value).MarkActive();
                return;
            }
            // FIXME: Remove the special handling for image elements.
            // The same special handling is in V8GCController::opaqueRootForGC().
            // Maybe should image elements be active DOM nodes?
            // See https://code.google.com/p/chromium/issues/detail?id=164882
            if (isHTMLImageElement(*node) && toHTMLImageElement(*node).hasPendingActivity()) {
                v8::Persistent<v8::Object>::Cast(*value).MarkActive();
                return;
            }
            // FIXME: Remove the special handling for SVG elements.
            // We currently can't collect SVG Elements from minor gc, as we have
            // strong references from SVG property tear-offs keeping context SVG element alive.
            if (node->isSVGElement()) {
                v8::Persistent<v8::Object>::Cast(*value).MarkActive();
                return;
            }
        }
    }
Beispiel #12
0
// FIXME: This doesn't take into account the animation timeline so animations will not
// restart on page load, nor will two animations in different pages have different timelines.
Image* ImageResource::svgImageForLayoutObject(const LayoutObject* layoutObject)
{
    if (!layoutObject)
        return Image::nullImage();

    ImageForContainerMap::iterator it = m_imageForContainerMap->find(layoutObject);
    if (it == m_imageForContainerMap->end())
        return Image::nullImage();

    RefPtr<SVGImageForContainer> imageForContainer = it->value;
    ASSERT(!imageForContainer->size().isEmpty());

    Node* node = layoutObject->node();
    if (node && isHTMLImageElement(node)) {
        const AtomicString& urlString = toHTMLImageElement(node)->imageSourceURL();
        KURL url = node->document().completeURL(urlString);
        imageForContainer->setURL(url);
    }

    return imageForContainer.get();
}
Beispiel #13
0
QVariant QtPixmapRuntime::toQt(JSContextRef context, JSObjectRef obj, QMetaType::Type hint, JSValueRef* exception)
{
    if (!obj)
        return emptyVariantForHint(hint);

    if (JSValueIsObjectOfClass(context, obj, QtPixmapRuntime::getClassRef())) {
        QVariant* originalVariant = static_cast<QVariant*>(JSObjectGetPrivate(obj));
        if (hint == qMetaTypeId<QPixmap>())
            return QVariant::fromValue<QPixmap>(toPixmap(*originalVariant));

        if (hint == qMetaTypeId<QImage>())
            return QVariant::fromValue<QImage>(toImage(*originalVariant));
    }

    JSObject* jsObject = ::toJS(obj);
    if (!jsObject->inherits(&JSHTMLImageElement::s_info))
        return emptyVariantForHint(hint);

    JSHTMLImageElement* elementJSWrapper = static_cast<JSHTMLImageElement*>(jsObject);
    HTMLImageElement* imageElement = toHTMLImageElement(elementJSWrapper->impl());

    if (!imageElement)
        return emptyVariantForHint(hint);

    CachedImage* cachedImage = imageElement->cachedImage();
    if (!cachedImage)
        return emptyVariantForHint(hint);

    Image* image = cachedImage->imageForRenderer(imageElement->renderer());
    if (!image)
        return emptyVariantForHint(hint);

    QPixmap* pixmap = image->nativeImageForCurrentFrame();
    if (!pixmap)
        return emptyVariantForHint(hint);

    return (hint == static_cast<QMetaType::Type>(qMetaTypeId<QPixmap>()))
        ? QVariant::fromValue<QPixmap>(*pixmap)
        : QVariant::fromValue<QImage>(pixmap->toImage());
}
Beispiel #14
0
static JSValueRef assignToHTMLImageElement(JSContextRef context, JSObjectRef function, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (!argumentCount)
        return JSValueMakeUndefined(context);

    JSObjectRef objectArg = JSValueToObject(context, arguments[0], exception);
    if (!objectArg)
        return JSValueMakeUndefined(context);

    JSObject* jsObject = ::toJS(objectArg);

    if (!jsObject->inherits(&JSHTMLImageElement::s_info))
        return JSValueMakeUndefined(context);

    QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object));

    // We now know that we have a valid <img> element as the argument, we can attach the pixmap to it.
    RefPtr<StillImage> stillImage = WebCore::StillImage::create(toPixmap(data));
    HTMLImageElement* imageElement = toHTMLImageElement(static_cast<JSHTMLImageElement*>(jsObject)->impl());
    imageElement->setCachedImage(new CachedImage(stillImage.get()));
    return JSValueMakeUndefined(context);
}
Beispiel #15
0
void ImagePainter::paintIntoRect(GraphicsContext* context, const LayoutRect& rect)
{
    IntRect alignedRect = pixelSnappedIntRect(rect);
    if (!m_renderImage.imageResource()->hasImage() || m_renderImage.imageResource()->errorOccurred() || alignedRect.width() <= 0 || alignedRect.height() <= 0)
        return;

    RefPtr<Image> img = m_renderImage.imageResource()->image(alignedRect.width(), alignedRect.height());
    if (!img || img->isNull())
        return;

    HTMLImageElement* imageElt = isHTMLImageElement(m_renderImage.node()) ? toHTMLImageElement(m_renderImage.node()) : 0;
    CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
    Image* image = img.get();
    InterpolationQuality interpolationQuality = BoxPainter::chooseInterpolationQuality(m_renderImage, context, image, image, alignedRect.size());

    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(m_renderImage));
    // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
    InspectorInstrumentation::willPaintImage(&m_renderImage);
    InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality();
    context->setImageInterpolationQuality(interpolationQuality);
    context->drawImage(image, alignedRect, compositeOperator, m_renderImage.shouldRespectImageOrientation());
    context->setImageInterpolationQuality(previousInterpolationQuality);
    InspectorInstrumentation::didPaintImage(&m_renderImage);
}