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