void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const KURL& url) { StringBuilder cssText; for (unsigned i = 0; i < styleSheet->length(); ++i) { StyleBase* item = styleSheet->item(i); String itemText = item->cssText(); if (!itemText.isEmpty()) { cssText.append(itemText); if (i < styleSheet->length() - 1) cssText.append("\n\n"); } // Some rules have resources associated with them that we need to retrieve. if (item->isImportRule()) { CSSImportRule* importRule = static_cast<CSSImportRule*>(item); KURL importURL = styleSheet->document()->completeURL(importRule->href()); if (m_resourceURLs.contains(importURL)) continue; serializeCSSStyleSheet(importRule->styleSheet(), importURL); } else if (item->isFontFaceRule()) { // FIXME: Add support for font face rule. It is not clear to me at this point if the actual otf/eot file can // be retrieved from the CSSFontFaceRule object. } else if (item->isStyleRule()) retrieveResourcesForCSSRule(static_cast<CSSStyleRule*>(item)); } if (url.isValid() && !m_resourceURLs.contains(url)) { // FIXME: We should check whether a charset has been specified and if none was found add one. TextEncoding textEncoding(styleSheet->charset()); ASSERT(textEncoding.isValid()); String textString = cssText.toString(); CString text = textEncoding.encode(textString.characters(), textString.length(), EntitiesForUnencodables); m_resources->append(Resource(url, String("text/css"), SharedBuffer::create(text.data(), text.length()))); m_resourceURLs.add(url); } }
void CSSStyleSheet::addSubresourceURLStrings(HashSet<String>& urls, const String& base) const { RefPtr<CSSRuleList> ruleList = const_cast<CSSStyleSheet*>(this)->cssRules(); // Add the URLs for each child import rule, and recurse for the stylesheet belonging to each of those rules. for (unsigned i = 0; i < ruleList->length(); ++i) { CSSRule* rule = ruleList->item(i); if (rule->type() != CSSRule::IMPORT_RULE) continue; CSSImportRule* importRule = static_cast<CSSImportRule*>(rule); CSSStyleSheet* ruleSheet = importRule->styleSheet(); if (!ruleSheet) continue; KURL fullURL(KURL(base), importRule->href()); urls.add(fullURL.string()); ruleSheet->addSubresourceURLStrings(urls, fullURL.string()); } }
CSSRule* ElementRuleCollector::findStyleRule(CSSRuleCollection* cssRules, StyleRule* styleRule) { if (!cssRules) return nullptr; CSSRule* result = 0; for (unsigned i = 0; i < cssRules->length() && !result; ++i) { CSSRule* cssRule = cssRules->item(i); CSSRule::Type cssRuleType = cssRule->type(); if (cssRuleType == CSSRule::kStyleRule) { CSSStyleRule* cssStyleRule = toCSSStyleRule(cssRule); if (cssStyleRule->styleRule() == styleRule) result = cssRule; } else if (cssRuleType == CSSRule::kImportRule) { CSSImportRule* cssImportRule = toCSSImportRule(cssRule); result = findStyleRule(cssImportRule->styleSheet(), styleRule); } else { result = findStyleRule(cssRule->cssRules(), styleRule); } } return result; }
CSSRule* ElementRuleCollector::findStyleRule(CSSRuleCollection* cssRules, StyleRule* styleRule) { if (!cssRules) return 0; CSSRule* result = 0; for (unsigned i = 0; i < cssRules->length() && !result; ++i) { CSSRule* cssRule = cssRules->item(i); CSSRule::Type cssRuleType = cssRule->type(); if (cssRuleType == CSSRule::STYLE_RULE) { CSSStyleRule* cssStyleRule = toCSSStyleRule(cssRule); if (cssStyleRule->styleRule() == styleRule) result = cssRule; } else if (cssRuleType == CSSRule::IMPORT_RULE) { CSSImportRule* cssImportRule = toCSSImportRule(cssRule); result = findStyleRule(cssImportRule->styleSheet(), styleRule); } else { result = findStyleRule(nestedRuleList(cssRule), styleRule); } } return result; }
void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const KURL& url) { StringBuilder cssText; for (unsigned i = 0; i < styleSheet->length(); ++i) { CSSRule* rule = styleSheet->item(i); String itemText = rule->cssText(); if (!itemText.isEmpty()) { cssText.append(itemText); if (i < styleSheet->length() - 1) cssText.append("\n\n"); } Document* document = styleSheet->ownerDocument(); // Some rules have resources associated with them that we need to retrieve. if (rule->type() == CSSRule::IMPORT_RULE) { CSSImportRule* importRule = toCSSImportRule(rule); KURL importURL = document->completeURL(importRule->href()); if (m_resourceURLs.contains(importURL)) continue; serializeCSSStyleSheet(importRule->styleSheet(), importURL); } else if (rule->type() == CSSRule::FONT_FACE_RULE) { retrieveResourcesForProperties(toCSSFontFaceRule(rule)->styleRule()->properties(), document); } else if (rule->type() == CSSRule::STYLE_RULE) { retrieveResourcesForProperties(toCSSStyleRule(rule)->styleRule()->properties(), document); } } if (url.isValid() && !m_resourceURLs.contains(url)) { // FIXME: We should check whether a charset has been specified and if none was found add one. WTF::TextEncoding textEncoding(styleSheet->contents()->charset()); ASSERT(textEncoding.isValid()); String textString = cssText.toString(); CString text = textEncoding.normalizeAndEncode(textString, WTF::EntitiesForUnencodables); m_resources->append(SerializedResource(url, String("text/css"), SharedBuffer::create(text.data(), text.length()))); m_resourceURLs.add(url); } }
JSValue* JSCSSImportRule::getValueProperty(ExecState* exec, int token) const { switch (token) { case HrefAttrNum: { CSSImportRule* imp = static_cast<CSSImportRule*>(impl()); return jsStringOrNull(exec, imp->href()); } case MediaAttrNum: { CSSImportRule* imp = static_cast<CSSImportRule*>(impl()); return toJS(exec, WTF::getPtr(imp->media())); } case StyleSheetAttrNum: { CSSImportRule* imp = static_cast<CSSImportRule*>(impl()); return toJS(exec, WTF::getPtr(imp->styleSheet())); } case ConstructorAttrNum: return getConstructor(exec); } return 0; }
CSSRule* CSSStream::ParseRule(CSSStyleSheet* parentStyleSheet, CSSRule* parentRule, ICSSRuleListener* pListener) { // stream->SkipSpaces(); getnextc(); if (m_c == L'/') { getnextc(); //if (c == L'*') EatChar(L'*'); { CSSCommentRule* p = new CSSCommentRule; //p->AddRef(); p->m_textOffset[0] = stream.m_ipos-2; p->m_textOffset[1] = stream.m_ipos-2; p->m_textOffset[2] = stream.m_ipos; p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; StringStream cssText; cssText << L"/*"; while (!stream.eof()) { if (stream.m_c == L'*') { stream.getnextc(); if (stream.m_c == L'/') { stream.getnextc(); break; } } cssText << (WCHAR)stream.m_c; } p->m_textOffset[3] = stream.m_ipos; stream.EatChar(L'*'); stream.EatChar(L'/'); p->m_textOffset[4] = stream.m_ipos; p->m_textOffset[5] = stream.m_ipos; cssText << L"*/"; p->m_cssText = cssText->str(); *pVal = p; } } else if (m_c == L'@') // at-rule { ASSERT(0); #if 0 String id = stream.GetID(); StringStream strbuilder; strbuilder << L"@"; strbuilder << id; int curly = 0; while (!stream.eof()) { strbuilder << (WCHAR)m_c; if (stream.m_c == L'{') { curly++; } else if (stream.m_c == L'}') { curly--; if (curly == 0) break; } else if (stream.m_c == L';') { if (curly == 0) { break; } } } // Read spaces while (!stream.eof()) { if (!isspace(stream.m_c)) { break; } strbuilder << (WCHAR)stream.m_c; stream.getnextc(); } String cssText = strbuilder->str(); pCallback->AtRule(id, cssText); if (id == L"charset") { CSSCharsetRule* p = new CSSCharsetRule; if (p) { // p->AddRef(); p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; p->set_cssText(cssText); *pVal = p; } } else if (id == L"import") { CSSImportRule* p = new CSSImportRule; if (p) { // p->AddRef(); p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; p->set_cssText(cssText); *pVal = p; } } else if (id == L"fontface") { CSSFontFaceRule* p = new CSSFontFaceRule; if (p) { // p->AddRef(); p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; p->set_cssText(cssText); *pVal = p; } } else if (id == L"media") { CSSMediaRule* p = new CSSMediaRule; if (p) { //p->AddRef(); p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; p->set_cssText(cssText); *pVal = p; } } else if (id == L"color-profile") { SVGColorProfileRule* p = new SVGColorProfileRule; if (p) { // p->AddRef(); p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; p->set_cssText(cssText); *pVal = p; } } /* else if (!tcscmp(id, L"charset")) { } */ else // Unknown at-rule { CSSUnknownRule* p = new CSSUnknownRule; if (p) { //p->AddRef(); p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; p->set_cssText(cssText); *pVal = p; } } #endif } else { ParseStyleRule(); if (p) { // p->m_textOffset[0] = stream.m_ipos; p->m_parentStyleSheet = parentStyleSheet; p->m_parentRule = parentRule; StringStream cssText; // Skip selectors while (!stream.eof()) { cssText << (WCHAR)stream.m_c; if (m_c == L'{') { break; } stream.getnextc(); } p->m_textOffset[1] = stream.m_ipos; // Skip style declaration stream.EatChar(L'{'); int curly = 1; p->m_textOffset[2] = stream.m_ipos; while (!stream.eof()) { cssText << (WCHAR)stream.m_c; p->m_textOffset[3] = stream.m_ipos; if (stream.m_c == '"') { stream.getnextc(); //if (delimiter == L'\'' || L'\"') { while (!stream.eof()) { cssText << (WCHAR)stream.m_c; if (stream.m_c == '\\') { stream.getnextc(); cssText << (WCHAR)stream.m_c; } else if (stream.m_c == '"') { break; } } } } else if (stream.m_c == L'{') { curly++; } else if (stream.m_c == L'}') { curly--; if (curly == 0) { break; } } } p->m_textOffset[4] = stream.m_ipos; // Read spaces while (!stream.eof()) { if (!isspace(stream.m_c)) { break; } cssText << (WCHAR)stream.m_c; stream.getnextc(); } p->m_textOffset[5] = stream.m_ipos; p->set_cssText(cssText->str()); p->m_pListener = pListener; *pVal = p; } } return Success; }