feat(android): devtools for elements & network requests (#10506)

This commit is contained in:
Osei Fortune
2024-04-07 13:27:42 -04:00
committed by GitHub
parent 7806cc46f4
commit 5324e508ba
19 changed files with 436 additions and 115 deletions

View File

@ -55,7 +55,7 @@ export namespace HeapDomain {
JSON.stringify({ JSON.stringify({
method: 'Heap.garbageCollected', method: 'Heap.garbageCollected',
params: { collection: collection }, params: { collection: collection },
}) }),
); );
} }
// Tracking started. // Tracking started.
@ -67,7 +67,7 @@ export namespace HeapDomain {
timestamp: timestamp, timestamp: timestamp,
snapshotData: snapshotData, snapshotData: snapshotData,
}, },
}) }),
); );
} }
// Tracking stopped. // Tracking stopped.
@ -79,7 +79,7 @@ export namespace HeapDomain {
timestamp: timestamp, timestamp: timestamp,
snapshotData: snapshotData, snapshotData: snapshotData,
}, },
}) }),
); );
} }
} }
@ -328,7 +328,7 @@ export namespace DebuggerDomain {
JSON.stringify({ JSON.stringify({
method: 'Debugger.globalObjectCleared', method: 'Debugger.globalObjectCleared',
params: {}, params: {},
}) }),
); );
} }
// Fired when virtual machine parses script. This event is also fired for all known and uncollected scripts upon enabling debugger. // Fired when virtual machine parses script. This event is also fired for all known and uncollected scripts upon enabling debugger.
@ -347,7 +347,7 @@ export namespace DebuggerDomain {
sourceURL: sourceURL, sourceURL: sourceURL,
sourceMapURL: sourceMapURL, sourceMapURL: sourceMapURL,
}, },
}) }),
); );
} }
// Fired when virtual machine fails to parse the script. // Fired when virtual machine fails to parse the script.
@ -362,7 +362,7 @@ export namespace DebuggerDomain {
errorLine: errorLine, errorLine: errorLine,
errorMessage: errorMessage, errorMessage: errorMessage,
}, },
}) }),
); );
} }
// Fired when breakpoint is resolved to an actual script and location. // Fired when breakpoint is resolved to an actual script and location.
@ -371,7 +371,7 @@ export namespace DebuggerDomain {
JSON.stringify({ JSON.stringify({
method: 'Debugger.breakpointResolved', method: 'Debugger.breakpointResolved',
params: { breakpointId: breakpointId, location: location }, params: { breakpointId: breakpointId, location: location },
}) }),
); );
} }
// Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria. // Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria.
@ -384,7 +384,7 @@ export namespace DebuggerDomain {
reason: reason, reason: reason,
data: data, data: data,
}, },
}) }),
); );
} }
// Fired when the virtual machine resumed execution. // Fired when the virtual machine resumed execution.
@ -397,7 +397,7 @@ export namespace DebuggerDomain {
JSON.stringify({ JSON.stringify({
method: 'Debugger.didSampleProbe', method: 'Debugger.didSampleProbe',
params: { sample: sample }, params: { sample: sample },
}) }),
); );
} }
// Fired when a "sound" breakpoint action is triggered on a breakpoint. // Fired when a "sound" breakpoint action is triggered on a breakpoint.
@ -406,7 +406,7 @@ export namespace DebuggerDomain {
JSON.stringify({ JSON.stringify({
method: 'Debugger.playBreakpointActionSound', method: 'Debugger.playBreakpointActionSound',
params: { breakpointActionId: breakpointActionId }, params: { breakpointActionId: breakpointActionId },
}) }),
); );
} }
} }
@ -755,7 +755,7 @@ export namespace RuntimeDomain {
JSON.stringify({ JSON.stringify({
method: 'Runtime.executionContextCreated', method: 'Runtime.executionContextCreated',
params: { context: context }, params: { context: context },
}) }),
); );
} }
} }
@ -829,7 +829,7 @@ export namespace ConsoleDomain {
JSON.stringify({ JSON.stringify({
method: 'Console.messageAdded', method: 'Console.messageAdded',
params: { message: message }, params: { message: message },
}) }),
); );
} }
// Issued when subsequent message(s) are equal to the previous one(s). // Issued when subsequent message(s) are equal to the previous one(s).
@ -838,7 +838,7 @@ export namespace ConsoleDomain {
JSON.stringify({ JSON.stringify({
method: 'Console.messageRepeatCountUpdated', method: 'Console.messageRepeatCountUpdated',
params: { count: count }, params: { count: count },
}) }),
); );
} }
// Issued when console is cleared. This happens either upon <code>clearMessages</code> command or after page navigation. // Issued when console is cleared. This happens either upon <code>clearMessages</code> command or after page navigation.
@ -847,7 +847,7 @@ export namespace ConsoleDomain {
JSON.stringify({ JSON.stringify({
method: 'Console.messagesCleared', method: 'Console.messagesCleared',
params: {}, params: {},
}) }),
); );
} }
// Issued from console.takeHeapSnapshot. // Issued from console.takeHeapSnapshot.
@ -860,7 +860,7 @@ export namespace ConsoleDomain {
snapshotData: snapshotData, snapshotData: snapshotData,
title: title, title: title,
}, },
}) }),
); );
} }
} }
@ -1126,7 +1126,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.domContentEventFired', method: 'Page.domContentEventFired',
params: { timestamp: timestamp }, params: { timestamp: timestamp },
}) }),
); );
} }
loadEventFired(timestamp: number): void { loadEventFired(timestamp: number): void {
@ -1134,7 +1134,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.loadEventFired', method: 'Page.loadEventFired',
params: { timestamp: timestamp }, params: { timestamp: timestamp },
}) }),
); );
} }
// Fired once navigation of the frame has completed. Frame is now associated with the new loader. // Fired once navigation of the frame has completed. Frame is now associated with the new loader.
@ -1143,7 +1143,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.frameNavigated', method: 'Page.frameNavigated',
params: { frame: frame }, params: { frame: frame },
}) }),
); );
} }
// Fired when frame has been detached from its parent. // Fired when frame has been detached from its parent.
@ -1152,7 +1152,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.frameDetached', method: 'Page.frameDetached',
params: { frameId: frameId }, params: { frameId: frameId },
}) }),
); );
} }
// Fired when frame has started loading. // Fired when frame has started loading.
@ -1161,7 +1161,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.frameStartedLoading', method: 'Page.frameStartedLoading',
params: { frameId: frameId }, params: { frameId: frameId },
}) }),
); );
} }
// Fired when frame has stopped loading. // Fired when frame has stopped loading.
@ -1170,7 +1170,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.frameStoppedLoading', method: 'Page.frameStoppedLoading',
params: { frameId: frameId }, params: { frameId: frameId },
}) }),
); );
} }
// Fired when frame schedules a potential navigation. // Fired when frame schedules a potential navigation.
@ -1179,7 +1179,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.frameScheduledNavigation', method: 'Page.frameScheduledNavigation',
params: { frameId: frameId, delay: delay }, params: { frameId: frameId, delay: delay },
}) }),
); );
} }
// Fired when frame no longer has a scheduled navigation. // Fired when frame no longer has a scheduled navigation.
@ -1188,7 +1188,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.frameClearedScheduledNavigation', method: 'Page.frameClearedScheduledNavigation',
params: { frameId: frameId }, params: { frameId: frameId },
}) }),
); );
} }
// Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open. // Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.
@ -1197,7 +1197,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.javascriptDialogOpening', method: 'Page.javascriptDialogOpening',
params: { message: message }, params: { message: message },
}) }),
); );
} }
// Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been closed. // Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been closed.
@ -1206,7 +1206,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.javascriptDialogClosed', method: 'Page.javascriptDialogClosed',
params: {}, params: {},
}) }),
); );
} }
// Fired when the JavaScript is enabled/disabled on the page // Fired when the JavaScript is enabled/disabled on the page
@ -1215,7 +1215,7 @@ export namespace PageDomain {
JSON.stringify({ JSON.stringify({
method: 'Page.scriptsEnabled', method: 'Page.scriptsEnabled',
params: { isEnabled: isEnabled }, params: { isEnabled: isEnabled },
}) }),
); );
} }
} }
@ -1384,7 +1384,7 @@ export namespace NetworkDomain {
redirectResponse: redirectResponse, redirectResponse: redirectResponse,
type: type, type: type,
}, },
}) }),
); );
} }
// Fired if request ended up loading from cache. // Fired if request ended up loading from cache.
@ -1393,7 +1393,7 @@ export namespace NetworkDomain {
JSON.stringify({ JSON.stringify({
method: 'Network.requestServedFromCache', method: 'Network.requestServedFromCache',
params: { requestId: requestId }, params: { requestId: requestId },
}) }),
); );
} }
// Fired when HTTP response is available. // Fired when HTTP response is available.
@ -1409,7 +1409,7 @@ export namespace NetworkDomain {
type: type, type: type,
response: response, response: response,
}, },
}) }),
); );
} }
// Fired when data chunk was received over the network. // Fired when data chunk was received over the network.
@ -1423,7 +1423,7 @@ export namespace NetworkDomain {
dataLength: dataLength, dataLength: dataLength,
encodedDataLength: encodedDataLength, encodedDataLength: encodedDataLength,
}, },
}) }),
); );
} }
// Fired when HTTP request has finished loading. // Fired when HTTP request has finished loading.
@ -1436,7 +1436,7 @@ export namespace NetworkDomain {
timestamp: timestamp, timestamp: timestamp,
sourceMapURL: sourceMapURL, sourceMapURL: sourceMapURL,
}, },
}) }),
); );
} }
// Fired when HTTP request has failed to load. // Fired when HTTP request has failed to load.
@ -1450,7 +1450,7 @@ export namespace NetworkDomain {
errorText: errorText, errorText: errorText,
canceled: canceled, canceled: canceled,
}, },
}) }),
); );
} }
// Fired when HTTP request has been served from memory cache. // Fired when HTTP request has been served from memory cache.
@ -1467,7 +1467,7 @@ export namespace NetworkDomain {
initiator: initiator, initiator: initiator,
resource: resource, resource: resource,
}, },
}) }),
); );
} }
// Fired when WebSocket is about to initiate handshake. // Fired when WebSocket is about to initiate handshake.
@ -1480,7 +1480,7 @@ export namespace NetworkDomain {
timestamp: timestamp, timestamp: timestamp,
request: request, request: request,
}, },
}) }),
); );
} }
// Fired when WebSocket handshake response becomes available. // Fired when WebSocket handshake response becomes available.
@ -1493,7 +1493,7 @@ export namespace NetworkDomain {
timestamp: timestamp, timestamp: timestamp,
response: response, response: response,
}, },
}) }),
); );
} }
// Fired upon WebSocket creation. // Fired upon WebSocket creation.
@ -1502,7 +1502,7 @@ export namespace NetworkDomain {
JSON.stringify({ JSON.stringify({
method: 'Network.webSocketCreated', method: 'Network.webSocketCreated',
params: { requestId: requestId, url: url }, params: { requestId: requestId, url: url },
}) }),
); );
} }
// Fired when WebSocket is closed. // Fired when WebSocket is closed.
@ -1511,7 +1511,7 @@ export namespace NetworkDomain {
JSON.stringify({ JSON.stringify({
method: 'Network.webSocketClosed', method: 'Network.webSocketClosed',
params: { requestId: requestId, timestamp: timestamp }, params: { requestId: requestId, timestamp: timestamp },
}) }),
); );
} }
// Fired when WebSocket frame is received. // Fired when WebSocket frame is received.
@ -1524,7 +1524,7 @@ export namespace NetworkDomain {
timestamp: timestamp, timestamp: timestamp,
response: response, response: response,
}, },
}) }),
); );
} }
// Fired when WebSocket frame error occurs. // Fired when WebSocket frame error occurs.
@ -1537,7 +1537,7 @@ export namespace NetworkDomain {
timestamp: timestamp, timestamp: timestamp,
errorMessage: errorMessage, errorMessage: errorMessage,
}, },
}) }),
); );
} }
// Fired when WebSocket frame is sent. // Fired when WebSocket frame is sent.
@ -1550,7 +1550,7 @@ export namespace NetworkDomain {
timestamp: timestamp, timestamp: timestamp,
response: response, response: response,
}, },
}) }),
); );
} }
} }
@ -1751,7 +1751,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.setChildNodes', method: 'DOM.setChildNodes',
params: { parentId: parentId, nodes: nodes }, params: { parentId: parentId, nodes: nodes },
}) }),
); );
} }
// Fired when <code>Element</code>'s attribute is modified. // Fired when <code>Element</code>'s attribute is modified.
@ -1760,7 +1760,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.attributeModified', method: 'DOM.attributeModified',
params: { nodeId: nodeId, name: name, value: value }, params: { nodeId: nodeId, name: name, value: value },
}) }),
); );
} }
// Fired when <code>Element</code>'s attribute is removed. // Fired when <code>Element</code>'s attribute is removed.
@ -1769,7 +1769,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.attributeRemoved', method: 'DOM.attributeRemoved',
params: { nodeId: nodeId, name: name }, params: { nodeId: nodeId, name: name },
}) }),
); );
} }
// Fired when <code>Element</code>'s inline style is modified via a CSS property modification. // Fired when <code>Element</code>'s inline style is modified via a CSS property modification.
@ -1778,7 +1778,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.inlineStyleInvalidated', method: 'DOM.inlineStyleInvalidated',
params: { nodeIds: nodeIds }, params: { nodeIds: nodeIds },
}) }),
); );
} }
// Mirrors <code>DOMCharacterDataModified</code> event. // Mirrors <code>DOMCharacterDataModified</code> event.
@ -1787,7 +1787,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.characterDataModified', method: 'DOM.characterDataModified',
params: { nodeId: nodeId, characterData: characterData }, params: { nodeId: nodeId, characterData: characterData },
}) }),
); );
} }
// Fired when <code>Container</code>'s child node count has changed. // Fired when <code>Container</code>'s child node count has changed.
@ -1796,7 +1796,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.childNodeCountUpdated', method: 'DOM.childNodeCountUpdated',
params: { nodeId: nodeId, childNodeCount: childNodeCount }, params: { nodeId: nodeId, childNodeCount: childNodeCount },
}) }),
); );
} }
// Mirrors <code>DOMNodeInserted</code> event. // Mirrors <code>DOMNodeInserted</code> event.
@ -1809,7 +1809,7 @@ export namespace DOMDomain {
previousNodeId: previousNodeId, previousNodeId: previousNodeId,
node: node, node: node,
}, },
}) }),
); );
} }
// Mirrors <code>DOMNodeRemoved</code> event. // Mirrors <code>DOMNodeRemoved</code> event.
@ -1818,7 +1818,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.childNodeRemoved', method: 'DOM.childNodeRemoved',
params: { parentNodeId: parentNodeId, nodeId: nodeId }, params: { parentNodeId: parentNodeId, nodeId: nodeId },
}) }),
); );
} }
// Called when shadow root is pushed into the element. // Called when shadow root is pushed into the element.
@ -1827,7 +1827,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.shadowRootPushed', method: 'DOM.shadowRootPushed',
params: { hostId: hostId, root: root }, params: { hostId: hostId, root: root },
}) }),
); );
} }
// Called when shadow root is popped from the element. // Called when shadow root is popped from the element.
@ -1836,7 +1836,7 @@ export namespace DOMDomain {
JSON.stringify({ JSON.stringify({
method: 'DOM.shadowRootPopped', method: 'DOM.shadowRootPopped',
params: { hostId: hostId, rootId: rootId }, params: { hostId: hostId, rootId: rootId },
}) }),
); );
} }
// Called when a pseudo element is added to an element. // Called when a pseudo element is added to an element.
@ -1848,7 +1848,7 @@ export namespace DOMDomain {
parentId: parentId, parentId: parentId,
pseudoElement: pseudoElement, pseudoElement: pseudoElement,
}, },
}) }),
); );
} }
// Called when a pseudo element is removed from an element. // Called when a pseudo element is removed from an element.
@ -1860,7 +1860,7 @@ export namespace DOMDomain {
parentId: parentId, parentId: parentId,
pseudoElementId: pseudoElementId, pseudoElementId: pseudoElementId,
}, },
}) }),
); );
} }
} }
@ -2128,7 +2128,7 @@ export namespace CSSDomain {
JSON.stringify({ JSON.stringify({
method: 'CSS.mediaQueryResultChanged', method: 'CSS.mediaQueryResultChanged',
params: {}, params: {},
}) }),
); );
} }
// Fires whenever a web font gets loaded. // Fires whenever a web font gets loaded.
@ -2141,7 +2141,7 @@ export namespace CSSDomain {
JSON.stringify({ JSON.stringify({
method: 'CSS.styleSheetChanged', method: 'CSS.styleSheetChanged',
params: { styleSheetId: styleSheetId }, params: { styleSheetId: styleSheetId },
}) }),
); );
} }
// Fired whenever an active document stylesheet is added. // Fired whenever an active document stylesheet is added.
@ -2150,7 +2150,7 @@ export namespace CSSDomain {
JSON.stringify({ JSON.stringify({
method: 'CSS.styleSheetAdded', method: 'CSS.styleSheetAdded',
params: { header: header }, params: { header: header },
}) }),
); );
} }
// Fired whenever an active document stylesheet is removed. // Fired whenever an active document stylesheet is removed.
@ -2159,7 +2159,7 @@ export namespace CSSDomain {
JSON.stringify({ JSON.stringify({
method: 'CSS.styleSheetRemoved', method: 'CSS.styleSheetRemoved',
params: { styleSheetId: styleSheetId }, params: { styleSheetId: styleSheetId },
}) }),
); );
} }
layoutEditorChange(styleSheetId: StyleSheetId, changeRange: SourceRange): void { layoutEditorChange(styleSheetId: StyleSheetId, changeRange: SourceRange): void {
@ -2170,7 +2170,7 @@ export namespace CSSDomain {
styleSheetId: styleSheetId, styleSheetId: styleSheetId,
changeRange: changeRange, changeRange: changeRange,
}, },
}) }),
); );
} }
} }

