Skip to content
Permalink
Browse files
…or user stylesheet injection. This is similar

to user script injection but allows for user stylesheets to be added.  The stylesheets are applied immediately
to all Frames in the PageGroup.

Reviewed by Adam Roben.

Added userscripts/simple-stylesheet.html test case.

* WebCore.base.exp:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::CSSStyleSelector):
* css/CSSStyleSelector.h:
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::attach):
(WebCore::Document::pageGroupUserSheets):
(WebCore::Document::clearPageGroupUserSheets):
(WebCore::Document::recalcStyleSelector):
* dom/Document.h:
* loader/PlaceholderDocument.cpp:
(WebCore::PlaceholderDocument::attach):
* page/PageGroup.cpp:
(WebCore::PageGroup::addUserStyleSheet):
(WebCore::PageGroup::removeUserContentForWorld):
(WebCore::PageGroup::removeAllUserContent):
* page/PageGroup.h:
(WebCore::PageGroup::userStyleSheets):
* page/UserStyleSheet.h: Added.
(WebCore::UserStyleSheet::UserStyleSheet):
(WebCore::UserStyleSheet::source):
(WebCore::UserStyleSheet::url):
(WebCore::UserStyleSheet::patterns):
(WebCore::UserStyleSheet::worldID):
* page/UserStyleSheetTypes.h: Added.

WebKit/mac: https://bugs.webkit.org/show_bug.cgi?id=29102, add support for user stylesheet injection.  This is similar
to user script injection but allows for user stylesheets to be added.  The stylesheets are applied immediately
to all Frames in the PageGroup.

Reviewed by Adam Roben.

Added userscripts/simple-stylesheet.html test case.

* WebView/WebView.mm:
(+[WebView _addUserStyleSheetToGroup:source:url:worldID:patterns:]):
* WebView/WebViewPrivate.h:

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=29102, add support for user stylesheet injection.  This is similar
to user script injection but allows for user stylesheets to be added.  The stylesheets are applied immediately
to all Frames in the PageGroup.

Reviewed by Adam Roben.

Added userscripts/simple-stylesheet.html test case.

* platform/mac/userscripts/simple-stylesheet-expected.checksum: Added.
* platform/mac/userscripts/simple-stylesheet-expected.png: Added.
* platform/mac/userscripts/simple-stylesheet-expected.txt: Added.
* userscripts/simple-stylesheet.html: Added.



Canonical link: https://commits.webkit.org/39791@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@48222 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
David Hyatt committed Sep 9, 2009
1 parent 7062dda commit ece8c11677add80904021dd682e4d76e840c530e
Showing 27 changed files with 386 additions and 18 deletions.
@@ -1,3 +1,18 @@
2009-09-09 Dave Hyatt <hyatt@apple.com>

Reviewed by Adam Roben.

https://bugs.webkit.org/show_bug.cgi?id=29102, add support for user stylesheet injection. This is similar
to user script injection but allows for user stylesheets to be added. The stylesheets are applied immediately
to all Frames in the PageGroup.

Added userscripts/simple-stylesheet.html test case.

* platform/mac/userscripts/simple-stylesheet-expected.checksum: Added.
* platform/mac/userscripts/simple-stylesheet-expected.png: Added.
* platform/mac/userscripts/simple-stylesheet-expected.txt: Added.
* userscripts/simple-stylesheet.html: Added.

2009-09-09 Carol Szabo <carol.szabo@nokia.com>

Reviewed by Ariya Hidayat.
@@ -0,0 +1 @@
PASS
@@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.addUserStyleSheet("div { width:0; }");
}
</script>
</head>
<body>
<div id="target">FAIL</div>
<script>
if (document.getElementById('target').offsetWidth == 0)
document.getElementById('target').innerHTML = 'PASS';
</script>
</body>
</html>
@@ -1,3 +1,43 @@
2009-09-09 Dave Hyatt <hyatt@apple.com>

Reviewed by Adam Roben.

https://bugs.webkit.org/show_bug.cgi?id=29102, add support for user stylesheet injection. This is similar
to user script injection but allows for user stylesheets to be added. The stylesheets are applied immediately
to all Frames in the PageGroup.

Added userscripts/simple-stylesheet.html test case.

