ExtensionServer.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. export default class ExtensionServer extends Common.Object{constructor(){super();this._clientObjects={};this._handlers={};this._subscribers={};this._subscriptionStartHandlers={};this._subscriptionStopHandlers={};this._extraHeaders={};this._requests={};this._lastRequestId=0;this._registeredExtensions={};this._status=new ExtensionStatus();this._sidebarPanes=[];this._traceProviders=[];this._traceSessions=new Map();const commands=Extensions.extensionAPI.Commands;this._registerHandler(commands.AddRequestHeaders,this._onAddRequestHeaders.bind(this));this._registerHandler(commands.AddTraceProvider,this._onAddTraceProvider.bind(this));this._registerHandler(commands.ApplyStyleSheet,this._onApplyStyleSheet.bind(this));this._registerHandler(commands.CompleteTraceSession,this._onCompleteTraceSession.bind(this));this._registerHandler(commands.CreatePanel,this._onCreatePanel.bind(this));this._registerHandler(commands.CreateSidebarPane,this._onCreateSidebarPane.bind(this));this._registerHandler(commands.CreateToolbarButton,this._onCreateToolbarButton.bind(this));this._registerHandler(commands.EvaluateOnInspectedPage,this._onEvaluateOnInspectedPage.bind(this));this._registerHandler(commands.ForwardKeyboardEvent,this._onForwardKeyboardEvent.bind(this));this._registerHandler(commands.GetHAR,this._onGetHAR.bind(this));this._registerHandler(commands.GetPageResources,this._onGetPageResources.bind(this));this._registerHandler(commands.GetRequestContent,this._onGetRequestContent.bind(this));this._registerHandler(commands.GetResourceContent,this._onGetResourceContent.bind(this));this._registerHandler(commands.Reload,this._onReload.bind(this));this._registerHandler(commands.SetOpenResourceHandler,this._onSetOpenResourceHandler.bind(this));this._registerHandler(commands.SetResourceContent,this._onSetResourceContent.bind(this));this._registerHandler(commands.SetSidebarHeight,this._onSetSidebarHeight.bind(this));this._registerHandler(commands.SetSidebarContent,this._onSetSidebarContent.bind(this));this._registerHandler(commands.SetSidebarPage,this._onSetSidebarPage.bind(this));this._registerHandler(commands.ShowPanel,this._onShowPanel.bind(this));this._registerHandler(commands.Subscribe,this._onSubscribe.bind(this));this._registerHandler(commands.OpenResource,this._onOpenResource.bind(this));this._registerHandler(commands.Unsubscribe,this._onUnsubscribe.bind(this));this._registerHandler(commands.UpdateButton,this._onUpdateButton.bind(this));window.addEventListener('message',this._onWindowMessage.bind(this),false);const existingTabId=window.DevToolsAPI&&window.DevToolsAPI.getInspectedTabId&&window.DevToolsAPI.getInspectedTabId();if(existingTabId){this._setInspectedTabId({data:existingTabId});}
  2. Host.InspectorFrontendHost.events.addEventListener(Host.InspectorFrontendHostAPI.Events.SetInspectedTabId,this._setInspectedTabId,this);this._initExtensions();}
  3. initializeExtensions(){Host.InspectorFrontendHost.setAddExtensionCallback(this._addExtension.bind(this));}
  4. hasExtensions(){return!!Object.keys(this._registeredExtensions).length;}
  5. notifySearchAction(panelId,action,searchString){this._postNotification(Extensions.extensionAPI.Events.PanelSearch+panelId,action,searchString);}
  6. notifyViewShown(identifier,frameIndex){this._postNotification(Extensions.extensionAPI.Events.ViewShown+identifier,frameIndex);}
  7. notifyViewHidden(identifier){this._postNotification(Extensions.extensionAPI.Events.ViewHidden+identifier);}
  8. notifyButtonClicked(identifier){this._postNotification(Extensions.extensionAPI.Events.ButtonClicked+identifier);}
  9. _inspectedURLChanged(event){if(event.data!==SDK.targetManager.mainTarget()){return;}
  10. this._requests={};const url=event.data.inspectedURL();this._postNotification(Extensions.extensionAPI.Events.InspectedURLChanged,url);}
  11. startTraceRecording(providerId,sessionId,session){this._traceSessions.set(sessionId,session);this._postNotification('trace-recording-started-'+providerId,sessionId);}
  12. stopTraceRecording(providerId){this._postNotification('trace-recording-stopped-'+providerId);}
  13. hasSubscribers(type){return!!this._subscribers[type];}
  14. _postNotification(type,vararg){const subscribers=this._subscribers[type];if(!subscribers){return;}
  15. const message={command:'notify-'+type,arguments:Array.prototype.slice.call(arguments,1)};for(let i=0;i<subscribers.length;++i){subscribers[i].postMessage(message);}}
  16. _onSubscribe(message,port){const subscribers=this._subscribers[message.type];if(subscribers){subscribers.push(port);}else{this._subscribers[message.type]=[port];if(this._subscriptionStartHandlers[message.type]){this._subscriptionStartHandlers[message.type]();}}}
  17. _onUnsubscribe(message,port){const subscribers=this._subscribers[message.type];if(!subscribers){return;}
  18. subscribers.remove(port);if(!subscribers.length){delete this._subscribers[message.type];if(this._subscriptionStopHandlers[message.type]){this._subscriptionStopHandlers[message.type]();}}}
  19. _onAddRequestHeaders(message){const id=message.extensionId;if(typeof id!=='string'){return this._status.E_BADARGTYPE('extensionId',typeof id,'string');}
  20. let extensionHeaders=this._extraHeaders[id];if(!extensionHeaders){extensionHeaders={};this._extraHeaders[id]=extensionHeaders;}
  21. for(const name in message.headers){extensionHeaders[name]=message.headers[name];}
  22. const allHeaders=({});for(const extension in this._extraHeaders){const headers=this._extraHeaders[extension];for(const name in headers){if(typeof headers[name]==='string'){allHeaders[name]=headers[name];}}}
  23. SDK.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);}
  24. _onApplyStyleSheet(message){if(!Root.Runtime.experiments.isEnabled('applyCustomStylesheet')){return;}
  25. const styleSheet=createElement('style');styleSheet.textContent=message.styleSheet;document.head.appendChild(styleSheet);UI.themeSupport.addCustomStylesheet(message.styleSheet);for(let node=document.body;node;node=node.traverseNextNode(document.body)){if(node instanceof ShadowRoot){UI.themeSupport.injectCustomStyleSheets(node);}}}
  26. _onCreatePanel(message,port){const id=message.id;if(id in this._clientObjects||UI.inspectorView.hasPanel(id)){return this._status.E_EXISTS(id);}
  27. const page=this._expandResourcePath(port._extensionOrigin,message.page);let persistentId=port._extensionOrigin+message.title;persistentId=persistentId.replace(/\s/g,'');const panelView=new ExtensionServerPanelView(persistentId,message.title,new Extensions.ExtensionPanel(this,persistentId,id,page));this._clientObjects[id]=panelView;UI.inspectorView.addPanel(panelView);return this._status.OK();}
  28. _onShowPanel(message){let panelViewId=message.id;const panelView=this._clientObjects[message.id];if(panelView&&panelView instanceof ExtensionServerPanelView){panelViewId=panelView.viewId();}
  29. UI.inspectorView.showPanel(panelViewId);}
  30. _onCreateToolbarButton(message,port){const panelView=this._clientObjects[message.panel];if(!panelView||!(panelView instanceof ExtensionServerPanelView)){return this._status.E_NOTFOUND(message.panel);}
  31. const button=new Extensions.ExtensionButton(this,message.id,this._expandResourcePath(port._extensionOrigin,message.icon),message.tooltip,message.disabled);this._clientObjects[message.id]=button;panelView.widget().then(appendButton);function appendButton(panel){(panel).addToolbarItem(button.toolbarButton());}
  32. return this._status.OK();}
  33. _onUpdateButton(message,port){const button=this._clientObjects[message.id];if(!button||!(button instanceof Extensions.ExtensionButton)){return this._status.E_NOTFOUND(message.id);}
  34. button.update(this._expandResourcePath(port._extensionOrigin,message.icon),message.tooltip,message.disabled);return this._status.OK();}
  35. _onCompleteTraceSession(message){const session=this._traceSessions.get(message.id);if(!session){return this._status.E_NOTFOUND(message.id);}
  36. this._traceSessions.delete(message.id);session.complete(message.url,message.timeOffset);}
  37. _onCreateSidebarPane(message){if(message.panel!=='elements'&&message.panel!=='sources'){return this._status.E_NOTFOUND(message.panel);}
  38. const id=message.id;const sidebar=new Extensions.ExtensionSidebarPane(this,message.panel,message.title,id);this._sidebarPanes.push(sidebar);this._clientObjects[id]=sidebar;this.dispatchEventToListeners(Events.SidebarPaneAdded,sidebar);return this._status.OK();}
  39. sidebarPanes(){return this._sidebarPanes;}
  40. _onSetSidebarHeight(message){const sidebar=this._clientObjects[message.id];if(!sidebar){return this._status.E_NOTFOUND(message.id);}
  41. sidebar.setHeight(message.height);return this._status.OK();}
  42. _onSetSidebarContent(message,port){const sidebar=this._clientObjects[message.id];if(!sidebar){return this._status.E_NOTFOUND(message.id);}
  43. function callback(error){const result=error?this._status.E_FAILED(error):this._status.OK();this._dispatchCallback(message.requestId,port,result);}
  44. if(message.evaluateOnPage){return sidebar.setExpression(message.expression,message.rootTitle,message.evaluateOptions,port._extensionOrigin,callback.bind(this));}
  45. sidebar.setObject(message.expression,message.rootTitle,callback.bind(this));}
  46. _onSetSidebarPage(message,port){const sidebar=this._clientObjects[message.id];if(!sidebar){return this._status.E_NOTFOUND(message.id);}
  47. sidebar.setPage(this._expandResourcePath(port._extensionOrigin,message.page));}
  48. _onOpenResource(message){const uiSourceCode=Workspace.workspace.uiSourceCodeForURL(message.url);if(uiSourceCode){Common.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber,0));return this._status.OK();}
  49. const resource=Bindings.resourceForURL(message.url);if(resource){Common.Revealer.reveal(resource);return this._status.OK();}
  50. const request=SDK.networkLog.requestForURL(message.url);if(request){Common.Revealer.reveal(request);return this._status.OK();}
  51. return this._status.E_NOTFOUND(message.url);}
  52. _onSetOpenResourceHandler(message,port){const name=this._registeredExtensions[port._extensionOrigin].name||('Extension '+port._extensionOrigin);if(message.handlerPresent){Components.Linkifier.registerLinkHandler(name,this._handleOpenURL.bind(this,port));}else{Components.Linkifier.unregisterLinkHandler(name);}}
  53. _handleOpenURL(port,contentProvider,lineNumber){port.postMessage({command:'open-resource',resource:this._makeResource(contentProvider),lineNumber:lineNumber+1});}
  54. _onReload(message){const options=(message.options||{});SDK.multitargetNetworkManager.setUserAgentOverride(typeof options.userAgent==='string'?options.userAgent:'');let injectedScript;if(options.injectedScript){injectedScript='(function(){'+options.injectedScript+'})()';}
  55. SDK.ResourceTreeModel.reloadAllPages(!!options.ignoreCache,injectedScript);return this._status.OK();}
  56. _onEvaluateOnInspectedPage(message,port){function callback(error,object,wasThrown){let result;if(error||!object){result=this._status.E_PROTOCOLERROR(error.toString());}else if(wasThrown){result={isException:true,value:object.description};}else{result={value:object.value};}
  57. this._dispatchCallback(message.requestId,port,result);}
  58. return this.evaluate(message.expression,true,true,message.evaluateOptions,port._extensionOrigin,callback.bind(this));}
  59. async _onGetHAR(){const requests=SDK.networkLog.requests();const harLog=await SDK.HARLog.build(requests);for(let i=0;i<harLog.entries.length;++i){harLog.entries[i]._requestId=this._requestId(requests[i]);}
  60. return harLog;}
  61. _makeResource(contentProvider){return{url:contentProvider.contentURL(),type:contentProvider.contentType().name()};}
  62. _onGetPageResources(){const resources=new Map();function pushResourceData(contentProvider){if(!resources.has(contentProvider.contentURL())){resources.set(contentProvider.contentURL(),this._makeResource(contentProvider));}}
  63. let uiSourceCodes=Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Network);uiSourceCodes=uiSourceCodes.concat(Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.ContentScripts));uiSourceCodes.forEach(pushResourceData.bind(this));for(const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel)){resourceTreeModel.forAllResources(pushResourceData.bind(this));}
  64. return resources.valuesArray();}
  65. async _getResourceContent(contentProvider,message,port){const{content}=await contentProvider.requestContent();const encoded=await contentProvider.contentEncoded();this._dispatchCallback(message.requestId,port,{encoding:encoded?'base64':'',content:content});}
  66. _onGetRequestContent(message,port){const request=this._requestById(message.id);if(!request){return this._status.E_NOTFOUND(message.id);}
  67. this._getResourceContent(request,message,port);}
  68. _onGetResourceContent(message,port){const url=(message.url);const contentProvider=Workspace.workspace.uiSourceCodeForURL(url)||Bindings.resourceForURL(url);if(!contentProvider){return this._status.E_NOTFOUND(url);}
  69. this._getResourceContent(contentProvider,message,port);}
  70. _onSetResourceContent(message,port){function callbackWrapper(error){const response=error?this._status.E_FAILED(error):this._status.OK();this._dispatchCallback(message.requestId,port,response);}
  71. const url=(message.url);const uiSourceCode=Workspace.workspace.uiSourceCodeForURL(url);if(!uiSourceCode||!uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()){const resource=SDK.ResourceTreeModel.resourceForURL(url);if(!resource){return this._status.E_NOTFOUND(url);}
  72. return this._status.E_NOTSUPPORTED('Resource is not editable');}
  73. uiSourceCode.setWorkingCopy(message.content);if(message.commit){uiSourceCode.commitWorkingCopy();}
  74. callbackWrapper.call(this,null);}
  75. _requestId(request){if(!request._extensionRequestId){request._extensionRequestId=++this._lastRequestId;this._requests[request._extensionRequestId]=request;}
  76. return request._extensionRequestId;}
  77. _requestById(id){return this._requests[id];}
  78. _onAddTraceProvider(message,port){const provider=new Extensions.ExtensionTraceProvider(port._extensionOrigin,message.id,message.categoryName,message.categoryTooltip);this._clientObjects[message.id]=provider;this._traceProviders.push(provider);this.dispatchEventToListeners(Events.TraceProviderAdded,provider);}
  79. traceProviders(){return this._traceProviders;}
  80. _onForwardKeyboardEvent(message){message.entries.forEach(handleEventEntry);function handleEventEntry(entry){const event=new window.KeyboardEvent(entry.eventType,{key:entry.key,code:entry.code,keyCode:entry.keyCode,location:entry.location,ctrlKey:entry.ctrlKey,altKey:entry.altKey,shiftKey:entry.shiftKey,metaKey:entry.metaKey});event.__keyCode=keyCodeForEntry(entry);document.dispatchEvent(event);}
  81. function keyCodeForEntry(entry){let keyCode=entry.keyCode;if(!keyCode){if(entry.key==='Escape'){keyCode=27;}}
  82. return keyCode||0;}}
  83. _dispatchCallback(requestId,port,result){if(requestId){port.postMessage({command:'callback',requestId:requestId,result:result});}}
  84. _initExtensions(){this._registerAutosubscriptionHandler(Extensions.extensionAPI.Events.ResourceAdded,Workspace.workspace,Workspace.Workspace.Events.UISourceCodeAdded,this._notifyResourceAdded);this._registerAutosubscriptionTargetManagerHandler(Extensions.extensionAPI.Events.NetworkRequestFinished,SDK.NetworkManager,SDK.NetworkManager.Events.RequestFinished,this._notifyRequestFinished);function onElementsSubscriptionStarted(){UI.context.addFlavorChangeListener(SDK.DOMNode,this._notifyElementsSelectionChanged,this);}
  85. function onElementsSubscriptionStopped(){UI.context.removeFlavorChangeListener(SDK.DOMNode,this._notifyElementsSelectionChanged,this);}
  86. this._registerSubscriptionHandler(Extensions.extensionAPI.Events.PanelObjectSelected+'elements',onElementsSubscriptionStarted.bind(this),onElementsSubscriptionStopped.bind(this));this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged,this._inspectedURLChanged,this);}
  87. _notifyResourceAdded(event){const uiSourceCode=(event.data);this._postNotification(Extensions.extensionAPI.Events.ResourceAdded,this._makeResource(uiSourceCode));}
  88. _notifyUISourceCodeContentCommitted(event){const uiSourceCode=(event.data.uiSourceCode);const content=(event.data.content);this._postNotification(Extensions.extensionAPI.Events.ResourceContentCommitted,this._makeResource(uiSourceCode),content);}
  89. async _notifyRequestFinished(event){const request=(event.data);const entry=await SDK.HARLog.Entry.build(request);this._postNotification(Extensions.extensionAPI.Events.NetworkRequestFinished,this._requestId(request),entry);}
  90. _notifyElementsSelectionChanged(){this._postNotification(Extensions.extensionAPI.Events.PanelObjectSelected+'elements');}
  91. sourceSelectionChanged(url,range){this._postNotification(Extensions.extensionAPI.Events.PanelObjectSelected+'sources',{startLine:range.startLine,startColumn:range.startColumn,endLine:range.endLine,endColumn:range.endColumn,url:url,});}
  92. _setInspectedTabId(event){this._inspectedTabId=(event.data);}
  93. _addExtension(extensionInfo){const urlOriginRegExp=new RegExp('([^:]+:\/\/[^/]*)\/');const startPage=extensionInfo.startPage;const name=extensionInfo.name;try{const originMatch=urlOriginRegExp.exec(startPage);if(!originMatch){console.error('Skipping extension with invalid URL: '+startPage);return false;}
  94. const extensionOrigin=originMatch[1];if(!this._registeredExtensions[extensionOrigin]){const injectedAPI=self.buildExtensionAPIInjectedScript(extensionInfo,this._inspectedTabId,UI.themeSupport.themeName(),UI.shortcutRegistry.globalShortcutKeys(),Extensions.extensionServer['_extensionAPITestHook']);Host.InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin,injectedAPI);this._registeredExtensions[extensionOrigin]={name:name};}
  95. const iframe=createElement('iframe');iframe.src=startPage;iframe.style.display='none';document.body.appendChild(iframe);}catch(e){console.error('Failed to initialize extension '+startPage+':'+e);return false;}
  96. return true;}
  97. _registerExtension(origin,port){if(!this._registeredExtensions.hasOwnProperty(origin)){if(origin!==window.location.origin)
  98. {console.error('Ignoring unauthorized client request from '+origin);}
  99. return;}
  100. port._extensionOrigin=origin;port.addEventListener('message',this._onmessage.bind(this),false);port.start();}
  101. _onWindowMessage(event){if(event.data==='registerExtension'){this._registerExtension(event.origin,event.ports[0]);}}
  102. async _onmessage(event){const message=event.data;let result;if(message.command in this._handlers){result=await this._handlers[message.command](message,event.target);}else{result=this._status.E_NOTSUPPORTED(message.command);}
  103. if(result&&message.requestId){this._dispatchCallback(message.requestId,event.target,result);}}
  104. _registerHandler(command,callback){console.assert(command);this._handlers[command]=callback;}
  105. _registerSubscriptionHandler(eventTopic,onSubscribeFirst,onUnsubscribeLast){this._subscriptionStartHandlers[eventTopic]=onSubscribeFirst;this._subscriptionStopHandlers[eventTopic]=onUnsubscribeLast;}
  106. _registerAutosubscriptionHandler(eventTopic,eventTarget,frontendEventType,handler){this._registerSubscriptionHandler(eventTopic,eventTarget.addEventListener.bind(eventTarget,frontendEventType,handler,this),eventTarget.removeEventListener.bind(eventTarget,frontendEventType,handler,this));}
  107. _registerAutosubscriptionTargetManagerHandler(eventTopic,modelClass,frontendEventType,handler){this._registerSubscriptionHandler(eventTopic,SDK.targetManager.addModelListener.bind(SDK.targetManager,modelClass,frontendEventType,handler,this),SDK.targetManager.removeModelListener.bind(SDK.targetManager,modelClass,frontendEventType,handler,this));}
  108. _registerResourceContentCommittedHandler(handler){function addFirstEventListener(){Workspace.workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser,handler,this);Workspace.workspace.setHasResourceContentTrackingExtensions(true);}
  109. function removeLastEventListener(){Workspace.workspace.setHasResourceContentTrackingExtensions(false);Workspace.workspace.removeEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser,handler,this);}
  110. this._registerSubscriptionHandler(Extensions.extensionAPI.Events.ResourceContentCommitted,addFirstEventListener.bind(this),removeLastEventListener.bind(this));}
  111. _expandResourcePath(extensionPath,resourcePath){if(!resourcePath){return;}
  112. return extensionPath+this._normalizePath(resourcePath);}
  113. _normalizePath(path){const source=path.split('/');const result=[];for(let i=0;i<source.length;++i){if(source[i]==='.'){continue;}
  114. if(source[i]===''){continue;}
  115. if(source[i]==='..'){result.pop();}else{result.push(source[i]);}}
  116. return'/'+result.join('/');}
  117. evaluate(expression,exposeCommandLineAPI,returnByValue,options,securityOrigin,callback){let context;function resolveURLToFrame(url){let found;function hasMatchingURL(frame){found=(frame.url===url)?frame:null;return found;}
  118. SDK.ResourceTreeModel.frames().some(hasMatchingURL);return found;}
  119. options=options||{};let frame;if(options.frameURL){frame=resolveURLToFrame(options.frameURL);}else{const target=SDK.targetManager.mainTarget();const resourceTreeModel=target&&target.model(SDK.ResourceTreeModel);frame=resourceTreeModel&&resourceTreeModel.mainFrame;}
  120. if(!frame){if(options.frameURL){console.warn('evaluate: there is no frame with URL '+options.frameURL);}else{console.warn('evaluate: the main frame is not yet available');}
  121. return this._status.E_NOTFOUND(options.frameURL||'<top>');}
  122. let contextSecurityOrigin;if(options.useContentScriptContext){contextSecurityOrigin=securityOrigin;}else if(options.scriptExecutionContext){contextSecurityOrigin=options.scriptExecutionContext;}
  123. const runtimeModel=frame.resourceTreeModel().target().model(SDK.RuntimeModel);const executionContexts=runtimeModel?runtimeModel.executionContexts():[];if(contextSecurityOrigin){for(let i=0;i<executionContexts.length;++i){const executionContext=executionContexts[i];if(executionContext.frameId===frame.id&&executionContext.origin===contextSecurityOrigin&&!executionContext.isDefault){context=executionContext;}}
  124. if(!context){console.warn('The JavaScript context '+contextSecurityOrigin+' was not found in the frame '+frame.url);return this._status.E_NOTFOUND(contextSecurityOrigin);}}else{for(let i=0;i<executionContexts.length;++i){const executionContext=executionContexts[i];if(executionContext.frameId===frame.id&&executionContext.isDefault){context=executionContext;}}
  125. if(!context){return this._status.E_FAILED(frame.url+' has no execution context');}}
  126. context.evaluate({expression:expression,objectGroup:'extension',includeCommandLineAPI:exposeCommandLineAPI,silent:true,returnByValue:returnByValue,generatePreview:false},false,false).then(onEvaluate);function onEvaluate(result){if(result.error){callback(result.error,null,false);return;}
  127. callback(null,result.object||null,!!result.exceptionDetails);}}}
  128. export const Events={SidebarPaneAdded:Symbol('SidebarPaneAdded'),TraceProviderAdded:Symbol('TraceProviderAdded')};class ExtensionServerPanelView extends UI.SimpleView{constructor(name,title,panel){super(title);this._name=name;this._panel=panel;}
  129. viewId(){return this._name;}
  130. widget(){return(Promise.resolve(this._panel));}}
  131. export class ExtensionStatus{constructor(){function makeStatus(code,description){const details=Array.prototype.slice.call(arguments,2);const status={code:code,description:description,details:details};if(code!=='OK'){status.isError=true;console.error('Extension server error: '+String.vsprintf(description,details));}
  132. return status;}
  133. this.OK=makeStatus.bind(null,'OK','OK');this.E_EXISTS=makeStatus.bind(null,'E_EXISTS','Object already exists: %s');this.E_BADARG=makeStatus.bind(null,'E_BADARG','Invalid argument %s: %s');this.E_BADARGTYPE=makeStatus.bind(null,'E_BADARGTYPE','Invalid type for argument %s: got %s, expected %s');this.E_NOTFOUND=makeStatus.bind(null,'E_NOTFOUND','Object not found: %s');this.E_NOTSUPPORTED=makeStatus.bind(null,'E_NOTSUPPORTED','Object does not support requested operation: %s');this.E_PROTOCOLERROR=makeStatus.bind(null,'E_PROTOCOLERROR','Inspector protocol error: %s');this.E_FAILED=makeStatus.bind(null,'E_FAILED','Operation failed: %s');}}
  134. self.Extensions=self.Extensions||{};Extensions=Extensions||{};Extensions.ExtensionServer=ExtensionServer;Extensions.ExtensionServer.Events=Events;Extensions.ExtensionStatus=ExtensionStatus;Extensions.ExtensionStatus.Record;Extensions.extensionServer;