View File

@ -1,35 +0,0 @@
// Types
import { InspectorEvents, InspectorCommands } from './devtools-elements-interfaces';
// Requires
import { getDocument, getComputedStylesForNode, removeNode, setAttributeAsText } from './devtools-elements.common';
import { registerInspectorEvents, DOMNode } from './dom-node';
export * from './devtools-elements-interfaces';
export function attachDOMInspectorEventCallbacks(DOMDomainFrontend: InspectorEvents) {
registerInspectorEvents(DOMDomainFrontend);
const originalChildNodeInserted: (parentId: number, lastId: number, node: string | DOMNode) => void = DOMDomainFrontend.childNodeInserted;
DOMDomainFrontend.childNodeInserted = (parentId: number, lastId: number, node: DOMNode) => {
originalChildNodeInserted(parentId, lastId, JSON.stringify(node.toObject()));
};
}
export function attachDOMInspectorCommandCallbacks(DOMDomainBackend: InspectorCommands) {
DOMDomainBackend.getDocument = () => {
return JSON.stringify(getDocument());
};
DOMDomainBackend.getComputedStylesForNode = (nodeId) => {
return JSON.stringify(getComputedStylesForNode(nodeId));
};
DOMDomainBackend.removeNode = removeNode;
DOMDomainBackend.setAttributeAsText = setAttributeAsText;
}
export function attachCSSInspectorCommandCallbacks(CSSDomainFrontend: InspectorCommands) {
// no op
}

