Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / common / Settings.js
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31
32 var Preferences = {
33     maxInlineTextChildLength: 80,
34     minSidebarWidth: 100,
35     minSidebarHeight: 75,
36     applicationTitle: "Developer Tools - %s"
37 }
38
39 var Capabilities = {
40     isMainFrontend: false,
41     canProfilePower: false,
42 }
43
44 /**
45  * @constructor
46  */
47 WebInspector.Settings = function()
48 {
49     this._eventSupport = new WebInspector.Object();
50     this._registry = /** @type {!Object.<string, !WebInspector.Setting>} */ ({});
51
52     this.colorFormat = this.createSetting("colorFormat", "original");
53     this.consoleHistory = this.createSetting("consoleHistory", []);
54     this.domWordWrap = this.createSetting("domWordWrap", true);
55     this.eventListenersFilter = this.createSetting("eventListenersFilter", "all");
56     this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
57     this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
58     this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
59     this.consoleTimestampsEnabled = this.createSetting("consoleTimestampsEnabled", false);
60     this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
61     this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
62     this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
63     this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false);
64     this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true);
65     this.watchExpressions = this.createSetting("watchExpressions", []);
66     this.breakpoints = this.createSetting("breakpoints", []);
67     this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []);
68     this.domBreakpoints = this.createSetting("domBreakpoints", []);
69     this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []);
70     this.jsSourceMapsEnabled = this.createSetting("sourceMapsEnabled", true);
71     this.cssSourceMapsEnabled = this.createSetting("cssSourceMapsEnabled", true);
72     this.cacheDisabled = this.createSetting("cacheDisabled", false);
73     this.showUAShadowDOM = this.createSetting("showUAShadowDOM", false);
74     this.savedURLs = this.createSetting("savedURLs", {});
75     this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false);
76     this.showAdvancedHeapSnapshotProperties = this.createSetting("showAdvancedHeapSnapshotProperties", false);
77     this.highResolutionCpuProfiling = this.createSetting("highResolutionCpuProfiling", false);
78     this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
79     this.textEditorIndent = this.createSetting("textEditorIndent", "    ");
80     this.textEditorAutoDetectIndent = this.createSetting("textEditorAutoIndentIndent", true);
81     this.textEditorAutocompletion = this.createSetting("textEditorAutocompletion", true);
82     this.textEditorBracketMatching = this.createSetting("textEditorBracketMatching", true);
83     this.cssReloadEnabled = this.createSetting("cssReloadEnabled", false);
84     this.timelineLiveUpdate = this.createSetting("timelineLiveUpdate", true);
85     this.showMetricsRulers = this.createSetting("showMetricsRulers", false);
86     this.workerInspectorWidth = this.createSetting("workerInspectorWidth", 600);
87     this.workerInspectorHeight = this.createSetting("workerInspectorHeight", 600);
88     this.messageURLFilters = this.createSetting("messageURLFilters", {});
89     this.networkHideDataURL = this.createSetting("networkHideDataURL", false);
90     this.networkResourceTypeFilters = this.createSetting("networkResourceTypeFilters", {});
91     this.messageLevelFilters = this.createSetting("messageLevelFilters", {});
92     this.splitVerticallyWhenDockedToRight = this.createSetting("splitVerticallyWhenDockedToRight", true);
93     this.visiblePanels = this.createSetting("visiblePanels", {});
94     this.shortcutPanelSwitch = this.createSetting("shortcutPanelSwitch", false);
95     this.showWhitespacesInEditor = this.createSetting("showWhitespacesInEditor", false);
96     this.skipStackFramesSwitch = this.createSetting("skipStackFramesSwitch", false);
97     this.skipStackFramesPattern = this.createRegExpSetting("skipStackFramesPattern", "");
98     this.pauseOnExceptionEnabled = this.createSetting("pauseOnExceptionEnabled", false);
99     this.pauseOnCaughtException = this.createSetting("pauseOnCaughtException", false);
100     this.enableAsyncStackTraces = this.createSetting("enableAsyncStackTraces", false);
101 }
102
103 WebInspector.Settings.prototype = {
104     /**
105      * @param {string} key
106      * @param {*} defaultValue
107      * @return {!WebInspector.Setting}
108      */
109     createSetting: function(key, defaultValue)
110     {
111         if (!this._registry[key])
112             this._registry[key] = new WebInspector.Setting(key, defaultValue, this._eventSupport, window.localStorage);
113         return this._registry[key];
114     },
115
116     /**
117      * @param {string} key
118      * @param {string} defaultValue
119      * @param {string=} regexFlags
120      * @return {!WebInspector.Setting}
121      */
122     createRegExpSetting: function(key, defaultValue, regexFlags)
123     {
124         if (!this._registry[key])
125             this._registry[key] = new WebInspector.RegExpSetting(key, defaultValue, this._eventSupport, window.localStorage, regexFlags);
126         return this._registry[key];
127     },
128
129     /**
130      * @param {string} key
131      * @param {*} defaultValue
132      * @param {function(*, function(string, ...))} setterCallback
133      * @return {!WebInspector.Setting}
134      */
135     createBackendSetting: function(key, defaultValue, setterCallback)
136     {
137         if (!this._registry[key])
138             this._registry[key] = new WebInspector.BackendSetting(key, defaultValue, this._eventSupport, window.localStorage, setterCallback);
139         return this._registry[key];
140     },
141
142     initializeBackendSettings: function()
143     {
144         this.showPaintRects = WebInspector.settings.createBackendSetting("showPaintRects", false, PageAgent.setShowPaintRects.bind(PageAgent));
145         this.showDebugBorders = WebInspector.settings.createBackendSetting("showDebugBorders", false, PageAgent.setShowDebugBorders.bind(PageAgent));
146         this.continuousPainting = WebInspector.settings.createBackendSetting("continuousPainting", false, PageAgent.setContinuousPaintingEnabled.bind(PageAgent));
147         this.showFPSCounter = WebInspector.settings.createBackendSetting("showFPSCounter", false, PageAgent.setShowFPSCounter.bind(PageAgent));
148         this.showScrollBottleneckRects = WebInspector.settings.createBackendSetting("showScrollBottleneckRects", false, PageAgent.setShowScrollBottleneckRects.bind(PageAgent));
149     }
150 }
151
152 /**
153  * @constructor
154  * @param {string} name
155  * @param {V} defaultValue
156  * @param {!WebInspector.Object} eventSupport
157  * @param {?Storage} storage
158  * @template V
159  */
160 WebInspector.Setting = function(name, defaultValue, eventSupport, storage)
161 {
162     this._name = name;
163     this._defaultValue = defaultValue;
164     this._eventSupport = eventSupport;
165     this._storage = storage;
166 }
167
168 WebInspector.Setting.prototype = {
169     /**
170      * @param {function(!WebInspector.Event)} listener
171      * @param {!Object=} thisObject
172      */
173     addChangeListener: function(listener, thisObject)
174     {
175         this._eventSupport.addEventListener(this._name, listener, thisObject);
176     },
177
178     /**
179      * @param {function(!WebInspector.Event)} listener
180      * @param {!Object=} thisObject
181      */
182     removeChangeListener: function(listener, thisObject)
183     {
184         this._eventSupport.removeEventListener(this._name, listener, thisObject);
185     },
186
187     get name()
188     {
189         return this._name;
190     },
191
192     /**
193      * @return {V}
194      */
195     get: function()
196     {
197         if (typeof this._value !== "undefined")
198             return this._value;
199
200         this._value = this._defaultValue;
201         if (this._storage && this._name in this._storage) {
202             try {
203                 this._value = JSON.parse(this._storage[this._name]);
204             } catch(e) {
205                 delete this._storage[this._name];
206             }
207         }
208         return this._value;
209     },
210
211     set: function(value)
212     {
213         this._value = value;
214         if (this._storage) {
215             try {
216                 this._storage[this._name] = JSON.stringify(value);
217             } catch(e) {
218                 console.error("Error saving setting with name:" + this._name);
219             }
220         }
221         this._eventSupport.dispatchEventToListeners(this._name, value);
222     }
223 }
224
225 /**
226  * @constructor
227  * @extends {WebInspector.Setting}
228  * @param {string} name
229  * @param {string} defaultValue
230  * @param {!WebInspector.Object} eventSupport
231  * @param {?Storage} storage
232  * @param {string=} regexFlags
233  */
234 WebInspector.RegExpSetting = function(name, defaultValue, eventSupport, storage, regexFlags)
235 {
236     WebInspector.Setting.call(this, name, defaultValue, eventSupport, storage);
237     this._regexFlags = regexFlags;
238 }
239
240 WebInspector.RegExpSetting.prototype = {
241     set: function(value)
242     {
243         delete this._regex;
244         WebInspector.Setting.prototype.set.call(this, value);
245     },
246
247     /**
248      * @return {?RegExp}
249      */
250     asRegExp: function()
251     {
252         if (typeof this._regex !== "undefined")
253             return this._regex;
254         this._regex = null;
255         try {
256             this._regex = new RegExp(this.get(), this._regexFlags || "");
257         } catch (e) {
258         }
259         return this._regex;
260     },
261
262     __proto__: WebInspector.Setting.prototype
263 }
264
265 /**
266  * @constructor
267  * @extends {WebInspector.Setting}
268  * @param {string} name
269  * @param {*} defaultValue
270  * @param {!WebInspector.Object} eventSupport
271  * @param {?Storage} storage
272  * @param {function(*,function(string, ...))} setterCallback
273  */
274 WebInspector.BackendSetting = function(name, defaultValue, eventSupport, storage, setterCallback)
275 {
276     WebInspector.Setting.call(this, name, defaultValue, eventSupport, storage);
277     this._setterCallback = setterCallback;
278     var currentValue = this.get();
279     if (currentValue !== defaultValue)
280         this.set(currentValue);
281 }
282
283 WebInspector.BackendSetting.prototype = {
284     set: function(value)
285     {
286         /**
287          * @param {?Protocol.Error} error
288          * @this {WebInspector.BackendSetting}
289          */
290         function callback(error)
291         {
292             if (error) {
293                 WebInspector.console.log("Error applying setting " + this._name + ": " + error);
294                 this._eventSupport.dispatchEventToListeners(this._name, this._value);
295                 return;
296             }
297             WebInspector.Setting.prototype.set.call(this, value);
298         }
299         this._setterCallback(value, callback.bind(this));
300     },
301
302     __proto__: WebInspector.Setting.prototype
303 }
304
305 /**
306  * @constructor
307  * @param {boolean} experimentsEnabled
308  */
309 WebInspector.ExperimentsSettings = function(experimentsEnabled)
310 {
311     this._experimentsEnabled = experimentsEnabled;
312     this._setting = WebInspector.settings.createSetting("experiments", {});
313     this._experiments = [];
314     this._enabledForTest = {};
315
316     // Add currently running experiments here.
317     this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
318     this.canvasInspection = this._createExperiment("canvasInspection ", "Canvas inspection");
319     this.frameworksDebuggingSupport = this._createExperiment("frameworksDebuggingSupport", "Enable frameworks debugging support");
320     this.layersPanel = this._createExperiment("layersPanel", "Show Layers panel");
321     this.showEditorInDrawer = this._createExperiment("showEditorInDrawer", "Show editor in drawer");
322     this.gpuTimeline = this._createExperiment("gpuTimeline", "Show GPU data on timeline");
323     this.applyCustomStylesheet = this._createExperiment("applyCustomStylesheet", "Allow custom UI themes");
324     this.workersInMainWindow = this._createExperiment("workersInMainWindow", "Show workers in main window");
325     this.dockToLeft = this._createExperiment("dockToLeft", "Enable dock to left mode");
326     this.allocationProfiler = this._createExperiment("allocationProfiler", "Enable JavaScript heap allocation profiler");
327     this.heapSnapshotStatistics = this._createExperiment("heapSnapshotStatistics", "Show memory breakdown statistics in heap snapshots");
328     this.timelineNoLiveUpdate = this._createExperiment("timelineNoLiveUpdate", "Timeline w/o live update");
329     this.powerProfiler = this._createExperiment("powerProfiler", "Enable power mode in Timeline");
330     this.timelineFlameChart = this._createExperiment("timelineFlameChart", "Enable FlameChart mode in Timeline");
331     this.timelineOnTraceEvents = this._createExperiment("timelineOnTraceEvents", "Use trace events as Timeline backend");
332     this.timelineTracingMode = this._createExperiment("timelineTracingMode", "Enable Tracing mode in Timeline");
333     this.devicesPanel = this._createExperiment("devicesPanel", "Show devices in drawer");
334     this.timelineJSCPUProfile = this._createExperiment("timelineJSCPUProfile", "Collect JavaScript CPU profile while recording timeline");
335
336     this._cleanUpSetting();
337 }
338
339 WebInspector.ExperimentsSettings.prototype = {
340     /**
341      * @return {!Array.<!WebInspector.Experiment>}
342      */
343     get experiments()
344     {
345         return this._experiments.slice();
346     },
347
348     /**
349      * @return {boolean}
350      */
351     get experimentsEnabled()
352     {
353         return this._experimentsEnabled;
354     },
355
356     /**
357      * @param {string} experimentName
358      * @param {string} experimentTitle
359      * @return {!WebInspector.Experiment}
360      */
361     _createExperiment: function(experimentName, experimentTitle)
362     {
363         var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
364         this._experiments.push(experiment);
365         return experiment;
366     },
367
368     /**
369      * @param {string} experimentName
370      * @return {boolean}
371      */
372     isEnabled: function(experimentName)
373     {
374         if (this._enabledForTest[experimentName])
375             return true;
376
377         if (!this.experimentsEnabled)
378             return false;
379
380         var experimentsSetting = this._setting.get();
381         return experimentsSetting[experimentName];
382     },
383
384     /**
385      * @param {string} experimentName
386      * @param {boolean} enabled
387      */
388     setEnabled: function(experimentName, enabled)
389     {
390         var experimentsSetting = this._setting.get();
391         experimentsSetting[experimentName] = enabled;
392         this._setting.set(experimentsSetting);
393     },
394
395     /**
396      * @param {string} experimentName
397      */
398     _enableForTest: function(experimentName)
399     {
400         this._enabledForTest[experimentName] = true;
401     },
402
403     _cleanUpSetting: function()
404     {
405         var experimentsSetting = this._setting.get();
406         var cleanedUpExperimentSetting = {};
407         for (var i = 0; i < this._experiments.length; ++i) {
408             var experimentName = this._experiments[i].name;
409             if (experimentsSetting[experimentName])
410                 cleanedUpExperimentSetting[experimentName] = true;
411         }
412         this._setting.set(cleanedUpExperimentSetting);
413     }
414 }
415
416 /**
417  * @constructor
418  * @param {!WebInspector.ExperimentsSettings} experimentsSettings
419  * @param {string} name
420  * @param {string} title
421  */
422 WebInspector.Experiment = function(experimentsSettings, name, title)
423 {
424     this._name = name;
425     this._title = title;
426     this._experimentsSettings = experimentsSettings;
427 }
428
429 WebInspector.Experiment.prototype = {
430     /**
431      * @return {string}
432      */
433     get name()
434     {
435         return this._name;
436     },
437
438     /**
439      * @return {string}
440      */
441     get title()
442     {
443         return this._title;
444     },
445
446     /**
447      * @return {boolean}
448      */
449     isEnabled: function()
450     {
451         return this._experimentsSettings.isEnabled(this._name);
452     },
453
454     /**
455      * @param {boolean} enabled
456      */
457     setEnabled: function(enabled)
458     {
459         this._experimentsSettings.setEnabled(this._name, enabled);
460     },
461
462     enableForTest: function()
463     {
464         this._experimentsSettings._enableForTest(this._name);
465     }
466 }
467
468 /**
469  * @constructor
470  */
471 WebInspector.VersionController = function()
472 {
473 }
474
475 WebInspector.VersionController.currentVersion = 8;
476
477 WebInspector.VersionController.prototype = {
478     updateVersion: function()
479     {
480         var versionSetting = WebInspector.settings.createSetting("inspectorVersion", 0);
481         var currentVersion = WebInspector.VersionController.currentVersion;
482         var oldVersion = versionSetting.get();
483         var methodsToRun = this._methodsToRunToUpdateVersion(oldVersion, currentVersion);
484         for (var i = 0; i < methodsToRun.length; ++i)
485             this[methodsToRun[i]].call(this);
486         versionSetting.set(currentVersion);
487     },
488
489     /**
490      * @param {number} oldVersion
491      * @param {number} currentVersion
492      */
493     _methodsToRunToUpdateVersion: function(oldVersion, currentVersion)
494     {
495         var result = [];
496         for (var i = oldVersion; i < currentVersion; ++i)
497             result.push("_updateVersionFrom" + i + "To" + (i + 1));
498         return result;
499     },
500
501     _updateVersionFrom0To1: function()
502     {
503         this._clearBreakpointsWhenTooMany(WebInspector.settings.breakpoints, 500000);
504     },
505
506     _updateVersionFrom1To2: function()
507     {
508         var versionSetting = WebInspector.settings.createSetting("previouslyViewedFiles", []);
509         versionSetting.set([]);
510     },
511
512     _updateVersionFrom2To3: function()
513     {
514         var fileSystemMappingSetting = WebInspector.settings.createSetting("fileSystemMapping", {});
515         fileSystemMappingSetting.set({});
516         if (window.localStorage)
517             delete window.localStorage["fileMappingEntries"];
518     },
519
520     _updateVersionFrom3To4: function()
521     {
522         var advancedMode = WebInspector.settings.createSetting("showHeaSnapshotObjectsHiddenProperties", false).get();
523         WebInspector.settings.showAdvancedHeapSnapshotProperties.set(advancedMode);
524     },
525
526     _updateVersionFrom4To5: function()
527     {
528         if (!window.localStorage)
529             return;
530         var settingNames = {
531             "FileSystemViewSidebarWidth": "fileSystemViewSplitViewState",
532             "canvasProfileViewReplaySplitLocation": "canvasProfileViewReplaySplitViewState",
533             "canvasProfileViewSplitLocation": "canvasProfileViewSplitViewState",
534             "elementsSidebarWidth": "elementsPanelSplitViewState",
535             "StylesPaneSplitRatio": "stylesPaneSplitViewState",
536             "heapSnapshotRetainersViewSize": "heapSnapshotSplitViewState",
537             "InspectorView.splitView": "InspectorView.splitViewState",
538             "InspectorView.screencastSplitView": "InspectorView.screencastSplitViewState",
539             "Inspector.drawerSplitView": "Inspector.drawerSplitViewState",
540             "layerDetailsSplitView": "layerDetailsSplitViewState",
541             "networkSidebarWidth": "networkPanelSplitViewState",
542             "sourcesSidebarWidth": "sourcesPanelSplitViewState",
543             "scriptsPanelNavigatorSidebarWidth": "sourcesPanelNavigatorSplitViewState",
544             "sourcesPanelSplitSidebarRatio": "sourcesPanelDebuggerSidebarSplitViewState",
545             "timeline-details": "timelinePanelDetailsSplitViewState",
546             "timeline-split": "timelinePanelRecorsSplitViewState",
547             "timeline-view": "timelinePanelTimelineStackSplitViewState",
548             "auditsSidebarWidth": "auditsPanelSplitViewState",
549             "layersSidebarWidth": "layersPanelSplitViewState",
550             "profilesSidebarWidth": "profilesPanelSplitViewState",
551             "resourcesSidebarWidth": "resourcesPanelSplitViewState"
552         };
553         for (var oldName in settingNames) {
554             var newName = settingNames[oldName];
555             var oldNameH = oldName + "H";
556
557             var newValue = null;
558             var oldSetting = WebInspector.settings.createSetting(oldName, undefined).get();
559             if (oldSetting) {
560                 newValue = newValue || {};
561                 newValue.vertical = {};
562                 newValue.vertical.size = oldSetting;
563                 delete window.localStorage[oldName];
564             }
565             var oldSettingH = WebInspector.settings.createSetting(oldNameH, undefined).get();
566             if (oldSettingH) {
567                 newValue = newValue || {};
568                 newValue.horizontal = {};
569                 newValue.horizontal.size = oldSettingH;
570                 delete window.localStorage[oldNameH];
571             }
572             var newSetting = WebInspector.settings.createSetting(newName, {});
573             if (newValue)
574                 newSetting.set(newValue);
575         }
576     },
577
578     _updateVersionFrom5To6: function()
579     {
580         if (!window.localStorage)
581             return;
582
583         var settingNames = {
584             "debuggerSidebarHidden": "sourcesPanelSplitViewState",
585             "navigatorHidden": "sourcesPanelNavigatorSplitViewState",
586             "WebInspector.Drawer.showOnLoad": "Inspector.drawerSplitViewState"
587         };
588
589         for (var oldName in settingNames) {
590             var newName = settingNames[oldName];
591
592             var oldSetting = WebInspector.settings.createSetting(oldName, undefined).get();
593             var invert = "WebInspector.Drawer.showOnLoad" === oldName;
594             var hidden = !!oldSetting !== invert;
595             delete window.localStorage[oldName];
596             var showMode = hidden ? "OnlyMain" : "Both";
597
598             var newSetting = WebInspector.settings.createSetting(newName, null);
599             var newValue = newSetting.get() || {};
600             newValue.vertical = newValue.vertical || {};
601             newValue.vertical.showMode = showMode;
602             newValue.horizontal = newValue.horizontal || {};
603             newValue.horizontal.showMode = showMode;
604             newSetting.set(newValue);
605         }
606     },
607
608     _updateVersionFrom6To7: function()
609     {
610         if (!window.localStorage)
611             return;
612
613         var settingNames = {
614             "sourcesPanelNavigatorSplitViewState": "sourcesPanelNavigatorSplitViewState",
615             "elementsPanelSplitViewState": "elementsPanelSplitViewState",
616             "canvasProfileViewReplaySplitViewState": "canvasProfileViewReplaySplitViewState",
617             "editorInDrawerSplitViewState": "editorInDrawerSplitViewState",
618             "stylesPaneSplitViewState": "stylesPaneSplitViewState",
619             "sourcesPanelDebuggerSidebarSplitViewState": "sourcesPanelDebuggerSidebarSplitViewState"
620         };
621
622         for (var name in settingNames) {
623             if (!(name in window.localStorage))
624                 continue;
625             var setting = WebInspector.settings.createSetting(name, undefined);
626             var value = setting.get();
627             if (!value)
628                 continue;
629             // Zero out saved percentage sizes, and they will be restored to defaults.
630             if (value.vertical && value.vertical.size && value.vertical.size < 1)
631                 value.vertical.size = 0;
632             if (value.horizontal && value.horizontal.size && value.horizontal.size < 1)
633                 value.horizontal.size = 0;
634             setting.set(value);
635         }
636     },
637
638     _updateVersionFrom7To8: function()
639     {
640         var settingName = "deviceMetrics";
641         if (!window.localStorage || !(settingName in window.localStorage))
642             return;
643         var setting = WebInspector.settings.createSetting(settingName, undefined);
644         var value = setting.get();
645         if (!value)
646             return;
647
648         var components = value.split("x");
649         if (components.length >= 3) {
650             var width = parseInt(components[0], 10);
651             var height = parseInt(components[1], 10);
652             var deviceScaleFactor = parseFloat(components[2]);
653             if (deviceScaleFactor) {
654                 components[0] = "" + Math.round(width / deviceScaleFactor);
655                 components[1] = "" + Math.round(height / deviceScaleFactor);
656             }
657         }
658         value = components.join("x");
659         setting.set(value);
660     },
661
662     /**
663      * @param {!WebInspector.Setting} breakpointsSetting
664      * @param {number} maxBreakpointsCount
665      */
666     _clearBreakpointsWhenTooMany: function(breakpointsSetting, maxBreakpointsCount)
667     {
668         // If there are too many breakpoints in a storage, it is likely due to a recent bug that caused
669         // periodical breakpoints duplication leading to inspector slowness.
670         if (breakpointsSetting.get().length > maxBreakpointsCount)
671             breakpointsSetting.set([]);
672     }
673 }
674
675 WebInspector.settings = new WebInspector.Settings();
676 WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings(WebInspector.queryParam("experiments") !== null);
677
678 // These methods are added for backwards compatibility with Devtools CodeSchool extension.
679 // DO NOT REMOVE
680
681 /**
682  * @constructor
683  */
684 WebInspector.PauseOnExceptionStateSetting = function()
685 {
686     WebInspector.settings.pauseOnExceptionEnabled.addChangeListener(this._enabledChanged, this);
687     WebInspector.settings.pauseOnCaughtException.addChangeListener(this._pauseOnCaughtChanged, this);
688     this._name = "pauseOnExceptionStateString";
689     this._eventSupport = new WebInspector.Object();
690     this._value = this._calculateValue();
691 }
692
693 WebInspector.PauseOnExceptionStateSetting.prototype = {
694     /**
695      * @param {function(!WebInspector.Event)} listener
696      * @param {!Object=} thisObject
697      */
698     addChangeListener: function(listener, thisObject)
699     {
700         this._eventSupport.addEventListener(this._name, listener, thisObject);
701     },
702
703     /**
704      * @param {function(!WebInspector.Event)} listener
705      * @param {!Object=} thisObject
706      */
707     removeChangeListener: function(listener, thisObject)
708     {
709         this._eventSupport.removeEventListener(this._name, listener, thisObject);
710     },
711
712     /**
713      * @return {string}
714      */
715     get: function()
716     {
717         return this._value;
718     },
719
720     /**
721      * @return {string}
722      */
723     _calculateValue: function()
724     {
725         if (!WebInspector.settings.pauseOnExceptionEnabled.get())
726             return "none";
727         // The correct code here would be
728         //     return WebInspector.settings.pauseOnCaughtException.get() ? "all" : "uncaught";
729         // But the CodeSchool DevTools relies on the fact that we used to enable pausing on ALL extensions by default, so we trick it here.
730         return "all";
731     },
732
733     _enabledChanged: function(event)
734     {
735         this._fireChangedIfNeeded();
736     },
737
738     _pauseOnCaughtChanged: function(event)
739     {
740         this._fireChangedIfNeeded();
741     },
742
743     _fireChangedIfNeeded: function()
744     {
745         var newValue = this._calculateValue();
746         if (newValue === this._value)
747             return;
748         this._value = newValue;
749         this._eventSupport.dispatchEventToListeners(this._name, this._value);
750     }
751 }
752
753 WebInspector.settings.pauseOnExceptionStateString = new WebInspector.PauseOnExceptionStateSetting();