1/* 2 * Copyright (C) 2014 Igalia S.L. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "WebKitUserContent.h" 22 23#include "WebKitPrivate.h" 24#include "WebKitUserContentPrivate.h" 25#include <wtf/text/CString.h> 26#include <wtf/text/StringBuilder.h> 27 28using namespace WebCore; 29 30/** 31 * SECTION:WebKitUserContent 32 * @short_description: Defines user content types which affect web pages. 33 * @title: User content 34 * 35 * See also: #WebKitUserContentManager 36 * 37 * Since: 2.6 38 */ 39 40static inline UserContentInjectedFrames toUserContentInjectedFrames(WebKitUserContentInjectedFrames injectedFrames) 41{ 42 switch (injectedFrames) { 43 case WEBKIT_USER_CONTENT_INJECT_TOP_FRAME: 44 return InjectInTopFrameOnly; 45 case WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES: 46 return InjectInAllFrames; 47 default: 48 ASSERT_NOT_REACHED(); 49 return InjectInAllFrames; 50 } 51} 52 53static inline UserStyleLevel toUserStyleLevel(WebKitUserStyleLevel styleLevel) 54{ 55 switch (styleLevel) { 56 case WEBKIT_USER_STYLE_LEVEL_USER: 57 return UserStyleUserLevel; 58 case WEBKIT_USER_STYLE_LEVEL_AUTHOR: 59 return UserStyleAuthorLevel; 60 default: 61 ASSERT_NOT_REACHED(); 62 return UserStyleAuthorLevel; 63 } 64} 65 66static inline Vector<String> toStringVector(const char* const* strv) 67{ 68 if (!strv) 69 return Vector<String>(); 70 71 Vector<String> result; 72 for (auto str = strv; *str; ++str) 73 result.append(std::move(String::fromUTF8(*str))); 74 return result; 75} 76 77struct _WebKitUserStyleSheet { 78 _WebKitUserStyleSheet(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserStyleLevel level, const char* const* whitelist, const char* const* blacklist) 79 : userStyleSheet(std::make_unique<UserStyleSheet>( 80 String::fromUTF8(source), URL { }, 81 toStringVector(whitelist), toStringVector(blacklist), 82 toUserContentInjectedFrames(injectedFrames), 83 toUserStyleLevel(level))) 84 , referenceCount(1) 85 { 86 } 87 88 std::unique_ptr<UserStyleSheet> userStyleSheet; 89 int referenceCount; 90}; 91 92G_DEFINE_BOXED_TYPE(WebKitUserStyleSheet, webkit_user_style_sheet, webkit_user_style_sheet_ref, webkit_user_style_sheet_unref) 93 94/** 95 * webkit_user_style_sheet_ref: 96 * @user_style_sheet: a #WebKitUserStyleSheet 97 * 98 * Atomically increments the reference count of @user_style_sheet by one. 99 * This function is MT-safe and may be called from any thread. 100 * 101 * Returns: The passed #WebKitUserStyleSheet 102 * 103 * Since: 2.6 104 */ 105WebKitUserStyleSheet* webkit_user_style_sheet_ref(WebKitUserStyleSheet* userStyleSheet) 106{ 107 g_atomic_int_inc(&userStyleSheet->referenceCount); 108 return userStyleSheet; 109} 110 111/** 112 * webkit_user_style_sheet_unref: 113 * @user_style_sheet: a #WebKitUserStyleSheet 114 * 115 * Atomically decrements the reference count of @user_style_sheet by one. 116 * If the reference count drops to 0, all memory allocated by 117 * #WebKitUserStyleSheet is released. This function is MT-safe and may be 118 * called from any thread. 119 * 120 * Since: 2.6 121 */ 122void webkit_user_style_sheet_unref(WebKitUserStyleSheet* userStyleSheet) 123{ 124 if (g_atomic_int_dec_and_test(&userStyleSheet->referenceCount)) { 125 userStyleSheet->~WebKitUserStyleSheet(); 126 g_slice_free(WebKitUserStyleSheet, userStyleSheet); 127 } 128} 129 130/** 131 * webkit_user_style_sheet_new: 132 * @source: Source code of the user style sheet. 133 * @injected_frames: A #WebKitUserContentInjectedFrames value 134 * @level: A #WebKitUserStyleLevel 135 * @whitelist: (array zero-terminated=1) (allow-none): A whitelist of URI patterns or %NULL 136 * @blacklist: (array zero-terminated=1) (allow-none): A blacklist of URI patterns or %NULL 137 * 138 * Creates a new user style sheet. Style sheets can be applied to some URIs 139 * only by passing non-null values for @whitelist or @blacklist. Passing a 140 * %NULL whitelist implies that all URIs are on the whitelist. The style 141 * sheet is applied if an URI matches the whitelist and not the blacklist. 142 * URI patterns must be of the form `[protocol]://[host]/[path]`, where the 143 * *host* and *path* components can contain the wildcard character (`*`) to 144 * represent zero or more other characters. 145 * 146 * Returns: A new #WebKitUserStyleSheet 147 * 148 * Since: 2.6 149 */ 150WebKitUserStyleSheet* webkit_user_style_sheet_new(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserStyleLevel level, const char* const* whitelist, const char* const* blacklist) 151{ 152 g_return_val_if_fail(source, nullptr); 153 WebKitUserStyleSheet* userStyleSheet = g_slice_new(WebKitUserStyleSheet); 154 new (userStyleSheet) WebKitUserStyleSheet(source, injectedFrames, level, whitelist, blacklist); 155 return userStyleSheet; 156} 157 158const UserStyleSheet& webkitUserStyleSheetGetUserStyleSheet(WebKitUserStyleSheet* userStyleSheet) 159{ 160 return *userStyleSheet->userStyleSheet; 161} 162