View File

@ -1,4 +1,4 @@
import * as inspectorCommandTypes from './InspectorBackendCommands.ios'; import * as inspectorCommandTypes from './InspectorBackendCommands';
const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands'); const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands');
import * as debuggerDomains from '.'; import * as debuggerDomains from '.';

View File

@ -1,4 +1,4 @@
import * as inspectorCommandTypes from './InspectorBackendCommands.ios'; import * as inspectorCommandTypes from './InspectorBackendCommands';
const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands'); const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands');
import * as debuggerDomains from '.'; import * as debuggerDomains from '.';

View File

@ -0,0 +1,251 @@
import * as inspectorCommandTypes from './InspectorBackendCommands';
const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands');
import * as debuggerDomains from '.';
const getApplicationContext = () => require('../utils/android').getApplicationContext();
declare let __inspectorSendEvent;
declare let __inspectorTimestamp;
const frameId = 'NativeScriptMainFrameIdentifier';
const loaderId = 'Loader Identifier';
const resources_datas = [];
const documentTypeByMimeType = {
'text/xml': 'Document',
'text/plain': 'Document',
'text/html': 'Document',
'application/xml': 'Document',
'application/xhtml+xml': 'Document',
'text/css': 'Stylesheet',
'text/javascript': 'Script',
'text/ecmascript': 'Script',
'application/javascript': 'Script',
'application/ecmascript': 'Script',
'application/x-javascript': 'Script',
'application/json': 'Script',
'application/x-json': 'Script',
'text/x-javascript': 'Script',
'text/x-json': 'Script',
'text/typescript': 'Script',
};
export class Request {
private _resourceType: string;
private _data: any;
private _mimeType: string;
constructor(
private _networkDomainDebugger: NetworkDomainDebugger,
private _requestID: string,
) {}
get mimeType(): string {
return this._mimeType;
}
set mimeType(value: string) {
if (this._mimeType !== value) {
if (!value) {
this._mimeType = 'text/plain';
this._resourceType = 'Other';
return;
}
this._mimeType = value;
let resourceType = 'Other';
if (this._mimeType in documentTypeByMimeType) {
resourceType = documentTypeByMimeType[this._mimeType];
}
if (this._mimeType.indexOf('image/') !== -1) {
resourceType = 'Image';
}
if (this._mimeType.indexOf('font/') !== -1) {
resourceType = 'Font';
}
this._resourceType = resourceType;
}
}
get requestID(): string {
return this._requestID;
}
get hasTextContent(): boolean {
return ['Document', 'Stylesheet', 'Script', 'XHR'].indexOf(this._resourceType) !== -1;
}
get data(): any {
return this._data;
}
set data(value: any) {
if (this._data !== value) {
this._data = value;
}
}
get resourceType() {
return this._resourceType;
}
set resourceType(value: string) {
if (this._resourceType !== value) {
this._resourceType = value;
}
}
public responseReceived(response: inspectorCommandTypes.NetworkDomain.Response): void {
if (this._networkDomainDebugger.enabled) {
this._networkDomainDebugger.events.responseReceived(this.requestID, frameId, loaderId, __inspectorTimestamp(), <any>this.resourceType, response);
}
}
public loadingFinished(): void {
if (this._networkDomainDebugger.enabled) {
this._networkDomainDebugger.events.loadingFinished(this.requestID, __inspectorTimestamp());
}
}
public requestWillBeSent(request: inspectorCommandTypes.NetworkDomain.Request): void {
if (this._networkDomainDebugger.enabled) {
this._networkDomainDebugger.events.requestWillBeSent(this.requestID, frameId, loaderId, request.url, request, __inspectorTimestamp(), { type: 'Script' });
}
}
}
@inspectorCommands.DomainDispatcher('Network')
export class NetworkDomainDebugger implements inspectorCommandTypes.NetworkDomain.NetworkDomainDispatcher {
private _enabled: boolean;
public events: inspectorCommandTypes.NetworkDomain.NetworkFrontend;
constructor() {
this.events = new inspectorCommands.NetworkDomain.NetworkFrontend();
// By default start enabled because we can miss the "enable" event when
// running with `--debug-brk` -- the frontend will send it before we've been created
this.enable();
}
get enabled(): boolean {
return this._enabled;
}
/**
* Enables network tracking, network events will now be delivered to the client.
*/
enable(): void {
if (debuggerDomains.getNetwork()) {
throw new Error('One NetworkDomainDebugger may be enabled at a time.');
} else {
debuggerDomains.setNetwork(this);
}
this._enabled = true;
}
/**
* Disables network tracking, prevents network events from being sent to the client.
*/
disable(): void {
if (debuggerDomains.getNetwork() === this) {
debuggerDomains.setNetwork(null);
}
this._enabled = false;
}
/**
* Specifies whether to always send extra HTTP headers with the requests from this page.
*/
setExtraHTTPHeaders(params: inspectorCommandTypes.NetworkDomain.SetExtraHTTPHeadersMethodArguments): void {
//
}
/**
* Returns content served for the given request.
*/
getResponseBody(params: inspectorCommandTypes.NetworkDomain.GetResponseBodyMethodArguments): { body: string; base64Encoded: boolean } {
const resource_data = resources_datas[params.requestId];
// java.io.ByteArrayOutputStream
const body = resource_data.hasTextContent ? resource_data.data.toString('UTF-8') : android.util.Base64.encodeToString(resource_data.data?.buf?.(), android.util.Base64.NO_WRAP);
if (resource_data) {
return {
body: body,
base64Encoded: !resource_data.hasTextContent,
};
}
}
/**
* Tells whether clearing browser cache is supported.
*/
canClearBrowserCache(): { result: boolean } {
return {
result: false,
};
}
/**
* Clears browser cache.
*/
clearBrowserCache(): void {
//
}
/**
* Tells whether clearing browser cookies is supported.
*/
canClearBrowserCookies(): { result: boolean } {
return {
result: false,
};
}
/**
* Clears browser cookies.
*/
clearBrowserCookies(): void {
//
}
/**
* Toggles ignoring cache for each request. If <code>true</code>, cache will not be used.
*/
setCacheDisabled(params: inspectorCommandTypes.NetworkDomain.SetCacheDisabledMethodArguments): void {
//
}
/**
* Loads a resource in the context of a frame on the inspected page without cross origin checks.
*/
loadResource(params: inspectorCommandTypes.NetworkDomain.LoadResourceMethodArguments): { content: string; mimeType: string; status: number } {
const appPath = getApplicationContext().getFilesDir().getCanonicalPath() + '/app';
const pathUrl = params.url.replace('file://', appPath);
const file = new java.io.File(pathUrl);
const is = file.exists() ? new java.io.FileInputStream(file) : undefined;
const data = is ? Array.create('bytes', file.length()) : undefined;
const read = data ? is.read(data) : 0;
const content = read ? new java.lang.String(data) : '';
return {
content: content.toString(), // Not sure why however we need to call toString() for NSString
mimeType: 'application/octet-stream',
status: 200,
};
}
public static idSequence = 0;
create(): Request {
const id = (++NetworkDomainDebugger.idSequence).toString();
const resourceData = new Request(this, id);
resources_datas[id] = resourceData;
return resourceData;
}
}

