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); }
void StyleElement::clearDocumentData(Document& document, Element* element) { if (m_sheet) m_sheet->clearOwnerNode(); if (element->inDocument()) { ContainerNode* scopingNode = isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0; TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : element->treeScope(); document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope); } }
void StyleInvalidationAnalysis::analyzeStyleSheet(StyleSheetContents* styleSheetContents) { ASSERT(!styleSheetContents->isLoading()); // See if all rules on the sheet are scoped to some specific ids or classes. // Then test if we actually have any of those in the tree at the moment. const Vector<RefPtr<StyleRuleImport> >& importRules = styleSheetContents->importRules(); for (unsigned i = 0; i < importRules.size(); ++i) { if (!importRules[i]->styleSheet()) continue; analyzeStyleSheet(importRules[i]->styleSheet()); if (m_dirtiesAllStyle) return; } if (styleSheetContents->hasSingleOwnerNode()) { Node* ownerNode = styleSheetContents->singleOwnerNode(); if (ownerNode && ownerNode->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(ownerNode)->isRegisteredAsScoped()) { m_scopingNodes.append(determineScopingNodeForStyleScoped(toHTMLStyleElement(ownerNode), styleSheetContents)); return; } } const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules(); for (unsigned i = 0; i < rules.size(); i++) { StyleRuleBase* rule = rules[i].get(); if (!rule->isStyleRule()) { if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) { m_dirtiesAllStyle = true; return; } continue; } StyleRule* styleRule = toStyleRule(rule); if (!determineSelectorScopes(styleRule->selectorList(), m_idScopes, m_classScopes)) { m_dirtiesAllStyle = true; return; } } }
const ContainerNode* ScopedStyleResolver::scopingNodeFor(const CSSStyleSheet* sheet) { ASSERT(sheet); Document* document = sheet->ownerDocument(); if (!document) return 0; Node* ownerNode = sheet->ownerNode(); if (!ownerNode || !ownerNode->hasTagName(HTMLNames::styleTag)) return 0; HTMLStyleElement* styleElement = toHTMLStyleElement(ownerNode); if (!styleElement->scoped()) return styleElement->isInShadowTree() ? styleElement->containingShadowRoot() : 0; ContainerNode* parent = styleElement->parentNode(); if (!parent) return 0; return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; }
ContainerNode* ScopedStyleResolver::scopingNodeFor(Document& document, const CSSStyleSheet* sheet) { ASSERT(sheet); Document* sheetDocument = sheet->ownerDocument(); if (!sheetDocument) return 0; Node* ownerNode = sheet->ownerNode(); if (!isHTMLStyleElement(ownerNode)) return &document; HTMLStyleElement& styleElement = toHTMLStyleElement(*ownerNode); if (!styleElement.scoped()) { if (styleElement.isInShadowTree()) return styleElement.containingShadowRoot(); return &document; } ContainerNode* parent = styleElement.parentNode(); if (!parent) return 0; return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; }
void StyleElement::clearDocumentData(Document& document, Element* element) { if (m_sheet) m_sheet->clearOwnerNode(); if (element->inDocument()) document.styleEngine()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0); }