mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: Scoped Packages (#7911)
* chore: move tns-core-modules to nativescript-core * chore: preparing compat generate script * chore: add missing definitions * chore: no need for http-request to be private * chore: packages chore * test: generate tests for tns-core-modules * chore: add anroid module for consistency * chore: add .npmignore * chore: added privateModulesWhitelist * chore(webpack): added bundle-entry-points * chore: scripts * chore: tests changed to use @ns/core * test: add scoped-packages test project * test: fix types * test: update test project * chore: build scripts * chore: update build script * chore: npm scripts cleanup * chore: make the compat pgk work with old wp config * test: generate diff friendly tests * chore: create barrel exports * chore: move files after rebase * chore: typedoc config * chore: compat mode * chore: review of barrels * chore: remove tns-core-modules import after rebase * chore: dev workflow setup * chore: update developer-workflow * docs: experiment with API extractor * chore: api-extractor and barrel exports * chore: api-extractor configs * chore: generate d.ts rollup with api-extractor * refactor: move methods inside Frame * chore: fic tests to use Frame static methods * refactor: create Builder class * refactor: use Builder class in tests * refactor: include Style in ui barrel * chore: separate compat build script * chore: fix tslint errors * chore: update NATIVESCRIPT_CORE_ARGS * chore: fix compat pack * chore: fix ui-test-app build with linked modules * chore: Application, ApplicationSettings, Connectivity and Http * chore: export Trace, Profiling and Utils * refactor: Static create methods for ImageSource * chore: fix deprecated usages of ImageSource * chore: move Span and FormattedString to ui * chore: add events-args and ImageSource to index files * chore: check for CLI >= 6.2 when building for IOS * chore: update travis build * chore: copy Pod file to compat package * chore: update error msg ui-tests-app * refactor: Apply suggestions from code review Co-Authored-By: Martin Yankov <m.i.yankov@gmail.com> * chore: typings and refs * chore: add missing d.ts files for public API * chore: adress code review FB * chore: update api-report * chore: dev-workflow for other apps * chore: api update * chore: update api-report
This commit is contained in:
committed by
GitHub
parent
6c7139477e
commit
cc97a16800
1734
nativescript-core/debugger/InspectorBackendCommands.ios.ts
Normal file
1734
nativescript-core/debugger/InspectorBackendCommands.ios.ts
Normal file
File diff suppressed because it is too large
Load Diff
59
nativescript-core/debugger/css-agent.d.ts
vendored
Normal file
59
nativescript-core/debugger/css-agent.d.ts
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
export interface CSSProperty {
|
||||
name: string;
|
||||
value: string;
|
||||
disabled: boolean;
|
||||
}
|
||||
export interface ShorthandEntry {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
export interface CSSStyle {
|
||||
cssProperties: CSSProperty[];
|
||||
shorthandEntries: ShorthandEntry[];
|
||||
cssText?: string;
|
||||
}
|
||||
export interface Value {
|
||||
text: string;
|
||||
}
|
||||
export interface SelectorList {
|
||||
selectors: Value[];
|
||||
text: string;
|
||||
}
|
||||
export interface CSSRule {
|
||||
selectorList: SelectorList;
|
||||
origin: string;
|
||||
style: CSSStyle;
|
||||
styleSheetId?: string;
|
||||
}
|
||||
export interface RuleMatch {
|
||||
rule: CSSRule;
|
||||
matchingSelectors: number[];
|
||||
}
|
||||
export interface InheritedStyleEntry {
|
||||
matchedCSSRules: RuleMatch[];
|
||||
inlineStyle?: CSSStyle;
|
||||
}
|
||||
export interface CSSComputedStyleProperty {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
export interface PlatformFontUsage {
|
||||
familyName: string;
|
||||
glyphCount: number;
|
||||
isCustomFont: boolean;
|
||||
}
|
||||
export interface CSSStyleSheetHeader {
|
||||
styleSheetId: string;
|
||||
frameId: string;
|
||||
sourceUrl: string;
|
||||
origin: string;
|
||||
title: string;
|
||||
disabled: boolean;
|
||||
isInLine: boolean;
|
||||
startLine: number;
|
||||
startColumn: number;
|
||||
}
|
||||
export interface PseudoElementMatches {
|
||||
pseudoType: string;
|
||||
matches: RuleMatch[];
|
||||
}
|
||||
224
nativescript-core/debugger/debugger.ts
Normal file
224
nativescript-core/debugger/debugger.ts
Normal file
@@ -0,0 +1,224 @@
|
||||
export namespace domains {
|
||||
export namespace network {
|
||||
export interface NetworkDomainDebugger {
|
||||
create(): domains.network.NetworkRequest;
|
||||
}
|
||||
|
||||
export interface Headers {
|
||||
}
|
||||
|
||||
export interface Request {
|
||||
url: string;
|
||||
method: string;
|
||||
headers: domains.network.Headers;
|
||||
postData?: string;
|
||||
}
|
||||
|
||||
export interface Response {
|
||||
url: string;
|
||||
status: number;
|
||||
statusText: string;
|
||||
headers: Headers;
|
||||
headersText?: string;
|
||||
mimeType: string;
|
||||
requestHeaders?: domains.network.Headers;
|
||||
requestHeadersText?: string;
|
||||
fromDiskCache?: boolean;
|
||||
}
|
||||
|
||||
export interface NetworkRequest {
|
||||
mimeType: string;
|
||||
data: any;
|
||||
responseReceived(response: domains.network.Response);
|
||||
loadingFinished();
|
||||
requestWillBeSent(request: domains.network.Request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let network;
|
||||
|
||||
export function getNetwork(): domains.network.NetworkDomainDebugger {
|
||||
return network;
|
||||
}
|
||||
export function setNetwork(newNetwork: domains.network.NetworkDomainDebugger) {
|
||||
network = newNetwork;
|
||||
}
|
||||
|
||||
let dom;
|
||||
|
||||
export function getDOM(): any {
|
||||
return dom;
|
||||
}
|
||||
|
||||
export function setDOM(newDOM) {
|
||||
dom = newDOM;
|
||||
}
|
||||
|
||||
let css;
|
||||
|
||||
export function getCSS(): any {
|
||||
return css;
|
||||
}
|
||||
|
||||
export function setCSS(newCSS) {
|
||||
css = newCSS;
|
||||
}
|
||||
|
||||
export namespace NetworkAgent {
|
||||
export interface Request {
|
||||
url: string;
|
||||
method: string;
|
||||
headers: any;
|
||||
initialPriority: string;
|
||||
referrerPolicy: string;
|
||||
postData?: string;
|
||||
}
|
||||
|
||||
export interface RequestData {
|
||||
requestId: string;
|
||||
url: string;
|
||||
request: Request;
|
||||
timestamp: number;
|
||||
type: string;
|
||||
wallTime: number;
|
||||
}
|
||||
|
||||
export interface Response {
|
||||
url: string;
|
||||
status: number;
|
||||
statusText: string;
|
||||
headers: any;
|
||||
headersText?: string;
|
||||
mimeType: string;
|
||||
connectionReused: boolean;
|
||||
connectionId: number;
|
||||
encodedDataLength: number;
|
||||
securityState: string;
|
||||
fromDiskCache?: boolean;
|
||||
}
|
||||
|
||||
export interface ResponseData {
|
||||
requestId: string;
|
||||
type: string;
|
||||
response: Response;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface SuccessfulRequestData {
|
||||
requestId: string;
|
||||
data: string;
|
||||
hasTextContent: boolean;
|
||||
}
|
||||
|
||||
export interface LoadingFinishedData {
|
||||
requestId: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export function responseReceived(requestId: number, result: org.nativescript.widgets.Async.Http.RequestResult, headers: any) {
|
||||
const requestIdStr = requestId.toString();
|
||||
// Content-Type and content-type are both common in headers spelling
|
||||
const mimeType: string = <string>headers["Content-Type"] || <string>headers["content-type"] || "application/octet-stream";
|
||||
const contentLengthHeader: string = <string>headers["Content-Length"] || <string>headers["content-length"];
|
||||
let contentLength = parseInt(contentLengthHeader, 10);
|
||||
if (isNaN(contentLength)) {
|
||||
contentLength = 0;
|
||||
}
|
||||
|
||||
const response: NetworkAgent.Response = {
|
||||
url: result.url || "",
|
||||
status: result.statusCode,
|
||||
statusText: result.statusText || "",
|
||||
headers: headers,
|
||||
mimeType: mimeType,
|
||||
fromDiskCache: false,
|
||||
connectionReused: true,
|
||||
connectionId: 0,
|
||||
encodedDataLength: contentLength,
|
||||
securityState: "info"
|
||||
};
|
||||
|
||||
const responseData: NetworkAgent.ResponseData = {
|
||||
requestId: requestIdStr,
|
||||
type: mimeTypeToType(response.mimeType),
|
||||
response: response,
|
||||
timestamp: getTimeStamp()
|
||||
};
|
||||
|
||||
global.__inspector.responseReceived(responseData);
|
||||
global.__inspector.loadingFinished({
|
||||
requestId: requestIdStr,
|
||||
timestamp: getTimeStamp(),
|
||||
encodedDataLength: contentLength
|
||||
});
|
||||
|
||||
const hasTextContent = responseData.type === "Document" || responseData.type === "Script";
|
||||
let data;
|
||||
|
||||
if (!hasTextContent) {
|
||||
if (responseData.type === "Image") {
|
||||
const bitmap = result.responseAsImage;
|
||||
if (bitmap) {
|
||||
const outputStream = new java.io.ByteArrayOutputStream();
|
||||
bitmap.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, outputStream);
|
||||
|
||||
const base64Image = android.util.Base64.encodeToString(outputStream.toByteArray(), android.util.Base64.DEFAULT);
|
||||
data = base64Image;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data = result.responseAsString;
|
||||
}
|
||||
|
||||
const successfulRequestData: NetworkAgent.SuccessfulRequestData = {
|
||||
requestId: requestIdStr,
|
||||
data: data,
|
||||
hasTextContent: hasTextContent
|
||||
};
|
||||
|
||||
global.__inspector.dataForRequestId(successfulRequestData);
|
||||
}
|
||||
|
||||
export function requestWillBeSent(requestId: number, options: any) {
|
||||
const request: NetworkAgent.Request = {
|
||||
url: options.url,
|
||||
method: options.method,
|
||||
headers: options.headers || {},
|
||||
postData: options.content ? options.content.toString() : "",
|
||||
initialPriority: "Medium",
|
||||
referrerPolicy: "no-referrer-when-downgrade"
|
||||
};
|
||||
|
||||
const requestData: NetworkAgent.RequestData = {
|
||||
requestId: requestId.toString(),
|
||||
url: request.url,
|
||||
request: request,
|
||||
timestamp: getTimeStamp(),
|
||||
type: "Document",
|
||||
wallTime: 0
|
||||
};
|
||||
|
||||
global.__inspector.requestWillBeSent(requestData);
|
||||
}
|
||||
|
||||
function getTimeStamp(): number {
|
||||
const d = new Date();
|
||||
|
||||
return Math.round(d.getTime() / 1000);
|
||||
}
|
||||
|
||||
function mimeTypeToType(mimeType: string): string {
|
||||
let type: string = "Document";
|
||||
|
||||
if (mimeType) {
|
||||
if (mimeType.indexOf("image") === 0) {
|
||||
type = "Image";
|
||||
} else if (mimeType.indexOf("javascript") !== -1 || mimeType.indexOf("json") !== -1) {
|
||||
type = "Script";
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
30
nativescript-core/debugger/devtools-elements.android.ts
Normal file
30
nativescript-core/debugger/devtools-elements.android.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { InspectorEvents, InspectorCommands } from "./devtools-elements";
|
||||
import { getDocument, getComputedStylesForNode, removeNode, setAttributeAsText } from "./devtools-elements.common";
|
||||
import { registerInspectorEvents, DOMNode } from "./dom-node";
|
||||
|
||||
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
|
||||
}
|
||||
98
nativescript-core/debugger/devtools-elements.common.ts
Normal file
98
nativescript-core/debugger/devtools-elements.common.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { getNodeById } from "./dom-node";
|
||||
|
||||
// Needed for typings only
|
||||
import { ViewBase } from "../ui/core/view-base";
|
||||
import { mainThreadify } from "../utils/utils";
|
||||
|
||||
// Use lazy requires for core modules
|
||||
const frameTopmost = () => require("../ui/frame").topmost();
|
||||
|
||||
let unsetValue;
|
||||
function unsetViewValue(view, name) {
|
||||
if (!unsetValue) {
|
||||
unsetValue = require("../ui/core/properties").unsetValue;
|
||||
}
|
||||
|
||||
view[name] = unsetValue;
|
||||
}
|
||||
|
||||
function getViewById(nodeId: number): ViewBase {
|
||||
const node = getNodeById(nodeId);
|
||||
let view;
|
||||
if (node) {
|
||||
view = node.viewRef.get();
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
export function getDocument() {
|
||||
const topMostFrame = frameTopmost();
|
||||
if (!topMostFrame) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
topMostFrame.ensureDomNode();
|
||||
|
||||
} catch (e) {
|
||||
console.log("ERROR in getDocument(): " + e);
|
||||
}
|
||||
|
||||
return topMostFrame.domNode.toObject();
|
||||
}
|
||||
|
||||
export function getComputedStylesForNode(nodeId): Array<{ name: string, value: string }> {
|
||||
const view = getViewById(nodeId);
|
||||
if (view) {
|
||||
return view.domNode.getComputedProperties();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export const removeNode = mainThreadify(function removeNode(nodeId) {
|
||||
const view = getViewById(nodeId);
|
||||
if (view) {
|
||||
// Avoid importing layout and content view
|
||||
let parent = <any>view.parent;
|
||||
if (parent.removeChild) {
|
||||
parent.removeChild(view);
|
||||
} else if (parent.content === view) {
|
||||
parent.content = null;
|
||||
}
|
||||
else {
|
||||
console.log("Can't remove child from " + parent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const setAttributeAsText = mainThreadify(function setAttributeAsText(nodeId, text, name) {
|
||||
const view = getViewById(nodeId);
|
||||
if (view) {
|
||||
// attribute is registered for the view instance
|
||||
let hasOriginalAttribute = !!name.trim();
|
||||
|
||||
if (text) {
|
||||
let textParts = text.split("=");
|
||||
|
||||
if (textParts.length === 2) {
|
||||
let attrName = textParts[0];
|
||||
let attrValue = textParts[1].replace(/['"]+/g, "");
|
||||
|
||||
// if attr name is being replaced with another
|
||||
if (name !== attrName && hasOriginalAttribute) {
|
||||
unsetViewValue(view, name);
|
||||
view[attrName] = attrValue;
|
||||
} else {
|
||||
view[hasOriginalAttribute ? name : attrName] = attrValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// delete attribute
|
||||
unsetViewValue(view, name);
|
||||
}
|
||||
|
||||
view.domNode.loadAttributes();
|
||||
}
|
||||
});
|
||||
23
nativescript-core/debugger/devtools-elements.d.ts
vendored
Normal file
23
nativescript-core/debugger/devtools-elements.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { DOMNode } from "./dom-node";
|
||||
|
||||
export interface InspectorCommands {
|
||||
// DevTools -> Application communication. Methods that devtools calls when needed.
|
||||
getDocument(): string | DOMNode;
|
||||
removeNode(nodeId: number): void;
|
||||
getComputedStylesForNode(nodeId: number): string | Array<{ name: string, value: string }>;
|
||||
setAttributeAsText(nodeId: number, text: string, name: string): void;
|
||||
}
|
||||
|
||||
export interface InspectorEvents {
|
||||
// Application -> DevTools communication. Methods that the app should call when needed.
|
||||
childNodeInserted(parentId: number, lastId: number, node: DOMNode): void;
|
||||
childNodeRemoved(parentId: number, nodeId: number): void;
|
||||
attributeModified(nodeId: number, attrName: string, attrValue: string): void;
|
||||
attributeRemoved(nodeId: number, attrName: string): void;
|
||||
}
|
||||
|
||||
export function attachDOMInspectorEventCallbacks(inspector: InspectorEvents);
|
||||
|
||||
export function attachDOMInspectorCommandCallbacks(inspector: InspectorCommands);
|
||||
|
||||
export function attachCSSInspectorCommandCallbacks(inspector: InspectorCommands);
|
||||
23
nativescript-core/debugger/devtools-elements.ios.ts
Normal file
23
nativescript-core/debugger/devtools-elements.ios.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { InspectorEvents, InspectorCommands } from "./devtools-elements";
|
||||
import { getDocument, getComputedStylesForNode, removeNode, setAttributeAsText } from "./devtools-elements.common";
|
||||
import { registerInspectorEvents, DOMNode } from "./dom-node";
|
||||
|
||||
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, node.toObject());
|
||||
};
|
||||
}
|
||||
|
||||
export function attachDOMInspectorCommandCallbacks(DOMDomainBackend: InspectorCommands) {
|
||||
DOMDomainBackend.getDocument = getDocument;
|
||||
DOMDomainBackend.removeNode = removeNode;
|
||||
DOMDomainBackend.setAttributeAsText = setAttributeAsText;
|
||||
}
|
||||
|
||||
export function attachCSSInspectorCommandCallbacks(CSSDomainBackend: InspectorCommands) {
|
||||
CSSDomainBackend.getComputedStylesForNode = getComputedStylesForNode;
|
||||
}
|
||||
22
nativescript-core/debugger/dom-node.d.ts
vendored
Normal file
22
nativescript-core/debugger/dom-node.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ViewBase } from "../ui/core/view";
|
||||
import { CSSComputedStyleProperty } from "./css-agent";
|
||||
export declare function getNodeById(id: number): DOMNode;
|
||||
export declare class DOMNode {
|
||||
nodeId: any;
|
||||
nodeType: any;
|
||||
nodeName: any;
|
||||
localName: any;
|
||||
nodeValue: string;
|
||||
attributes: string[];
|
||||
viewRef: WeakRef<ViewBase>;
|
||||
constructor(view: ViewBase);
|
||||
loadAttributes(): void;
|
||||
readonly children: DOMNode[];
|
||||
onChildAdded(childView: ViewBase): void;
|
||||
onChildRemoved(view: ViewBase): void;
|
||||
attributeModified(name: string, value: any): void;
|
||||
attributeRemoved(name: string): void;
|
||||
getComputedProperties(): CSSComputedStyleProperty[];
|
||||
dispose(): void;
|
||||
toJSON(): string;
|
||||
}
|
||||
220
nativescript-core/debugger/dom-node.ts
Normal file
220
nativescript-core/debugger/dom-node.ts
Normal file
@@ -0,0 +1,220 @@
|
||||
import { CSSComputedStyleProperty } from "./css-agent";
|
||||
import { InspectorEvents } from "./devtools-elements";
|
||||
|
||||
// Needed for typings only
|
||||
import { ViewBase } from "../ui/core/view";
|
||||
|
||||
const registeredDomNodes = {};
|
||||
const ELEMENT_NODE_TYPE = 1;
|
||||
const ROOT_NODE_TYPE = 9;
|
||||
const propertyBlacklist = [
|
||||
"effectivePaddingLeft",
|
||||
"effectivePaddingBottom",
|
||||
"effectivePaddingRight",
|
||||
"effectivePaddingTop",
|
||||
"effectiveBorderTopWidth",
|
||||
"effectiveBorderRightWidth",
|
||||
"effectiveBorderBottomWidth",
|
||||
"effectiveBorderLeftWidth",
|
||||
"effectiveMinWidth",
|
||||
"effectiveMinHeight",
|
||||
"effectiveWidth",
|
||||
"effectiveHeight",
|
||||
"effectiveMarginLeft",
|
||||
"effectiveMarginTop",
|
||||
"effectiveMarginRight",
|
||||
"effectiveMarginBottom",
|
||||
"nodeName",
|
||||
"nodeType",
|
||||
"decodeWidth",
|
||||
"decodeHeight",
|
||||
"ng-reflect-items",
|
||||
"domNode",
|
||||
"touchListenerIsSet",
|
||||
"bindingContext",
|
||||
"nativeView"
|
||||
];
|
||||
|
||||
function lazy<T>(action: () => T): () => T {
|
||||
let _value: T;
|
||||
|
||||
return () => _value || (_value = action());
|
||||
}
|
||||
const percentLengthToStringLazy = lazy<(length) => string>(() => require("../ui/styling/style-properties").PercentLength.convertToString);
|
||||
const getSetPropertiesLazy = lazy<(view: ViewBase) => [string, any][]>(() => require("../ui/core/properties").getSetProperties);
|
||||
const getComputedCssValuesLazy = lazy<(view: ViewBase) => [string, any][]>(() => require("../ui/core/properties").getComputedCssValues);
|
||||
|
||||
export function registerInspectorEvents(inspector: InspectorEvents) {
|
||||
inspectorFrontendInstance = inspector;
|
||||
}
|
||||
|
||||
let inspectorFrontendInstance: any;
|
||||
function notifyInspector(callback: (inspector: InspectorEvents) => void) {
|
||||
if (inspectorFrontendInstance) {
|
||||
callback(inspectorFrontendInstance);
|
||||
}
|
||||
}
|
||||
|
||||
function valueToString(value: any): string {
|
||||
if (typeof value === "undefined" || value === null) {
|
||||
return "";
|
||||
} else if (typeof value === "object" && value.unit) {
|
||||
return percentLengthToStringLazy()(value);
|
||||
} else {
|
||||
return value + "";
|
||||
}
|
||||
}
|
||||
|
||||
function propertyFilter([name, value]: [string, any]): boolean {
|
||||
if (name[0] === "_") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value !== null && typeof value === "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (propertyBlacklist.indexOf(name) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function registerNode(domNode: DOMNode) {
|
||||
registeredDomNodes[domNode.nodeId] = domNode;
|
||||
}
|
||||
|
||||
function unregisterNode(domNode: DOMNode) {
|
||||
delete registeredDomNodes[domNode.nodeId];
|
||||
}
|
||||
|
||||
export function getNodeById(id: number): DOMNode {
|
||||
return registeredDomNodes[id];
|
||||
}
|
||||
|
||||
export class DOMNode {
|
||||
nodeId;
|
||||
nodeType;
|
||||
nodeName;
|
||||
localName;
|
||||
nodeValue = "";
|
||||
attributes: string[] = [];
|
||||
viewRef: WeakRef<ViewBase>;
|
||||
|
||||
constructor(view: ViewBase) {
|
||||
this.viewRef = new WeakRef(view);
|
||||
this.nodeType = view.typeName === "Frame" ? ROOT_NODE_TYPE : ELEMENT_NODE_TYPE;
|
||||
this.nodeId = view._domId;
|
||||
this.nodeName = view.typeName;
|
||||
this.localName = this.nodeName;
|
||||
|
||||
// Load all attributes
|
||||
this.loadAttributes();
|
||||
|
||||
registerNode(this);
|
||||
}
|
||||
|
||||
public loadAttributes() {
|
||||
this.attributes = [];
|
||||
getSetPropertiesLazy()(this.viewRef.get())
|
||||
.filter(propertyFilter)
|
||||
.forEach(pair => this.attributes.push(pair[0], pair[1] + ""));
|
||||
|
||||
}
|
||||
|
||||
get children(): DOMNode[] {
|
||||
const view = this.viewRef.get();
|
||||
if (!view) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const res = [];
|
||||
|
||||
view.eachChild((child) => {
|
||||
child.ensureDomNode();
|
||||
res.push(child.domNode);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
onChildAdded(childView: ViewBase): void {
|
||||
notifyInspector((ins) => {
|
||||
const view = this.viewRef.get();
|
||||
|
||||
let previousChild: ViewBase;
|
||||
view.eachChild((child) => {
|
||||
if (child === childView) {
|
||||
return false;
|
||||
}
|
||||
|
||||
previousChild = child;
|
||||
|
||||
return true;
|
||||
});
|
||||
const index = !!previousChild ? previousChild._domId : 0;
|
||||
|
||||
childView.ensureDomNode();
|
||||
ins.childNodeInserted(this.nodeId, index, childView.domNode);
|
||||
});
|
||||
}
|
||||
|
||||
onChildRemoved(view: ViewBase): void {
|
||||
notifyInspector((ins) => {
|
||||
ins.childNodeRemoved(this.nodeId, view._domId);
|
||||
});
|
||||
}
|
||||
|
||||
attributeModified(name: string, value: any) {
|
||||
notifyInspector((ins) => {
|
||||
if (propertyBlacklist.indexOf(name) < 0) {
|
||||
ins.attributeModified(this.nodeId, name, valueToString(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
attributeRemoved(name: string) {
|
||||
notifyInspector((ins) => {
|
||||
ins.attributeRemoved(this.nodeId, name);
|
||||
});
|
||||
}
|
||||
|
||||
getComputedProperties(): CSSComputedStyleProperty[] {
|
||||
const view = this.viewRef.get();
|
||||
if (!view) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const result = getComputedCssValuesLazy()(view)
|
||||
.filter(pair => pair[0][0] !== "_")
|
||||
.map((pair) => {
|
||||
return {
|
||||
name: pair[0],
|
||||
value: valueToString(pair[1])
|
||||
};
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
unregisterNode(this);
|
||||
this.viewRef.clear();
|
||||
}
|
||||
|
||||
public toObject() {
|
||||
return {
|
||||
nodeId: this.nodeId,
|
||||
nodeType: this.nodeType,
|
||||
nodeName: this.nodeName,
|
||||
localName: this.localName,
|
||||
nodeValue: this.nodeValue,
|
||||
children: this.children.map(c => c.toObject()),
|
||||
attributes: this.attributes,
|
||||
backendNodeId: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
5
nativescript-core/debugger/package.json
Normal file
5
nativescript-core/debugger/package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "debugger",
|
||||
"main": "debugger",
|
||||
"nativescript": {}
|
||||
}
|
||||
80
nativescript-core/debugger/webinspector-css.ios.ts
Normal file
80
nativescript-core/debugger/webinspector-css.ios.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import * as inspectorCommandTypes from "./InspectorBackendCommands.ios";
|
||||
const inspectorCommands: typeof inspectorCommandTypes = require("./InspectorBackendCommands");
|
||||
|
||||
import * as debuggerDomains from "./debugger";
|
||||
|
||||
import { attachCSSInspectorCommandCallbacks } from "./devtools-elements";
|
||||
|
||||
@inspectorCommands.DomainDispatcher("CSS")
|
||||
export class CSSDomainDebugger implements inspectorCommandTypes.CSSDomain.CSSDomainDispatcher {
|
||||
|
||||
private _enabled: boolean;
|
||||
public events: inspectorCommandTypes.CSSDomain.CSSFrontend;
|
||||
public commands: any;
|
||||
|
||||
constructor() {
|
||||
this.events = new inspectorCommands.CSSDomain.CSSFrontend();
|
||||
|
||||
this.commands = {};
|
||||
|
||||
attachCSSInspectorCommandCallbacks(this.commands);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
enable(): void {
|
||||
if (debuggerDomains.getCSS()) {
|
||||
throw new Error("One CSSDomainDebugger may be enabled at a time.");
|
||||
} else {
|
||||
debuggerDomains.setCSS(this);
|
||||
}
|
||||
this._enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables network tracking, prevents network events from being sent to the client.
|
||||
*/
|
||||
disable(): void {
|
||||
if (debuggerDomains.getCSS() === this) {
|
||||
debuggerDomains.setCSS(null);
|
||||
}
|
||||
this._enabled = false;
|
||||
}
|
||||
|
||||
getMatchedStylesForNode(params: inspectorCommandTypes.CSSDomain.GetMatchedStylesForNodeMethodArguments): { inlineStyle?: inspectorCommandTypes.CSSDomain.CSSStyle, attributesStyle?: inspectorCommandTypes.CSSDomain.CSSStyle, matchedCSSRules?: inspectorCommandTypes.CSSDomain.RuleMatch[], pseudoElements?: inspectorCommandTypes.CSSDomain.PseudoElementMatches[], inherited?: inspectorCommandTypes.CSSDomain.InheritedStyleEntry[], cssKeyframesRules?: inspectorCommandTypes.CSSDomain.CSSKeyframesRule[] } {
|
||||
return {};
|
||||
}
|
||||
// Returns the styles defined inline (explicitly in the "style" attribute and implicitly, using DOM attributes) for a DOM node identified by <code>nodeId</code>.
|
||||
getInlineStylesForNode(params: inspectorCommandTypes.CSSDomain.GetInlineStylesForNodeMethodArguments): { inlineStyle?: inspectorCommandTypes.CSSDomain.CSSStyle, attributesStyle?: inspectorCommandTypes.CSSDomain.CSSStyle } {
|
||||
return {};
|
||||
}
|
||||
// Returns the computed style for a DOM node identified by <code>nodeId</code>.
|
||||
getComputedStyleForNode(params: inspectorCommandTypes.CSSDomain.GetComputedStyleForNodeMethodArguments): { computedStyle: inspectorCommandTypes.CSSDomain.CSSComputedStyleProperty[] } {
|
||||
return { computedStyle: this.commands.getComputedStylesForNode(params.nodeId) };
|
||||
}
|
||||
// Requests information about platform fonts which we used to render child TextNodes in the given node.
|
||||
getPlatformFontsForNode(params: inspectorCommandTypes.CSSDomain.GetPlatformFontsForNodeMethodArguments): { fonts: inspectorCommandTypes.CSSDomain.PlatformFontUsage[] } {
|
||||
return {
|
||||
fonts: [
|
||||
{
|
||||
// Font's family name reported by platform.
|
||||
familyName: "Standard Font",
|
||||
// Indicates if the font was downloaded or resolved locally.
|
||||
isCustomFont: false,
|
||||
// Amount of glyphs that were rendered with this font.
|
||||
glyphCount: 0
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
// Returns the current textual content and the URL for a stylesheet.
|
||||
getStyleSheetText(params: inspectorCommandTypes.CSSDomain.GetStyleSheetTextMethodArguments): { text: string } {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
96
nativescript-core/debugger/webinspector-dom.ios.ts
Normal file
96
nativescript-core/debugger/webinspector-dom.ios.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as inspectorCommandTypes from "./InspectorBackendCommands.ios";
|
||||
const inspectorCommands: typeof inspectorCommandTypes = require("./InspectorBackendCommands");
|
||||
|
||||
import * as debuggerDomains from "./debugger";
|
||||
|
||||
import { attachDOMInspectorEventCallbacks, attachDOMInspectorCommandCallbacks } from "./devtools-elements";
|
||||
|
||||
@inspectorCommands.DomainDispatcher("DOM")
|
||||
export class DOMDomainDebugger implements inspectorCommandTypes.DOMDomain.DOMDomainDispatcher {
|
||||
|
||||
private _enabled: boolean;
|
||||
public events: inspectorCommandTypes.DOMDomain.DOMFrontend;
|
||||
public commands: any;
|
||||
|
||||
constructor() {
|
||||
this.events = new inspectorCommands.DOMDomain.DOMFrontend();
|
||||
|
||||
this.commands = {};
|
||||
|
||||
attachDOMInspectorEventCallbacks(this.events);
|
||||
attachDOMInspectorCommandCallbacks(this.commands);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
enable(): void {
|
||||
if (debuggerDomains.getDOM()) {
|
||||
throw new Error("One DOMDomainDebugger may be enabled at a time.");
|
||||
} else {
|
||||
debuggerDomains.setDOM(this);
|
||||
}
|
||||
this._enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables network tracking, prevents network events from being sent to the client.
|
||||
*/
|
||||
disable(): void {
|
||||
if (debuggerDomains.getDOM() === this) {
|
||||
debuggerDomains.setDOM(null);
|
||||
}
|
||||
this._enabled = false;
|
||||
}
|
||||
|
||||
getDocument(): { root: inspectorCommandTypes.DOMDomain.Node } {
|
||||
const domNode = this.commands.getDocument();
|
||||
|
||||
return { root: domNode };
|
||||
}
|
||||
|
||||
removeNode(params: inspectorCommandTypes.DOMDomain.RemoveNodeMethodArguments): void {
|
||||
this.commands.removeNode(params.nodeId);
|
||||
}
|
||||
|
||||
setAttributeValue(params: inspectorCommandTypes.DOMDomain.SetAttributeValueMethodArguments): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
setAttributesAsText(params: inspectorCommandTypes.DOMDomain.SetAttributesAsTextMethodArguments): void {
|
||||
this.commands.setAttributeAsText(params.nodeId, params.text, params.name);
|
||||
}
|
||||
|
||||
removeAttribute(params: inspectorCommandTypes.DOMDomain.RemoveAttributeMethodArguments): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
performSearch(params: inspectorCommandTypes.DOMDomain.PerformSearchMethodArguments): { searchId: string, resultCount: number } {
|
||||
return null;
|
||||
}
|
||||
|
||||
getSearchResults(params: inspectorCommandTypes.DOMDomain.GetSearchResultsMethodArguments): { nodeIds: inspectorCommandTypes.DOMDomain.NodeId[] } {
|
||||
return null;
|
||||
}
|
||||
|
||||
discardSearchResults(params: inspectorCommandTypes.DOMDomain.DiscardSearchResultsMethodArguments): void {
|
||||
return;
|
||||
}
|
||||
|
||||
highlightNode(params: inspectorCommandTypes.DOMDomain.HighlightNodeMethodArguments): void {
|
||||
return;
|
||||
}
|
||||
|
||||
hideHighlight(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
resolveNode(params: inspectorCommandTypes.DOMDomain.ResolveNodeMethodArguments): { object: inspectorCommandTypes.RuntimeDomain.RemoteObject } {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
260
nativescript-core/debugger/webinspector-network.ios.ts
Normal file
260
nativescript-core/debugger/webinspector-network.ios.ts
Normal file
@@ -0,0 +1,260 @@
|
||||
import * as inspectorCommandTypes from "./InspectorBackendCommands.ios";
|
||||
const inspectorCommands: typeof inspectorCommandTypes = require("./InspectorBackendCommands");
|
||||
|
||||
import * as debuggerDomains from "./debugger";
|
||||
|
||||
declare var __inspectorSendEvent;
|
||||
|
||||
declare var __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];
|
||||
const body = resource_data.hasTextContent ? NSString.alloc().initWithDataEncoding(resource_data.data, 4).toString() :
|
||||
resource_data.data.base64EncodedStringWithOptions(0);
|
||||
|
||||
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 } {
|
||||
let appPath = NSBundle.mainBundle.bundlePath;
|
||||
let pathUrl = params.url.replace("file://", appPath);
|
||||
let fileManager = NSFileManager.defaultManager;
|
||||
let data = fileManager.fileExistsAtPath(pathUrl) ? fileManager.contentsAtPath(pathUrl) : undefined;
|
||||
let content = data ? NSString.alloc().initWithDataEncoding(data, NSUTF8StringEncoding) : "";
|
||||
|
||||
return {
|
||||
content: content.toString(), // Not sure why however we need to call toString() for NSString
|
||||
mimeType: "application/octet-stream",
|
||||
status: 200
|
||||
};
|
||||
}
|
||||
|
||||
public static idSequence: number = 0;
|
||||
create(): Request {
|
||||
let id = (++NetworkDomainDebugger.idSequence).toString();
|
||||
let resourceData = new Request(this, id);
|
||||
resources_datas[id] = resourceData;
|
||||
|
||||
return resourceData;
|
||||
}
|
||||
}
|
||||
|
||||
@inspectorCommands.DomainDispatcher("Runtime")
|
||||
export class RuntimeDomainDebugger {
|
||||
constructor() {
|
||||
__inspectorSendEvent(`{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"origin":"http://main.xml","name":"","auxData":{"isDefault":true,"frameId":"${frameId}"}}}}`);
|
||||
}
|
||||
|
||||
compileScript(): { scriptId?: string, exceptionDetails?: Object } {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user