2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 * Copyright (C) 2016 Devin Rousso <webkit@devinrousso.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
27 WI.ResourceCollection = class ResourceCollection extends WI.Collection
29 constructor(resourceType)
31 super(WI.ResourceCollection.verifierForType(resourceType));
33 this._resourceType = resourceType || null;
34 this._resourceURLMap = new Map;
35 this._resourcesTypeMap = new Map;
40 static verifierForType(type) {
42 case WI.Resource.Type.Document:
43 return WI.ResourceCollection.TypeVerifier.Document;
44 case WI.Resource.Type.Stylesheet:
45 return WI.ResourceCollection.TypeVerifier.Stylesheet;
46 case WI.Resource.Type.Image:
47 return WI.ResourceCollection.TypeVerifier.Image;
48 case WI.Resource.Type.Font:
49 return WI.ResourceCollection.TypeVerifier.Font;
50 case WI.Resource.Type.Script:
51 return WI.ResourceCollection.TypeVerifier.Script;
52 case WI.Resource.Type.XHR:
53 return WI.ResourceCollection.TypeVerifier.XHR;
54 case WI.Resource.Type.Fetch:
55 return WI.ResourceCollection.TypeVerifier.Fetch;
56 case WI.Resource.Type.Ping:
57 return WI.ResourceCollection.TypeVerifier.Ping;
58 case WI.Resource.Type.Beacon:
59 return WI.ResourceCollection.TypeVerifier.Beacon;
60 case WI.Resource.Type.WebSocket:
61 return WI.ResourceCollection.TypeVerifier.WebSocket;
62 case WI.Resource.Type.Other:
63 return WI.ResourceCollection.TypeVerifier.Other;
65 return WI.Collection.TypeVerifier.Resource;
71 get resourceType() { return this._resourceType; }
75 return this._resourceURLMap.get(url) || null;
78 resourceCollectionForType(type)
80 if (this._resourceType) {
81 console.assert(type === this._resourceType);
85 let resourcesCollectionForType = this._resourcesTypeMap.get(type);
86 if (!resourcesCollectionForType) {
87 resourcesCollectionForType = new WI.ResourceCollection(type);
88 this._resourcesTypeMap.set(type, resourcesCollectionForType);
91 return resourcesCollectionForType;
98 this._resourceURLMap.clear();
100 if (!this._resourceType)
101 this._resourcesTypeMap.clear();
108 this._associateWithResource(item);
113 this._disassociateWithResource(item);
118 const skipRemoval = true;
120 for (let item of items)
121 this._disassociateWithResource(item, skipRemoval);
126 _associateWithResource(resource)
128 this._resourceURLMap.set(resource.url, resource);
130 if (!this._resourceType) {
131 let resourcesCollectionForType = this.resourceCollectionForType(resource.type);
132 resourcesCollectionForType.add(resource);
135 resource.addEventListener(WI.Resource.Event.URLDidChange, this._resourceURLDidChange, this);
136 resource.addEventListener(WI.Resource.Event.TypeDidChange, this._resourceTypeDidChange, this);
139 _disassociateWithResource(resource, skipRemoval)
141 resource.removeEventListener(WI.Resource.Event.URLDidChange, this._resourceURLDidChange, this);
142 resource.removeEventListener(WI.Resource.Event.TypeDidChange, this._resourceTypeDidChange, this);
147 if (!this._resourceType) {
148 let resourcesCollectionForType = this.resourceCollectionForType(resource.type);
149 resourcesCollectionForType.remove(resource);
152 this._resourceURLMap.delete(resource.url);
155 _resourceURLDidChange(event)
157 let resource = event.target;
158 console.assert(resource instanceof WI.Resource);
159 if (!(resource instanceof WI.Resource))
162 let oldURL = event.data.oldURL;
163 console.assert(oldURL);
167 this._resourceURLMap.set(resource.url, resource);
168 this._resourceURLMap.delete(oldURL);
171 _resourceTypeDidChange(event)
173 let resource = event.target;
174 console.assert(resource instanceof WI.Resource);
175 if (!(resource instanceof WI.Resource))
178 if (this._resourceType) {
179 console.assert(resource.type !== this._resourceType);
180 this.remove(resource);
184 console.assert(event.data.oldType);
186 let resourcesWithNewType = this.resourceCollectionForType(resource.type);
187 resourcesWithNewType.add(resource);
189 // It is not necessary to remove the resource from the sub-collection for the old type since
190 // this is handled by that sub-collection's own _resourceTypeDidChange handler (via the
191 // above if statement).
195 WI.ResourceCollection.TypeVerifier = {
196 Document: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Document,
197 Stylesheet: (object) => {
198 if (WI.Collection.TypeVerifier.CSSStyleSheet(object))
200 return WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Stylesheet;
202 Image: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Image,
203 Font: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Font,
204 Script: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Script,
205 XHR: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.XHR,
206 Fetch: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Fetch,
207 Ping: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Ping,
208 Beacon: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Beacon,
209 WebSocket: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.WebSocket,
210 Other: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Other,