1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "webkit/renderer/webpreferences_renderer.h"
6
7#include "base/strings/utf_string_conversions.h"
8#include "third_party/WebKit/public/web/WebKit.h"
9#include "third_party/WebKit/public/web/WebNetworkStateNotifier.h"
10#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
11#include "third_party/WebKit/public/web/WebSettings.h"
12#include "third_party/WebKit/public/web/WebView.h"
13#include "third_party/WebKit/public/platform/WebString.h"
14#include "third_party/WebKit/public/platform/WebURL.h"
15#include "third_party/icu/source/common/unicode/uchar.h"
16#include "third_party/icu/source/common/unicode/uscript.h"
17#include "webkit/common/webpreferences.h"
18
19using WebKit::WebNetworkStateNotifier;
20using WebKit::WebRuntimeFeatures;
21using WebKit::WebSettings;
22using WebKit::WebString;
23using WebKit::WebURL;
24using WebKit::WebView;
25
26namespace {
27
28typedef void (*SetFontFamilyWrapper)(
29    WebKit::WebSettings*, const base::string16&, UScriptCode);
30
31void setStandardFontFamilyWrapper(WebSettings* settings,
32                                  const base::string16& font,
33                                  UScriptCode script) {
34  settings->setStandardFontFamily(font, script);
35}
36
37void setFixedFontFamilyWrapper(WebSettings* settings,
38                               const base::string16& font,
39                               UScriptCode script) {
40  settings->setFixedFontFamily(font, script);
41}
42
43void setSerifFontFamilyWrapper(WebSettings* settings,
44                               const base::string16& font,
45                               UScriptCode script) {
46  settings->setSerifFontFamily(font, script);
47}
48
49void setSansSerifFontFamilyWrapper(WebSettings* settings,
50                                   const base::string16& font,
51                                   UScriptCode script) {
52  settings->setSansSerifFontFamily(font, script);
53}
54
55void setCursiveFontFamilyWrapper(WebSettings* settings,
56                                 const base::string16& font,
57                                 UScriptCode script) {
58  settings->setCursiveFontFamily(font, script);
59}
60
61void setFantasyFontFamilyWrapper(WebSettings* settings,
62                                 const base::string16& font,
63                                 UScriptCode script) {
64  settings->setFantasyFontFamily(font, script);
65}
66
67void setPictographFontFamilyWrapper(WebSettings* settings,
68                               const base::string16& font,
69                               UScriptCode script) {
70  settings->setPictographFontFamily(font, script);
71}
72
73// If |scriptCode| is a member of a family of "similar" script codes, returns
74// the script code in that family that is used by WebKit for font selection
75// purposes.  For example, USCRIPT_KATAKANA_OR_HIRAGANA and USCRIPT_JAPANESE are
76// considered equivalent for the purposes of font selection.  WebKit uses the
77// script code USCRIPT_KATAKANA_OR_HIRAGANA.  So, if |scriptCode| is
78// USCRIPT_JAPANESE, the function returns USCRIPT_KATAKANA_OR_HIRAGANA.  WebKit
79// uses different scripts than the ones in Chrome pref names because the version
80// of ICU included on certain ports does not have some of the newer scripts.  If
81// |scriptCode| is not a member of such a family, returns |scriptCode|.
82UScriptCode GetScriptForWebSettings(UScriptCode scriptCode) {
83  switch (scriptCode) {
84  case USCRIPT_HIRAGANA:
85  case USCRIPT_KATAKANA:
86  case USCRIPT_JAPANESE:
87    return USCRIPT_KATAKANA_OR_HIRAGANA;
88  case USCRIPT_KOREAN:
89    return USCRIPT_HANGUL;
90  default:
91    return scriptCode;
92  }
93}
94
95void ApplyFontsFromMap(const webkit_glue::ScriptFontFamilyMap& map,
96                       SetFontFamilyWrapper setter,
97                       WebSettings* settings) {
98  for (webkit_glue::ScriptFontFamilyMap::const_iterator it = map.begin();
99       it != map.end(); ++it) {
100    int32 script = u_getPropertyValueEnum(UCHAR_SCRIPT, (it->first).c_str());
101    if (script >= 0 && script < USCRIPT_CODE_LIMIT) {
102      UScriptCode code = static_cast<UScriptCode>(script);
103      (*setter)(settings, it->second, GetScriptForWebSettings(code));
104    }
105  }
106}
107
108}  // namespace
109
110namespace webkit_glue {
111
112void ApplyWebPreferences(const WebPreferences& prefs, WebView* web_view) {
113  WebSettings* settings = web_view->settings();
114  ApplyFontsFromMap(prefs.standard_font_family_map,
115                    setStandardFontFamilyWrapper, settings);
116  ApplyFontsFromMap(prefs.fixed_font_family_map,
117                    setFixedFontFamilyWrapper, settings);
118  ApplyFontsFromMap(prefs.serif_font_family_map,
119                    setSerifFontFamilyWrapper, settings);
120  ApplyFontsFromMap(prefs.sans_serif_font_family_map,
121                    setSansSerifFontFamilyWrapper, settings);
122  ApplyFontsFromMap(prefs.cursive_font_family_map,
123                    setCursiveFontFamilyWrapper, settings);
124  ApplyFontsFromMap(prefs.fantasy_font_family_map,
125                    setFantasyFontFamilyWrapper, settings);
126  ApplyFontsFromMap(prefs.pictograph_font_family_map,
127                    setPictographFontFamilyWrapper, settings);
128  settings->setDefaultFontSize(prefs.default_font_size);
129  settings->setDefaultFixedFontSize(prefs.default_fixed_font_size);
130  settings->setMinimumFontSize(prefs.minimum_font_size);
131  settings->setMinimumLogicalFontSize(prefs.minimum_logical_font_size);
132  settings->setDefaultTextEncodingName(ASCIIToUTF16(prefs.default_encoding));
133  settings->setJavaScriptEnabled(prefs.javascript_enabled);
134  settings->setWebSecurityEnabled(prefs.web_security_enabled);
135  settings->setJavaScriptCanOpenWindowsAutomatically(
136      prefs.javascript_can_open_windows_automatically);
137  settings->setLoadsImagesAutomatically(prefs.loads_images_automatically);
138  settings->setImagesEnabled(prefs.images_enabled);
139  settings->setPluginsEnabled(prefs.plugins_enabled);
140  settings->setDOMPasteAllowed(prefs.dom_paste_enabled);
141  settings->setNeedsSiteSpecificQuirks(prefs.site_specific_quirks_enabled);
142  settings->setShrinksStandaloneImagesToFit(
143      prefs.shrinks_standalone_images_to_fit);
144  settings->setUsesEncodingDetector(prefs.uses_universal_detector);
145  settings->setTextAreasAreResizable(prefs.text_areas_are_resizable);
146  settings->setAllowScriptsToCloseWindows(prefs.allow_scripts_to_close_windows);
147  if (prefs.user_style_sheet_enabled)
148    settings->setUserStyleSheetLocation(prefs.user_style_sheet_location);
149  else
150    settings->setUserStyleSheetLocation(WebURL());
151  settings->setAuthorAndUserStylesEnabled(prefs.author_and_user_styles_enabled);
152  settings->setDownloadableBinaryFontsEnabled(prefs.remote_fonts_enabled);
153  settings->setJavaScriptCanAccessClipboard(
154      prefs.javascript_can_access_clipboard);
155  settings->setXSSAuditorEnabled(prefs.xss_auditor_enabled);
156  settings->setDNSPrefetchingEnabled(prefs.dns_prefetching_enabled);
157  settings->setLocalStorageEnabled(prefs.local_storage_enabled);
158  settings->setSyncXHRInDocumentsEnabled(prefs.sync_xhr_in_documents_enabled);
159  WebRuntimeFeatures::enableDatabase(prefs.databases_enabled);
160  settings->setOfflineWebApplicationCacheEnabled(
161      prefs.application_cache_enabled);
162  settings->setCaretBrowsingEnabled(prefs.caret_browsing_enabled);
163  settings->setHyperlinkAuditingEnabled(prefs.hyperlink_auditing_enabled);
164  settings->setCookieEnabled(prefs.cookie_enabled);
165
166  // This setting affects the behavior of links in an editable region:
167  // clicking the link should select it rather than navigate to it.
168  // Safari uses the same default. It is unlikley an embedder would want to
169  // change this, since it would break existing rich text editors.
170  settings->setEditableLinkBehaviorNeverLive();
171
172  settings->setJavaEnabled(prefs.java_enabled);
173
174  // By default, allow_universal_access_from_file_urls is set to false and thus
175  // we mitigate attacks from local HTML files by not granting file:// URLs
176  // universal access. Only test shell will enable this.
177  settings->setAllowUniversalAccessFromFileURLs(
178      prefs.allow_universal_access_from_file_urls);
179  settings->setAllowFileAccessFromFileURLs(
180      prefs.allow_file_access_from_file_urls);
181
182  // Enable the web audio API if requested on the command line.
183  settings->setWebAudioEnabled(prefs.webaudio_enabled);
184
185  // Enable experimental WebGL support if requested on command line
186  // and support is compiled in.
187  settings->setExperimentalWebGLEnabled(prefs.experimental_webgl_enabled);
188
189  // Disable GL multisampling if requested on command line.
190  settings->setOpenGLMultisamplingEnabled(prefs.gl_multisampling_enabled);
191
192  // Enable privileged WebGL extensions for Chrome extensions or if requested
193  // on command line.
194  settings->setPrivilegedWebGLExtensionsEnabled(
195      prefs.privileged_webgl_extensions_enabled);
196
197  // Enable WebGL errors to the JS console if requested.
198  settings->setWebGLErrorsToConsoleEnabled(
199      prefs.webgl_errors_to_console_enabled);
200
201  // Enables accelerated compositing for overflow scroll.
202  settings->setAcceleratedCompositingForOverflowScrollEnabled(
203      prefs.accelerated_compositing_for_overflow_scroll_enabled);
204
205  // Enables accelerated compositing for scrollable frames if requested on
206  // command line.
207  settings->setAcceleratedCompositingForScrollableFramesEnabled(
208      prefs.accelerated_compositing_for_scrollable_frames_enabled);
209
210  // Enables composited scrolling for frames if requested on command line.
211  settings->setCompositedScrollingForFramesEnabled(
212      prefs.composited_scrolling_for_frames_enabled);
213
214  // Uses the mock theme engine for scrollbars.
215  settings->setMockScrollbarsEnabled(prefs.mock_scrollbars_enabled);
216
217  settings->setThreadedHTMLParser(prefs.threaded_html_parser);
218
219  // Display visualization of what has changed on the screen using an
220  // overlay of rects, if requested on the command line.
221  settings->setShowPaintRects(prefs.show_paint_rects);
222
223  // Enable gpu-accelerated compositing if requested on the command line.
224  settings->setAcceleratedCompositingEnabled(
225      prefs.accelerated_compositing_enabled);
226
227  // Enable gpu-accelerated 2d canvas if requested on the command line.
228  settings->setAccelerated2dCanvasEnabled(prefs.accelerated_2d_canvas_enabled);
229
230  settings->setMinimumAccelerated2dCanvasSize(
231      prefs.minimum_accelerated_2d_canvas_size);
232
233  // Disable antialiasing for 2d canvas if requested on the command line.
234  settings->setAntialiased2dCanvasEnabled(
235      !prefs.antialiased_2d_canvas_disabled);
236
237  // Enable gpu-accelerated filters if requested on the command line.
238  settings->setAcceleratedFiltersEnabled(prefs.accelerated_filters_enabled);
239
240  // Enable gesture tap highlight if requested on the command line.
241  settings->setGestureTapHighlightEnabled(prefs.gesture_tap_highlight_enabled);
242
243  // Enabling accelerated layers from the command line enabled accelerated
244  // 3D CSS, Video, and Animations.
245  settings->setAcceleratedCompositingFor3DTransformsEnabled(
246      prefs.accelerated_compositing_for_3d_transforms_enabled);
247  settings->setAcceleratedCompositingForVideoEnabled(
248      prefs.accelerated_compositing_for_video_enabled);
249  settings->setAcceleratedCompositingForAnimationEnabled(
250      prefs.accelerated_compositing_for_animation_enabled);
251
252  // Enabling accelerated plugins if specified from the command line.
253  settings->setAcceleratedCompositingForPluginsEnabled(
254      prefs.accelerated_compositing_for_plugins_enabled);
255
256  // WebGL and accelerated 2D canvas are always gpu composited.
257  settings->setAcceleratedCompositingForCanvasEnabled(
258      prefs.experimental_webgl_enabled || prefs.accelerated_2d_canvas_enabled);
259
260  // Enable memory info reporting to page if requested on the command line.
261  settings->setMemoryInfoEnabled(prefs.memory_info_enabled);
262
263  settings->setAsynchronousSpellCheckingEnabled(
264      prefs.asynchronous_spell_checking_enabled);
265  settings->setUnifiedTextCheckerEnabled(prefs.unified_textchecker_enabled);
266
267  for (webkit_glue::WebInspectorPreferences::const_iterator it =
268           prefs.inspector_settings.begin();
269       it != prefs.inspector_settings.end(); ++it)
270    web_view->setInspectorSetting(WebString::fromUTF8(it->first),
271                                  WebString::fromUTF8(it->second));
272
273  // Tabs to link is not part of the settings. WebCore calls
274  // ChromeClient::tabsToLinks which is part of the glue code.
275  web_view->setTabsToLinks(prefs.tabs_to_links);
276
277  settings->setFullScreenEnabled(prefs.fullscreen_enabled);
278  settings->setAllowDisplayOfInsecureContent(
279      prefs.allow_displaying_insecure_content);
280  settings->setAllowRunningOfInsecureContent(
281      prefs.allow_running_insecure_content);
282  settings->setPasswordEchoEnabled(prefs.password_echo_enabled);
283  settings->setShouldPrintBackgrounds(prefs.should_print_backgrounds);
284  settings->setShouldClearDocumentBackground(
285      prefs.should_clear_document_background);
286  settings->setEnableScrollAnimator(prefs.enable_scroll_animator);
287  settings->setVisualWordMovementEnabled(prefs.visual_word_movement_enabled);
288
289  settings->setCSSStickyPositionEnabled(prefs.css_sticky_position_enabled);
290  settings->setExperimentalCSSCustomFilterEnabled(prefs.css_shaders_enabled);
291  settings->setRegionBasedColumnsEnabled(prefs.region_based_columns_enabled);
292
293  WebRuntimeFeatures::enableLazyLayout(prefs.lazy_layout_enabled);
294  WebRuntimeFeatures::enableTouch(prefs.touch_enabled);
295  settings->setDeviceSupportsTouch(prefs.device_supports_touch);
296  settings->setDeviceSupportsMouse(prefs.device_supports_mouse);
297  settings->setEnableTouchAdjustment(prefs.touch_adjustment_enabled);
298
299  settings->setFixedPositionCreatesStackingContext(
300      prefs.fixed_position_creates_stacking_context);
301
302  settings->setDeferredImageDecodingEnabled(
303      prefs.deferred_image_decoding_enabled);
304  settings->setShouldRespectImageOrientation(
305      prefs.should_respect_image_orientation);
306
307  settings->setUnsafePluginPastingEnabled(false);
308  settings->setEditingBehavior(
309      static_cast<WebSettings::EditingBehavior>(prefs.editing_behavior));
310
311  settings->setSupportsMultipleWindows(prefs.supports_multiple_windows);
312
313  settings->setViewportEnabled(prefs.viewport_enabled);
314  settings->setInitializeAtMinimumPageScale(
315      prefs.initialize_at_minimum_page_scale);
316
317  settings->setSmartInsertDeleteEnabled(prefs.smart_insert_delete_enabled);
318
319  settings->setSpatialNavigationEnabled(prefs.spatial_navigation_enabled);
320
321  settings->setSelectionIncludesAltImageText(true);
322
323#if defined(OS_ANDROID)
324  settings->setAllowCustomScrollbarInMainFrame(false);
325  settings->setTextAutosizingEnabled(prefs.text_autosizing_enabled);
326  settings->setTextAutosizingFontScaleFactor(prefs.font_scale_factor);
327  web_view->setIgnoreViewportTagScaleLimits(prefs.force_enable_zoom);
328  settings->setAutoZoomFocusedNodeToLegibleScale(true);
329  settings->setDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
330  settings->setMediaPlaybackRequiresUserGesture(
331      prefs.user_gesture_required_for_media_playback);
332  settings->setDefaultVideoPosterURL(
333        ASCIIToUTF16(prefs.default_video_poster_url.spec()));
334  settings->setSupportDeprecatedTargetDensityDPI(
335      prefs.support_deprecated_target_density_dpi);
336  settings->setUseLegacyBackgroundSizeShorthandBehavior(
337      prefs.use_legacy_background_size_shorthand_behavior);
338  settings->setWideViewportQuirkEnabled(prefs.wide_viewport_quirk);
339  settings->setUseWideViewport(prefs.use_wide_viewport);
340  settings->setViewportMetaLayoutSizeQuirk(
341      prefs.viewport_meta_layout_size_quirk);
342  settings->setViewportMetaMergeQuirk(prefs.viewport_meta_merge_quirk);
343  settings->setViewportMetaZeroValuesQuirk(
344      prefs.viewport_meta_zero_values_quirk);
345  settings->setIgnoreMainFrameOverflowHiddenQuirk(
346      prefs.ignore_main_frame_overflow_hidden_quirk);
347  settings->setReportScreenSizeInPhysicalPixelsQuirk(
348      prefs.report_screen_size_in_physical_pixels_quirk);
349#endif
350
351  WebNetworkStateNotifier::setOnLine(prefs.is_online);
352  settings->setExperimentalWebSocketEnabled(
353      prefs.experimental_websocket_enabled);
354  settings->setPinchVirtualViewportEnabled(
355      prefs.pinch_virtual_viewport_enabled);
356
357  settings->setPinchOverlayScrollbarThickness(
358      prefs.pinch_overlay_scrollbar_thickness);
359  settings->setCompositorTouchHitTesting(prefs.compositor_touch_hit_testing);
360}
361
362
363}  // namespace webkit_glue
364