Commit 63e0ac2f authored by hyatt@apple.com's avatar hyatt@apple.com

WebCore: https://bugs.webkit.org/show_bug.cgi?id=29102, add support for user...

WebCore: 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.

* 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.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48222 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1c73cb51
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.
......
<!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>
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 @@ public:
// 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 @@ public:
CSSStyleSheet* pageUserSheet();
void clearPageUserSheet();
const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets() const;
void clearPageGroupUserSheets();
CSSStyleSheet* elementSheet();
CSSStyleSheet* mappedElementSheet();
......@@ -934,7 +937,9 @@ private:
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
......@@ -31,6 +31,7 @@
#include "LinkHash.h"
#include "StringHash.h"
#include "UserScript.h"
#include "UserStyleSheet.h"
namespace WebCore {
......@@ -72,7 +73,10 @@ namespace WebCore {
void addUserScript(const String& source, const KURL&, const Vector<String>& patterns,
unsigned worldID, UserScriptInjectionTime);
const UserScriptMap* userScripts() const { return m_userScripts.get(); }
void addUserStyleSheet(const String& source, const KURL&, const Vector<String>& patterns, unsigned worldID);
const UserStyleSheetMap* userStyleSheets() const { return m_userStyleSheets.get(); }
void removeUserContentForWorld(unsigned);
void removeAllUserContent();
......@@ -92,6 +96,7 @@ namespace WebCore {
#endif
OwnPtr<UserScriptMap> m_userScripts;
OwnPtr<UserStyleSheetMap> m_userStyleSheets;
};
} // namespace WebCore
......
......@@ -36,7 +36,7 @@ enum UserScriptInjectionTime { InjectAtDocumentStart, InjectAtDocumentEnd };
class UserScript;
typedef Vector<OwnPtr<UserScript> > UserScriptVector;
typedef HashMap<int, UserScriptVector*> UserScriptMap;
typedef HashMap<unsigned, UserScriptVector*> UserScriptMap;
} // namsepace WebCore
......
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UserStyleSheet_h
#define UserStyleSheet_h
#include "KURL.h"
#include "UserStyleSheetTypes.h"
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
class UserStyleSheet {
public:
UserStyleSheet(const String& source, const KURL& url,
const Vector<String>& patterns, unsigned worldID)
: m_source(source)
, m_url(url)
, m_patterns(patterns)
, m_worldID(worldID)
{
}
const String& source() const { return m_source; }
const KURL& url() const { return m_url; }
const Vector<String>& patterns() const { return m_patterns; }
unsigned worldID() const { return m_worldID; }
private:
String m_source;
KURL m_url;
Vector<String> m_patterns;
unsigned m_worldID;
};
} // namsepace WebCore
#endif // UserStyleSheet_h
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UserStyleSheetTypes_h
#define UserStyleSheetTypes_h
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
namespace WebCore {
class UserStyleSheet;
typedef Vector<OwnPtr<UserStyleSheet> > UserStyleSheetVector;
typedef HashMap<unsigned, UserStyleSheetVector*> UserStyleSheetMap;
} // namsepace WebCore
#endif // UserStyleSheetTypes_h
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.
* WebView/WebView.mm:
(+[WebView _addUserStyleSheetToGroup:source:url:worldID:patterns:]):
* WebView/WebViewPrivate.h:
2009-09-07 Steve Block <steveblock@google.com>
Reviewed by Adam Barth.
......
......@@ -2133,6 +2133,28 @@ static inline IMP getMethod(id o, SEL s)
injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd);
}
+ (void)_addUserStyleSheetToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID patterns:(NSArray *)patterns
{
String group(groupName);
if (group.isEmpty() || worldID == UINT_MAX)
return;
PageGroup* pageGroup = PageGroup::pageGroup(group);
if (!pageGroup)
return;
// Convert the patterns into a Vector.
Vector<String> patternsVector;
NSUInteger count = [patterns count];
for (NSUInteger i = 0; i < count; ++i) {
id entry = [patterns objectAtIndex: i];
if ([entry isKindOfClass:[NSString class]])
patternsVector.append(String((NSString*)entry));
}
pageGroup->addUserStyleSheet(source, url, patternsVector, worldID);
}
+ (void)_removeUserContentFromGroup:(NSString *)groupName worldID:(unsigned)worldID
{
String group(groupName);
......
......@@ -458,6 +458,7 @@ Could be worth adding to the API.
+ (void)_resetOriginAccessWhiteLists;
+ (void)_addUserScriptToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID patterns:(NSArray *)patterns injectionTime:(WebUserScriptInjectionTime)injectionTime;
+ (void)_addUserStyleSheetToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID patterns:(NSArray *)patterns;
+ (void)_removeUserContentFromGroup:(NSString *)groupName worldID:(unsigned)worldID;
+ (void)_removeAllUserContentFromGroup:(NSString *)groupName;
......
......@@ -968,6 +968,19 @@ static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObj
return JSValueMakeUndefined(context);
}
static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
if (argumentCount != 1)
return JSValueMakeUndefined(context);
JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
ASSERT(!*exception);
LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
controller->addUserStyleSheet(source.get());
return JSValueMakeUndefined(context);
}
// Static Values
static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
......@@ -1045,6 +1058,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
static JSStaticFunction staticFunctions[] = {
{ "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
......
......@@ -188,6 +188,7 @@ public:
void whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains);
void addUserScript(JSStringRef source, bool runAtStart);
void addUserStyleSheet(JSStringRef source);
void setGeolocationPermission(bool allow);
bool isGeolocationPermissionSet() const { return m_isGeolocationPermissionSet; }
......
......@@ -466,3 +466,8 @@ void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart)
{
printf("LayoutTestController::addUserScript not implemented.\n");
}
void LayoutTestController::addUserStyleSheet(JSStringRef source)
{
printf("LayoutTestController::addUserStyleSheet not implemented.\n");
}
......@@ -484,3 +484,11 @@ void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart)