Web Inspector: Audit: allow audits to be enabled/disabled
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Models / AuditTestBase.js
1 /*
2  * Copyright (C) 2018 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WI.AuditTestBase = class AuditTestBase extends WI.Object
27 {
28     constructor(name, {description, disabled} = {})
29     {
30         console.assert(typeof name === "string");
31         console.assert(!description || typeof description === "string");
32         console.assert(disabled === undefined || typeof disabled === "boolean");
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);
38
39         this._name = name;
40         this._description = description || null;
41
42         this._runningState = disabled ? WI.AuditManager.RunningState.Disabled : WI.AuditManager.RunningState.Inactive;
43         this._result = null;
44     }
45
46     // Public
47
48     get name() { return this._name; }
49     get description() { return this._description; }
50     get runningState() { return this._runningState; }
51     get result() { return this._result; }
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
73     async start()
74     {
75         // Called from WI.AuditManager.
76
77         if (this.disabled)
78             return;
79
80         console.assert(WI.auditManager.runningState === WI.AuditManager.RunningState.Active);
81
82         console.assert(this._runningState === WI.AuditManager.RunningState.Inactive);
83         if (this._runningState !== WI.AuditManager.RunningState.Inactive)
84             return;
85
86         this._runningState = WI.AuditManager.RunningState.Active;
87         this.dispatchEventToListeners(WI.AuditTestBase.Event.Scheduled);
88
89         await this.run();
90
91         this._runningState = WI.AuditManager.RunningState.Inactive;
92         this.dispatchEventToListeners(WI.AuditTestBase.Event.Completed);
93     }
94
95     stop()
96     {
97         // Called from WI.AuditManager.
98
99         if (this.disabled)
100             return;
101
102         console.assert(WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping);
103
104         if (this._runningState !== WI.AuditManager.RunningState.Active)
105             return;
106
107         this._runningState = WI.AuditManager.RunningState.Stopping;
108         this.dispatchEventToListeners(WI.AuditTestBase.Event.Stopping);
109     }
110
111     clearResult(options = {})
112     {
113         if (!this._result)
114             return false;
115
116         this._result = null;
117
118         if (!options.suppressResultClearedEvent)
119             this.dispatchEventToListeners(WI.AuditTestBase.Event.ResultCleared);
120
121         return true;
122     }
123
124     saveIdentityToCookie(cookie)
125     {
126         cookie["audit-" + this.constructor.TypeIdentifier + "-name"] = this._name;
127     }
128
129     toJSON(key)
130     {
131         let json = {
132             type: this.constructor.TypeIdentifier,
133             name: this._name,
134         };
135         if (this._description)
136             json.description = this._description;
137         if (key === WI.ObjectStore.toJSONSymbol)
138             json.disabled = this.disabled;
139         return json;
140     }
141
142     // Protected
143
144     async run()
145     {
146         throw WI.NotImplementedError.subclassMustOverride();
147     }
148 };
149
150 WI.AuditTestBase.Event = {
151     Completed: "audit-test-base-completed",
152     DisabledChanged: "audit-test-base-disabled-changed",
153     Progress: "audit-test-base-progress",
154     ResultCleared: "audit-test-base-result-cleared",
155     Scheduled: "audit-test-base-scheduled",
156     Stopping: "audit-test-base-stopping",
157 };