WebKit Bugzilla
Attachment 358871 Details for
Bug 192210
: Web Inspector: Audit: allow audits to be enabled/disabled
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192210-20190110215421.patch (text/plain), 47.87 KB, created by
Devin Rousso
on 2019-01-10 20:54:22 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Devin Rousso
Created:
2019-01-10 20:54:22 PST
Size:
47.87 KB
patch
obsolete
>diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index 1015bffbcced2e70707665e8d8df79b60ad5ce4b..819fc0b5ac1ceaa9912b8cd6390d08f29b052e24 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,109 @@ >+2019-01-10 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: Audit: allow audits to be enabled/disabled >+ https://bugs.webkit.org/show_bug.cgi?id=192210 >+ <rdar://problem/46423583> >+ >+ Reviewed by Joseph Pecoraro. >+ >+ * UserInterface/Controllers/AuditManager.js: >+ (WI.AuditManager.prototype.get editing): Added. >+ (WI.AuditManager.prototype.set editing): Added. >+ (WI.AuditManager.prototype.stop): >+ (WI.AuditManager.prototype.addDefaultTestsIfNeeded): >+ Since default audits aren't stored, keep a list of disabled default tests in a `WI.Setting`. >+ >+ * UserInterface/Models/AuditTestBase.js: >+ (WI.AuditTestBase): >+ (WI.AuditTestBase.prototype.get disabled): Added. >+ (WI.AuditTestBase.prototype.set disabled): Added. >+ (WI.AuditTestBase.prototype.async start): >+ (WI.AuditTestBase.prototype.stop): >+ (WI.AuditTestBase.toJSON): >+ >+ * UserInterface/Models/AuditTestCase.js: >+ (WI.AuditTestCase): >+ (WI.AuditTestCase.async fromPayload): >+ (WI.AuditTestCase.prototype.toJSON): >+ >+ * UserInterface/Models/AuditTestGroup.js: >+ (WI.AuditTestGroup): >+ (WI.AuditTestGroup.async fromPayload): >+ (WI.AuditTestGroup.prototype.get disabled): Added. >+ (WI.AuditTestGroup.prototype.set disabled): Added. >+ (WI.AuditTestGroup.prototype.toJSON): >+ (WI.AuditTestGroup.prototype.async run): >+ (WI.AuditTestGroup.prototype._handleTestDisabledChanged): Added. >+ (WI.AuditTestGroup.prototype._handleTestProgress): >+ Propagate `disabled` changes to all sub-tests, unless the change was caused by one of the >+ sub-tests, in which case we are now in an intermediate state. >+ >+ * UserInterface/Views/AuditNavigationSidebarPanel.js: >+ (WI.AuditNavigationSidebarPanel): >+ (WI.AuditNavigationSidebarPanel.prototype.showDefaultContentView): >+ (WI.AuditNavigationSidebarPanel.prototype.initialLayout): >+ (WI.AuditNavigationSidebarPanel.prototype.hasCustomFilters): Added. >+ (WI.AuditNavigationSidebarPanel.prototype.matchTreeElementAgainstCustomFilters): Added. >+ (WI.AuditNavigationSidebarPanel.prototype._addTest): >+ (WI.AuditNavigationSidebarPanel.prototype._addResult): >+ (WI.AuditNavigationSidebarPanel.prototype._updateStartStopButtonNavigationItemState): >+ (WI.AuditNavigationSidebarPanel.prototype._updateEditButtonNavigationItemState): Added. >+ (WI.AuditNavigationSidebarPanel.prototype._handleAuditManagerEditingChanged): Added. >+ (WI.AuditNavigationSidebarPanel.prototype._handleAuditTestRemoved): >+ (WI.AuditNavigationSidebarPanel.prototype._handleAuditTestScheduled): >+ (WI.AuditNavigationSidebarPanel.prototype._treeSelectionDidChange): >+ (WI.AuditNavigationSidebarPanel.prototype._handleEditButtonNavigationItemClicked): Added. >+ * UserInterface/Views/AuditNavigationSidebarPanel.css: >+ (.sidebar > .panel.navigation.audit > .content): >+ (.sidebar > .panel.navigation.audit > .content > .tree-outline): Added. >+ (.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled):active): Added. >+ (.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated): Added. >+ (.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated:active): Added. >+ (.sidebar > .panel.navigation.audit > .content .edit-audits.disabled): Added. >+ (.finish-editing-audits-placeholder.message-text-view .navigation-item-help .navigation-bar): Added. >+ Leverage custom filters to ensure that disabled audits arent shown when not editing and that >+ result tree elements aren't shown while editing. >+ >+ * UserInterface/Views/AuditTestGroupContentView.js: >+ (WI.AuditTestGroupContentView.prototype.shown): >+ >+ * UserInterface/Views/AuditTreeElement.js: >+ (WI.AuditTreeElement.prototype.onattach): >+ (WI.AuditTreeElement.prototype.canSelectOnMouseDown): Added. >+ (WI.AuditTreeElement.prototype._updateTestGroupDisabled): Added. >+ (WI.AuditTreeElement.prototype._handleTestDisabledChanged): Added. >+ (WI.AuditTreeElement.prototype._handleManagerEditingChanged): Added. >+ * UserInterface/Views/AuditTreeElement.css: >+ (.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. >+ (.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. >+ (.tree-outline .item.audit > .status:not(:hover) > img.show-on-hover, .tree-outline .item.audit.test-group.expanded > .status:not(:hover)): Deleted. >+ (.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. >+ Prevent selection and running when editing. >+ >+ * UserInterface/Views/TreeOutline.css: >+ (.tree-outline .children.expanded:not([hidden])): Added. >+ (.tree-outline .children.expanded): Deleted. >+ >+ * UserInterface/Base/ObjectStore.js: >+ (WI.ObjectStore._open): >+ Batch operations together to help avoid multiple simultaneous `indexedDB.open` calls. This >+ should also help preserve the order of operations, as once the database is open, operations >+ are executed in the order they were enqueued. >+ >+ (WI.ObjectStore.prototype.async.addObject): >+ Pass a unique `Symbol` to the `toJSON` call on the given object so that the object can save >+ additional values that wouldn't normally be saved. This doesn't conflict with normal usage >+ of `toJSON` (e.g. `JSON.stringify`) because that case also passes in a value: >+ - `undefined`, if it was called directly on the object >+ - the key for this object in the containing object >+ - the index of this object in the containing array >+ In any case, the value can never equal the unique `Symbol`, so it's guaranteed that the code >+ will only run for `WI.ObjectStore` operations. >+ >+ (WI.ObjectStore.prototype.async.clear): Added. >+ >+ * Localizations/en.lproj/localizedStrings.js: >+ > 2019-01-09 Devin Rousso <drousso@apple.com> > > Web Inspector: Protocol Logging: log messages as objects if inspector^2 is open >diff --git a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >index 90fa41ed08f5e6db003fd7357d9b08055d95d901..61d2f6d6bd12e061a06939f58c625ef646fae4b4 100644 >--- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >+++ b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >@@ -324,6 +324,7 @@ localizedStrings["Edit \u201Ccubic-bezier\u201D function"] = "Edit \u201Ccubic-b > localizedStrings["Edit \u201Cspring\u201D function"] = "Edit \u201Cspring\u201D function"; > localizedStrings["Edit configuration"] = "Edit configuration"; > localizedStrings["Edit custom gradient"] = "Edit custom gradient"; >+localizedStrings["Editing audits"] = "Editing audits"; > localizedStrings["Element"] = "Element"; > localizedStrings["Element clips compositing descendants"] = "Element clips compositing descendants"; > localizedStrings["Element has CSS blending applied and composited descendants"] = "Element has CSS blending applied and composited descendants"; >@@ -688,6 +689,7 @@ localizedStrings["Preserve Log"] = "Preserve Log"; > localizedStrings["Press %s to import a test or result file"] = "Press %s to import a test or result file"; > localizedStrings["Press %s to load a recording from file."] = "Press %s to load a recording from file."; > localizedStrings["Press %s to start running the audit"] = "Press %s to start running the audit"; >+localizedStrings["Press %s to stop editing"] = "Press %s to stop editing"; > localizedStrings["Pressed"] = "Pressed"; > localizedStrings["Pretty print"] = "Pretty print"; > localizedStrings["Preview"] = "Preview"; >diff --git a/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js b/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js >index b7bf8931b6608b01c6cbcebaa576aebf0f829bf1..c03ed8d3c256e1676ce7f0dcd5df1bf2c8403bc5 100644 >--- a/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js >+++ b/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js >@@ -52,6 +52,13 @@ WI.ObjectStore = class ObjectStore > return; > } > >+ if (Array.isArray(WI.ObjectStore._databaseCallbacks)) { >+ WI.ObjectStore._databaseCallbacks.push(callback); >+ return; >+ } >+ >+ WI.ObjectStore._databaseCallbacks = [callback]; >+ > const version = 1; // Increment this for every edit to `WI.objectStores`. > > let databaseRequest = indexedDB.open(WI.ObjectStore._databaseName, version); >@@ -81,7 +88,10 @@ WI.ObjectStore = class ObjectStore > WI.ObjectStore._database = null; > }); > >- callback(WI.ObjectStore._database); >+ for (let databaseCallback of WI.ObjectStore._databaseCallbacks) >+ databaseCallback(WI.ObjectStore._database); >+ >+ WI.ObjectStore._databaseCallbacks = null; > }); > } > >@@ -118,7 +128,7 @@ WI.ObjectStore = class ObjectStore > return undefined; > > console.assert(typeof object.toJSON === "function", "ObjectStore cannot store an object without JSON serialization", object.constructor.name); >- let result = await this.add(object.toJSON(), ...args); >+ let result = await this.add(object.toJSON(WI.ObjectStore.toJSONSymbol), ...args); > this.associateObject(object, args[0], result); > return result; > } >@@ -139,6 +149,14 @@ WI.ObjectStore = class ObjectStore > return this.delete(this._resolveKeyPath(object).value, ...args); > } > >+ async clear(...args) >+ { >+ if (!WI.ObjectStore.supported()) >+ return undefined; >+ >+ return this._operation("readwrite", (objectStore) => objectStore.clear(...args)); >+ } >+ > // Private > > _resolveKeyPath(object, keyPath) >@@ -203,6 +221,9 @@ WI.ObjectStore = class ObjectStore > }; > > WI.ObjectStore._database = null; >+WI.ObjectStore._databaseCallbacks = null; >+ >+WI.ObjectStore.toJSONSymbol = Symbol("ObjectStore-toJSON"); > > // Be sure to update the `version` above when making changes. > WI.objectStores = { >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >index 7684b4d9601f445b1397f326b824a15a24b42ef0..6d0c7e63b3a67d9d5ecbc89f70f52ce272d9cf85 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >@@ -35,6 +35,8 @@ WI.AuditManager = class AuditManager extends WI.Object > this._runningState = WI.AuditManager.RunningState.Inactive; > this._runningTests = []; > >+ this._disabledDefaultTestsSetting = new WI.Setting("audit-disabled-default-tests", []); >+ > WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._handleFrameMainResourceDidChange, this); > } > >@@ -52,6 +54,51 @@ WI.AuditManager = class AuditManager extends WI.Object > get results() { return this._results; } > get runningState() { return this._runningState; } > >+ get editing() >+ { >+ return this._runningState === WI.AuditManager.RunningState.Disabled; >+ } >+ >+ set editing(editing) >+ { >+ console.assert(this._runningState === WI.AuditManager.RunningState.Disabled || this._runningState === WI.AuditManager.RunningState.Inactive); >+ if (this._runningState !== WI.AuditManager.RunningState.Disabled && this._runningState !== WI.AuditManager.RunningState.Inactive) >+ return; >+ >+ let runningState = editing ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive; >+ console.assert(runningState !== this._runningState); >+ if (runningState === this._runningState) >+ return; >+ >+ this._runningState = runningState; >+ >+ this.dispatchEventToListeners(WI.AuditManager.Event.EditingChanged); >+ >+ if (!this.editing) { >+ WI.objectStores.audits.clear(); >+ >+ let disabledDefaultTests = []; >+ let saveDisabledDefaultTest = (test) => { >+ if (test.disabled) >+ disabledDefaultTests.push(test.name); >+ >+ if (test instanceof WI.AuditTestGroup) { >+ for (let child of test.tests) >+ saveDisabledDefaultTest(child); >+ } >+ }; >+ >+ for (let test of this._tests) { >+ if (test.__default) >+ saveDisabledDefaultTest(test); >+ else >+ WI.objectStores.audits.addObject(test); >+ } >+ >+ this._disabledDefaultTestsSetting.value = disabledDefaultTests; >+ } >+ } >+ > async start(tests) > { > console.assert(this._runningState === WI.AuditManager.RunningState.Inactive); >@@ -97,10 +144,10 @@ WI.AuditManager = class AuditManager extends WI.Object > if (this._runningState !== WI.AuditManager.RunningState.Active) > return; > >+ this._runningState = WI.AuditManager.RunningState.Stopping; >+ > for (let test of this._runningTests) > test.stop(); >- >- this._runningState = WI.AuditManager.RunningState.Stopping; > } > > async processJSON({json, error}) >@@ -253,7 +300,19 @@ WI.AuditManager = class AuditManager extends WI.Object > ], {description: WI.UIString("Tests for ways to improve accessibility.")}), > ]; > >+ let checkDisabledDefaultTest = (test) => { >+ if (this._disabledDefaultTestsSetting.value.includes(test.name)) >+ test.disabled = true; >+ >+ if (test instanceof WI.AuditTestGroup) { >+ for (let child of test.tests) >+ checkDisabledDefaultTest(child); >+ } >+ }; >+ > for (let test of defaultTests) { >+ checkDisabledDefaultTest(test); >+ > test.__default = true; > this._addTest(test); > } >@@ -261,12 +320,14 @@ WI.AuditManager = class AuditManager extends WI.Object > }; > > WI.AuditManager.RunningState = { >+ Disabled: "disabled", > Inactive: "inactive", > Active: "active", > Stopping: "stopping", > }; > > WI.AuditManager.Event = { >+ EditingChanged: "audit-manager-editing-changed", > TestAdded: "audit-manager-test-added", > TestCompleted: "audit-manager-test-completed", > TestRemoved: "audit-manager-test-removed", >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >index 04dfdbc44586d711f576255e311a9c9eab6d7155..d41dafb36bce5e87f53d34881e08f6ec2a60fa3c 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >@@ -25,17 +25,21 @@ > > WI.AuditTestBase = class AuditTestBase extends WI.Object > { >- constructor(name, {description} = {}) >+ constructor(name, {description, disabled} = {}) > { > console.assert(typeof name === "string"); > console.assert(!description || typeof description === "string"); >+ console.assert(disabled === undefined || typeof disabled === "boolean"); > > super(); > >+ // This class should not be instantiated directly. Create a concrete subclass instead. >+ console.assert(this.constructor !== WI.AuditTestBase && this instanceof WI.AuditTestBase); >+ > this._name = name; > this._description = description || null; > >- this._runningState = WI.AuditManager.RunningState.Inactive; >+ this._runningState = disabled ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive; > this._result = null; > } > >@@ -46,10 +50,33 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > get runningState() { return this._runningState; } > get result() { return this._result; } > >+ get disabled() >+ { >+ return this._runningState === WI.AuditManager.RunningState.Disabled; >+ } >+ >+ set disabled(disabled) >+ { >+ console.assert(this._runningState === WI.AuditManager.RunningState.Disabled || this._runningState === WI.AuditManager.RunningState.Inactive); >+ if (this._runningState !== WI.AuditManager.RunningState.Disabled && this._runningState !== WI.AuditManager.RunningState.Inactive) >+ return; >+ >+ let runningState = disabled ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive; >+ if (runningState === this._runningState) >+ return; >+ >+ this._runningState = runningState; >+ >+ this.dispatchEventToListeners(WI.AuditTestBase.Event.DisabledChanged); >+ } >+ > async start() > { > // Called from WI.AuditManager. > >+ if (this.disabled) >+ return; >+ > console.assert(WI.auditManager.runningState === WI.AuditManager.RunningState.Active); > > console.assert(this._runningState === WI.AuditManager.RunningState.Inactive); >@@ -69,7 +96,10 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > { > // Called from WI.AuditManager. > >- console.assert(this._runningState !== WI.AuditManager.RunningState.Inactive); >+ if (this.disabled) >+ return; >+ >+ console.assert(WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping); > > if (this._runningState !== WI.AuditManager.RunningState.Active) > return; >@@ -96,7 +126,7 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > cookie["audit-" + this.constructor.TypeIdentifier + "-name"] = this._name; > } > >- toJSON() >+ toJSON(key) > { > let json = { > type: this.constructor.TypeIdentifier, >@@ -104,6 +134,8 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > }; > if (this._description) > json.description = this._description; >+ if (key === WI.ObjectStore.toJSONSymbol) >+ json.disabled = this.disabled; > return json; > } > >@@ -117,6 +149,7 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > > WI.AuditTestBase.Event = { > Completed: "audit-test-base-completed", >+ DisabledChanged: "audit-test-base-disabled-changed", > Progress: "audit-test-base-progress", > ResultCleared: "audit-test-base-result-cleared", > Scheduled: "audit-test-base-scheduled", >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >index a6daef2582bc4e9463c2eb453b15f93a3c7048c8..128b5b7b8cf87b4e5aed624c7f561a4d91bcf3bb 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >@@ -25,11 +25,11 @@ > > WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase > { >- constructor(name, test, {description} = {}) >+ constructor(name, test, options = {}) > { > console.assert(typeof test === "string"); > >- super(name, {description}); >+ super(name, options); > > this._test = test; > } >@@ -41,7 +41,7 @@ WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase > if (typeof payload !== "object" || payload === null) > return null; > >- let {type, name, test, description} = payload; >+ let {type, name, test, description, disabled} = payload; > > if (type !== WI.AuditTestCase.TypeIdentifier) > return null; >@@ -55,6 +55,8 @@ WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase > let options = {}; > if (typeof description === "string") > options.description = description; >+ if (typeof disabled === "boolean") >+ options.disabled = disabled; > > return new WI.AuditTestCase(name, test, options); > } >@@ -63,9 +65,9 @@ WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase > > get test() { return this._test; } > >- toJSON() >+ toJSON(key) > { >- let json = super.toJSON(); >+ let json = super.toJSON(key); > json.test = this._test; > return json; > } >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js >index e37ca634318cca3bbd06e749f71afd95e12bc566..2a1631323a271ac3b3429e5a04e97bd7fbb9c02a 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js >@@ -25,16 +25,25 @@ > > WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > { >- constructor(name, tests, {description} = {}) >+ constructor(name, tests, options = {}) > { > console.assert(Array.isArray(tests)); > >- super(name, {description}); >+ // Set disabled once `_tests` is set so that it propagates. >+ let disabled = options.disabled; >+ options.disabled = false; >+ >+ super(name, options); > > this._tests = tests; >+ this._preventDisabledPropagation = false; >+ >+ if (disabled) >+ this.disabled = disabled; > > for (let test of this._tests) { > test.addEventListener(WI.AuditTestBase.Event.Completed, this._handleTestCompleted, this); >+ test.addEventListener(WI.AuditTestBase.Event.DisabledChanged, this._handleTestDisabledChanged, this); > test.addEventListener(WI.AuditTestBase.Event.Progress, this._handleTestProgress, this); > } > } >@@ -46,7 +55,7 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > if (typeof payload !== "object" || payload === null) > return null; > >- let {type, name, tests, description} = payload; >+ let {type, name, tests, description, disabled} = payload; > > if (type !== WI.AuditTestGroup.TypeIdentifier) > return null; >@@ -75,6 +84,8 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > let options = {}; > if (typeof description === "string") > options.description = description; >+ if (typeof disabled === "boolean") >+ options.disabled = disabled; > > return new WI.AuditTestGroup(name, tests, options); > } >@@ -83,6 +94,21 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > > get tests() { return this._tests; } > >+ get disabled() >+ { >+ return super.disabled; >+ } >+ >+ set disabled(disabled) >+ { >+ if (!this._preventDisabledPropagation) { >+ for (let test of this._tests) >+ test.disabled = disabled; >+ } >+ >+ super.disabled = disabled; >+ } >+ > stop() > { > // Called from WI.AuditManager. >@@ -107,10 +133,10 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > }); > } > >- toJSON() >+ toJSON(key) > { >- let json = super.toJSON(); >- json.tests = this._tests.map((testCase) => testCase.toJSON()); >+ let json = super.toJSON(key); >+ json.tests = this._tests.map((testCase) => testCase.toJSON(key)); > return json; > } > >@@ -121,6 +147,8 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > let count = this._tests.length; > for (let index = 0; index < count && this._runningState === WI.AuditManager.RunningState.Active; ++index) { > let test = this._tests[index]; >+ if (test.disabled) >+ continue; > > await test.start(); > >@@ -153,6 +181,21 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > this.dispatchEventToListeners(WI.AuditTestBase.Event.Completed); > } > >+ _handleTestDisabledChanged(event) >+ { >+ let enabledTestCount = this._tests.filter((test) => !test.disabled).length; >+ if (event.target.disabled && !enabledTestCount) >+ this.disabled = true; >+ else if (!event.target.disabled && enabledTestCount === 1) { >+ this._preventDisabledPropagation = true; >+ this.disabled = false; >+ this._preventDisabledPropagation = false; >+ } else { >+ // Don't change `disabled`, as we're currently in an "indeterminate" state. >+ this.dispatchEventToListeners(WI.AuditTestBase.Event.DisabledChanged); >+ } >+ } >+ > _handleTestProgress(event) > { > if (this._runningState !== WI.AuditManager.RunningState.Active) >@@ -161,6 +204,9 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > let walk = (tests) => { > let count = 0; > for (let test of tests) { >+ if (test.disabled) >+ continue; >+ > if (test instanceof WI.AuditTestCase) > ++count; > else if (test instanceof WI.AuditTestGroup) >@@ -170,8 +216,8 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > }; > > this.dispatchEventToListeners(WI.AuditTestBase.Event.Progress, { >- index: event.data.index + walk(this.tests.slice(0, this.tests.indexOf(event.target))), >- count: walk(this.tests), >+ index: event.data.index + walk(this._tests.slice(0, this._tests.indexOf(event.target))), >+ count: walk(this._tests), > }); > } > }; >diff --git a/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.css b/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.css >index 9fa88d8db2e114845240317958e6f49c2c67f307..fcbdc510d9ea9480007e21b4b0ec4738b39bd03f 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.css >+++ b/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.css >@@ -24,9 +24,31 @@ > */ > > .sidebar > .panel.navigation.audit > .content { >+ display: flex; >+ flex-direction: column; > top: var(--navigation-bar-height); > } > >+.sidebar > .panel.navigation.audit > .content > .tree-outline { >+ flex-grow: 1; >+} >+ >+.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled):active { >+ color: var(--glyph-color-pressed); >+} >+ >+.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated { >+ color: var(--glyph-color-active); >+} >+ >+.sidebar > .panel.navigation.audit > .content .edit-audits:not(.disabled).activated:active { >+ color: var(--glyph-color-active-pressed); >+} >+ >+.sidebar > .panel.navigation.audit > .content .edit-audits.disabled { >+ color: var(--glyph-color-disabled); >+} >+ > .sidebar > .panel.navigation.audit.has-results:not(.has-tests) > .content > .message-text-view { > position: initial; > border-bottom: 1px solid var(--border-color); >@@ -39,3 +61,8 @@ > .sidebar > .panel.navigation.audit.has-results:not(.has-tests) > .content > .message-text-view > button { > margin: 8px 0 7px; > } >+ >+.finish-editing-audits-placeholder.message-text-view .navigation-item-help .navigation-bar { >+ padding: 0; >+ vertical-align: 0.5px; >+} >diff --git a/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.js b/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.js >index d7232206bc4c637cb3f42001cd2e532de3f92e6b..9c8fa8361169e12f270d3967c2f04061c39e19d7 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.js >+++ b/Source/WebInspectorUI/UserInterface/Views/AuditNavigationSidebarPanel.js >@@ -36,15 +36,29 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > { > let contentView = new WI.ContentView; > >- let contentPlaceholder = WI.createMessageTextView(WI.UIString("No audit selected")); >- contentView.element.appendChild(contentPlaceholder); >+ if (WI.auditManager.editing) { >+ let contentPlaceholder = WI.createMessageTextView(WI.UIString("Editing audits")); >+ contentPlaceholder.classList.add("finish-editing-audits-placeholder"); >+ contentView.element.appendChild(contentPlaceholder); > >- let importNavigationItem = new WI.ButtonNavigationItem("import-audit", WI.UIString("Import"), "Images/Import.svg", 15, 15); >- importNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText; >- importNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this); >+ let finishEditingNavigationItem = new WI.ButtonNavigationItem("finish-editing-audits", WI.UIString("Done")); >+ finishEditingNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, (event) => { >+ WI.auditManager.editing = false; >+ }); > >- let importHelpElement = WI.createNavigationItemHelp(WI.UIString("Press %s to import a test or result file"), importNavigationItem); >- contentPlaceholder.appendChild(importHelpElement); >+ let importHelpElement = WI.createNavigationItemHelp(WI.UIString("Press %s to stop editing"), finishEditingNavigationItem); >+ contentPlaceholder.appendChild(importHelpElement); >+ } else { >+ let contentPlaceholder = WI.createMessageTextView(WI.UIString("No audit selected")); >+ contentView.element.appendChild(contentPlaceholder); >+ >+ let importNavigationItem = new WI.ButtonNavigationItem("import-audit", WI.UIString("Import"), "Images/Import.svg", 15, 15); >+ importNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText; >+ importNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this); >+ >+ let importHelpElement = WI.createNavigationItemHelp(WI.UIString("Press %s to import a test or result file"), importNavigationItem); >+ contentPlaceholder.appendChild(importHelpElement); >+ } > > this.contentBrowser.showContentView(contentView); > } >@@ -57,23 +71,31 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > > this.contentTreeOutline.allowsRepeatSelection = false; > >- let navigationBar = new WI.NavigationBar; >+ let controlsNavigationBar = new WI.NavigationBar; > > this._startStopButtonNavigationItem = new WI.ToggleButtonNavigationItem("audit-start-stop", WI.UIString("Start"), WI.UIString("Stop"), "Images/AuditStart.svg", "Images/AuditStop.svg", 13, 13); > this._startStopButtonNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText; > this._updateStartStopButtonNavigationItemState(); > this._startStopButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleStartStopButtonNavigationItemClicked, this); >- navigationBar.addNavigationItem(this._startStopButtonNavigationItem); >+ controlsNavigationBar.addNavigationItem(this._startStopButtonNavigationItem); > >- navigationBar.addNavigationItem(new WI.DividerNavigationItem); >+ controlsNavigationBar.addNavigationItem(new WI.DividerNavigationItem); > > let importButtonNavigationItem = new WI.ButtonNavigationItem("audit-import", WI.UIString("Import"), "Images/Import.svg", 15, 15); > importButtonNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText; > importButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low; > importButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this); >- navigationBar.addNavigationItem(importButtonNavigationItem); >+ controlsNavigationBar.addNavigationItem(importButtonNavigationItem); > >- this.addSubview(navigationBar); >+ this.addSubview(controlsNavigationBar); >+ >+ let editNavigationbar = new WI.NavigationBar; >+ >+ this._editButtonNavigationItem = new WI.ActivateButtonNavigationItem("edit-audits", WI.UIString("Edit"), WI.UIString("Done")); >+ this._editButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleEditButtonNavigationItemClicked, this); >+ editNavigationbar.addNavigationItem(this._editButtonNavigationItem); >+ >+ this.contentView.addSubview(editNavigationbar); > > for (let test of WI.auditManager.tests) > this._addTest(test); >@@ -82,6 +104,7 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > this._addResult(result, i); > }); > >+ WI.auditManager.addEventListener(WI.AuditManager.Event.EditingChanged, this._handleAuditManagerEditingChanged, this); > WI.auditManager.addEventListener(WI.AuditManager.Event.TestAdded, this._handleAuditTestAdded, this); > WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditTestCompleted, this); > WI.auditManager.addEventListener(WI.AuditManager.Event.TestRemoved, this._handleAuditTestRemoved, this); >@@ -105,14 +128,30 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > this._updateNoAuditsPlaceholder(); > } > >+ hasCustomFilters() >+ { >+ return true; >+ } >+ >+ matchTreeElementAgainstCustomFilters(treeElement, flags) >+ { >+ if (WI.auditManager.editing) { >+ if (treeElement.representedObject instanceof WI.AuditTestResultBase || treeElement.hasAncestor(this._resultsFolderTreeElement) || treeElement === this._resultsFolderTreeElement) >+ return false; >+ } else { >+ if (treeElement.representedObject instanceof WI.AuditTestBase && treeElement.representedObject.disabled) >+ return false; >+ } >+ >+ return super.matchTreeElementAgainstCustomFilters(treeElement, flags); >+ } >+ > // Private > > _addTest(test) > { > this.element.classList.add("has-tests"); > >- this._updateStartStopButtonNavigationItemState(); >- > let treeElement = new WI.AuditTreeElement(test); > > if (this._resultsFolderTreeElement) { >@@ -121,6 +160,9 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > } else > this.contentTreeOutline.appendChild(treeElement); > >+ this._updateStartStopButtonNavigationItemState(); >+ this._updateEditButtonNavigationItemState(); >+ > this.hideEmptyContentPlaceholder(); > } > >@@ -128,8 +170,6 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > { > this.element.classList.add("has-results"); > >- this._updateStartStopButtonNavigationItemState(); >- > if (!this._resultsFolderTreeElement) { > this._resultsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Results")); > this.contentTreeOutline.appendChild(this._resultsFolderTreeElement); >@@ -144,14 +184,26 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > } > this._resultsFolderTreeElement.appendChild(resultFolderTreeElement); > >+ console.assert(this._resultsFolderTreeElement.children.length === WI.auditManager.results.length); >+ > for (let resultItem of result) > resultFolderTreeElement.appendChild(new WI.AuditTreeElement(resultItem)); >+ >+ this._updateStartStopButtonNavigationItemState(); >+ this._updateEditButtonNavigationItemState(); > } > > _updateStartStopButtonNavigationItemState() > { >- this._startStopButtonNavigationItem.toggled = WI.auditManager.runningState !== WI.AuditManager.RunningState.Inactive; >- this._startStopButtonNavigationItem.enabled = WI.auditManager.tests.length && WI.auditManager.runningState !== WI.AuditManager.RunningState.Stopping; >+ this._startStopButtonNavigationItem.toggled = WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping; >+ this._startStopButtonNavigationItem.enabled = WI.auditManager.tests.length && (WI.auditManager.runningState === WI.AuditManager.RunningState.Inactive || WI.auditManager.runningState === WI.AuditManager.RunningState.Active); >+ } >+ >+ _updateEditButtonNavigationItemState() >+ { >+ this._editButtonNavigationItem.label = WI.auditManager.editing ? this._editButtonNavigationItem.activatedToolTip : this._editButtonNavigationItem.defaultToolTip; >+ this._editButtonNavigationItem.activated = WI.auditManager.editing; >+ this._editButtonNavigationItem.enabled = WI.auditManager.tests.length && (WI.auditManager.editing || WI.auditManager.runningState === WI.AuditManager.RunningState.Inactive); > } > > _updateNoAuditsPlaceholder() >@@ -176,6 +228,30 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > // be styled such that only the button is visible. > this.contentView.element.insertBefore(contentPlaceholder, this.contentView.element.firstChild); > } >+ >+ this._updateEditButtonNavigationItemState(); >+ } >+ >+ _handleAuditManagerEditingChanged(event) >+ { >+ if (WI.auditManager.editing) { >+ console.assert(!this._selectedTreeElementBeforeEditing); >+ this._selectedTreeElementBeforeEditing = this.contentTreeOutline.selectedTreeElement; >+ if (this._selectedTreeElementBeforeEditing) >+ this._selectedTreeElementBeforeEditing.deselect(); >+ } else if (this._selectedTreeElementBeforeEditing) { >+ if (!(this._selectedTreeElementBeforeEditing.representedObject instanceof WI.AuditTestBase) || !this._selectedTreeElementBeforeEditing.representedObject.disabled) >+ this._selectedTreeElementBeforeEditing.select(); >+ this._selectedTreeElementBeforeEditing = null; >+ } >+ >+ if (!this.contentTreeOutline.selectedTreeElement) >+ this.showDefaultContentView(); >+ >+ this._updateStartStopButtonNavigationItemState(); >+ this._updateEditButtonNavigationItemState(); >+ >+ this.updateFilter(); > } > > _handleAuditTestAdded(event) >@@ -204,6 +280,7 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > _handleAuditTestScheduled(event) > { > this._updateStartStopButtonNavigationItemState(); >+ this._updateEditButtonNavigationItemState(); > } > > _treeSelectionDidChange(event) >@@ -217,6 +294,10 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > return; > } > >+ console.assert(!WI.auditManager.editing); >+ if (WI.auditManager.editing) >+ return; >+ > let representedObject = treeElement.representedObject; > if (representedObject instanceof WI.AuditTestCase || representedObject instanceof WI.AuditTestGroup > || representedObject instanceof WI.AuditTestCaseResult || representedObject instanceof WI.AuditTestGroupResult) { >@@ -241,4 +322,9 @@ WI.AuditNavigationSidebarPanel = class AuditNavigationSidebarPanel extends WI.Na > { > WI.FileUtilities.importJSON((result) => WI.auditManager.processJSON(result)); > } >+ >+ _handleEditButtonNavigationItemClicked(event) >+ { >+ WI.auditManager.editing = !WI.auditManager.editing; >+ } > }; >diff --git a/Source/WebInspectorUI/UserInterface/Views/AuditTestGroupContentView.js b/Source/WebInspectorUI/UserInterface/Views/AuditTestGroupContentView.js >index 628eb1b30dff3cc30b215acdd5aa36236fd0f097..d5bbec5c5c20f5956d36172b9b7af02609dddcfe 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/AuditTestGroupContentView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/AuditTestGroupContentView.js >@@ -149,6 +149,9 @@ WI.AuditTestGroupContentView = class AuditTestGroupContentView extends WI.AuditT > } > > for (let subobject of this._subobjects()) { >+ if (subobject instanceof WI.AuditTestBase && subobject.disabled) >+ continue; >+ > let view = WI.ContentView.contentViewForRepresentedObject(subobject); > this.contentView.addSubview(view); > view.shown(); >diff --git a/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.css b/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.css >index ddd2d95aea8910ca67d0cfaa816b907eb4027956..6922f6a69462c89b892956c007e2e83e0a37c0e9 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.css >+++ b/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.css >@@ -43,12 +43,12 @@ > } > > .tree-outline .item.audit > .status:not(:hover) > img.show-on-hover, >-.tree-outline .item.audit.test-group.expanded > .status:not(:hover) { >+.tree-outline .item.audit.test-group.expanded:not(.editing-audits) > .status:not(:hover) { > opacity: 0; > } > > .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.expanded:not(.editing-audits) > .status:hover > :not(img), > .tree-outline .item.audit.test-group-result.expanded > .status { > display: none; > } >diff --git a/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.js >index cd28ade014ea01b54fccd203fde33d2f9b97098a..62f92b40d0158bcb9ab5225355760d1c3dd5cb50 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.js >+++ b/Source/WebInspectorUI/UserInterface/Views/AuditTreeElement.js >@@ -61,6 +61,7 @@ WI.AuditTreeElement = class AuditTreeElement extends WI.GeneralTreeElement > super.onattach(); > > if (this.representedObject instanceof WI.AuditTestBase) { >+ this.representedObject.addEventListener(WI.AuditTestBase.Event.DisabledChanged, this._handleTestDisabledChanged, this); > this.representedObject.addEventListener(WI.AuditTestBase.Event.ResultCleared, this._handleTestResultCleared, this); > > if (this.representedObject instanceof WI.AuditTestCase) >@@ -68,6 +69,7 @@ WI.AuditTreeElement = class AuditTreeElement extends WI.GeneralTreeElement > else if (this.representedObject instanceof WI.AuditTestGroup) > this.representedObject.addEventListener(WI.AuditTestBase.Event.Scheduled, this._handleTestGroupScheduled, this); > >+ WI.auditManager.addEventListener(WI.AuditManager.Event.EditingChanged, this._handleManagerEditingChanged, this); > WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this); > WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this); > } >@@ -162,6 +164,11 @@ WI.AuditTreeElement = class AuditTreeElement extends WI.GeneralTreeElement > super.populateContextMenu(contextMenu, event); > } > >+ canSelectOnMouseDown(event) >+ { >+ return !WI.auditManager.editing; >+ } >+ > // Private > > _start() >@@ -232,6 +239,14 @@ WI.AuditTreeElement = class AuditTreeElement extends WI.GeneralTreeElement > this.status.value = progress || 0; > } > >+ _updateTestGroupDisabled() >+ { >+ this.status.checked = !this.representedObject.disabled; >+ >+ if (this.representedObject instanceof WI.AuditTestGroup) >+ this.status.indeterminate = this.representedObject.tests.some((test) => test.disabled !== this.representedObject.tests[0].disabled); >+ } >+ > _handleTestCaseCompleted(event) > { > this.representedObject.removeEventListener(WI.AuditTestBase.Event.Completed, this._handleTestCaseCompleted, this); >@@ -239,6 +254,12 @@ WI.AuditTreeElement = class AuditTreeElement extends WI.GeneralTreeElement > this._updateLevel(); > } > >+ _handleTestDisabledChanged(event) >+ { >+ if (this.status instanceof HTMLInputElement && this.status.type === "checkbox") >+ this._updateTestGroupDisabled(); >+ } >+ > _handleTestResultCleared(event) > { > this._updateLevel(); >@@ -273,6 +294,24 @@ WI.AuditTreeElement = class AuditTreeElement extends WI.GeneralTreeElement > this._showRunningProgress(); > } > >+ _handleManagerEditingChanged(event) >+ { >+ if (WI.auditManager.editing) { >+ this.status = document.createElement("input"); >+ this.status.type = "checkbox"; >+ this._updateTestGroupDisabled(); >+ this.status.addEventListener("change", () => { >+ this.representedObject.disabled = !this.representedObject.disabled; >+ }); >+ >+ this.addClassName("editing-audits"); >+ } else { >+ this.removeClassName("editing-audits"); >+ >+ this._updateLevel(); >+ } >+ } >+ > _handleAuditManagerTestScheduled(event) > { > this.addClassName("manager-active"); >diff --git a/Source/WebInspectorUI/UserInterface/Views/TreeOutline.css b/Source/WebInspectorUI/UserInterface/Views/TreeOutline.css >index 98925cac907a307bbd471c92f5827efd245eb27c..2291459bbee1c830c68ccd2d69d1498ce845a58f 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/TreeOutline.css >+++ b/Source/WebInspectorUI/UserInterface/Views/TreeOutline.css >@@ -40,7 +40,7 @@ > display: none; > } > >-.tree-outline .children.expanded { >+.tree-outline .children.expanded:not([hidden]) { > display: block; > } > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 9c1c3ba62de4622d5de7e41ef7af961e7de5e138..0f0b2e369220c092c403dfcadc84f921c2ff62cb 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2019-01-10 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: Audit: allow audits to be enabled/disabled >+ https://bugs.webkit.org/show_bug.cgi?id=192210 >+ <rdar://problem/46423583> >+ >+ Reviewed by Joseph Pecoraro. >+ >+ * inspector/unit-tests/objectStore/clear.html: Added. >+ * inspector/unit-tests/objectStore/clear-expected.txt: Added. >+ > 2019-01-09 Zalan Bujtas <zalan@apple.com> > > [Datalist] Crash when input with datalist is dynamically added. >diff --git a/LayoutTests/inspector/unit-tests/objectStore/clear-expected.txt b/LayoutTests/inspector/unit-tests/objectStore/clear-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..babfb793b1318aaeb0fcf66f75cb077fff47b4f2 >--- /dev/null >+++ b/LayoutTests/inspector/unit-tests/objectStore/clear-expected.txt >@@ -0,0 +1,12 @@ >+Tests WI.ObjectStore.prototype.clear. >+ >+ >+== Running test suite: WI.ObjectStore.prototype.clear >+-- Running test case: WI.ObjectStore.prototype.clear.Empty >+[] >+[] >+ >+-- Running test case: WI.ObjectStore.prototype.clear.NotEmpty >+[true,1,"foo",["bar"],{"a":1}] >+[] >+ >diff --git a/LayoutTests/inspector/unit-tests/objectStore/clear.html b/LayoutTests/inspector/unit-tests/objectStore/clear.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d9e714ef9a0c4c596c040a77ab24b19eb8df1372 >--- /dev/null >+++ b/LayoutTests/inspector/unit-tests/objectStore/clear.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../../../http/tests/inspector/resources/inspector-test.js"></script> >+<script src="resources/objectStore-utilities.js"></script> >+<script> >+function test() >+{ >+ let suite = InspectorTest.ObjectStore.createSuite("WI.ObjectStore.prototype.clear"); >+ >+ function testClear(name, {objects}) { >+ InspectorTest.ObjectStore.wrapTest(name, async function() { >+ let objectStore = InspectorTest.ObjectStore.createObjectStore({autoIncrement: true}); >+ >+ for (let object of objects) >+ await objectStore.add(object); >+ >+ await InspectorTest.ObjectStore.logValues(); >+ >+ await objectStore.clear(); >+ }); >+ } >+ >+ testClear("WI.ObjectStore.prototype.clear.Empty", { >+ objects: [], >+ }); >+ >+ testClear("WI.ObjectStore.prototype.clear.NotEmpty", { >+ objects: [true, 1, "foo", ["bar"], {a: 1}], >+ }); >+ >+ suite.runTestCasesAndFinish(); >+} >+</script> >+</head> >+<body onload="runTest()"> >+ <p>Tests WI.ObjectStore.prototype.clear.</p> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192210
:
356125
|
356126
|
358868
| 358871