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