Merge branch 'main' into feat/page-transition-improvements

This commit is contained in:
Nathan Walker
2023-03-28 10:54:10 -07:00
committed by GitHub
24 changed files with 478 additions and 253 deletions

View File

@@ -278,8 +278,8 @@ allTests['TAB-VIEW-ROOT'] = tabViewRootTests;
import * as resetRootViewTests from './ui/root-view/reset-root-view-tests';
allTests['RESET-ROOT-VIEW'] = resetRootViewTests;
// import * as rootViewTests from './ui/root-view/root-view-tests';
// allTests['ROOT-VIEW'] = rootViewTests;
import * as rootViewTests from './ui/root-view/root-view-tests';
allTests['ROOT-VIEW'] = rootViewTests;
import * as utilsTests from './utils/utils-tests';
allTests['UTILS'] = utilsTests;

View File

@@ -210,6 +210,7 @@ export class View extends ViewCommon implements ViewDefinition {
const boundsOrigin = nativeView.bounds.origin;
const boundsFrame = adjustedFrame || frame;
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, boundsFrame.size.width, boundsFrame.size.height);
nativeView.layoutIfNeeded();
this._raiseLayoutChangedEvent();
this._isLaidOut = true;
@@ -914,9 +915,6 @@ export class View extends ViewCommon implements ViewDefinition {
}
_setNativeClipToBounds() {
if (!this.nativeViewProtected) {
return;
}
const backgroundInternal = this.style.backgroundInternal;
this.nativeViewProtected.clipsToBounds = (this.nativeViewProtected instanceof UIScrollView || backgroundInternal.hasBorderWidth() || backgroundInternal.hasBorderRadius()) && !backgroundInternal.hasBoxShadow();
}

View File