* WebCore.base.exp:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::CSSStyleSelector):
* css/CSSStyleSelector.h:
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::attach):
(WebCore::Document::pageGroupUserSheets):
(WebCore::Document::clearPageGroupUserSheets):
(WebCore::Document::recalcStyleSelector):
* dom/Document.h:
* loader/PlaceholderDocument.cpp:
(WebCore::PlaceholderDocument::attach):
* page/PageGroup.cpp:
(WebCore::PageGroup::addUserStyleSheet):
(WebCore::PageGroup::removeUserContentForWorld):
(WebCore::PageGroup::removeAllUserContent):
* page/PageGroup.h:
(WebCore::PageGroup::userStyleSheets):
* page/UserStyleSheet.h: Added.
(WebCore::UserStyleSheet::UserStyleSheet):
(WebCore::UserStyleSheet::source):
(WebCore::UserStyleSheet::url):
(WebCore::UserStyleSheet::patterns):
(WebCore::UserStyleSheet::worldID):
* page/UserStyleSheetTypes.h: Added.

2009-09-09 Carol Szabo <carol.szabo@nokia.com>

Reviewed by Ariya Hidayat.
@@ -744,6 +744,7 @@ __ZN7WebCore9HTMLNames9scriptTagE
__ZN7WebCore9PageCache11setCapacityEi
__ZN7WebCore9PageCache27releaseAutoreleasedPagesNowEv
__ZN7WebCore9PageGroup13addUserScriptERKNS_6StringERKNS_4KURLERKN3WTF6VectorIS1_Lm0EEEjNS_23UserScriptInjectionTimeE
__ZN7WebCore9PageGroup17addUserStyleSheetERKNS_6StringERKNS_4KURLERKN3WTF6VectorIS1_Lm0EEEj
__ZN7WebCore9PageGroup14addVisitedLinkEPKtm
__ZN7WebCore9PageGroup20removeAllUserContentEv
__ZN7WebCore9PageGroup17closeLocalStorageEv
@@ -1701,6 +1701,8 @@
'page/Settings.h',
'page/UserScript.h',
'page/UserScriptTypes.h',
'page/UserStyleSheet.h',
'page/UserStyleSheetTypes.h',
'page/WebKitPoint.h',
'page/WindowFeatures.cpp',
'page/WindowFeatures.h',
@@ -17068,14 +17068,22 @@
RelativePath="..\page\Settings.h"
>
</File>
<File
<File
RelativePath="..\page\UserScript.h"
>
</File>
<File
<File
RelativePath="..\page\UserScriptTypes.h"
>
</File>
<File
RelativePath="..\page\UserStyleSheet.h"
>
</File>
<File
RelativePath="..\page\UserStyleSheetTypes.h"
>
</File>
<File
RelativePath="..\page\WebKitPoint.h"
>
@@ -4271,6 +4271,8 @@
BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8243E70D0CFD7500460C8F /* WindowFeatures.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC8B853E0E7C7F1100AB6984 /* ScrollbarThemeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */; };
BC8B854B0E7C7F5600AB6984 /* ScrollbarTheme.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8B854A0E7C7F5600AB6984 /* ScrollbarTheme.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC8BF151105813BF00A40A07 /* UserStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8BF150105813BF00A40A07 /* UserStyleSheet.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC8BF15A1058141800A40A07 /* UserStyleSheetTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8BF1591058141800A40A07 /* UserStyleSheetTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC8C8FAD0DDCD31B00B592F4 /* RenderStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC8C8FAB0DDCD31B00B592F4 /* RenderStyle.cpp */; };
BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8C8FAC0DDCD31B00B592F4 /* RenderStyle.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC904B760D10998F00680D32 /* ClassNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC904B720D10998F00680D32 /* ClassNodeList.cpp */; };
@@ -9336,6 +9338,8 @@
BC8243E70D0CFD7500460C8F /* WindowFeatures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowFeatures.h; sourceTree = "<group>"; };
BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeMac.h; sourceTree = "<group>"; };
BC8B854A0E7C7F5600AB6984 /* ScrollbarTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarTheme.h; sourceTree = "<group>"; };
BC8BF150105813BF00A40A07 /* UserStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserStyleSheet.h; sourceTree = "<group>"; };
BC8BF1591058141800A40A07 /* UserStyleSheetTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserStyleSheetTypes.h; sourceTree = "<group>"; };
BC8C8FAB0DDCD31B00B592F4 /* RenderStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderStyle.cpp; path = style/RenderStyle.cpp; sourceTree = "<group>"; };
BC8C8FAC0DDCD31B00B592F4 /* RenderStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RenderStyle.h; path = style/RenderStyle.h; sourceTree = "<group>"; };
BC904B720D10998F00680D32 /* ClassNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassNodeList.cpp; sourceTree = "<group>"; };
@@ -11049,6 +11053,8 @@
F587863A02DE3A1401EA4122 /* Settings.h */,
BCA2B0601050475F0043BD1C /* UserScript.h */,
BCA2B08A10505BCD0043BD1C /* UserScriptTypes.h */,
BC8BF150105813BF00A40A07 /* UserStyleSheet.h */,
BC8BF1591058141800A40A07 /* UserStyleSheetTypes.h */,
494BD7930F55C8EE00747828 /* WebKitPoint.h */,
494BD7940F55C8EE00747828 /* WebKitPoint.idl */,
BC8243E60D0CFD7500460C8F /* WindowFeatures.cpp */,
@@ -17788,6 +17794,8 @@
49EED1451051969400099FAB /* JSCanvasRenderingContext2D.h in Headers */,
49EED1471051969400099FAB /* JSCanvasRenderingContext3D.h in Headers */,
59C77F2B10545B3B00506104 /* GeolocationServiceMock.h in Headers */,
BC8BF151105813BF00A40A07 /* UserStyleSheet.h in Headers */,
BC8BF15A1058141800A40A07 /* UserStyleSheetTypes.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -408,7 +408,9 @@ static const MediaQueryEvaluator& printEval()
return staticPrintEval;
}

CSSStyleSelector::CSSStyleSelector(Document* doc, CSSStyleSheet* userSheet, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet, bool strictParsing, bool matchAuthorAndUserStyles)
CSSStyleSelector::CSSStyleSelector(Document* doc, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet,
CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
bool strictParsing, bool matchAuthorAndUserStyles)
: m_backgroundData(BackgroundFillLayer)
, m_checker(doc, strictParsing)
, m_fontSelector(CSSFontSelector::create(doc))
@@ -449,9 +451,15 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, CSSStyleSheet* userSheet, Styl
}

// FIXME: This sucks! The user sheet is reparsed every time!
if (userSheet) {
if (pageUserSheet || pageGroupUserSheets) {
m_userStyle = new CSSRuleSet();
m_userStyle->addRulesFromSheet(userSheet, *m_medium, this);
if (pageUserSheet)
m_userStyle->addRulesFromSheet(pageUserSheet, *m_medium, this);
if (pageGroupUserSheets) {
unsigned length = pageGroupUserSheets->size();
for (unsigned i = 0; i < length; i++)
m_userStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this);
}
}

// add stylesheets from document
@@ -80,7 +80,8 @@ class MediaQueryResult {
// This class selects a RenderStyle for a given element based on a collection of stylesheets.
class CSSStyleSelector : public Noncopyable {
public:
CSSStyleSelector(Document*, CSSStyleSheet* userStyleSheet, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
bool strictParsing, bool matchAuthorAndUserStyles);
~CSSStyleSelector();

@@ -94,6 +94,7 @@
#include "NodeWithIndex.h"
#include "OverflowEvent.h"
#include "Page.h"
#include "PageGroup.h"
#include "PageTransitionEvent.h"
#include "PlatformKeyboardEvent.h"
#include "ProcessingInstruction.h"
@@ -349,6 +350,8 @@ Document::Document(Frame* frame, bool isXHTML)
{
m_document = this;

m_pageGroupUserSheetCacheValid = false;

m_printing = false;

m_ignoreAutofocus = false;
@@ -1376,7 +1379,8 @@ void Document::attach()
bool matchAuthorAndUserStyles = true;
if (Settings* docSettings = settings())
matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
m_styleSelector = new CSSStyleSelector(this, pageUserSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
m_styleSelector = new CSSStyleSelector(this, m_styleSheets.get(), m_mappedElementSheet.get(), pageUserSheet(), pageGroupUserSheets(),
!inCompatMode(), matchAuthorAndUserStyles);
}

recalcStyle(Force);
@@ -1941,6 +1945,45 @@ void Document::clearPageUserSheet()
updateStyleSelector();
}

const Vector<RefPtr<CSSStyleSheet> >* Document::pageGroupUserSheets() const
{
if (m_pageGroupUserSheetCacheValid)
return m_pageGroupUserSheets.get();

m_pageGroupUserSheetCacheValid = true;

Page* owningPage = page();
if (!owningPage)
return 0;

const PageGroup& pageGroup = owningPage->group();
const UserStyleSheetMap* sheetsMap = pageGroup.userStyleSheets();
if (!sheetsMap)
return 0;

UserStyleSheetMap::const_iterator end = sheetsMap->end();
for (UserStyleSheetMap::const_iterator it = sheetsMap->begin(); it != end; ++it) {
const UserStyleSheetVector* sheets = it->second;
for (unsigned i = 0; i < sheets->size(); ++i) {
const UserStyleSheet* sheet = sheets->at(i).get();
RefPtr<CSSStyleSheet> parsedSheet = CSSStyleSheet::create(const_cast<Document*>(this));
parsedSheet->parseString(sheet->source(), !inCompatMode());
if (!m_pageGroupUserSheets)
m_pageGroupUserSheets.set(new Vector<RefPtr<CSSStyleSheet> >);
m_pageGroupUserSheets->append(parsedSheet.release());
}
}

return m_pageGroupUserSheets.get();
}

void Document::clearPageGroupUserSheets()
{
m_pageGroupUserSheets.clear();
m_pageGroupUserSheetCacheValid = false;
updateStyleSelector();
}

CSSStyleSheet* Document::elementSheet()
{
if (!m_elemSheet)
@@ -2502,7 +2545,8 @@ void Document::recalcStyleSelector()

// Create a new style selector
delete m_styleSelector;
m_styleSelector = new CSSStyleSelector(this, pageUserSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
m_styleSelector = new CSSStyleSelector(this, m_styleSheets.get(), m_mappedElementSheet.get(),
pageUserSheet(), pageGroupUserSheets(), !inCompatMode(), matchAuthorAndUserStyles);
m_didCalculateStyleSelector = true;
}

@@ -444,6 +444,9 @@ class Document : public ContainerNode, public ScriptExecutionContext {
CSSStyleSheet* pageUserSheet();
void clearPageUserSheet();

const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets() const;
void clearPageGroupUserSheets();

CSSStyleSheet* elementSheet();
CSSStyleSheet* mappedElementSheet();

@@ -934,7 +937,9 @@ class Document : public ContainerNode, public ScriptExecutionContext {
RefPtr<CSSStyleSheet> m_elemSheet;
RefPtr<CSSStyleSheet> m_mappedElementSheet;
RefPtr<CSSStyleSheet> m_pageUserSheet;

mutable OwnPtr<Vector<RefPtr<CSSStyleSheet> > > m_pageGroupUserSheets;
mutable bool m_pageGroupUserSheetCacheValid;

bool m_printing;

bool m_ignoreAutofocus;
@@ -37,7 +37,7 @@ void PlaceholderDocument::attach()

if (!styleSelector()) {
RefPtr<StyleSheetList> styleSheetList = StyleSheetList::create(this);
setStyleSelector(new CSSStyleSelector(this, pageUserSheet(), styleSheetList.get(), 0, true, false));
setStyleSelector(new CSSStyleSelector(this, styleSheetList.get(), 0, pageUserSheet(), pageGroupUserSheets(), true, false));
}

// Skipping Document::attach().
@@ -28,6 +28,7 @@

#include "ChromeClient.h"
#include "Document.h"
#include "Frame.h"
#include "Page.h"
#include "Settings.h"

@@ -212,15 +213,42 @@ void PageGroup::addUserScript(const String& source, const KURL& url, const Vecto
scriptsInWorld->append(userScript.release());
}

void PageGroup::removeUserContentForWorld(unsigned worldID)
void PageGroup::addUserStyleSheet(const String& source, const KURL& url, const Vector<String>& patterns, unsigned worldID)
{
if (!m_userScripts)
if (worldID == UINT_MAX)
return;
OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, patterns, worldID));
if (!m_userStyleSheets)
m_userStyleSheets.set(new UserStyleSheetMap);
UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(worldID, 0).first->second;
if (!styleSheetsInWorld)
styleSheetsInWorld = new UserStyleSheetVector;
styleSheetsInWorld->append(userStyleSheet.release());

// Clear our cached sheets and have them just reparse.
HashSet<Page*>::const_iterator end = m_pages.end();
for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
frame->document()->clearPageGroupUserSheets();
}
}

UserScriptMap::iterator it = m_userScripts->find(worldID);
if (it != m_userScripts->end()) {
m_userScripts->remove(it);
delete it->second;
void PageGroup::removeUserContentForWorld(unsigned worldID)
{
if (m_userScripts) {
UserScriptMap::iterator it = m_userScripts->find(worldID);
if (it != m_userScripts->end()) {
m_userScripts->remove(it);
delete it->second;
}
}

if (m_userStyleSheets) {
UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID);
if (it != m_userStyleSheets->end()) {
m_userStyleSheets->remove(it);
delete it->second;
}
}
}

@@ -230,6 +258,12 @@ void PageGroup::removeAllUserContent()
deleteAllValues(*m_userScripts);
m_userScripts.clear();
}


if (m_userStyleSheets) {
deleteAllValues(*m_userStyleSheets);
m_userStyleSheets.clear();
}
}

} // namespace WebCore

0 comments on commit ece8c11

Please sign in to comment.