Changeset 239858 in webkit
- Timestamp:
- Jan 10, 2019 9:54:54 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r239853 r239858 1 2019-01-10 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: Audit: allow audits to be enabled/disabled 4 https://bugs.webkit.org/show_bug.cgi?id=192210 5 <rdar://problem/46423583> 6 7 Reviewed by Joseph Pecoraro. 8 9 * inspector/unit-tests/objectStore/clear.html: Added. 10 * inspector/unit-tests/objectStore/clear-expected.txt: Added. 11 1 12 2019-01-10 Justin Fan <justin_fan@apple.com> 2 13 -
trunk/Source/WebInspectorUI/ChangeLog
r239779 r239858 1 2019-01-10 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: Audit: allow audits to be enabled/disabled 4 https://bugs.webkit.org/show_bug.cgi?id=192210 5 <rdar://problem/46423583> 6 7 Reviewed by Joseph Pecoraro. 8 9 * UserInterface/Controllers/AuditManager.js: 10 (WI.AuditManager.prototype.get editing): Added. 11 (WI.AuditManager.prototype.set editing): Added. 12 (WI.AuditManager.prototype.stop): 13 (WI.AuditManager.prototype.addDefaultTestsIfNeeded): 14 Since default audits aren't stored, keep a list of disabled default tests in a `WI.Setting`. 15 16 * UserInterface/Models/AuditTestBase.js: 17 (WI.AuditTestBase): 18 (WI.AuditTestBase.prototype.get disabled): Added. 19 (WI.AuditTestBase.prototype.set disabled): Added. 20 (WI.AuditTestBase.prototype.async start): 21 (WI.AuditTestBase.prototype.stop): 22 (WI.AuditTestBase.toJSON): 23 24 * UserInterface/Models/AuditTestCase.js: 25 (WI.AuditTestCase): 26 (WI.AuditTestCase.async fromPayload): 27 (WI.AuditTestCase.prototype.toJSON): 28 29 * UserInterface/Models/AuditTestGroup.js: 30 (WI.AuditTestGroup): 31 (WI.AuditTestGroup.async fromPayload): 32 (WI.AuditTestGroup.prototype.get disabled): Added. 33 (WI.AuditTestGroup.prototype.set disabled): Added. 34 (WI.AuditTestGroup.prototype.toJSON): 35 (WI.AuditTestGroup.prototype.async run): 36 (WI.AuditTestGroup.prototype._handleTestDisabledChanged): Added. 37 (WI.AuditTestGroup.prototype._handleTestProgress): 38 Propagate `disabled` changes to all sub-tests, unless the change was caused by one of the 39 sub-tests, in which case we are now in an intermediate state. 40 41 * UserInterface/Views/AuditNavigationSidebarPanel.js: 42 (WI.AuditNavigationSidebarPanel): 43 (WI.AuditNavigationSidebarPanel.prototype.showDefaultContentView): 44 (WI.AuditNavigationSidebarPanel.prototype.initialLayout): 45 (WI.AuditNavigationSidebarPanel.prototype.hasCustomFilters): Added. 46 (WI.AuditNavigationSidebarPanel.prototype.matchTreeElementAgainstCustomFilters): Added. 47 (WI.AuditNavigationSidebarPanel.prototype._addTest): 48 (WI.AuditNavigationSidebarPanel.prototype._addResult): 49 (WI.AuditNavigationSidebarPanel.prototype._updateStartStopButtonNavigationItemState): 50 (WI.AuditNavigationSidebarPanel.prototype._updateEditButtonNavigationItemState): Added. 51 (WI.AuditNavigationSidebarPanel.prototype._handleAuditManagerEditingChanged): Added. 52 (WI.AuditNavigationSidebarPanel.prototype._handleAuditTestRemoved): 53 (WI.AuditNavigationSidebarPanel.prototype._handleAuditTestScheduled): 54 (WI.AuditNavigationSidebarPanel.prototype._treeSelectionDidChange): 55 (WI.AuditNavigationSidebarPanel.prototype._handleEditButtonNavigationItemClicked): Added. 56 * UserInterface/Views/AuditNavigationSidebarPanel.css: 57 (.sidebar > .panel.navigation.audit > .content): 58 (.sidebar > .panel.navigation.audit > .content > .tree-outline): Added. 59 (.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled):active): Added. 60 (.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated): Added. 61 (.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated:active): Added. 62 (.sidebar > .panel.navigation.audit > .content .edit-audits.disabled): Added. 63 (.finish-editing-audits-placeholder.message-text-view .navigation-item-help .navigation-bar): Added. 64 Leverage custom filters to ensure that disabled audits arent shown when not editing and that 65 result tree elements aren't shown while editing. 66 67 * UserInterface/Views/AuditTestGroupContentView.js: 68 (WI.AuditTestGroupContentView.prototype.shown): 69 70 * UserInterface/Views/AuditTreeElement.js: 71 (WI.AuditTreeElement.prototype.onattach): 72 (WI.AuditTreeElement.prototype.canSelectOnMouseDown): Added. 73 (WI.AuditTreeElement.prototype._updateTestGroupDisabled): Added. 74 (WI.AuditTreeElement.prototype._handleTestDisabledChanged): Added. 75 (WI.AuditTreeElement.prototype._handleManagerEditingChanged): Added. 76 * UserInterface/Views/AuditTreeElement.css: 77 (.tree-outline .item.audit > .status:not(:hover) > img.show-on-hover, .tree-outline .item.audit.test-group.expanded:not(.editing-audits) > .status:not(:hover)): Added. 78 (.tree-outline .item.audit.manager-active > .status > img.show-on-hover, .tree-outline .item.audit.test-group.expanded:not(.editing-audits) > .status:hover > :not(img), .tree-outline .item.audit.test-group-result.expanded > .status): Added. 79 (.tree-outline .item.audit > .status:not(:hover) > img.show-on-hover, .tree-outline .item.audit.test-group.expanded > .status:not(:hover)): Deleted. 80 (.tree-outline .item.audit.manager-active > .status > img.show-on-hover, .tree-outline .item.audit.test-group.expanded > .status:hover > :not(img), .tree-outline .item.audit.test-group-result.expanded > .status): Deleted. 81 Prevent selection and running when editing. 82 83 * UserInterface/Views/TreeOutline.css: 84 (.tree-outline .children.expanded:not([hidden])): Added. 85 (.tree-outline .children.expanded): Deleted. 86 87 * UserInterface/Base/ObjectStore.js: 88 (WI.ObjectStore._open): 89 Batch operations together to help avoid multiple simultaneous `indexedDB.open` calls. This 90 should also help preserve the order of operations, as once the database is open, operations 91 are executed in the order they were enqueued. 92 93 (WI.ObjectStore.prototype.async.addObject): 94 Pass a unique `Symbol` to the `toJSON` call on the given object so that the object can save 95 additional values that wouldn't normally be saved. This doesn't conflict with normal usage 96 of `toJSON` (e.g. `JSON.stringify`) because that case also passes in a value: 97 - `undefined`, if it was called directly on the object 98 - the key for this object in the containing object 99 - the index of this object in the containing array 100 In any case, the value can never equal the unique `Symbol`, so it's guaranteed that the code 101 will only run for `WI.ObjectStore` operations. 102 103 (WI.ObjectStore.prototype.async.clear): Added. 104 105 * Localizations/en.lproj/localizedStrings.js: 106 1 107 2019-01-09 Devin Rousso <drousso@apple.com> 2 108 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r239703 r239858 325 325 localizedStrings["Edit configuration"] = "Edit configuration"; 326 326 localizedStrings["Edit custom gradient"] = "Edit custom gradient"; 327 localizedStrings["Editing audits"] = "Editing audits"; 327 328 localizedStrings["Element"] = "Element"; 328 329 localizedStrings["Element clips compositing descendants"] = "Element clips compositing descendants"; … … 689 690 localizedStrings["Press %s to load a recording from file."] = "Press %s to load a recording from file."; 690 691 localizedStrings["Press %s to start running the audit"] = "Press %s to start running the audit"; 692 localizedStrings["Press %s to stop editing"] = "Press %s to stop editing"; 691 693 localizedStrings["Pressed"] = "Pressed"; 692 694 localizedStrings["Pretty print"] = "Pretty print"; -
trunk/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js
r237665 r239858 53 53 } 54 54 55 if (Array.isArray(WI.ObjectStore._databaseCallbacks)) { 56 WI.ObjectStore._databaseCallbacks.push(callback); 57 return; 58 } 59 60 WI.ObjectStore._databaseCallbacks = [callback]; 61 55 62 const version = 1; // Increment this for every edit to `WI.objectStores`. 56 63 … … 82 89 }); 83 90 84 callback(WI.ObjectStore._database); 91 for (let databaseCallback of WI.ObjectStore._databaseCallbacks) 92 databaseCallback(WI.ObjectStore._database); 93 94 WI.ObjectStore._databaseCallbacks = null; 85 95 }); 86 96 } … … 119 129 120 130 console.assert(typeof object.toJSON === "function", "ObjectStore cannot store an object without JSON serialization", object.constructor.name); 121 let result = await this.add(object.toJSON( ), ...args);131 let result = await this.add(object.toJSON(WI.ObjectStore.toJSONSymbol), ...args); 122 132 this.associateObject(object, args[0], result); 123 133 return result; … … 138 148 139 149 return this.delete(this._resolveKeyPath(object).value, ...args); 150 } 151 152 async clear(...args) 153 { 154 if (!WI.ObjectStore.supported()) 155 return undefined; 156 157 return this._operation("readwrite", (objectStore) => objectStore.clear(...args)); 140 158 } 141 159 … … 204 222 205 223 WI.ObjectStore._database = null; 224 WI.ObjectStore._databaseCallbacks = null; 225 226 WI.ObjectStore.toJSONSymbol = Symbol("ObjectStore-toJSON"); 206 227 207 228 // Be sure to update the `version` above when making changes. -
trunk/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js
r239449 r239858 36 36 this._runningTests = []; 37 37 38 this._disabledDefaultTestsSetting = new WI.Setting("audit-disabled-default-tests", []); 39 38 40 WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._handleFrameMainResourceDidChange, this); 39 41 } … … 52 54 get results() { return this._results; } 53 55 get runningState() { return this._runningState; } 56 57 get editing() 58 { 59 return this._runningState === WI.AuditManager.RunningState.Disabled; 60 } 61 62 set editing(editing) 63 { 64 console.assert(this._runningState === WI.AuditManager.RunningState.Disabled || this._runningState === WI.AuditManager.RunningState.Inactive); 65 if (this._runningState !== WI.AuditManager.RunningState.Disabled && this._runningState !== WI.AuditManager.RunningState.Inactive) 66 return; 67 68 let runningState = editing ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive; 69 console.assert(runningState !== this._runningState); 70 if (runningState === this._runningState) 71 return; 72 73 this._runningState = runningState; 74 75 this.dispatchEventToListeners(WI.AuditManager.Event.EditingChanged); 76 77 if (!this.editing) { 78 WI.objectStores.audits.clear(); 79 80 let disabledDefaultTests = []; 81 let saveDisabledDefaultTest = (test) => { 82 if (test.disabled) 83 disabledDefaultTests.push(test.name); 84 85 if (test instanceof WI.AuditTestGroup) { 86 for (let child of test.tests) 87 saveDisabledDefaultTest(child); 88 } 89 }; 90 91 for (let test of this._tests) { 92 if (test.__default) 93 saveDisabledDefaultTest(test); 94 else 95 WI.objectStores.audits.addObject(test); 96 } 97 98 this._disabledDefaultTestsSetting.value = disabledDefaultTests; 99 } 100 } 54 101 55 102 async start(tests) … … 98 145 return; 99 146 147 this._runningState = WI.AuditManager.RunningState.Stopping; 148 100 149 for (let test of this._runningTests) 101 150 test.stop(); 102 103 this._runningState = WI.AuditManager.RunningState.Stopping;104 151 } 105 152 … … 254 301 ]; 255 302 303 let checkDisabledDefaultTest = (test) => { 304 if (this._disabledDefaultTestsSetting.value.includes(test.name)) 305 test.disabled = true; 306 307 if (test instanceof WI.AuditTestGroup) { 308 for (let child of test.tests) 309 checkDisabledDefaultTest(child); 310 } 311 }; 312 256 313 for (let test of defaultTests) { 314 checkDisabledDefaultTest(test); 315 257 316 test.__default = true; 258 317 this._addTest(test); … … 262 321 263 322 WI.AuditManager.RunningState = { 323 Disabled: "disabled", 264 324 Inactive: "inactive", 265 325 Active: "active", … … 268 328 269 329 WI.AuditManager.Event = { 330 EditingChanged: "audit-manager-editing-changed", 270 331 TestAdded: "audit-manager-test-added", 271 332 TestCompleted: "audit-manager-test-completed", -
trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js
r237613 r239858 26 26 WI.AuditTestBase = class AuditTestBase extends WI.Object 27 27 { 28 constructor(name, {description } = {})28 constructor(name, {description, disabled} = {}) 29 29 { 30 30 console.assert(typeof name === "string"); 31 31 console.assert(!description || typeof description === "string"); 32 console.assert(disabled === undefined || typeof disabled === "boolean"); 32 33 33 34 super(); 35 36 // This class should not be instantiated directly. Create a concrete subclass instead. 37 console.assert(this.constructor !== WI.AuditTestBase && this instanceof WI.AuditTestBase); 34 38 35 39 this._name = name; 36 40 this._description = description || null; 37 41 38 this._runningState = WI.AuditManager.RunningState.Inactive;42 this._runningState = disabled ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive; 39 43 this._result = null; 40 44 } … … 47 51 get result() { return this._result; } 48 52 53 get disabled() 54 { 55 return this._runningState === WI.AuditManager.RunningState.Disabled; 56 } 57 58 set disabled(disabled) 59 { 60 console.assert(this._runningState === WI.AuditManager.RunningState.Disabled || this._runningState === WI.AuditManager.RunningState.Inactive); 61 if (this._runningState !== WI.AuditManager.RunningState.Disabled && this._runningState !== WI.AuditManager.RunningState.Inactive) 62 return; 63 64 let runningState = disabled ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive; 65 if (runningState === this._runningState) 66 return; 67 68 this._runningState = runningState; 69 70 this.dispatchEventToListeners(WI.AuditTestBase.Event.DisabledChanged); 71 } 72 49 73 async start() 50 74 { 51 75 // Called from WI.AuditManager. 76 77 if (this.disabled) 78 return; 52 79 53 80 console.assert(WI.auditManager.runningState === WI.AuditManager.RunningState.Active); … … 70 97 // Called from WI.AuditManager. 71 98 72 console.assert(this._runningState !== WI.AuditManager.RunningState.Inactive); 99 if (this.disabled) 100 return; 101 102 console.assert(WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping); 73 103 74 104 if (this._runningState !== WI.AuditManager.RunningState.Active) … … 97 127 } 98 128 99 toJSON( )129 toJSON(key) 100 130 { 101 131 let json = { … … 105 135 if (this._description) 106 136 json.description = this._description; 137 if (key === WI.ObjectStore.toJSONSymbol) 138 json.disabled = this.disabled; 107 139 return json; 108 140 } … … 118 150 WI.AuditTestBase.Event = { 119 151 Completed: "audit-test-base-completed", 152 DisabledChanged: "audit-test-base-disabled-changed", 120 153 Progress: "audit-test-base-progress", 121 154 ResultCleared: "audit-test-base-result-cleared", -
trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js
r238850 r239858 26 26 WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase 27 27 { 28 constructor(name, test, {description}= {})28 constructor(name, test, options = {}) 29 29 { 30 30 console.assert(typeof test === "string"); 31 31 32 super(name, {description});32 super(name, options); 33 33 34 34 this._test = test; … … 42 42 return null; 43 43 44 let {type, name, test, description } = payload;44 let {type, name, test, description, disabled} = payload; 45 45 46 46 if (type !== WI.AuditTestCase.TypeIdentifier) … … 56 56 if (typeof description === "string") 57 57 options.description = description; 58 if (typeof disabled === "boolean") 59 options.disabled = disabled; 58 60 59 61 return new WI.AuditTestCase(name, test, options); … … 64 66 get test() { return this._test; } 65 67 66 toJSON( )67 { 68 let json = super.toJSON( );68 toJSON(key) 69 { 70 let json = super.toJSON(key); 69 71 json.test = this._test; 70 72 return json; -
trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js
r237656 r239858 26 26 WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase 27 27 { 28 constructor(name, tests, {description}= {})28 constructor(name, tests, options = {}) 29 29 { 30 30 console.assert(Array.isArray(tests)); 31 31 32 super(name, {description}); 32 // Set disabled once `_tests` is set so that it propagates. 33 let disabled = options.disabled; 34 options.disabled = false; 35 36 super(name, options); 33 37 34 38 this._tests = tests; 39 this._preventDisabledPropagation = false; 40 41 if (disabled) 42 this.disabled = disabled; 35 43 36 44 for (let test of this._tests) { 37 45 test.addEventListener(WI.AuditTestBase.Event.Completed, this._handleTestCompleted, this); 46 test.addEventListener(WI.AuditTestBase.Event.DisabledChanged, this._handleTestDisabledChanged, this); 38 47 test.addEventListener(WI.AuditTestBase.Event.Progress, this._handleTestProgress, this); 39 48 } … … 47 56 return null; 48 57 49 let {type, name, tests, description } = payload;58 let {type, name, tests, description, disabled} = payload; 50 59 51 60 if (type !== WI.AuditTestGroup.TypeIdentifier) … … 76 85 if (typeof description === "string") 77 86 options.description = description; 87 if (typeof disabled === "boolean") 88 options.disabled = disabled; 78 89 79 90 return new WI.AuditTestGroup(name, tests, options); … … 83 94 84 95 get tests() { return this._tests; } 96 97 get disabled() 98 { 99 return super.disabled; 100 } 101 102 set disabled(disabled) 103 { 104 if (!this._preventDisabledPropagation) { 105 for (let test of this._tests) 106 test.disabled = disabled; 107 } 108 109 super.disabled = disabled; 110 } 85 111 86 112 stop() … … 108 134 } 109 135 110 toJSON( )111 { 112 let json = super.toJSON( );113 json.tests = this._tests.map((testCase) => testCase.toJSON( ));136 toJSON(key) 137 { 138 let json = super.toJSON(key); 139 json.tests = this._tests.map((testCase) => testCase.toJSON(key)); 114 140 return json; 115 141 } … … 122 148 for (let index = 0; index < count && this._runningState === WI.AuditManager.RunningState.Active; ++index) { 123 149 let test = this._tests[index]; 150 if (test.disabled) 151 continue; 124 152 125 153 await test.start(); … … 154 182 } 155 183 184 _handleTestDisabledChanged(event) 185 { 186 let enabledTestCount = this._tests.filter((test) => !test.disabled).length; 187 if (event.target.disabled && !enabledTestCount) 188 this.disabled = true; 189 else if (!event.target.disabled && enabledTestCount === 1) { 190 this._preventDisabledPropagation = true; 191 this.disabled = false; 192 this._preventDisabledPropagation = false; 193 } else { 194 // Don't change `disabled`, as we're currently in an "indeterminate" state. 195 this.dispatchEventToListeners(WI.AuditTestBase.Event.DisabledChanged); 196 } 197 } 198 156 199 _handleTestProgress(event) 157 200 { … … 162 205 let count = 0; 163 206 for (let test of tests) { 207 if (test.disabled) 208 continue; 209 164 210 if (test instanceof WI.AuditTestCase) 165 211 ++count; … … 171 217 172 218 this.dispatchEventToListeners(WI.AuditTestBase.Event.Progress, { 173 index: event.data.index + walk(this. tests.slice(0, this.tests.indexOf(event.target))),174 count: walk(this. tests),219 index: event.data.index + walk(this._tests.slice(0, this._tests.indexOf(event.target))), 220 count: walk(this._tests), 175 221 }); 176 222 } -
trunk/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.css
r238334 r239858 25 25 26 26 .sidebar > .panel.navigation.audit > .content { 27 display: flex; 28 flex-direction: column; 27 29 top: var(--navigation-bar-height); 30 } 31 32 .sidebar > .panel.navigation.audit > .content > .tree-outline { 33 flex-grow: 1; 34 } 35 36 .sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled):active { 37 color: var(--glyph-color-pressed); 38 } 39 40 .sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated { 41 color: var(--glyph-color-active); 42 } 43 44 .sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated:active { 45 color: var(--glyph-color-active-pressed); 46 } 47 48 .sidebar > .panel.navigation.audit > .content .edit-audits.disabled { 49 color: var(--glyph-color-disabled); 28 50 } 29 51 … … 40 62 margin: 8px 0 7px; 41 63 } 64 65 .finish-editing-audits-placeholder.message-text-view .navigation-item-help .navigation-bar { 66 padding: 0; 67 vertical-align: 0.5px; 68 } -
trunk/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.js
r238842 r239858 37 37 let contentView = new WI.ContentView; 38 38 39 let contentPlaceholder = WI.createMessageTextView(WI.UIString("No audit selected")); 40 contentView.element.appendChild(contentPlaceholder); 41 42 let importNavigationItem = new WI.ButtonNavigationItem("import-audit", WI.UIString("Import"), "Images/Import.svg", 15, 15); 43 importNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText; 44 importNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this); 45 46 let importHelpElement = WI.createNavigationItemHelp(WI.UIString("Press %s to import a test or result file"), importNavigationItem); 47 contentPlaceholder.appendChild(importHelpElement); 39 if (WI.auditManager.editing) { 40 let contentPlaceholder = WI.createMessageTextView(WI.UIString("Editing audits")); 41 contentPlaceholder.classList.add("finish-editing-audits-placeholder"); 42 contentView.element.appendChild(contentPlaceholder); 43 44 let finishEditingNavigationItem = new WI.ButtonNavigationItem("finish-editing-audits", WI.UIString("Done")); 45 finishEditingNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, (event) => { 46 WI.auditManager.editing = false; 47 }); 48 49 let importHelpElement = WI.createNavigationItemHelp(WI.UIString("Press %s to stop editing"), finishEditingNavigationItem); 50 contentPlaceholder.appendChild(importHelpElement); 51 } else { 52 let contentPlaceholder = WI.createMessageTextView(WI.UIString("No audit selected")); 53 contentView.element.appendChild(contentPlaceholder); 54 55 let importNavigationItem = new WI.ButtonNavigationItem("import-audit", WI.UIString("Import"), "Images/Import.svg", 15, 15); 56 importNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText; 57 importNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this); 58 59 let importHelpElement = WI.createNavigationItemHelp(WI.UIString("Press %s to import a test or result file"), importNavigationItem); 60 contentPlaceholder.appendChild(importHelpElement); 61 } 48 62 49 63 this.contentBrowser.showContentView(contentView); … … 58 72 this.contentTreeOutline.allowsRepeatSelection = false; 59 73 60 let navigationBar = new WI.NavigationBar;74 let controlsNavigationBar = new WI.NavigationBar; 61 75 62 76 this._startStopButtonNavigationItem = new WI.ToggleButtonNavigationItem("audit-start-stop", WI.UIString("Start"), WI.UIString("Stop"), "Images/AuditStart.svg", "Images/AuditStop.svg", 13, 13); … … 64 78 this._updateStartStopButtonNavigationItemState(); 65 79 this._startStopButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleStartStopButtonNavigationItemClicked, this); 66 navigationBar.addNavigationItem(this._startStopButtonNavigationItem);67 68 navigationBar.addNavigationItem(new WI.DividerNavigationItem);80 controlsNavigationBar.addNavigationItem(this._startStopButtonNavigationItem); 81 82 controlsNavigationBar.addNavigationItem(new WI.DividerNavigationItem); 69 83 70 84 let importButtonNavigationItem = new WI.ButtonNavigationItem("audit-import", WI.UIString("Import"), "Images/Import.svg", 15, 15); … … 72 86 importButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low; 73 87 importButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this); 74 navigationBar.addNavigationItem(importButtonNavigationItem); 75 76 this.addSubview(navigationBar); 88 controlsNavigationBar.addNavigationItem(importButtonNavigationItem); 89 90 this.addSubview(controlsNavigationBar); 91 92 let editNavigationbar = new WI.NavigationBar; 93 94 this._editButtonNavigationItem = new WI.ActivateButtonNavigationItem("edit-audits", WI.UIString("Edit"), WI.UIString("Done")); 95 this._editButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleEditButtonNavigationItemClicked, this); 96 editNavigationbar.addNavigationItem(this._editButtonNavigationItem); 97 98 this.contentView.addSubview(editNavigationbar); 77 99 78 100 for (let test of WI.auditManager.tests) … … 83 105 }); 84 106 107 WI.auditManager.addEventListener(WI.AuditManager.Event.EditingChanged, this._handleAuditManagerEditingChanged, this); 85 108 WI.auditManager.addEventListener(WI.AuditManager.Event.TestAdded, this._handleAuditTestAdded, this); 86 109 WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditTestCompleted, this); … … 106 129 } 107 130 131 hasCustomFilters() 132 { 133 return true; 134 } 135 136 matchTreeElementAgainstCustomFilters(treeElement, flags) 137 { 138 if (WI.auditManager.editing) { 139 if (treeElement.representedObject instanceof WI.AuditTestResultBase || treeElement.hasAncestor(this._resultsFolderTreeElement) || treeElement === this._resultsFolderTreeElement) 140 return false; 141 } else { 142 if (treeElement.representedObject instanceof WI.AuditTestBase && treeElement.representedObject.disabled) 143 return false; 144 } 145 146 return super.matchTreeElementAgainstCustomFilters(treeElement, flags); 147 } 148 108 149 // Private 109 150 … … 111 152 { 112 153 this.element.classList.add("has-tests"); 113 114 this._updateStartStopButtonNavigationItemState();115 154 116 155 let treeElement = new WI.AuditTreeElement(test); … … 122 161 this.contentTreeOutline.appendChild(treeElement); 123 162 163 this._updateStartStopButtonNavigationItemState(); 164 this._updateEditButtonNavigationItemState(); 165 124 166 this.hideEmptyContentPlaceholder(); 125 167 } … … 128 170 { 129 171 this.element.classList.add("has-results"); 130 131 this._updateStartStopButtonNavigationItemState();132 172 133 173 if (!this._resultsFolderTreeElement) { … … 145 185 this._resultsFolderTreeElement.appendChild(resultFolderTreeElement); 146 186 187 console.assert(this._resultsFolderTreeElement.children.length === WI.auditManager.results.length); 188 147 189 for (let resultItem of result) 148 190 resultFolderTreeElement.appendChild(new WI.AuditTreeElement(resultItem)); 191 192 this._updateStartStopButtonNavigationItemState(); 193 this._updateEditButtonNavigationItemState(); 149 194 } 150 195 151 196 _updateStartStopButtonNavigationItemState() 152 197 { 153 this._startStopButtonNavigationItem.toggled = WI.auditManager.runningState !== WI.AuditManager.RunningState.Inactive; 154 this._startStopButtonNavigationItem.enabled = WI.auditManager.tests.length && WI.auditManager.runningState !== WI.AuditManager.RunningState.Stopping; 198 this._startStopButtonNavigationItem.toggled = WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping; 199 this._startStopButtonNavigationItem.enabled = WI.auditManager.tests.length && (WI.auditManager.runningState === WI.AuditManager.RunningState.Inactive || WI.auditManager.runningState === WI.AuditManager.RunningState.Active); 200 } 201 202 _updateEditButtonNavigationItemState() 203 { 204 this._editButtonNavigationItem.label = WI.auditManager.editing ? this._editButtonNavigationItem.activatedToolTip : this._editButtonNavigationItem.defaultToolTip; 205 this._editButtonNavigationItem.activated = WI.auditManager.editing; 206 this._editButtonNavigationItem.enabled = WI.auditManager.tests.length && (WI.auditManager.editing || WI.auditManager.runningState === WI.AuditManager.RunningState.Inactive); 155 207 } 156 208 … … 177 229 this.contentView.element.insertBefore(contentPlaceholder, this.contentView.element.firstChild); 178 230 } 231 232 this._updateEditButtonNavigationItemState(); 233 } 234 235 _handleAuditManagerEditingChanged(event) 236 { 237 if (WI.auditManager.editing) { 238 console.assert(!this._selectedTreeElementBeforeEditing); 239 this._selectedTreeElementBeforeEditing = this.contentTreeOutline.selectedTreeElement; 240 if (this._selectedTreeElementBeforeEditing) 241 this._selectedTreeElementBeforeEditing.deselect(); 242 } else if (this._selectedTreeElementBeforeEditing) { 243 if (!(this._selectedTreeElementBeforeEditing.representedObject instanceof WI.AuditTestBase) || !this._selectedTreeElementBeforeEditing.representedObject.disabled) 244 this._selectedTreeElementBeforeEditing.select(); 245 this._selectedTreeElementBeforeEditing = null; 246 } 247 248 if (!this.contentTreeOutline.selectedTreeElement) 249 this.showDefaultContentView(); 250 251 this._updateStartStopButtonNavigationItemState(); 252 this._updateEditButtonNavigationItemState(); 253 254 this.updateFilter(); 179 255 } 180 256 … … 205 281 { 206 282 this._updateStartStopButtonNavigationItemState(); 283 this._updateEditButtonNavigationItemState(); 207 284 } 208 285 … … 217 294 return; 218 295 } 296 297 console.assert(!WI.auditManager.editing); 298 if (WI.auditManager.editing) 299 return; 219 300 220 301 let representedObject = treeElement.representedObject; … … 242 323 WI.FileUtilities.importJSON((result) => WI.auditManager.processJSON(result)); 243 324 } 325 326 _handleEditButtonNavigationItemClicked(event) 327 { 328 WI.auditManager.editing = !WI.auditManager.editing; 329 } 244 330 }; -
trunk/Source/WebInspectorUI/UserInterface/Views/AuditTestGroupContentView.js
r239452 r239858 150 150 151 151 for (let subobject of this._subobjects()) { 152 if (subobject instanceof WI.AuditTestBase && subobject.disabled) 153 continue; 154 152 155 let view = WI.ContentView.contentViewForRepresentedObject(subobject); 153 156 this.contentView.addSubview(view); -
trunk/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.css
r239705 r239858 44 44 45 45 .tree-outline .item.audit > .status:not(:hover) > img.show-on-hover, 46 .tree-outline .item.audit.test-group.expanded > .status:not(:hover) {46 .tree-outline .item.audit.test-group.expanded:not(.editing-audits) > .status:not(:hover) { 47 47 opacity: 0; 48 48 } 49 49 50 50 .tree-outline .item.audit.manager-active > .status > img.show-on-hover, 51 .tree-outline .item.audit.test-group.expanded > .status:hover > :not(img),51 .tree-outline .item.audit.test-group.expanded:not(.editing-audits) > .status:hover > :not(img), 52 52 .tree-outline .item.audit.test-group-result.expanded > .status { 53 53 display: none; -
trunk/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.js
r239705 r239858 62 62 63 63 if (this.representedObject instanceof WI.AuditTestBase) { 64 this.representedObject.addEventListener(WI.AuditTestBase.Event.DisabledChanged, this._handleTestDisabledChanged, this); 64 65 this.representedObject.addEventListener(WI.AuditTestBase.Event.ResultCleared, this._handleTestResultCleared, this); 65 66 … … 69 70 this.representedObject.addEventListener(WI.AuditTestBase.Event.Scheduled, this._handleTestGroupScheduled, this); 70 71 72 WI.auditManager.addEventListener(WI.AuditManager.Event.EditingChanged, this._handleManagerEditingChanged, this); 71 73 WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this); 72 74 WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this); … … 161 163 162 164 super.populateContextMenu(contextMenu, event); 165 } 166 167 canSelectOnMouseDown(event) 168 { 169 return !WI.auditManager.editing; 163 170 } 164 171 … … 233 240 } 234 241 242 _updateTestGroupDisabled() 243 { 244 this.status.checked = !this.representedObject.disabled; 245 246 if (this.representedObject instanceof WI.AuditTestGroup) 247 this.status.indeterminate = this.representedObject.tests.some((test) => test.disabled !== this.representedObject.tests[0].disabled); 248 } 249 235 250 _handleTestCaseCompleted(event) 236 251 { … … 238 253 239 254 this._updateLevel(); 255 } 256 257 _handleTestDisabledChanged(event) 258 { 259 if (this.status instanceof HTMLInputElement && this.status.type === "checkbox") 260 this._updateTestGroupDisabled(); 240 261 } 241 262 … … 274 295 } 275 296 297 _handleManagerEditingChanged(event) 298 { 299 if (WI.auditManager.editing) { 300 this.status = document.createElement("input"); 301 this.status.type = "checkbox"; 302 this._updateTestGroupDisabled(); 303 this.status.addEventListener("change", () => { 304 this.representedObject.disabled = !this.representedObject.disabled; 305 }); 306 307 this.addClassName("editing-audits"); 308 } else { 309 this.removeClassName("editing-audits"); 310 311 this._updateLevel(); 312 } 313 } 314 276 315 _handleAuditManagerTestScheduled(event) 277 316 { -
trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.css
r239760 r239858 41 41 } 42 42 43 .tree-outline .children.expanded {43 .tree-outline .children.expanded:not([hidden]) { 44 44 display: block; 45 45 }
Note: See TracChangeset
for help on using the changeset viewer.