View File

@ -1,4 +1,4 @@
import * as inspectorCommandTypes from './InspectorBackendCommands.ios'; import * as inspectorCommandTypes from './InspectorBackendCommands';
const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands'); const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands');
import * as debuggerDomains from '.'; import * as debuggerDomains from '.';
@ -36,7 +36,10 @@ export class Request {
private _data: any; private _data: any;
private _mimeType: string; private _mimeType: string;
constructor(private _networkDomainDebugger: NetworkDomainDebugger, private _requestID: string) {} constructor(
private _networkDomainDebugger: NetworkDomainDebugger,
private _requestID: string,
) {}
get mimeType(): string { get mimeType(): string {
return this._mimeType; return this._mimeType;

View File

@ -5,7 +5,7 @@ import { Screen } from '../../platform';
import * as fsModule from '../../file-system'; import * as fsModule from '../../file-system';
import { getFilenameFromUrl } from './http-request-common'; import { getFilenameFromUrl } from './http-request-common';
import { NetworkAgent } from '../../debugger'; import * as domainDebugger from '../../debugger';
export enum HttpResponseEncoding { export enum HttpResponseEncoding {
UTF8, UTF8,
@ -37,7 +37,10 @@ function ensureFileSystem() {
fs = require('../../file-system'); fs = require('../../file-system');
} }
} }
let debugRequests: Map<number, { debugRequest: domainDebugger.domains.network.NetworkRequest; timestamp: number }>;
if (__DEV__) {
debugRequests = new Map();
}
let completeCallback: org.nativescript.widgets.Async.CompleteCallback; let completeCallback: org.nativescript.widgets.Async.CompleteCallback;
function ensureCompleteCallback() { function ensureCompleteCallback() {
if (completeCallback) { if (completeCallback) {
@ -77,9 +80,47 @@ function onRequestComplete(requestId: number, result: org.nativescript.widgets.A
} }
} }
// send response data (for requestId) to network debugger if (__DEV__) {
if (global.__inspector && global.__inspector.isConnected) { const debugRequestInfo = debugRequests.get(requestId);
NetworkAgent.responseReceived(requestId, result, headers);
if (debugRequestInfo) {
const debugRequest = debugRequestInfo.debugRequest;
let mime = (headers['Content-Type'] ?? 'text/plain') as string;
if (typeof mime === 'string') {
mime = mime.split(';')[0] ?? 'text/plain';
}
debugRequest.mimeType = mime;
debugRequest.data = result.raw;
const debugResponse = {
url: result.url,
status: result.statusCode,
statusText: result.statusText,
headers: headers,
mimeType: mime,
fromDiskCache: false,
timing: {
requestTime: debugRequestInfo.timestamp,
proxyStart: -1,
proxyEnd: -1,
dnsStart: -1,
dnsEnd: -1,
connectStart: -1,
connectEnd: -1,
sslStart: -1,
sslEnd: -1,
serviceWorkerFetchStart: -1,
serviceWorkerFetchReady: -1,
serviceWorkerFetchEnd: -1,
sendStart: -1,
sendEnd: -1,
receiveHeadersEnd: -1,
},
};
debugRequest.responseReceived(debugResponse);
debugRequest.loadingFinished();
debugRequests.delete(requestId);
}
} }
callbacks.resolveCallback({ callbacks.resolveCallback({
@ -216,9 +257,29 @@ export function request(options: httpModule.HttpRequestOptions): Promise<httpMod
// initialize the options // initialize the options
const javaOptions = buildJavaOptions(options); const javaOptions = buildJavaOptions(options);
// send request data to network debugger // // send request data to network debugger
if (global.__inspector && global.__inspector.isConnected) { // if (global.__inspector && global.__inspector.isConnected) {
NetworkAgent.requestWillBeSent(requestIdCounter, options); // NetworkAgent.requestWillBeSent(requestIdCounter, options);
// }
if (__DEV__) {
const network = domainDebugger.getNetwork();
const debugRequest = network && network.create();
if (options.url && debugRequest) {
const timestamp = Date.now() / 1000;
debugRequests.set(requestIdCounter, {
debugRequest,
timestamp,
});
const request = {
url: options.url,
method: 'GET',
headers: options.headers,
timestamp,
};
debugRequest.requestWillBeSent(request);
}
} }
// remember the callbacks so that we can use them when the CompleteCallback is called // remember the callbacks so that we can use them when the CompleteCallback is called

View File

@ -112,6 +112,7 @@ export function request(options: httpModule.HttpRequestOptions): Promise<httpMod
session = defaultSession; session = defaultSession;
} }
let timestamp = -1;
const dataTask = session.dataTaskWithRequestCompletionHandler(urlRequest, function (data: NSData, response: NSHTTPURLResponse, error: NSError) { const dataTask = session.dataTaskWithRequestCompletionHandler(urlRequest, function (data: NSData, response: NSHTTPURLResponse, error: NSError) {
if (error) { if (error) {
reject(new Error(error.localizedDescription)); reject(new Error(error.localizedDescription));
@ -135,6 +136,24 @@ export function request(options: httpModule.HttpRequestOptions): Promise<httpMod
headers: headers, headers: headers,
mimeType: response.MIMEType, mimeType: response.MIMEType,
fromDiskCache: false, fromDiskCache: false,
timing: {
requestTime: timestamp,
proxyStart: -1,
proxyEnd: -1,
dnsStart: -1,
dnsEnd: -1,
connectStart: -1,
connectEnd: -1,
sslStart: -1,
sslEnd: -1,
serviceWorkerFetchStart: -1,
serviceWorkerFetchReady: -1,
serviceWorkerFetchEnd: -1,
sendStart: -1,
sendEnd: -1,
receiveHeadersEnd: -1,
},
headersSize: headers?.length ?? -1,
}; };
debugRequest.responseReceived(debugResponse); debugRequest.responseReceived(debugResponse);
debugRequest.loadingFinished(); debugRequest.loadingFinished();
@ -191,10 +210,13 @@ export function request(options: httpModule.HttpRequestOptions): Promise<httpMod
}); });
if (options.url && debugRequest) { if (options.url && debugRequest) {
timestamp = Date.now() / 1000;
const request = { const request = {
url: options.url, url: options.url,
method: 'GET', method: 'GET',
headers: options.headers, headers: options.headers,
timestamp,
headersSize: options?.headers?.length ?? -1,
}; };
debugRequest.requestWillBeSent(request); debugRequest.requestWillBeSent(request);
} }

View File

@ -1,4 +1,5 @@
import './globals'; require('./globals');
require('./debugger/webinspector-network'); require('./debugger/webinspector-network');
require('./debugger/webinspector-dom'); require('./debugger/webinspector-dom');
require('./debugger/webinspector-css'); require('./debugger/webinspector-css');

View File

@ -33,12 +33,6 @@ let fragmentId = -1;
export let moduleLoaded: boolean; export let moduleLoaded: boolean;
if (global && global.__inspector) {
const devtools = require('../../debugger/devtools-elements');
devtools.attachDOMInspectorEventCallbacks(global.__inspector);
devtools.attachDOMInspectorCommandCallbacks(global.__inspector);
}
export let attachStateChangeListener: android.view.View.OnAttachStateChangeListener; export let attachStateChangeListener: android.view.View.OnAttachStateChangeListener;
function getAttachListener(): android.view.View.OnAttachStateChangeListener { function getAttachListener(): android.view.View.OnAttachStateChangeListener {

View File

@ -435,6 +435,9 @@ exports[`angular configuration for android 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -323,6 +323,9 @@ exports[`base configuration for android 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -322,6 +322,9 @@ exports[`javascript configuration for android 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -352,6 +352,9 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"
@ -680,6 +683,9 @@ exports[`react configuration > android > base config 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -344,6 +344,9 @@ exports[`svelte configuration for android 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -322,6 +322,9 @@ exports[`typescript configuration for android 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -357,6 +357,9 @@ exports[`vue configuration for android 1`] = `
'__jest__/src/app.js', '__jest__/src/app.js',
'@nativescript/core/ui/frame', '@nativescript/core/ui/frame',
'@nativescript/core/ui/frame/activity' '@nativescript/core/ui/frame/activity'
],
'tns_modules/inspector_modules': [
'@nativescript/core/inspector_modules'
] ]
} }
}" }"

View File

@ -86,7 +86,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
const sourceMapAbsolutePath = getProjectFilePath( const sourceMapAbsolutePath = getProjectFilePath(
`./${ `./${
env.buildPath ?? 'platforms' env.buildPath ?? 'platforms'
}/${platform}-sourceMaps/[file].map[query]` }/${platform}-sourceMaps/[file].map[query]`,
); );
const sourceMapRelativePath = relative(outputPath, sourceMapAbsolutePath); const sourceMapRelativePath = relative(outputPath, sourceMapAbsolutePath);
config.output.sourceMapFilename(sourceMapRelativePath); config.output.sourceMapFilename(sourceMapRelativePath);
@ -272,7 +272,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
const configFile = tsConfigPath const configFile = tsConfigPath
? { ? {
configFile: tsConfigPath, configFile: tsConfigPath,
} }
: undefined; : undefined;
// set up ts support // set up ts support
@ -451,7 +451,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
* +-----------------------------------------------------------------------------------------+ * +-----------------------------------------------------------------------------------------+
*/ */
/System.import\(\) is deprecated/, /System.import\(\) is deprecated/,
]) ]),
); );
// todo: refine defaults // todo: refine defaults
@ -518,5 +518,5 @@ function shouldIncludeInspectorModules(): boolean {
const platform = getPlatformName(); const platform = getPlatformName();
// todo: check if core modules are external // todo: check if core modules are external
// todo: check if we are testing // todo: check if we are testing
return platform === 'ios'; return platform === 'ios' || platform === 'android';
} }