@@ -14,51 +14,9 @@ const majorVersion = iOSNativeHelper.MajorVersion;
class UILayoutViewController extends UIViewController {
public owner: WeakRef<View>;
private _isRunningLayout: number;
private get isRunningLayout() {
return this._isRunningLayout !== 0;
}
private startRunningLayout() {
this._isRunningLayout++;
}
private finishRunningLayout() {
this._isRunningLayout--;
this.clearScheduledLayout();
}
private runLayout(cb: () => void) {
try {
this.startRunningLayout();
cb();
} finally {
this.finishRunningLayout();
}
}
layoutTimer: number;
private clearScheduledLayout() {
if (this.layoutTimer) {
clearTimeout(this.layoutTimer);
this.layoutTimer = null;
}
}
private scheduleLayout() {
if (this.layoutTimer) {
return;
}
setTimeout(() => {
this.layoutTimer = null;
if (!this.isRunningLayout) {
this.runLayout(() => this.layoutOwner());
}
});
}
public static initWithOwner(owner: WeakRef<View>): UILayoutViewController {
const controller = <UILayoutViewController>UILayoutViewController.new();
controller.owner = owner;
controller._isRunningLayout = 0;
return controller;
}
@@ -71,11 +29,6 @@ class UILayoutViewController extends UIViewController {
this.extendedLayoutIncludesOpaqueBars = true;
}
public viewSafeAreaInsetsDidChange(): void {
super.viewSafeAreaInsetsDidChange();
this.scheduleLayout();
}
public viewWillLayoutSubviews(): void {
super.viewWillLayoutSubviews();
const owner = this.owner?.deref();
@@ -85,69 +38,56 @@ class UILayoutViewController extends UIViewController {
}
public viewDidLayoutSubviews(): void {
this.startRunningLayout();
super.viewDidLayoutSubviews();
this.layoutOwner();
this.finishRunningLayout();
}
layoutOwner(force = false) {
const owner = this.owner?.deref();
if (!owner) {
return;
}
if (!force && owner.isLayoutValid && !owner.nativeViewProtected?.layer.needsLayout?.()) {
// we skip layout if the view is not yet laid out yet
// this usually means that viewDidLayoutSubviews will be called again
// so doing a layout pass now will layout with the wrong parameters
return;
}
if (owner) {
if (majorVersion >= 11) {
// Handle nested UILayoutViewController safe area application.
// Currently, UILayoutViewController can be nested only in a TabView.
// The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout).
const tabViewItem = owner.parent;
const tabView = tabViewItem && tabViewItem.parent;
let parent = tabView && tabView.parent;
if (majorVersion >= 11) {
// Handle nested UILayoutViewController safe area application.
// Currently, UILayoutViewController can be nested only in a TabView.
// The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout).
const tabViewItem = owner.parent;
const tabView = tabViewItem && tabViewItem.parent;
let parent = tabView && tabView.parent;
// Handle Angular scenario where TabView is in a ProxyViewContainer
// It is possible to wrap components in ProxyViewContainers indefinitely
// Not using instanceof ProxyViewContainer to avoid circular dependency
// TODO: Try moving UILayoutViewController out of view module
while (parent && !parent.nativeViewProtected) {
parent = parent.parent;
}
if (parent) {
const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top;
const parentPageInsetsBottom = parent.nativeViewProtected.safeAreaInsets.bottom;
let currentInsetsTop = this.view.safeAreaInsets.top;
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
// Safe area insets include additional safe area insets too, so subtract old values
if (this.additionalSafeAreaInsets) {
currentInsetsTop -= this.additionalSafeAreaInsets.top;
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
// Handle Angular scenario where TabView is in a ProxyViewContainer
// It is possible to wrap components in ProxyViewContainers indefinitely
// Not using instanceof ProxyViewContainer to avoid circular dependency
// TODO: Try moving UILayoutViewController out of view module
while (parent && !parent.nativeViewProtected) {
parent = parent.parent;
}
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
if (parent) {
const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top;
const parentPageInsetsBottom = parent.nativeViewProtected.safeAreaInsets.bottom;
let currentInsetsTop = this.view.safeAreaInsets.top;
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
const additionalInsets = new UIEdgeInsets({
top: additionalInsetsTop,
left: 0,
bottom: additionalInsetsBottom,
right: 0,
});
this.additionalSafeAreaInsets = additionalInsets;
} else {
this.additionalSafeAreaInsets = null;
// Safe area insets include additional safe area insets too, so subtract old values
if (this.additionalSafeAreaInsets) {
currentInsetsTop -= this.additionalSafeAreaInsets.top;
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
}
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
const additionalInsets = new UIEdgeInsets({
top: additionalInsetsTop,
left: 0,
bottom: additionalInsetsBottom,
right: 0,
});
this.additionalSafeAreaInsets = additionalInsets;
} else {
this.additionalSafeAreaInsets = null;
}
}
}
}
IOSHelper.layoutView(this, owner);
IOSHelper.layoutView(this, owner);
}
}
public viewWillAppear(animated: boolean): void {

View File

@@ -75,6 +75,7 @@ class UIViewControllerImpl extends UIViewController {
public isBackstackSkipped: boolean;
public isBackstackCleared: boolean;
private didFirstLayout: boolean;
// this is initialized in initWithOwner since the constructor doesn't run on native classes
private _isRunningLayout: number;
private get isRunningLayout() {
@@ -85,7 +86,7 @@ class UIViewControllerImpl extends UIViewController {
}
private finishRunningLayout() {
this._isRunningLayout--;
this.clearScheduledLayout();
this.didFirstLayout = true;
}
private runLayout(cb: () => void) {
try {
@@ -96,31 +97,11 @@ class UIViewControllerImpl extends UIViewController {
}
}
layoutTimer: number;
private clearScheduledLayout() {
if (this.layoutTimer) {
clearTimeout(this.layoutTimer);
this.layoutTimer = null;
}
}
private scheduleLayout() {
if (this.layoutTimer) {
return;
}
setTimeout(() => {
this.layoutTimer = null;
if (!this.isRunningLayout) {
this.runLayout(() => this.layoutOwner());
}
});
}
public static initWithOwner(owner: WeakRef<Page>): UIViewControllerImpl {
const controller = <UIViewControllerImpl>UIViewControllerImpl.new();
controller._owner = owner;
controller._isRunningLayout = 0;
controller.didFirstLayout = false;
return controller;
}
@@ -305,77 +286,71 @@ class UIViewControllerImpl extends UIViewController {
public viewSafeAreaInsetsDidChange(): void {
super.viewSafeAreaInsetsDidChange();
this.scheduleLayout();
if (this.isRunningLayout || !this.didFirstLayout) {
return;
}
const owner = this._owner?.deref();
if (owner) {
this.runLayout(() => IOSHelper.layoutView(this, owner));
}
}
public viewDidLayoutSubviews(): void {
this.startRunningLayout();
super.viewDidLayoutSubviews();
this.layoutOwner();
this.finishRunningLayout();
}
layoutOwner(force = false) {
const owner = this._owner?.deref();
if (!owner) {
return;
}
if (!force && owner.isLayoutValid && !owner.nativeViewProtected?.layer.needsLayout?.()) {
// we skip layout if the view is not yet laid out yet
// this usually means that viewDidLayoutSubviews will be called again
// so doing a layout pass now will layout with the wrong parameters
return;
}
if (owner) {
// layout(owner.actionBar)
// layout(owner.content)
// layout(owner.actionBar)
// layout(owner.content)
if (majorVersion >= 11) {
// Handle nested Page safe area insets application.
// A Page is nested if its Frame has a parent.
// If the Page is nested, cross check safe area insets on top and bottom with Frame parent.
const frame = owner.parent;
// There is a legacy scenario where Page is not in a Frame - the root of a Modal View, so it has no parent.
let frameParent = frame && frame.parent;
if (majorVersion >= 11) {
// Handle nested Page safe area insets application.
// A Page is nested if its Frame has a parent.
// If the Page is nested, cross check safe area insets on top and bottom with Frame parent.
const frame = owner.parent;
// There is a legacy scenario where Page is not in a Frame - the root of a Modal View, so it has no parent.
let frameParent = frame && frame.parent;
// Handle Angular scenario where TabView is in a ProxyViewContainer
// It is possible to wrap components in ProxyViewContainers indefinitely
// Not using instanceof ProxyViewContainer to avoid circular dependency
// TODO: Try moving UIViewControllerImpl out of page module
while (frameParent && !frameParent.nativeViewProtected) {
frameParent = frameParent.parent;
}
if (frameParent) {
const parentPageInsetsTop = frameParent.nativeViewProtected.safeAreaInsets.top;
const parentPageInsetsBottom = frameParent.nativeViewProtected.safeAreaInsets.bottom;
let currentInsetsTop = this.view.safeAreaInsets.top;
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
// Safe area insets include additional safe area insets too, so subtract old values
if (this.additionalSafeAreaInsets) {
currentInsetsTop -= this.additionalSafeAreaInsets.top;
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
// Handle Angular scenario where TabView is in a ProxyViewContainer
// It is possible to wrap components in ProxyViewContainers indefinitely
// Not using instanceof ProxyViewContainer to avoid circular dependency
// TODO: Try moving UIViewControllerImpl out of page module
while (frameParent && !frameParent.nativeViewProtected) {
frameParent = frameParent.parent;
}
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
if (frameParent) {
const parentPageInsetsTop = frameParent.nativeViewProtected.safeAreaInsets.top;
const parentPageInsetsBottom = frameParent.nativeViewProtected.safeAreaInsets.bottom;
let currentInsetsTop = this.view.safeAreaInsets.top;
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
const additionalInsets = new UIEdgeInsets({
top: additionalInsetsTop,
left: 0,
bottom: additionalInsetsBottom,
right: 0,
});
this.additionalSafeAreaInsets = additionalInsets;
} else {
this.additionalSafeAreaInsets = null;
// Safe area insets include additional safe area insets too, so subtract old values
if (this.additionalSafeAreaInsets) {
currentInsetsTop -= this.additionalSafeAreaInsets.top;
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
}
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
const additionalInsets = new UIEdgeInsets({
top: additionalInsetsTop,
left: 0,
bottom: additionalInsetsBottom,
right: 0,
});
this.additionalSafeAreaInsets = additionalInsets;
} else {
this.additionalSafeAreaInsets = null;
}
}
}
}
IOSHelper.layoutView(this, owner);
IOSHelper.layoutView(this, owner);
}
this.finishRunningLayout();
}
// Mind implementation for other controllerss

View File

@@ -1,6 +1,6 @@
{
"name": "@nativescript/types-android",
"version": "8.4.0",
"version": "8.5.0",
"description": "NativeScript Types for Android.",
"homepage": "https://nativescript.org",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@nativescript/types-ios",
"version": "8.4.0",
"version": "8.5.0",
"description": "NativeScript Types for iOS.",
"homepage": "https://nativescript.org",
"repository": {

View File

@@ -120,7 +120,6 @@
/// <reference path="objc-x86_64/objc!PencilKit.d.ts" />
/// <reference path="objc-x86_64/objc!Photos.d.ts" />
/// <reference path="objc-x86_64/objc!PhotosUI.d.ts" />
/// <reference path="objc-x86_64/objc!Pods_iostypingsprj.d.ts" />
/// <reference path="objc-x86_64/objc!ProximityReader.d.ts" />
/// <reference path="objc-x86_64/objc!PushKit.d.ts" />
/// <reference path="objc-x86_64/objc!PushToTalk.d.ts" />

View File

@@ -1067,7 +1067,11 @@ declare class GKMatchmaker extends NSObject {
startBrowsingForNearbyPlayersWithReachableHandler(reachableHandler: (p1: string, p2: boolean) => void): void;
startGroupActivityWithPlayerHandler(handler: (p1: GKPlayer) => void): void;
stopBrowsingForNearbyPlayers(): void;
stopGroupActivity(): void;
}
declare class GKMatchmakerViewController extends UINavigationController {

View File

@@ -499,6 +499,62 @@ declare const enum INAmountType {
StatementBalance = 6
}
declare class INAnswerCallIntent extends INIntent {
static alloc(): INAnswerCallIntent; // inherited from NSObject
static new(): INAnswerCallIntent; // inherited from NSObject
constructor(o: { audioRoute: INCallAudioRoute; callIdentifier: string; });
initWithAudioRouteCallIdentifier(audioRoute: INCallAudioRoute, callIdentifier: string): this;
}
interface INAnswerCallIntentHandling extends NSObjectProtocol {
confirmAnswerCallCompletion?(intent: INAnswerCallIntent, completion: (p1: INAnswerCallIntentResponse) => void): void;
handleAnswerCallCompletion(intent: INAnswerCallIntent, completion: (p1: INAnswerCallIntentResponse) => void): void;
}
declare var INAnswerCallIntentHandling: {
prototype: INAnswerCallIntentHandling;
};
declare var INAnswerCallIntentIdentifier: string;
declare class INAnswerCallIntentResponse extends INIntentResponse {
static alloc(): INAnswerCallIntentResponse; // inherited from NSObject
static new(): INAnswerCallIntentResponse; // inherited from NSObject
callRecords: NSArray<INCallRecord>;
readonly code: INAnswerCallIntentResponseCode;
constructor(o: { code: INAnswerCallIntentResponseCode; userActivity: NSUserActivity; });
initWithCodeUserActivity(code: INAnswerCallIntentResponseCode, userActivity: NSUserActivity): this;
}
declare const enum INAnswerCallIntentResponseCode {
Unspecified = 0,
Ready = 1,
ContinueInApp = 2,
InProgress = 3,
Success = 4,
Failure = 5,
FailureRequiringAppLaunch = 6
}
declare class INAppendToNoteIntent extends INIntent {
static alloc(): INAppendToNoteIntent; // inherited from NSObject
@@ -3150,6 +3206,60 @@ declare const enum INGetVisualCodeIntentResponseCode {
FailureAppConfigurationRequired = 7
}
declare class INHangUpCallIntent extends INIntent {
static alloc(): INHangUpCallIntent; // inherited from NSObject
static new(): INHangUpCallIntent; // inherited from NSObject
constructor(o: { callIdentifier: string; });
initWithCallIdentifier(callIdentifier: string): this;
}
interface INHangUpCallIntentHandling extends NSObjectProtocol {
confirmHangUpCallCompletion?(intent: INHangUpCallIntent, completion: (p1: INHangUpCallIntentResponse) => void): void;
handleHangUpCallCompletion(intent: INHangUpCallIntent, completion: (p1: INHangUpCallIntentResponse) => void): void;
}
declare var INHangUpCallIntentHandling: {
prototype: INHangUpCallIntentHandling;
};
declare var INHangUpCallIntentIdentifier: string;
declare class INHangUpCallIntentResponse extends INIntentResponse {
static alloc(): INHangUpCallIntentResponse; // inherited from NSObject
static new(): INHangUpCallIntentResponse; // inherited from NSObject
readonly code: INHangUpCallIntentResponseCode;
constructor(o: { code: INHangUpCallIntentResponseCode; userActivity: NSUserActivity; });
initWithCodeUserActivity(code: INHangUpCallIntentResponseCode, userActivity: NSUserActivity): this;
}
declare const enum INHangUpCallIntentResponseCode {
Unspecified = 0,
Ready = 1,
InProgress = 2,
Success = 3,
Failure = 4,
FailureRequiringAppLaunch = 5,
FailureNoCallToHangUp = 6
}
declare class INImage extends NSObject implements NSCopying, NSSecureCoding {
static alloc(): INImage; // inherited from NSObject

View File

@@ -7250,6 +7250,8 @@ declare class MTRBaseClusterTestCluster extends MTRCluster {
static readAttributeVendorIdWithAttributeCacheEndpointQueueCompletionHandler(attributeCacheContainer: MTRAttributeCacheContainer, endpoint: number, queue: NSObject, completionHandler: (p1: number, p2: NSError) => void): void;
static readAttributeWriteOnlyInt8uWithAttributeCacheEndpointQueueCompletionHandler(attributeCacheContainer: MTRAttributeCacheContainer, endpoint: number, queue: NSObject, completionHandler: (p1: number, p2: NSError) => void): void;
constructor(o: { device: MTRBaseDevice; endpoint: number; queue: NSObject; });
initWithDeviceEndpointQueue(device: MTRBaseDevice, endpoint: number, queue: NSObject): this;
@@ -7426,6 +7428,8 @@ declare class MTRBaseClusterTestCluster extends MTRCluster {
readAttributeVendorIdWithCompletionHandler(completionHandler: (p1: number, p2: NSError) => void): void;
readAttributeWriteOnlyInt8uWithCompletionHandler(completionHandler: (p1: number, p2: NSError) => void): void;
simpleStructEchoRequestWithParamsCompletionHandler(params: MTRTestClusterClusterSimpleStructEchoRequestParams, completionHandler: (p1: MTRTestClusterClusterSimpleStructResponseParams, p2: NSError) => void): void;
subscribeAttributeAcceptedCommandListWithMinIntervalMaxIntervalParamsSubscriptionEstablishedReportHandler(minInterval: number, maxInterval: number, params: MTRSubscribeParams, subscriptionEstablishedHandler: () => void, reportHandler: (p1: NSArray<any>, p2: NSError) => void): void;
@@ -7600,6 +7604,8 @@ declare class MTRBaseClusterTestCluster extends MTRCluster {
subscribeAttributeVendorIdWithMinIntervalMaxIntervalParamsSubscriptionEstablishedReportHandler(minInterval: number, maxInterval: number, params: MTRSubscribeParams, subscriptionEstablishedHandler: () => void, reportHandler: (p1: number, p2: NSError) => void): void;
subscribeAttributeWriteOnlyInt8uWithMinIntervalMaxIntervalParamsSubscriptionEstablishedReportHandler(minInterval: number, maxInterval: number, params: MTRSubscribeParams, subscriptionEstablishedHandler: () => void, reportHandler: (p1: number, p2: NSError) => void): void;
testAddArgumentsWithParamsCompletionHandler(params: MTRTestClusterClusterTestAddArgumentsParams, completionHandler: (p1: MTRTestClusterClusterTestAddArgumentsResponseParams, p2: NSError) => void): void;
testComplexNullableOptionalRequestWithParamsCompletionHandler(params: MTRTestClusterClusterTestComplexNullableOptionalRequestParams, completionHandler: (p1: MTRTestClusterClusterTestComplexNullableOptionalResponseParams, p2: NSError) => void): void;
@@ -7975,6 +7981,10 @@ declare class MTRBaseClusterTestCluster extends MTRCluster {
writeAttributeVendorIdWithValueCompletionHandler(value: number, completionHandler: (p1: NSError) => void): void;
writeAttributeVendorIdWithValueParamsCompletionHandler(value: number, params: MTRWriteParams, completionHandler: (p1: NSError) => void): void;
writeAttributeWriteOnlyInt8uWithValueCompletionHandler(value: number, completionHandler: (p1: NSError) => void): void;
writeAttributeWriteOnlyInt8uWithValueParamsCompletionHandler(value: number, params: MTRWriteParams, completionHandler: (p1: NSError) => void): void;
}
declare class MTRBaseClusterThermostat extends MTRCluster {
@@ -9470,6 +9480,8 @@ declare class MTRBaseDevice extends NSObject {
invokeCommandWithEndpointIdClusterIdCommandIdCommandFieldsTimedInvokeTimeoutClientQueueCompletion(endpointId: number, clusterId: number, commandId: number, commandFields: any, timeoutMs: number, clientQueue: NSObject, completion: (p1: NSArray<NSDictionary<string, any>>, p2: NSError) => void): void;
openCommissioningWindowWithSetupPasscodeDiscriminatorDurationQueueCompletion(setupPasscode: number, discriminator: number, duration: number, queue: NSObject, completion: (p1: MTRSetupPayload, p2: NSError) => void): void;
readAttributeWithEndpointIdClusterIdAttributeIdParamsClientQueueCompletion(endpointId: number, clusterId: number, attributeId: number, params: MTRReadParams, clientQueue: NSObject, completion: (p1: NSArray<NSDictionary<string, any>>, p2: NSError) => void): void;
subscribeAttributeWithEndpointIdClusterIdAttributeIdMinIntervalMaxIntervalParamsClientQueueReportHandlerSubscriptionEstablished(endpointId: number, clusterId: number, attributeId: number, minInterval: number, maxInterval: number, params: MTRSubscribeParams, clientQueue: NSObject, reportHandler: (p1: NSArray<NSDictionary<string, any>>, p2: NSError) => void, subscriptionEstablishedHandler: () => void): void;
@@ -10154,6 +10166,8 @@ declare const enum MTRClusterAttributeIDType {
PulseWidthModulationAttributeClusterRevisionID = 65533,
DescriptorAttributeDeviceTypeListID = 0,
DescriptorAttributeDeviceListID = 0,
DescriptorAttributeServerListID = 1,
@@ -12228,6 +12242,8 @@ declare const enum MTRClusterAttributeIDType {
TestClusterAttributeNullableRangeRestrictedInt16sID = 16425,
TestClusterAttributeWriteOnlyInt8uID = 16426,
TestClusterAttributeGeneratedCommandListID = 65528,
TestClusterAttributeAcceptedCommandListID = 65529,
@@ -15945,6 +15961,8 @@ declare class MTRClusterTestCluster extends MTRCluster {
readAttributeVendorIdWithParams(params: MTRReadParams): NSDictionary<string, any>;
readAttributeWriteOnlyInt8uWithParams(params: MTRReadParams): NSDictionary<string, any>;
simpleStructEchoRequestWithParamsExpectedValuesExpectedValueIntervalCompletionHandler(params: MTRTestClusterClusterSimpleStructEchoRequestParams, expectedDataValueDictionaries: NSArray<NSDictionary<string, any>> | NSDictionary<string, any>[], expectedValueIntervalMs: number, completionHandler: (p1: MTRTestClusterClusterSimpleStructResponseParams, p2: NSError) => void): void;
testAddArgumentsWithParamsExpectedValuesExpectedValueIntervalCompletionHandler(params: MTRTestClusterClusterTestAddArgumentsParams, expectedDataValueDictionaries: NSArray<NSDictionary<string, any>> | NSDictionary<string, any>[], expectedValueIntervalMs: number, completionHandler: (p1: MTRTestClusterClusterTestAddArgumentsResponseParams, p2: NSError) => void): void;
@@ -16322,6 +16340,10 @@ declare class MTRClusterTestCluster extends MTRCluster {
writeAttributeVendorIdWithValueExpectedValueInterval(dataValueDictionary: NSDictionary<string, any>, expectedValueIntervalMs: number): void;
writeAttributeVendorIdWithValueExpectedValueIntervalParams(dataValueDictionary: NSDictionary<string, any>, expectedValueIntervalMs: number, params: MTRWriteParams): void;
writeAttributeWriteOnlyInt8uWithValueExpectedValueInterval(dataValueDictionary: NSDictionary<string, any>, expectedValueIntervalMs: number): void;
writeAttributeWriteOnlyInt8uWithValueExpectedValueIntervalParams(dataValueDictionary: NSDictionary<string, any>, expectedValueIntervalMs: number, params: MTRWriteParams): void;
}
declare class MTRClusterThermostat extends MTRCluster {
@@ -17805,6 +17827,19 @@ declare class MTRDescriptorClusterDeviceType extends NSObject implements NSCopyi
copyWithZone(zone: interop.Pointer | interop.Reference<any>): any;
}
declare class MTRDescriptorClusterDeviceTypeStruct extends NSObject implements NSCopying {
static alloc(): MTRDescriptorClusterDeviceTypeStruct; // inherited from NSObject
static new(): MTRDescriptorClusterDeviceTypeStruct; // inherited from NSObject
revision: number;
type: number;
copyWithZone(zone: interop.Pointer | interop.Reference<any>): any;
}
declare class MTRDevice extends NSObject {
static alloc(): MTRDevice; // inherited from NSObject
@@ -17817,6 +17852,8 @@ declare class MTRDevice extends NSObject {
invokeCommandWithEndpointIDClusterIDCommandIDCommandFieldsExpectedValuesExpectedValueIntervalTimedInvokeTimeoutClientQueueCompletion(endpointID: number, clusterID: number, commandID: number, commandFields: any, expectedValues: NSArray<NSDictionary<string, any>> | NSDictionary<string, any>[], expectedValueInterval: number, timeout: number, clientQueue: NSObject, completion: (p1: NSArray<NSDictionary<string, any>>, p2: NSError) => void): void;
openCommissioningWindowWithSetupPasscodeDiscriminatorDurationQueueCompletion(setupPasscode: number, discriminator: number, duration: number, queue: NSObject, completion: (p1: MTRSetupPayload, p2: NSError) => void): void;
readAttributeWithEndpointIDClusterIDAttributeIDParams(endpointID: number, clusterID: number, attributeID: number, params: MTRReadParams): NSDictionary<string, any>;
setDelegateQueue(delegate: MTRDeviceDelegate, queue: NSObject): void;
@@ -17898,6 +17935,8 @@ declare class MTRDeviceController extends NSObject {
setPairingDelegateQueue(delegate: MTRDevicePairingDelegate, queue: NSObject): void;
setupCommissioningSessionWithPayloadNewNodeIDError(payload: MTRSetupPayload, newNodeID: number): boolean;
shutdown(): void;
stopDevicePairingError(deviceID: number): boolean;
@@ -20875,6 +20914,13 @@ declare class MTRMediaPlaybackClusterStopPlaybackParams extends NSObject impleme
copyWithZone(zone: interop.Pointer | interop.Reference<any>): any;
}
declare const enum MTRMediaPlaybackFeature {
AdvancedSeek = 1,
VariableSpeed = 2
}
declare const enum MTRMediaPlaybackPlaybackState {
Playing = 0,
@@ -22729,8 +22775,12 @@ declare class MTRSetupPayload extends NSObject implements NSSecureCoding {
static generateRandomPIN(): number;
static generateRandomSetupPasscode(): number;
static new(): MTRSetupPayload; // inherited from NSObject
static setupPayloadWithOnboardingPayloadError(onboardingPayload: string): MTRSetupPayload;
commissioningFlow: MTRCommissioningFlow;
discriminator: number;
@@ -22753,13 +22803,19 @@ declare class MTRSetupPayload extends NSObject implements NSSecureCoding {
constructor(o: { coder: NSCoder; }); // inherited from NSCoding
constructor(o: { setupPasscode: number; discriminator: number; });
encodeWithCoder(coder: NSCoder): void;
getAllOptionalVendorData(): NSArray<MTROptionalQRCodeInfo>;
initWithCoder(coder: NSCoder): this;
initWithSetupPasscodeDiscriminator(setupPasscode: number, discriminator: number): this;
manualEntryCode(): string;
qrCodeString(): string;
}
declare var MTRSignedIntegerValueType: string;
@@ -22916,6 +22972,19 @@ declare class MTRSwitchClusterSwitchLatchedEvent extends NSObject implements NSC
copyWithZone(zone: interop.Pointer | interop.Reference<any>): any;
}
declare const enum MTRSwitchFeature {
LatchingSwitch = 1,
MomentarySwitch = 2,
MomentarySwitchRelease = 4,
MomentarySwitchLongPress = 8,
MomentarySwitchMultiPress = 16
}
declare class MTRTargetNavigatorClusterNavigateTargetParams extends NSObject implements NSCopying {
static alloc(): MTRTargetNavigatorClusterNavigateTargetParams; // inherited from NSObject

View File

@@ -481,6 +481,10 @@ declare class MPSGraph extends NSObject {
runWithMTLCommandQueueFeedsTargetTensorsTargetOperations(commandQueue: MTLCommandQueue, feeds: NSDictionary<MPSGraphTensor, MPSGraphTensorData>, targetTensors: NSArray<MPSGraphTensor> | MPSGraphTensor[], targetOperations: NSArray<MPSGraphOperation> | MPSGraphOperation[]): NSDictionary<MPSGraphTensor, MPSGraphTensorData>;
sampleGridWithSourceTensorCoordinateTensorLayoutNormalizeCoordinatesRelativeCoordinatesAlignCornersPaddingModeNearestRoundingModeConstantValueName(source: MPSGraphTensor, coordinates: MPSGraphTensor, layout: MPSGraphTensorNamedDataLayout, normalizeCoordinates: boolean, relativeCoordinates: boolean, alignCorners: boolean, paddingMode: MPSGraphPaddingMode, nearestRoundingMode: MPSGraphResizeNearestRoundingMode, constantValue: number, name: string): MPSGraphTensor;
sampleGridWithSourceTensorCoordinateTensorLayoutNormalizeCoordinatesRelativeCoordinatesAlignCornersPaddingModeSamplingModeConstantValueName(source: MPSGraphTensor, coordinates: MPSGraphTensor, layout: MPSGraphTensorNamedDataLayout, normalizeCoordinates: boolean, relativeCoordinates: boolean, alignCorners: boolean, paddingMode: MPSGraphPaddingMode, samplingMode: MPSGraphResizeMode, constantValue: number, name: string): MPSGraphTensor;
scatterAlongAxisTensorWithDataTensorUpdatesTensorIndicesTensorModeName(axisTensor: MPSGraphTensor, dataTensor: MPSGraphTensor, updatesTensor: MPSGraphTensor, indicesTensor: MPSGraphTensor, mode: MPSGraphScatterMode, name: string): MPSGraphTensor;
scatterAlongAxisTensorWithUpdatesTensorIndicesTensorShapeModeName(axisTensor: MPSGraphTensor, updatesTensor: MPSGraphTensor, indicesTensor: MPSGraphTensor, shape: NSArray<number> | number[], mode: MPSGraphScatterMode, name: string): MPSGraphTensor;

View File

@@ -11,7 +11,7 @@ declare class NativeScriptUtils extends NSObject {
static getImageDataFormatQuality(image: UIImage, format: string, quality: number): NSData;
static getSystemFontWeightItalicSymbolicTraits(size: number, weight: number, italic: boolean, symbolicTraits: number): UIFont;
static getSystemFontWeightItalicSymbolicTraits(size: number, weight: number, italic: boolean, symbolicTraits: UIFontDescriptorSymbolicTraits): UIFont;
static new(): NativeScriptUtils; // inherited from NSObject

View File

@@ -1,4 +0,0 @@
declare var Pods_iostypingsprjVersionNumber: number;
declare var Pods_iostypingsprjVersionString: interop.Reference<number>;

View File

@@ -57,6 +57,8 @@ declare class SRApplicationUsage extends NSObject {
readonly reportApplicationIdentifier: string;
readonly supplementalCategories: NSArray<SRSupplementalCategory>;
readonly textInputSessions: NSArray<SRTextInputSession>;
readonly usageTime: number;
@@ -315,6 +317,8 @@ declare class SRKeyboardMetrics extends NSObject {
readonly longWordTouchDownUp: NSArray<SRKeyboardProbabilityMetric<NSUnitDuration>>;
readonly longWordTouchUpDown: NSArray<SRKeyboardProbabilityMetric<NSUnitDuration>>;
readonly longWordUpErrorDistance: NSArray<SRKeyboardProbabilityMetric<NSUnitLength>>;
readonly pathErrorDistanceRatio: NSArray<number>;
@@ -407,6 +411,8 @@ declare class SRKeyboardMetrics extends NSObject {
readonly touchDownUp: SRKeyboardProbabilityMetric<NSUnitDuration>;
readonly touchUpDown: SRKeyboardProbabilityMetric<NSUnitDuration>;
readonly typingSpeed: number;
readonly upErrorDistance: SRKeyboardProbabilityMetric<NSUnitLength>;
@@ -625,6 +631,25 @@ declare var SRSensorTelephonySpeechMetrics: string;
declare var SRSensorVisits: string;
declare class SRSupplementalCategory extends NSObject implements NSCopying, NSSecureCoding {
static alloc(): SRSupplementalCategory; // inherited from NSObject
static new(): SRSupplementalCategory; // inherited from NSObject
readonly identifier: string;
static readonly supportsSecureCoding: boolean; // inherited from NSSecureCoding
constructor(o: { coder: NSCoder; }); // inherited from NSCoding
copyWithZone(zone: interop.Pointer | interop.Reference<any>): any;
encodeWithCoder(coder: NSCoder): void;
initWithCoder(coder: NSCoder): this;
}
declare class SRTextInputSession extends NSObject {
static alloc(): SRTextInputSession; // inherited from NSObject

View File

@@ -5835,7 +5835,9 @@ declare const enum UICalendarViewDecorationSize {
interface UICalendarViewDelegate extends NSObjectProtocol {
calendarViewDecorationForDateComponents(calendarView: UICalendarView, dateComponents: NSDateComponents): UICalendarViewDecoration;
calendarViewDecorationForDateComponents?(calendarView: UICalendarView, dateComponents: NSDateComponents): UICalendarViewDecoration;
calendarViewDidChangeVisibleDateComponentsFrom?(calendarView: UICalendarView, previousDateComponents: NSDateComponents): void;
}
declare var UICalendarViewDelegate: {
@@ -24087,7 +24089,7 @@ declare class UIView extends UIResponder implements CALayerDelegate, NSCoding, U
layoutSubviews(): void;
nativeScriptSetFormattedTextDecorationAndTransform(details: NSDictionary<any, any>): void;
nativeScriptSetFormattedTextDecorationAndTransformLetterSpacingLineHeight(details: NSDictionary<any, any>, letterSpacing: number, lineHeight: number): void;
nativeScriptSetTextDecorationAndTransformTextDecorationLetterSpacingLineHeight(text: string, textDecoration: string, letterSpacing: number, lineHeight: number): void;

View File

@@ -1,6 +1,6 @@
{
"name": "@nativescript/types-minimal",
"version": "8.4.0",
"version": "8.5.0",
"description": "NativeScript 'Minimal' Types for only the latest Android and iOS sdks.",
"homepage": "https://nativescript.org",
"repository": {

View File

@@ -5835,7 +5835,9 @@ declare const enum UICalendarViewDecorationSize {
interface UICalendarViewDelegate extends NSObjectProtocol {
calendarViewDecorationForDateComponents(calendarView: UICalendarView, dateComponents: NSDateComponents): UICalendarViewDecoration;
calendarViewDecorationForDateComponents?(calendarView: UICalendarView, dateComponents: NSDateComponents): UICalendarViewDecoration;
calendarViewDidChangeVisibleDateComponentsFrom?(calendarView: UICalendarView, previousDateComponents: NSDateComponents): void;
}
declare var UICalendarViewDelegate: {
@@ -24087,7 +24089,7 @@ declare class UIView extends UIResponder implements CALayerDelegate, NSCoding, U
layoutSubviews(): void;
nativeScriptSetFormattedTextDecorationAndTransform(details: NSDictionary<any, any>): void;
nativeScriptSetFormattedTextDecorationAndTransformLetterSpacingLineHeight(details: NSDictionary<any, any>, letterSpacing: number, lineHeight: number): void;
nativeScriptSetTextDecorationAndTransformTextDecorationLetterSpacingLineHeight(text: string, textDecoration: string, letterSpacing: number, lineHeight: number): void;

View File

@@ -1,6 +1,6 @@
{
"name": "@nativescript/types",
"version": "8.4.0",
"version": "8.5.0",
"description": "NativeScript Types for all supported platforms.",
"homepage": "https://nativescript.org",
"repository": {
@@ -12,7 +12,7 @@
],
"license": "Apache-2.0",
"dependencies": {
"@nativescript/types-ios": "~8.4.0",
"@nativescript/types-android": "~8.4.0"
"@nativescript/types-ios": "~8.5.0",
"@nativescript/types-android": "~8.5.0"
}
}

View File

@@ -22,6 +22,84 @@ describe('base configuration', () => {
});
}
it('supports tsconfig.app.json if exists', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('tsconfig.app.json');
},
() => {
init({
ios: true,
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.app.json');
expect(fsSpy).not.toHaveBeenCalledWith('__jest__/tsconfig.json');
let configFiles = [];
config.module
.rule('ts')
.use('ts-loader')
.tap((options) => {
configFiles.push(options.configFile);
return options;
});
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
configFiles.push(args.at(0).typescript.configFile);
return args;
});
expect(configFiles.length).toBe(2);
expect(configFiles).toEqual([
'__jest__/tsconfig.app.json', // ts-loader
'__jest__/tsconfig.app.json', // fork-ts-checker
]);
}
);
});
it('falls back to tsconfig.json if no tsconfig.app.json exists', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('tsconfig.json');
},
() => {
init({
ios: true,
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.app.json');
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.json');
let configFiles = [];
config.module
.rule('ts')
.use('ts-loader')
.tap((options) => {
configFiles.push(options.configFile);
return options;
});
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
configFiles.push(args.at(0).typescript.configFile);
return args;
});
expect(configFiles.length).toBe(2);
expect(configFiles).toEqual([
'__jest__/tsconfig.json', // ts-loader
'__jest__/tsconfig.json', // fork-ts-checker
]);
}
);
});
it('support env.watchNodeModules', () => {
init({
ios: true,
@@ -32,60 +110,73 @@ describe('base configuration', () => {
it('supports dotenv', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.mockReturnValue(true);
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('__jest__/.env');
},
() => {
init({
ios: true,
});
const config = base(new Config());
init({
ios: true,
});
const config = base(new Config());
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
}
);
fsSpy.mockRestore();
});
it('supports env specific dotenv', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.mockReturnValue(true);
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('__jest__/.env.prod');
},
() => {
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(fsSpy).toHaveBeenCalledTimes(1);
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env.prod');
return args;
});
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env.prod');
return args;
});
}
);
fsSpy.mockRestore();
});
it('falls back to default .env', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.mockReturnValueOnce(false).mockReturnValueOnce(true);
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('__jest__/.env');
},
() => {
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env');
expect(fsSpy).toHaveBeenCalledTimes(2);
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env');
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
}
);
fsSpy.mockRestore();
});

View File

@@ -1,6 +1,6 @@
{
"name": "@nativescript/webpack",
"version": "5.0.13",
"version": "5.0.14",
"private": false,
"main": "dist/index.js",
"files": [

View File

@@ -4,7 +4,7 @@ import { existsSync } from 'fs';
import { getTypescript, readTsConfig } from '../helpers/typescript';
import { getDependencyPath } from '../helpers/dependencies';
import { getProjectFilePath } from '../helpers/project';
import { getProjectTSConfigPath } from '../helpers/project';
import { env as _env, IWebpackEnv } from '../index';
import { warnOnce } from '../helpers/log';
import {
@@ -18,12 +18,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
base(config, env);
const platform = getPlatformName();
const tsConfigPath = [
getProjectFilePath('tsconfig.app.json'),
getProjectFilePath('tsconfig.json'),
].find((path) => existsSync(path));
const tsConfigPath = getProjectTSConfigPath();
const disableAOT = !!env.disableAOT;
// remove default ts rule

View File

@@ -15,7 +15,7 @@ import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
import { applyFileReplacements } from '../helpers/fileReplacements';
import { addCopyRule, applyCopyRules } from '../helpers/copyRules';
import { WatchStatePlugin } from '../plugins/WatchStatePlugin';
import { getProjectFilePath } from '../helpers/project';
import { getProjectFilePath, getProjectTSConfigPath } from '../helpers/project';
import { hasDependency } from '../helpers/dependencies';
import { applyDotEnvPlugin } from '../helpers/dotEnv';
import { env as _env, IWebpackEnv } from '../index';
@@ -234,6 +234,13 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
.use('nativescript-worker-loader')
.loader('nativescript-worker-loader');
const tsConfigPath = getProjectTSConfigPath();
const configFile = tsConfigPath
? {
configFile: tsConfigPath,
}
: undefined;
// set up ts support
config.module
.rule('ts')
@@ -243,7 +250,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
.options({
// todo: perhaps we can provide a default tsconfig
// and use that if the project doesn't have one?
// configFile: '',
...configFile,
transpileOnly: true,
allowTsInNodeModules: true,
compilerOptions: {
@@ -266,6 +273,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
async: !!env.watch,
typescript: {
memoryLimit: 4096,
...configFile,
},
},
]);

View File

@@ -1,3 +1,4 @@
import { existsSync } from 'fs';
import { resolve } from 'path';
export function getProjectRootPath(): string {
@@ -30,6 +31,13 @@ export function getProjectFilePath(filePath: string): string {
return resolve(getProjectRootPath(), filePath);
}
export function getProjectTSConfigPath(): string | undefined {
return [
getProjectFilePath('tsconfig.app.json'),
getProjectFilePath('tsconfig.json'),
].find((path) => existsSync(path));
}
// unused helper, but keeping it here as we may need it
// todo: remove if unused for next few releases
// function findFile(fileName, currentDir): string | null {

View File

@@ -49,10 +49,9 @@ export class WatchStatePlugin {
isWatchMode ? messages.startWatching : messages.compilationComplete
);
// Do not notify the CLI if the compilation failed
const stats = compilation.getStats();
if (stats.hasErrors()) {
return;
env.verbose && console.log(`[${id}] Warn: Compilation had errors!`);
}
// logic taken from CleanWebpackPlugin