1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @constructor
7 */
8WebInspector.Context = function()
9{
10    this._flavors = new Map();
11    this._eventDispatchers = new Map();
12}
13
14/**
15 * @enum {string}
16 */
17WebInspector.Context.Events = {
18    FlavorChanged: "FlavorChanged"
19}
20
21WebInspector.Context.prototype = {
22    /**
23     * @param {function(new:T, ...)} flavorType
24     * @param {?T} flavorValue
25     * @template T
26     */
27    setFlavor: function(flavorType, flavorValue)
28    {
29        var value = this._flavors.get(flavorType) || null;
30        if (value === flavorValue)
31            return;
32        if (flavorValue)
33            this._flavors.set(flavorType, flavorValue);
34        else
35            this._flavors.remove(flavorType);
36
37        this._dispatchFlavorChange(flavorType, flavorValue);
38    },
39
40    /**
41     * @param {function(new:T, ...)} flavorType
42     * @param {?T} flavorValue
43     * @template T
44     */
45    _dispatchFlavorChange: function(flavorType, flavorValue)
46    {
47        var dispatcher = this._eventDispatchers.get(flavorType);
48        if (!dispatcher)
49            return;
50        dispatcher.dispatchEventToListeners(WebInspector.Context.Events.FlavorChanged, flavorValue);
51    },
52
53    /**
54     * @param {function(new:Object, ...)} flavorType
55     * @param {function(!WebInspector.Event)} listener
56     * @param {!Object=} thisObject
57     */
58    addFlavorChangeListener: function(flavorType, listener, thisObject)
59    {
60        var dispatcher = this._eventDispatchers.get(flavorType);
61        if (!dispatcher) {
62            dispatcher = new WebInspector.Object();
63            this._eventDispatchers.set(flavorType, dispatcher);
64        }
65        dispatcher.addEventListener(WebInspector.Context.Events.FlavorChanged, listener, thisObject);
66    },
67
68    /**
69     * @param {function(new:Object, ...)} flavorType
70     * @param {function(!WebInspector.Event)} listener
71     * @param {!Object=} thisObject
72     */
73    removeFlavorChangeListener: function(flavorType, listener, thisObject)
74    {
75        var dispatcher = this._eventDispatchers.get(flavorType);
76        if (!dispatcher)
77            return;
78        dispatcher.removeEventListener(WebInspector.Context.Events.FlavorChanged, listener, thisObject);
79        if (!dispatcher.hasEventListeners(WebInspector.Context.Events.FlavorChanged))
80            this._eventDispatchers.remove(flavorType);
81    },
82
83    /**
84     * @param {function(new:T, ...)} flavorType
85     * @return {?T}
86     * @template T
87     */
88    flavor: function(flavorType)
89    {
90        return this._flavors.get(flavorType) || null;
91    },
92
93    /**
94     * @return {!Array.<function(new:Object, ...)>}
95     */
96    flavors: function()
97    {
98        return this._flavors.keys();
99    },
100
101    /**
102     * @param {!Array.<!Runtime.Extension>} extensions
103     * @return {!Set.<!Runtime.Extension>}
104     */
105    applicableExtensions: function(extensions)
106    {
107        var targetExtensionSet = new Set();
108
109        var availableFlavors = this.flavors();
110        extensions.forEach(function(extension) {
111            if (self.runtime.isExtensionApplicableToContextTypes(extension, availableFlavors))
112                targetExtensionSet.add(extension);
113        });
114
115        return targetExtensionSet;
116    }
117}
118
119WebInspector.context = new WebInspector.Context();