// 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); }
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); }