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 * @implements {WebInspector.TargetManager.Observer} 8 */ 9 WebInspector.ExecutionContextSelector = function() 10 { 11 WebInspector.targetManager.observeTargets(this); 12 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this); 13 WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChanged, this); 14 } 15 16 WebInspector.ExecutionContextSelector.prototype = { 17 18 /** 19 * @param {!WebInspector.Target} target 20 */ 21 targetAdded: function(target) 22 { 23 if (!WebInspector.context.flavor(WebInspector.Target)) 24 WebInspector.context.setFlavor(WebInspector.Target, target); 25 26 target.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this); 27 target.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this); 28 }, 29 30 /** 31 * @param {!WebInspector.Target} target 32 */ 33 targetRemoved: function(target) 34 { 35 target.runtimeModel.removeEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this); 36 target.runtimeModel.removeEventListener(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this); 37 var currentExecutionContext = WebInspector.context.flavor(WebInspector.Target); 38 if (currentExecutionContext && currentExecutionContext.target() === target) 39 this._currentExecutionContextGone(); 40 41 var targets = WebInspector.targetManager.targets(); 42 if (WebInspector.context.flavor(WebInspector.Target) === target && targets.length) 43 WebInspector.context.setFlavor(WebInspector.Target, targets[0]); 44 }, 45 46 /** 47 * @param {!WebInspector.Event} event 48 */ 49 _executionContextChanged: function(event) 50 { 51 var newContext = /** @type {?WebInspector.ExecutionContext} */ (event.data); 52 if (newContext) 53 WebInspector.context.setFlavor(WebInspector.Target, newContext.target()); 54 }, 55 56 /** 57 * @param {!WebInspector.Event} event 58 */ 59 _targetChanged: function(event) 60 { 61 var newTarget = /** @type {?WebInspector.Target} */(event.data); 62 var currentContext = WebInspector.context.flavor(WebInspector.ExecutionContext); 63 64 if (!newTarget || (currentContext && currentContext.target() === newTarget)) 65 return; 66 67 var executionContexts = newTarget.runtimeModel.executionContexts(); 68 if (!executionContexts.length) 69 return; 70 71 var newContext = executionContexts[0]; 72 for (var i = 1; i < executionContexts.length; ++i) { 73 if (executionContexts[i].isMainWorldContext) 74 newContext = executionContexts[i]; 75 } 76 WebInspector.context.setFlavor(WebInspector.ExecutionContext, newContext); 77 }, 78 79 /** 80 * @param {!WebInspector.Event} event 81 */ 82 _onExecutionContextCreated: function(event) 83 { 84 var executionContext = /** @type {!WebInspector.ExecutionContext}*/ (event.data); 85 if (!WebInspector.context.flavor(WebInspector.ExecutionContext)) 86 WebInspector.context.setFlavor(WebInspector.ExecutionContext, executionContext); 87 }, 88 89 /** 90 * @param {!WebInspector.Event} event 91 */ 92 _onExecutionContextDestroyed: function(event) 93 { 94 var executionContext = /** @type {!WebInspector.ExecutionContext}*/ (event.data); 95 if (WebInspector.context.flavor(WebInspector.ExecutionContext) === executionContext) 96 this._currentExecutionContextGone(); 97 }, 98 99 _currentExecutionContextGone: function() 100 { 101 var targets = WebInspector.targetManager.targets(); 102 var newContext = null; 103 for (var i = 0; i < targets.length; ++i) { 104 var executionContexts = targets[i].runtimeModel.executionContexts(); 105 if (executionContexts.length) { 106 newContext = executionContexts[0]; 107 break; 108 } 109 } 110 WebInspector.context.setFlavor(WebInspector.ExecutionContext, newContext); 111 } 112 113 } 114 115 /** 116 * @param {!Element} proxyElement 117 * @param {!Range} wordRange 118 * @param {boolean} force 119 * @param {function(!Array.<string>, number=)} completionsReadyCallback 120 */ 121 WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext = function(proxyElement, wordRange, force, completionsReadyCallback) 122 { 123 var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext); 124 if (!executionContext) { 125 completionsReadyCallback([]); 126 return; 127 } 128 129 // Pass less stop characters to rangeOfWord so the range will be a more complete expression. 130 var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, " =:[({;,!+-*/&|^<>", proxyElement, "backward"); 131 var expressionString = expressionRange.toString(); 132 var prefix = wordRange.toString(); 133 executionContext.completionsForExpression(expressionString, prefix, force, completionsReadyCallback); 134 }