From 5324e508ba8f7e24af99d959760f3b300bc1163a Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Sun, 7 Apr 2024 13:27:42 -0400 Subject: [PATCH] feat(android): devtools for elements & network requests (#10506) --- ...nds.ios.ts => InspectorBackendCommands.ts} | 114 ++++---- .../debugger/devtools-elements.android.ts | 35 --- ...s-elements.ios.ts => devtools-elements.ts} | 0 ...spector-css.ios.ts => webinspector-css.ts} | 2 +- ...spector-dom.ios.ts => webinspector-dom.ts} | 2 +- .../debugger/webinspector-network.android.ts | 251 ++++++++++++++++++ .../core/debugger/webinspector-network.ios.ts | 7 +- .../core/http/http-request/index.android.ts | 77 +++++- packages/core/http/http-request/index.ios.ts | 22 ++ ...or_modules.ios.ts => inspector_modules.ts} | 3 +- packages/core/ui/frame/index.android.ts | 6 - .../__snapshots__/angular.spec.ts.snap | 3 + .../__snapshots__/base.spec.ts.snap | 3 + .../__snapshots__/javascript.spec.ts.snap | 3 + .../__snapshots__/react.spec.ts.snap | 6 + .../__snapshots__/svelte.spec.ts.snap | 3 + .../__snapshots__/typescript.spec.ts.snap | 3 + .../__snapshots__/vue.spec.ts.snap | 3 + packages/webpack5/src/configuration/base.ts | 8 +- 19 files changed, 436 insertions(+), 115 deletions(-) rename packages/core/debugger/{InspectorBackendCommands.ios.ts => InspectorBackendCommands.ts} (99%) delete mode 100644 packages/core/debugger/devtools-elements.android.ts rename packages/core/debugger/{devtools-elements.ios.ts => devtools-elements.ts} (100%) rename packages/core/debugger/{webinspector-css.ios.ts => webinspector-css.ts} (99%) rename packages/core/debugger/{webinspector-dom.ios.ts => webinspector-dom.ts} (99%) create mode 100644 packages/core/debugger/webinspector-network.android.ts rename packages/core/{inspector_modules.ios.ts => inspector_modules.ts} (84%) diff --git a/packages/core/debugger/InspectorBackendCommands.ios.ts b/packages/core/debugger/InspectorBackendCommands.ts similarity index 99% rename from packages/core/debugger/InspectorBackendCommands.ios.ts rename to packages/core/debugger/InspectorBackendCommands.ts index 6dad2f441..d0743886b 100644 --- a/packages/core/debugger/InspectorBackendCommands.ios.ts +++ b/packages/core/debugger/InspectorBackendCommands.ts @@ -55,7 +55,7 @@ export namespace HeapDomain { JSON.stringify({ method: 'Heap.garbageCollected', params: { collection: collection }, - }) + }), ); } // Tracking started. @@ -67,7 +67,7 @@ export namespace HeapDomain { timestamp: timestamp, snapshotData: snapshotData, }, - }) + }), ); } // Tracking stopped. @@ -79,7 +79,7 @@ export namespace HeapDomain { timestamp: timestamp, snapshotData: snapshotData, }, - }) + }), ); } } @@ -328,7 +328,7 @@ export namespace DebuggerDomain { JSON.stringify({ method: 'Debugger.globalObjectCleared', params: {}, - }) + }), ); } // 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, sourceMapURL: sourceMapURL, }, - }) + }), ); } // Fired when virtual machine fails to parse the script. @@ -362,7 +362,7 @@ export namespace DebuggerDomain { errorLine: errorLine, errorMessage: errorMessage, }, - }) + }), ); } // Fired when breakpoint is resolved to an actual script and location. @@ -371,7 +371,7 @@ export namespace DebuggerDomain { JSON.stringify({ method: 'Debugger.breakpointResolved', params: { breakpointId: breakpointId, location: location }, - }) + }), ); } // Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria. @@ -384,7 +384,7 @@ export namespace DebuggerDomain { reason: reason, data: data, }, - }) + }), ); } // Fired when the virtual machine resumed execution. @@ -397,7 +397,7 @@ export namespace DebuggerDomain { JSON.stringify({ method: 'Debugger.didSampleProbe', params: { sample: sample }, - }) + }), ); } // Fired when a "sound" breakpoint action is triggered on a breakpoint. @@ -406,7 +406,7 @@ export namespace DebuggerDomain { JSON.stringify({ method: 'Debugger.playBreakpointActionSound', params: { breakpointActionId: breakpointActionId }, - }) + }), ); } } @@ -755,7 +755,7 @@ export namespace RuntimeDomain { JSON.stringify({ method: 'Runtime.executionContextCreated', params: { context: context }, - }) + }), ); } } @@ -829,7 +829,7 @@ export namespace ConsoleDomain { JSON.stringify({ method: 'Console.messageAdded', params: { message: message }, - }) + }), ); } // Issued when subsequent message(s) are equal to the previous one(s). @@ -838,7 +838,7 @@ export namespace ConsoleDomain { JSON.stringify({ method: 'Console.messageRepeatCountUpdated', params: { count: count }, - }) + }), ); } // Issued when console is cleared. This happens either upon clearMessages command or after page navigation. @@ -847,7 +847,7 @@ export namespace ConsoleDomain { JSON.stringify({ method: 'Console.messagesCleared', params: {}, - }) + }), ); } // Issued from console.takeHeapSnapshot. @@ -860,7 +860,7 @@ export namespace ConsoleDomain { snapshotData: snapshotData, title: title, }, - }) + }), ); } } @@ -1126,7 +1126,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.domContentEventFired', params: { timestamp: timestamp }, - }) + }), ); } loadEventFired(timestamp: number): void { @@ -1134,7 +1134,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.loadEventFired', params: { timestamp: timestamp }, - }) + }), ); } // 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({ method: 'Page.frameNavigated', params: { frame: frame }, - }) + }), ); } // Fired when frame has been detached from its parent. @@ -1152,7 +1152,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.frameDetached', params: { frameId: frameId }, - }) + }), ); } // Fired when frame has started loading. @@ -1161,7 +1161,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.frameStartedLoading', params: { frameId: frameId }, - }) + }), ); } // Fired when frame has stopped loading. @@ -1170,7 +1170,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.frameStoppedLoading', params: { frameId: frameId }, - }) + }), ); } // Fired when frame schedules a potential navigation. @@ -1179,7 +1179,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.frameScheduledNavigation', params: { frameId: frameId, delay: delay }, - }) + }), ); } // Fired when frame no longer has a scheduled navigation. @@ -1188,7 +1188,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.frameClearedScheduledNavigation', params: { frameId: frameId }, - }) + }), ); } // Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open. @@ -1197,7 +1197,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.javascriptDialogOpening', params: { message: message }, - }) + }), ); } // Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been closed. @@ -1206,7 +1206,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.javascriptDialogClosed', params: {}, - }) + }), ); } // Fired when the JavaScript is enabled/disabled on the page @@ -1215,7 +1215,7 @@ export namespace PageDomain { JSON.stringify({ method: 'Page.scriptsEnabled', params: { isEnabled: isEnabled }, - }) + }), ); } } @@ -1384,7 +1384,7 @@ export namespace NetworkDomain { redirectResponse: redirectResponse, type: type, }, - }) + }), ); } // Fired if request ended up loading from cache. @@ -1393,7 +1393,7 @@ export namespace NetworkDomain { JSON.stringify({ method: 'Network.requestServedFromCache', params: { requestId: requestId }, - }) + }), ); } // Fired when HTTP response is available. @@ -1409,7 +1409,7 @@ export namespace NetworkDomain { type: type, response: response, }, - }) + }), ); } // Fired when data chunk was received over the network. @@ -1423,7 +1423,7 @@ export namespace NetworkDomain { dataLength: dataLength, encodedDataLength: encodedDataLength, }, - }) + }), ); } // Fired when HTTP request has finished loading. @@ -1436,7 +1436,7 @@ export namespace NetworkDomain { timestamp: timestamp, sourceMapURL: sourceMapURL, }, - }) + }), ); } // Fired when HTTP request has failed to load. @@ -1450,7 +1450,7 @@ export namespace NetworkDomain { errorText: errorText, canceled: canceled, }, - }) + }), ); } // Fired when HTTP request has been served from memory cache. @@ -1467,7 +1467,7 @@ export namespace NetworkDomain { initiator: initiator, resource: resource, }, - }) + }), ); } // Fired when WebSocket is about to initiate handshake. @@ -1480,7 +1480,7 @@ export namespace NetworkDomain { timestamp: timestamp, request: request, }, - }) + }), ); } // Fired when WebSocket handshake response becomes available. @@ -1493,7 +1493,7 @@ export namespace NetworkDomain { timestamp: timestamp, response: response, }, - }) + }), ); } // Fired upon WebSocket creation. @@ -1502,7 +1502,7 @@ export namespace NetworkDomain { JSON.stringify({ method: 'Network.webSocketCreated', params: { requestId: requestId, url: url }, - }) + }), ); } // Fired when WebSocket is closed. @@ -1511,7 +1511,7 @@ export namespace NetworkDomain { JSON.stringify({ method: 'Network.webSocketClosed', params: { requestId: requestId, timestamp: timestamp }, - }) + }), ); } // Fired when WebSocket frame is received. @@ -1524,7 +1524,7 @@ export namespace NetworkDomain { timestamp: timestamp, response: response, }, - }) + }), ); } // Fired when WebSocket frame error occurs. @@ -1537,7 +1537,7 @@ export namespace NetworkDomain { timestamp: timestamp, errorMessage: errorMessage, }, - }) + }), ); } // Fired when WebSocket frame is sent. @@ -1550,7 +1550,7 @@ export namespace NetworkDomain { timestamp: timestamp, response: response, }, - }) + }), ); } } @@ -1751,7 +1751,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.setChildNodes', params: { parentId: parentId, nodes: nodes }, - }) + }), ); } // Fired when Element's attribute is modified. @@ -1760,7 +1760,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.attributeModified', params: { nodeId: nodeId, name: name, value: value }, - }) + }), ); } // Fired when Element's attribute is removed. @@ -1769,7 +1769,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.attributeRemoved', params: { nodeId: nodeId, name: name }, - }) + }), ); } // Fired when Element's inline style is modified via a CSS property modification. @@ -1778,7 +1778,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.inlineStyleInvalidated', params: { nodeIds: nodeIds }, - }) + }), ); } // Mirrors DOMCharacterDataModified event. @@ -1787,7 +1787,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.characterDataModified', params: { nodeId: nodeId, characterData: characterData }, - }) + }), ); } // Fired when Container's child node count has changed. @@ -1796,7 +1796,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.childNodeCountUpdated', params: { nodeId: nodeId, childNodeCount: childNodeCount }, - }) + }), ); } // Mirrors DOMNodeInserted event. @@ -1809,7 +1809,7 @@ export namespace DOMDomain { previousNodeId: previousNodeId, node: node, }, - }) + }), ); } // Mirrors DOMNodeRemoved event. @@ -1818,7 +1818,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.childNodeRemoved', params: { parentNodeId: parentNodeId, nodeId: nodeId }, - }) + }), ); } // Called when shadow root is pushed into the element. @@ -1827,7 +1827,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.shadowRootPushed', params: { hostId: hostId, root: root }, - }) + }), ); } // Called when shadow root is popped from the element. @@ -1836,7 +1836,7 @@ export namespace DOMDomain { JSON.stringify({ method: 'DOM.shadowRootPopped', params: { hostId: hostId, rootId: rootId }, - }) + }), ); } // Called when a pseudo element is added to an element. @@ -1848,7 +1848,7 @@ export namespace DOMDomain { parentId: parentId, pseudoElement: pseudoElement, }, - }) + }), ); } // Called when a pseudo element is removed from an element. @@ -1860,7 +1860,7 @@ export namespace DOMDomain { parentId: parentId, pseudoElementId: pseudoElementId, }, - }) + }), ); } } @@ -2128,7 +2128,7 @@ export namespace CSSDomain { JSON.stringify({ method: 'CSS.mediaQueryResultChanged', params: {}, - }) + }), ); } // Fires whenever a web font gets loaded. @@ -2141,7 +2141,7 @@ export namespace CSSDomain { JSON.stringify({ method: 'CSS.styleSheetChanged', params: { styleSheetId: styleSheetId }, - }) + }), ); } // Fired whenever an active document stylesheet is added. @@ -2150,7 +2150,7 @@ export namespace CSSDomain { JSON.stringify({ method: 'CSS.styleSheetAdded', params: { header: header }, - }) + }), ); } // Fired whenever an active document stylesheet is removed. @@ -2159,7 +2159,7 @@ export namespace CSSDomain { JSON.stringify({ method: 'CSS.styleSheetRemoved', params: { styleSheetId: styleSheetId }, - }) + }), ); } layoutEditorChange(styleSheetId: StyleSheetId, changeRange: SourceRange): void { @@ -2170,7 +2170,7 @@ export namespace CSSDomain { styleSheetId: styleSheetId, changeRange: changeRange, }, - }) + }), ); } } diff --git a/packages/core/debugger/devtools-elements.android.ts b/packages/core/debugger/devtools-elements.android.ts deleted file mode 100644 index 24b72670b..000000000 --- a/packages/core/debugger/devtools-elements.android.ts +++ /dev/null @@ -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 -} diff --git a/packages/core/debugger/devtools-elements.ios.ts b/packages/core/debugger/devtools-elements.ts similarity index 100% rename from packages/core/debugger/devtools-elements.ios.ts rename to packages/core/debugger/devtools-elements.ts diff --git a/packages/core/debugger/webinspector-css.ios.ts b/packages/core/debugger/webinspector-css.ts similarity index 99% rename from packages/core/debugger/webinspector-css.ios.ts rename to packages/core/debugger/webinspector-css.ts index d11a14d47..20407dc8a 100644 --- a/packages/core/debugger/webinspector-css.ios.ts +++ b/packages/core/debugger/webinspector-css.ts @@ -1,4 +1,4 @@ -import * as inspectorCommandTypes from './InspectorBackendCommands.ios'; +import * as inspectorCommandTypes from './InspectorBackendCommands'; const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands'); import * as debuggerDomains from '.'; diff --git a/packages/core/debugger/webinspector-dom.ios.ts b/packages/core/debugger/webinspector-dom.ts similarity index 99% rename from packages/core/debugger/webinspector-dom.ios.ts rename to packages/core/debugger/webinspector-dom.ts index 302d67a3b..c7cd2c4c1 100644 --- a/packages/core/debugger/webinspector-dom.ios.ts +++ b/packages/core/debugger/webinspector-dom.ts @@ -1,4 +1,4 @@ -import * as inspectorCommandTypes from './InspectorBackendCommands.ios'; +import * as inspectorCommandTypes from './InspectorBackendCommands'; const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands'); import * as debuggerDomains from '.'; diff --git a/packages/core/debugger/webinspector-network.android.ts b/packages/core/debugger/webinspector-network.android.ts new file mode 100644 index 000000000..2e1536c39 --- /dev/null +++ b/packages/core/debugger/webinspector-network.android.ts @@ -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(), 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 true, 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; + } +} diff --git a/packages/core/debugger/webinspector-network.ios.ts b/packages/core/debugger/webinspector-network.ios.ts index c82d6ee78..b8ddf0771 100644 --- a/packages/core/debugger/webinspector-network.ios.ts +++ b/packages/core/debugger/webinspector-network.ios.ts @@ -1,4 +1,4 @@ -import * as inspectorCommandTypes from './InspectorBackendCommands.ios'; +import * as inspectorCommandTypes from './InspectorBackendCommands'; const inspectorCommands: typeof inspectorCommandTypes = require('./InspectorBackendCommands'); import * as debuggerDomains from '.'; @@ -36,7 +36,10 @@ export class Request { private _data: any; private _mimeType: string; - constructor(private _networkDomainDebugger: NetworkDomainDebugger, private _requestID: string) {} + constructor( + private _networkDomainDebugger: NetworkDomainDebugger, + private _requestID: string, + ) {} get mimeType(): string { return this._mimeType; diff --git a/packages/core/http/http-request/index.android.ts b/packages/core/http/http-request/index.android.ts index 6959415c2..470a97aa8 100644 --- a/packages/core/http/http-request/index.android.ts +++ b/packages/core/http/http-request/index.android.ts @@ -5,7 +5,7 @@ import { Screen } from '../../platform'; import * as fsModule from '../../file-system'; import { getFilenameFromUrl } from './http-request-common'; -import { NetworkAgent } from '../../debugger'; +import * as domainDebugger from '../../debugger'; export enum HttpResponseEncoding { UTF8, @@ -37,7 +37,10 @@ function ensureFileSystem() { fs = require('../../file-system'); } } - +let debugRequests: Map; +if (__DEV__) { + debugRequests = new Map(); +} let completeCallback: org.nativescript.widgets.Async.CompleteCallback; function ensureCompleteCallback() { if (completeCallback) { @@ -77,9 +80,47 @@ function onRequestComplete(requestId: number, result: org.nativescript.widgets.A } } - // send response data (for requestId) to network debugger - if (global.__inspector && global.__inspector.isConnected) { - NetworkAgent.responseReceived(requestId, result, headers); + if (__DEV__) { + const debugRequestInfo = debugRequests.get(requestId); + + 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({ @@ -216,9 +257,29 @@ export function request(options: httpModule.HttpRequestOptions): Promise android > adds ReactRefreshWebpackPlugin when HMR '__jest__/src/app.js', '@nativescript/core/ui/frame', '@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', '@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity' + ], + 'tns_modules/inspector_modules': [ + '@nativescript/core/inspector_modules' ] } }" diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap index 276d6790a..19276b868 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap @@ -344,6 +344,9 @@ exports[`svelte configuration for android 1`] = ` '__jest__/src/app.js', '@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity' + ], + 'tns_modules/inspector_modules': [ + '@nativescript/core/inspector_modules' ] } }" diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap index 4c59228e5..59e4f1f10 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap @@ -322,6 +322,9 @@ exports[`typescript configuration for android 1`] = ` '__jest__/src/app.js', '@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity' + ], + 'tns_modules/inspector_modules': [ + '@nativescript/core/inspector_modules' ] } }" diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap index da0ab5b34..43758bc19 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap @@ -357,6 +357,9 @@ exports[`vue configuration for android 1`] = ` '__jest__/src/app.js', '@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity' + ], + 'tns_modules/inspector_modules': [ + '@nativescript/core/inspector_modules' ] } }" diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index b5d7e0c61..3d4b070b8 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -86,7 +86,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { const sourceMapAbsolutePath = getProjectFilePath( `./${ env.buildPath ?? 'platforms' - }/${platform}-sourceMaps/[file].map[query]` + }/${platform}-sourceMaps/[file].map[query]`, ); const sourceMapRelativePath = relative(outputPath, sourceMapAbsolutePath); config.output.sourceMapFilename(sourceMapRelativePath); @@ -272,7 +272,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { const configFile = tsConfigPath ? { configFile: tsConfigPath, - } + } : undefined; // set up ts support @@ -451,7 +451,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { * +-----------------------------------------------------------------------------------------+ */ /System.import\(\) is deprecated/, - ]) + ]), ); // todo: refine defaults @@ -518,5 +518,5 @@ function shouldIncludeInspectorModules(): boolean { const platform = getPlatformName(); // todo: check if core modules are external // todo: check if we are testing - return platform === 'ios'; + return platform === 'ios' || platform === 'android'; }