// Return a set of rectangles that should not be overdrawn by the
// plugin ("cutouts"). This helps implement the "iframe shim"
// technique of overlaying a windowed plugin with content from the
// page. In a nutshell, iframe elements should occlude plugins when
// they occur higher in the stacking order.
void getPluginOcclusions(Element* element, Widget* parentWidget, const IntRect& frameRect, Vector<IntRect>& occlusions)
{
    RenderObject* pluginNode = element->renderer();
    ASSERT(pluginNode);
    if (!pluginNode->style())
        return;
    Vector<const RenderObject*> pluginZstack;
    Vector<const RenderObject*> iframeZstack;
    getObjectStack(pluginNode, &pluginZstack);

    if (!parentWidget->isFrameView())
        return;

    FrameView* parentFrameView = toFrameView(parentWidget);

    // Occlusions by iframes.
    const FrameView::ChildrenWidgetSet* children = parentFrameView->children();
    for (FrameView::ChildrenWidgetSet::const_iterator it = children->begin(); it != children->end(); ++it) {
        // We only care about FrameView's because iframes show up as FrameViews.
        if (!(*it)->isFrameView())
            continue;

        const FrameView* frameView = toFrameView(it->get());
        // Check to make sure we can get both the element and the RenderObject
        // for this FrameView, if we can't just move on to the next object.
        // FIXME: Plugin occlusion by remote frames is probably broken.
        HTMLElement* element = frameView->frame().deprecatedLocalOwner();
        if (!element || !element->renderer())
            continue;

        RenderObject* iframeRenderer = element->renderer();

        if (isHTMLIFrameElement(*element) && intersectsRect(iframeRenderer, frameRect)) {
            getObjectStack(iframeRenderer, &iframeZstack);
            if (iframeIsAbovePlugin(iframeZstack, pluginZstack))
                addToOcclusions(toRenderBox(iframeRenderer), occlusions);
        }
    }

    // Occlusions by top layer elements.
    // FIXME: There's no handling yet for the interaction between top layer and
    // iframes. For example, a plugin in the top layer will be occluded by an
    // iframe. And a plugin inside an iframe in the top layer won't be respected
    // as being in the top layer.
    const Element* ancestor = topLayerAncestor(element);
    Document* document = parentFrameView->frame().document();
    const WillBeHeapVector<RefPtrWillBeMember<Element> >& elements = document->topLayerElements();
    size_t start = ancestor ? elements.find(ancestor) + 1 : 0;
    for (size_t i = start; i < elements.size(); ++i)
        addTreeToOcclusions(elements[i]->renderer(), frameRect, occlusions);
}
bool DocumentNameCollection::elementMatches(const HTMLElement& element) const {
  // Match images, forms, embeds, objects and iframes by name,
  // object by id, and images by id but only if they have
  // a name attribute (this very strange rule matches IE)
  if (isHTMLFormElement(element) || isHTMLIFrameElement(element) ||
      (isHTMLEmbedElement(element) && toHTMLEmbedElement(element).isExposed()))
    return element.getNameAttribute() == m_name;
  if (isHTMLObjectElement(element) && toHTMLObjectElement(element).isExposed())
    return element.getNameAttribute() == m_name ||
           element.getIdAttribute() == m_name;
  if (isHTMLImageElement(element))
    return element.getNameAttribute() == m_name ||
           (element.getIdAttribute() == m_name && element.hasName());
  return false;
}
static v8::Local<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const AtomicString& key, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
{
    if (!htmlDocument->hasNamedItem(key) && !htmlDocument->hasExtraNamedItem(key))
        return v8Undefined();

    RefPtrWillBeRawPtr<DocumentNameCollection> items = htmlDocument->documentNamedItems(key);
    if (items->isEmpty())
        return v8Undefined();

    if (items->hasExactlyOneItem()) {
        HTMLElement* element = items->item(0);
        ASSERT(element);
        Frame* frame = isHTMLIFrameElement(*element) ? toHTMLIFrameElement(*element).contentFrame() : 0;
        if (frame)
            return toV8(frame->domWindow(), creationContext, isolate);
        return toV8(element, creationContext, isolate);
    }
    return toV8(PassRefPtrWillBeRawPtr<HTMLCollection>(items.release()), creationContext, isolate);
}
Beispiel #4
0
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString, Frame* frame, const Vector<Node*>& nodes, FrameFilter* frameFilter)
{
    ASSERT(frame);
    
    const ResourceResponse& response = frame->loader().documentLoader()->response();
    URL responseURL = response.url();
    
    // it's possible to have a response without a URL here
    // <rdar://problem/5454935>
    if (responseURL.isNull())
        responseURL = URL(ParsedURLString, emptyString());
        
    RefPtr<ArchiveResource> mainResource = ArchiveResource::create(utf8Buffer(markupString), responseURL, response.mimeType(), "UTF-8", frame->tree().uniqueName());

    Vector<PassRefPtr<LegacyWebArchive>> subframeArchives;
    Vector<PassRefPtr<ArchiveResource>> subresources;
    HashSet<URL> uniqueSubresources;

    size_t nodesSize = nodes.size();    
    for (size_t i = 0; i < nodesSize; ++i) {
        Node& node = *nodes[i];
        Frame* childFrame;
        if ((isHTMLFrameElement(node) || isHTMLIFrameElement(node) || isHTMLObjectElement(node))
            && (childFrame = toHTMLFrameOwnerElement(node).contentFrame())) {
            if (frameFilter && !frameFilter->shouldIncludeSubframe(childFrame))
                continue;
                
            RefPtr<LegacyWebArchive> subframeArchive = create(childFrame->document(), frameFilter);
            
            if (subframeArchive)
                subframeArchives.append(subframeArchive);
            else
                LOG_ERROR("Unabled to archive subframe %s", childFrame->tree().uniqueName().string().utf8().data());
        } else {
            ListHashSet<URL> subresourceURLs;
            node.getSubresourceURLs(subresourceURLs);
            
            DocumentLoader* documentLoader = frame->loader().documentLoader();
            ListHashSet<URL>::iterator iterEnd = subresourceURLs.end();
            for (ListHashSet<URL>::iterator iter = subresourceURLs.begin(); iter != iterEnd; ++iter) {
                const URL& subresourceURL = *iter;
                if (uniqueSubresources.contains(subresourceURL))
                    continue;

                uniqueSubresources.add(subresourceURL);

                RefPtr<ArchiveResource> resource = documentLoader->subresource(subresourceURL);
                if (resource) {
                    subresources.append(resource.release());
                    continue;
                }

                ResourceRequest request(subresourceURL);
#if ENABLE(CACHE_PARTITIONING)
                request.setCachePartition(frame->document()->topOrigin()->cachePartition());
#endif
                CachedResource* cachedResource = memoryCache()->resourceForRequest(request);
                if (cachedResource) {
                    ResourceBuffer* data = cachedResource->resourceBuffer();
                    resource = ArchiveResource::create(data ? data->sharedBuffer() : 0, subresourceURL, cachedResource->response());
                    if (resource) {
                        subresources.append(resource.release());
                        continue;
                    }
                }

                // FIXME: should do something better than spew to console here
                LOG_ERROR("Failed to archive subresource for %s", subresourceURL.string().utf8().data());
            }
        }
    }

    // Add favicon if one exists for this page, if we are archiving the entire page.
    if (nodesSize && nodes[0]->isDocumentNode() && iconDatabase().isEnabled()) {
        const String& iconURL = iconDatabase().synchronousIconURLForPageURL(responseURL);
        if (!iconURL.isEmpty() && iconDatabase().synchronousIconDataKnownForIconURL(iconURL)) {
            if (Image* iconImage = iconDatabase().synchronousIconForPageURL(responseURL, IntSize(16, 16))) {
                if (RefPtr<ArchiveResource> resource = ArchiveResource::create(iconImage->data(), URL(ParsedURLString, iconURL), "image/x-icon", "", ""))
                    subresources.append(resource.release());
            }
        }
    }

    return create(mainResource.release(), subresources, subframeArchives);
}
void WebFrameSerializerImpl::openTagToString(
    Element* element,
    SerializeDomParam* param)
{
    bool needSkip;
    StringBuilder result;
    // Do pre action for open tag.
    result.append(preActionBeforeSerializeOpenTag(element, param, &needSkip));
    if (needSkip)
        return;
    // Add open tag
    result.append('<');
    result.append(element->nodeName().lower());

    // Find out if we need to do frame-specific link rewriting.
    WebFrame* frame = nullptr;
    if (element->isFrameOwnerElement()) {
        frame = WebFrame::fromFrame(
            toHTMLFrameOwnerElement(element)->contentFrame());
    }
    WebString rewrittenFrameLink;
    bool shouldRewriteFrameSrc =
        frame && m_delegate->rewriteFrameSource(frame, &rewrittenFrameLink);
    bool didRewriteFrameSrc = false;

    // Go through all attributes and serialize them.
    for (const auto& it : element->attributes()) {
        const QualifiedName& attrName = it.name();
        String attrValue = it.value();

        // Skip srcdoc attribute if we will emit src attribute (for frames).
        if (shouldRewriteFrameSrc && attrName == HTMLNames::srcdocAttr)
            continue;

        // Rewrite the attribute value if requested.
        if (element->hasLegalLinkAttribute(attrName)) {
            // For links start with "javascript:", we do not change it.
            if (!attrValue.startsWith("javascript:", TextCaseInsensitive)) {
                // Get the absolute link.
                KURL completeURL = param->document->completeURL(attrValue);

                // Check whether we have a local file to link to.
                WebString rewrittenURL;
                if (shouldRewriteFrameSrc) {
                    attrValue = rewrittenFrameLink;
                    didRewriteFrameSrc = true;
                } else if (m_delegate->rewriteLink(completeURL, &rewrittenURL)) {
                    attrValue = rewrittenURL;
                } else {
                    attrValue = completeURL;
                }
            }
        }

        appendAttribute(result, param->isHTMLDocument, attrName.toString(), attrValue);
    }

    // For frames where link rewriting was requested, ensure that src attribute
    // is written even if the original document didn't have that attribute
    // (mainly needed for iframes with srcdoc, but with no src attribute).
    if (shouldRewriteFrameSrc && !didRewriteFrameSrc && isHTMLIFrameElement(element)) {
        appendAttribute(
            result, param->isHTMLDocument, HTMLNames::srcAttr.toString(), rewrittenFrameLink);
    }

    // Do post action for open tag.
    String addedContents = postActionAfterSerializeOpenTag(element, param);
    // Complete the open tag for element when it has child/children.
    if (element->hasChildren() || param->haveAddedContentsBeforeEnd)
        result.append('>');
    // Append the added contents generate in  post action of open tag.
    result.append(addedContents);
    // Save the result to data buffer.
    saveHTMLContentToBuffer(result.toString(), param);
}