mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Merge branch 'main' into farfromrefug-patch-2
This commit is contained in:
@@ -24,7 +24,22 @@
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier", "plugin:@nrwl/nx/typescript"],
|
||||
"rules": {}
|
||||
"rules": {
|
||||
"no-empty": "off",
|
||||
"no-useless-escape": "off",
|
||||
"no-inner-declarations": "off",
|
||||
"no-prototype-builtins": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-this-alias": "warn",
|
||||
"@typescript-eslint/no-namespace": "off",
|
||||
"@typescript-eslint/no-inferrable-types": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
|
||||
62
CHANGELOG.md
62
CHANGELOG.md
@@ -1,3 +1,65 @@
|
||||
## [8.4.6](https://github.com/NativeScript/NativeScript/compare/8.4.5-core...8.4.6-core) (2023-01-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** ScrollView event wiring sequencing improvement ([#10178](https://github.com/NativeScript/NativeScript/issues/10178)) ([75821ea](https://github.com/NativeScript/NativeScript/commit/75821ead07dc69ffeb82c6bd6d6992095ee4fed1))
|
||||
|
||||
|
||||
|
||||
## [8.4.5](https://github.com/NativeScript/NativeScript/compare/8.4.4-core...8.4.5-core) (2023-01-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** improve loaded/unloaded handling ([18b911e](https://github.com/NativeScript/NativeScript/commit/18b911ed84173928d1d0cfc91be605e046a7e3d1))
|
||||
* **core:** improve loaded/unloaded handling to be stable and consistent ([#10170](https://github.com/NativeScript/NativeScript/issues/10170)) ([c9e29aa](https://github.com/NativeScript/NativeScript/commit/c9e29aa9af8b4b82cd259f8402fa11af4640f1b4))
|
||||
* **ios:** embedder usage of window ([#10167](https://github.com/NativeScript/NativeScript/issues/10167)) ([a69a9d6](https://github.com/NativeScript/NativeScript/commit/a69a9d6921bd1df11b29c9b697bfb847a3885458))
|
||||
|
||||
|
||||
|
||||
## [8.4.4](https://github.com/NativeScript/NativeScript/compare/8.4.3-core...8.4.4-core) (2023-01-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **android:** openUrl ([#10161](https://github.com/NativeScript/NativeScript/issues/10161)) ([451c3cf](https://github.com/NativeScript/NativeScript/commit/451c3cfe43a90be705bb6cc7abb220e674d1d906))
|
||||
* **mac:** utils for mac catalyst ([#10157](https://github.com/NativeScript/NativeScript/issues/10157)) ([5b6e4d6](https://github.com/NativeScript/NativeScript/commit/5b6e4d68986f22219c41f434f2bf51e714e485a5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **core:** new autoFillTypes for newUsername, newPassword and oneTimeCode ([#10159](https://github.com/NativeScript/NativeScript/issues/10159)) ([bff35e5](https://github.com/NativeScript/NativeScript/commit/bff35e5163d126d44ae3b2828ed96dbdc6c2e6ef))
|
||||
|
||||
|
||||
|
||||
## [8.4.3](https://github.com/NativeScript/NativeScript/compare/8.4.2-core...8.4.3-core) (2023-01-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **android:** WebView url and event handling ([#10147](https://github.com/NativeScript/NativeScript/issues/10147)) ([#10148](https://github.com/NativeScript/NativeScript/issues/10148)) ([8444087](https://github.com/NativeScript/NativeScript/commit/84440876feb8a0b4bc5bc2309dc7a9315d1f91ef))
|
||||
* **ios:** prevent layout in viewSafeAreaInsetsDidChange until first viewDidLayoutSubviews ([#10151](https://github.com/NativeScript/NativeScript/issues/10151)) ([760bbd0](https://github.com/NativeScript/NativeScript/commit/760bbd06faf3acb7e0694acaf1ad3e029f1cd278))
|
||||
* **ios:** prevent transitionCoordinator usage during modal presentation ([#10153](https://github.com/NativeScript/NativeScript/issues/10153)) ([d138ac0](https://github.com/NativeScript/NativeScript/commit/d138ac000df2e2dfc890db992c39a4429e6ed8dc))
|
||||
* **ios:** TextField keyboard handling with emoji, autofill, and shortcuts ([#10154](https://github.com/NativeScript/NativeScript/issues/10154)) ([00944bb](https://github.com/NativeScript/NativeScript/commit/00944bb1b5b6f4cc8084cf7cde3db6448e28e0bd))
|
||||
|
||||
|
||||
|
||||
## [8.4.2](https://github.com/NativeScript/NativeScript/compare/8.4.1-core...8.4.2-core) (2022-12-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **android:** backwards compat Java cast Float to Long for ApplicationSettings.getNumber ([#10140](https://github.com/NativeScript/NativeScript/issues/10140)) ([7c1590a](https://github.com/NativeScript/NativeScript/commit/7c1590abff0127fd1e5254648cdd1d8c7ab49869))
|
||||
* **core:** update metadata filtering for IOS 16 ([#10133](https://github.com/NativeScript/NativeScript/issues/10133)) ([c461f1b](https://github.com/NativeScript/NativeScript/commit/c461f1bb551a69e721548fa5ae6ca2c7601d0b87))
|
||||
* **ios:** box shadow border radius ([#10142](https://github.com/NativeScript/NativeScript/issues/10142)) ([6948f7c](https://github.com/NativeScript/NativeScript/commit/6948f7c03265ebf9b92a7d5f69bfbb4743ce449b))
|
||||
* **ios:** navigatingTo event handling ([#10120](https://github.com/NativeScript/NativeScript/issues/10120)) ([a4f28b8](https://github.com/NativeScript/NativeScript/commit/a4f28b831785c8cf6ba76c170fcd7a5628b12c35))
|
||||
* **ios:** reset additional insets if they're zero ([#10134](https://github.com/NativeScript/NativeScript/issues/10134)) ([8b7d5ab](https://github.com/NativeScript/NativeScript/commit/8b7d5ab5fc34fa7785b7801ca5de60e69bbf7392))
|
||||
* **listview:** delegate handling removed from unloaded ([#10138](https://github.com/NativeScript/NativeScript/issues/10138)) ([04c3d9a](https://github.com/NativeScript/NativeScript/commit/04c3d9a9795898386f26656018bc05cf697d09e2))
|
||||
* **utils:** ios to filter out null values ([#10117](https://github.com/NativeScript/NativeScript/issues/10117)) ([4723114](https://github.com/NativeScript/NativeScript/commit/47231145acb851552d7990e5a75b66dd6d06fee8))
|
||||
|
||||
|
||||
|
||||
## [8.4.1](https://github.com/NativeScript/NativeScript/compare/8.4.0-core...8.4.1-core) (2022-11-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -32,6 +32,18 @@ function attachEventListeners(page: Page, events: Array<string>) {
|
||||
});
|
||||
}
|
||||
|
||||
function attachFrameEventListeners(frame: Frame, events: Array<string>) {
|
||||
let argsToString = (args: frame.NavigationData) => {
|
||||
return `${(<frame.BackstackEntry>args.entry).resolvedPage.id} ${args.eventName} ${args.isBack ? 'back' : 'forward'}`;
|
||||
};
|
||||
frame.on(Page.navigatingToEvent, (args: NavigatedData) => {
|
||||
events.push(argsToString(args));
|
||||
});
|
||||
frame.on(Page.navigatedToEvent, (args: NavigatedData) => {
|
||||
events.push(argsToString(args));
|
||||
});
|
||||
}
|
||||
|
||||
function _test_backstackVisible(transition?: NavigationTransition) {
|
||||
let topmost = Frame.topmost();
|
||||
let mainTestPage = topmost.currentPage;
|
||||
@@ -186,86 +198,86 @@ export function test_backToEntry_WithTransition() {
|
||||
_test_backToEntry({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
function _test_ClearHistory(transition?: NavigationTransition) {
|
||||
let topmost = Frame.topmost();
|
||||
// function _test_ClearHistory(transition?: NavigationTransition) {
|
||||
// let topmost = Frame.topmost();
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||
// TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
|
||||
// TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
|
||||
// helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
// TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
|
||||
// TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
|
||||
// helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
// TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
|
||||
// TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
|
||||
}
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||
// TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
|
||||
// TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
|
||||
// }
|
||||
|
||||
export function test_ClearHistory() {
|
||||
_test_ClearHistory();
|
||||
}
|
||||
// export function test_ClearHistory() {
|
||||
// _test_ClearHistory();
|
||||
// }
|
||||
|
||||
export function test_ClearHistory_WithTransition() {
|
||||
_test_ClearHistory({ name: 'fade', duration: 10 });
|
||||
}
|
||||
// export function test_ClearHistory_WithTransition() {
|
||||
// _test_ClearHistory({ name: 'fade', duration: 10 });
|
||||
// }
|
||||
|
||||
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
|
||||
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
|
||||
let topmost = Frame.topmost();
|
||||
let mainTestPage = new Page();
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
// export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
|
||||
// let topmost = Frame.topmost();
|
||||
// let mainTestPage = new Page();
|
||||
// let mainPageFactory = function (): Page {
|
||||
// return mainTestPage;
|
||||
// };
|
||||
|
||||
// Go to details-page
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||
// // Go to details-page
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||
|
||||
// Go back to main-page with clearHistory
|
||||
topmost.transition = { name: 'fade', duration: 10 };
|
||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
// // Go back to main-page with clearHistory
|
||||
// topmost.transition = { name: 'fade', duration: 10 };
|
||||
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
|
||||
// Go to details-page AGAIN
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||
// // Go to details-page AGAIN
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||
|
||||
// Go back to main-page with clearHistory
|
||||
topmost.transition = { name: 'fade', duration: 10 };
|
||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
// // Go back to main-page with clearHistory
|
||||
// topmost.transition = { name: 'fade', duration: 10 };
|
||||
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
|
||||
// Clean up
|
||||
topmost.transition = undefined;
|
||||
// // Clean up
|
||||
// topmost.transition = undefined;
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||
}
|
||||
// TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
// TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||
// }
|
||||
|
||||
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
|
||||
const topmost = Frame.topmost();
|
||||
// export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
|
||||
// const topmost = Frame.topmost();
|
||||
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
// let mainTestPage = topmost.currentPage;
|
||||
// let mainPageFactory = function (): Page {
|
||||
// return mainTestPage;
|
||||
// };
|
||||
|
||||
// Go to 1st page
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
// // Go to 1st page
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
// Go to 2nd page
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
// // Go to 2nd page
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
// Go to 3rd page with clearHistory
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
// // Go to 3rd page with clearHistory
|
||||
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
// Go back to main
|
||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
// // Go back to main
|
||||
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||
}
|
||||
// TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
// TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||
// }
|
||||
|
||||
function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
const topmost = Frame.topmost();
|
||||
@@ -274,7 +286,9 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
|
||||
mainTestPage.id = 'main-page';
|
||||
let actualMainPageEvents = new Array<string>();
|
||||
let actualMainFrameEvents = new Array<string>();
|
||||
attachEventListeners(mainTestPage, actualMainPageEvents);
|
||||
attachFrameEventListeners(topmost, actualMainFrameEvents);
|
||||
|
||||
let actualSecondPageEvents = new Array<string>();
|
||||
let secondPageFactory = function (): Page {
|
||||
@@ -298,6 +312,9 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
let expectedMainPageEvents = ['main-page navigatingFrom forward', 'main-page navigatedFrom forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
|
||||
TKUnit.arrayAssert(actualMainPageEvents, expectedMainPageEvents, 'Actual main-page events are different from expected.');
|
||||
|
||||
let expectedMainFrameEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
|
||||
TKUnit.arrayAssert(actualMainFrameEvents, expectedMainFrameEvents, 'Actual main-page events are different from expected.');
|
||||
|
||||
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom back', 'second-page navigatedFrom back'];
|
||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
|
||||
|
||||
|
||||
@@ -264,8 +264,8 @@ allTests['TRANSITIONS'] = transitionTests;
|
||||
import * as searchBarTests from './ui/search-bar/search-bar-tests';
|
||||
allTests['SEARCH-BAR'] = searchBarTests;
|
||||
|
||||
// import * as navigationTests from './navigation/navigation-tests';
|
||||
// allTests['NAVIGATION'] = navigationTests;
|
||||
import * as navigationTests from './navigation/navigation-tests';
|
||||
allTests['NAVIGATION'] = navigationTests;
|
||||
|
||||
// import * as livesyncTests from './livesync/livesync-tests';
|
||||
// allTests['LIVESYNC'] = livesyncTests;
|
||||
|
||||
@@ -34,4 +34,4 @@ Using a WebView requires the web-view module.
|
||||
|
||||
{%snippet web-view-loaded%}
|
||||
|
||||
>Note: to be able to use gestures in `WebView` component on Android, we should first disabled the zoom control. To do that we could access the `android` property and with the help of `setDisplayZoomControls` to set this controll to `false`.
|
||||
>Note: to be able to use gestures in `WebView` component on Android, we should first disabled the zoom control. To do that we could access the `android` property and with the help of `setDisplayZoomControls` to set this control to `false`.
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
<Button text="box-shadow" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="css-playground" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="datepicker" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="forms" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="image-async" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="image-handling" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="labels" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="list-page" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="root-layout" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="scroll-view" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="switch" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="touch-animations" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
<Button text="vector-image" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
|
||||
|
||||
16
apps/toolbox/src/pages/forms.ts
Normal file
16
apps/toolbox/src/pages/forms.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Page, Observable, EventData } from '@nativescript/core';
|
||||
|
||||
let page: Page;
|
||||
|
||||
export function navigatingTo(args: EventData) {
|
||||
page = <Page>args.object;
|
||||
page.bindingContext = new SampleData();
|
||||
}
|
||||
|
||||
export class SampleData extends Observable {
|
||||
textInput = '';
|
||||
textChange(args) {
|
||||
console.log(args.object.text);
|
||||
this.notifyPropertyChange('textInput', args.object.text);
|
||||
}
|
||||
}
|
||||
15
apps/toolbox/src/pages/forms.xml
Normal file
15
apps/toolbox/src/pages/forms.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
||||
<Page.actionBar>
|
||||
<ActionBar title="Labels and TextView" class="action-bar">
|
||||
</ActionBar>
|
||||
</Page.actionBar>
|
||||
<ScrollView>
|
||||
<StackLayout padding="20">
|
||||
<Label text="TextField:" fontWeight="bold" />
|
||||
<TextField textChange="{{ textChange }}" marginTop="6" backgroundColor="#efefef" padding="8" fontSize="18" keyboardType="url" />
|
||||
|
||||
<Label text="{{ textInput }}" marginTop="6" />
|
||||
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
26
apps/toolbox/src/pages/scroll-view.ts
Normal file
26
apps/toolbox/src/pages/scroll-view.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Observable, EventData, Page, ScrollEventData } from '@nativescript/core';
|
||||
|
||||
let page: Page;
|
||||
|
||||
export function navigatingTo(args: EventData) {
|
||||
page = <Page>args.object;
|
||||
page.bindingContext = new ScrollViewModel();
|
||||
}
|
||||
|
||||
export class ScrollViewModel extends Observable {
|
||||
longText = `The standard Lorem Ipsum passage, used since the 1500s
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||||
|
||||
Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC
|
||||
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"
|
||||
|
||||
1914 translation by H. Rackham
|
||||
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
|
||||
|
||||
Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC
|
||||
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."`;
|
||||
|
||||
scroll(args: ScrollEventData) {
|
||||
console.log('scroll:', args.scrollY);
|
||||
}
|
||||
}
|
||||
14
apps/toolbox/src/pages/scroll-view.xml
Normal file
14
apps/toolbox/src/pages/scroll-view.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
||||
<Page.actionBar>
|
||||
<ActionBar title="ScrollView" icon="" class="action-bar">
|
||||
</ActionBar>
|
||||
</Page.actionBar>
|
||||
|
||||
<ScrollView scroll="{{ scroll }}">
|
||||
<StackLayout>
|
||||
|
||||
<Label text="{{longText}}" textWrap="true" />
|
||||
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nativescript",
|
||||
"version": "8.4.1",
|
||||
"version": "8.4.6",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "git clean -f -X -d --exclude=!.idea/ --exclude=!.vscode/* --exclude=!.npmrc",
|
||||
@@ -44,6 +44,7 @@
|
||||
"css": "^3.0.0",
|
||||
"css-tree": "^1.1.2",
|
||||
"dotenv": "10.0.0",
|
||||
"emoji-regex": "^10.2.1",
|
||||
"eslint": "7.22.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"gonzales": "^1.0.7",
|
||||
|
||||
@@ -41,8 +41,20 @@ export function getString(key: string, defaultValue?: string): string {
|
||||
export function getNumber(key: string, defaultValue?: number): number {
|
||||
verify(key);
|
||||
if (hasKey(key)) {
|
||||
// SharedPreferences has no getter or setter for double so use long instead
|
||||
return java.lang.Double.longBitsToDouble(sharedPreferences.getLong(key, long(0)));
|
||||
let val;
|
||||
|
||||
// TODO: Remove this migration step in a future release
|
||||
try {
|
||||
val = sharedPreferences.getLong(key, long(0));
|
||||
} catch (err) {
|
||||
// If value is old, it might have been stored as a float so we store it anew as a long value to avoid errors
|
||||
const oldVal = sharedPreferences.getFloat(key, float(0.0));
|
||||
setNumber(key, oldVal);
|
||||
|
||||
val = sharedPreferences.getLong(key, long(0));
|
||||
}
|
||||
// SharedPreferences has no getter or setter for double so we retrieve value as a long and convert it to double
|
||||
return java.lang.Double.longBitsToDouble(val);
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
@@ -69,7 +81,7 @@ export function setNumber(key: string, value: number): void {
|
||||
verify(key);
|
||||
common.ensureValidValue(value, 'number');
|
||||
const editor = sharedPreferences.edit();
|
||||
// SharedPreferences has no getter or setter for double so use long instead
|
||||
// SharedPreferences has no getter or setter for double so we convert value and store it as a long
|
||||
editor.putLong(key, java.lang.Double.doubleToRawLongBits(double(value)));
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ export class iOSApplication implements iOSApplicationDefinition {
|
||||
|
||||
get rootController(): UIViewController {
|
||||
if (NativeScriptEmbedder.sharedInstance().delegate && !this._window) {
|
||||
this._window = UIApplication.sharedApplication.delegate.window;
|
||||
this._window = UIApplication.sharedApplication.keyWindow;
|
||||
}
|
||||
return this._window.rootViewController;
|
||||
}
|
||||
@@ -254,7 +254,7 @@ export class iOSApplication implements iOSApplicationDefinition {
|
||||
this.setWindowContent(args.root);
|
||||
}
|
||||
} else {
|
||||
this._window = UIApplication.sharedApplication.delegate.window;
|
||||
this._window = UIApplication.sharedApplication.keyWindow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ export namespace CoreTypes {
|
||||
};
|
||||
|
||||
export type KeyboardInputType = 'datetime' | 'phone' | 'number' | 'url' | 'email' | 'integer';
|
||||
export module KeyboardType {
|
||||
export namespace KeyboardType {
|
||||
export const datetime = 'datetime';
|
||||
export const phone = 'phone';
|
||||
export const number = 'number';
|
||||
@@ -47,14 +47,17 @@ export namespace CoreTypes {
|
||||
export const integer = 'integer';
|
||||
}
|
||||
export type AutofillType = 'username' | 'password' | 'none' | string;
|
||||
export module AutofillType {
|
||||
export namespace AutofillType {
|
||||
export const username = 'username';
|
||||
export const password = 'password';
|
||||
export const newUsername = 'newUsername';
|
||||
export const newPassword = 'newPassword';
|
||||
export const oneTimeCode = 'oneTimeCode';
|
||||
export const none = 'none';
|
||||
}
|
||||
|
||||
export type ReturnKeyButtonType = 'done' | 'next' | 'go' | 'search' | 'send';
|
||||
export module ReturnKeyType {
|
||||
export namespace ReturnKeyType {
|
||||
export const done = 'done';
|
||||
export const next = 'next';
|
||||
export const go = 'go';
|
||||
@@ -63,7 +66,7 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type TextAlignmentType = 'initial' | 'left' | 'center' | 'right' | 'justify';
|
||||
export module TextAlignment {
|
||||
export namespace TextAlignment {
|
||||
export const left = 'left';
|
||||
export const center = 'center';
|
||||
export const right = 'right';
|
||||
@@ -71,14 +74,14 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type TextDecorationType = 'none' | 'underline' | 'line-through' | 'underline line-through';
|
||||
export module TextDecoration {
|
||||
export namespace TextDecoration {
|
||||
export const none = 'none';
|
||||
export const underline = 'underline';
|
||||
export const lineThrough = 'line-through';
|
||||
}
|
||||
|
||||
export type TextTransformType = 'initial' | 'none' | 'capitalize' | 'uppercase' | 'lowercase';
|
||||
export module TextTransform {
|
||||
export namespace TextTransform {
|
||||
export const none = 'none';
|
||||
export const capitalize = 'capitalize';
|
||||
export const uppercase = 'uppercase';
|
||||
@@ -86,7 +89,7 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type WhiteSpaceType = 'initial' | 'normal' | 'nowrap';
|
||||
export module WhiteSpace {
|
||||
export namespace WhiteSpace {
|
||||
export const normal = 'normal';
|
||||
export const nowrap = 'nowrap';
|
||||
}
|
||||
@@ -94,20 +97,20 @@ export namespace CoreTypes {
|
||||
export type MaxLinesType = number;
|
||||
|
||||
export type OrientationType = 'horizontal' | 'vertical';
|
||||
export module Orientation {
|
||||
export namespace Orientation {
|
||||
export const horizontal = 'horizontal';
|
||||
export const vertical = 'vertical';
|
||||
}
|
||||
|
||||
export type DeviceOrientationType = 'portrait' | 'landscape' | 'unknown';
|
||||
export module DeviceOrientation {
|
||||
export namespace DeviceOrientation {
|
||||
export const portrait = 'portrait';
|
||||
export const landscape = 'landscape';
|
||||
export const unknown = 'unknown';
|
||||
}
|
||||
|
||||
export type HorizontalAlignmentType = 'left' | 'center' | 'right' | 'stretch';
|
||||
export module HorizontalAlignment {
|
||||
export namespace HorizontalAlignment {
|
||||
export const left = 'left';
|
||||
export const center = 'center';
|
||||
export const right = 'right';
|
||||
@@ -117,7 +120,7 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type VerticalAlignmentType = 'top' | 'middle' | 'bottom' | 'stretch';
|
||||
export module VerticalAlignment {
|
||||
export namespace VerticalAlignment {
|
||||
export const top = 'top';
|
||||
export const middle = 'middle';
|
||||
export const bottom = 'bottom';
|
||||
@@ -140,7 +143,7 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type ImageStretchType = 'none' | 'aspectFill' | 'aspectFit' | 'fill';
|
||||
export module ImageStretch {
|
||||
export namespace ImageStretch {
|
||||
export const none: ImageStretchType = 'none';
|
||||
export const aspectFill: ImageStretchType = 'aspectFill';
|
||||
export const aspectFit: ImageStretchType = 'aspectFit';
|
||||
@@ -148,7 +151,7 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type VisibilityType = 'visible' | 'hidden' | 'collapse' | 'collapsed';
|
||||
export module Visibility {
|
||||
export namespace Visibility {
|
||||
export const visible: VisibilityType = 'visible';
|
||||
export const collapse: VisibilityType = 'collapse';
|
||||
export const collapsed: VisibilityType = 'collapsed';
|
||||
@@ -158,30 +161,30 @@ export namespace CoreTypes {
|
||||
const parseStrict = makeParser<CoreTypes.VisibilityType>(isValid);
|
||||
}
|
||||
|
||||
export module FontAttributes {
|
||||
export namespace FontAttributes {
|
||||
export const Normal = 0;
|
||||
export const Bold = 1;
|
||||
export const Italic = 1 << 1;
|
||||
}
|
||||
|
||||
export module DeviceType {
|
||||
export namespace DeviceType {
|
||||
export const Phone: string = 'Phone';
|
||||
export const Tablet: string = 'Tablet';
|
||||
}
|
||||
|
||||
export type UpdateTextTriggerType = 'focusLost' | 'textChanged';
|
||||
export module UpdateTextTrigger {
|
||||
export namespace UpdateTextTrigger {
|
||||
export const focusLost: UpdateTextTriggerType = 'focusLost';
|
||||
export const textChanged: UpdateTextTriggerType = 'textChanged';
|
||||
}
|
||||
|
||||
export module Accuracy {
|
||||
export namespace Accuracy {
|
||||
export const any: number = 300;
|
||||
export const high: number = 3;
|
||||
}
|
||||
|
||||
export type DockType = 'left' | 'top' | 'right' | 'bottom';
|
||||
export module Dock {
|
||||
export namespace Dock {
|
||||
export const left: DockType = 'left';
|
||||
export const top: DockType = 'top';
|
||||
export const right: DockType = 'right';
|
||||
@@ -189,48 +192,48 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type AutocapitalizationInputType = 'none' | 'words' | 'sentences' | 'allcharacters';
|
||||
export module AutocapitalizationType {
|
||||
export namespace AutocapitalizationType {
|
||||
export const none: AutocapitalizationInputType = 'none';
|
||||
export const words: AutocapitalizationInputType = 'words';
|
||||
export const sentences: AutocapitalizationInputType = 'sentences';
|
||||
export const allCharacters: AutocapitalizationInputType = 'allcharacters';
|
||||
}
|
||||
|
||||
export module NavigationBarVisibility {
|
||||
export namespace NavigationBarVisibility {
|
||||
export const auto: string = 'auto';
|
||||
export const never: string = 'never';
|
||||
export const always: string = 'always';
|
||||
}
|
||||
|
||||
export module AndroidActionBarIconVisibility {
|
||||
export namespace AndroidActionBarIconVisibility {
|
||||
export const auto: string = 'auto';
|
||||
export const never: string = 'never';
|
||||
export const always: string = 'always';
|
||||
}
|
||||
|
||||
export module AndroidActionItemPosition {
|
||||
export namespace AndroidActionItemPosition {
|
||||
export const actionBar: string = 'actionBar';
|
||||
export const actionBarIfRoom: string = 'actionBarIfRoom';
|
||||
export const popup: string = 'popup';
|
||||
}
|
||||
|
||||
export module IOSActionItemPosition {
|
||||
export namespace IOSActionItemPosition {
|
||||
export const left: string = 'left';
|
||||
export const right: string = 'right';
|
||||
}
|
||||
|
||||
export module ImageFormat {
|
||||
export namespace ImageFormat {
|
||||
export const png: string = 'png';
|
||||
export const jpeg: string = 'jpeg';
|
||||
export const jpg: string = 'jpg';
|
||||
}
|
||||
|
||||
export module FontStyle {
|
||||
export namespace FontStyle {
|
||||
export const normal: string = 'normal';
|
||||
export const italic: string = 'italic';
|
||||
}
|
||||
|
||||
export module FontWeight {
|
||||
export namespace FontWeight {
|
||||
export const thin: string = '100';
|
||||
export const extraLight: string = '200';
|
||||
export const light: string = '300';
|
||||
@@ -243,7 +246,7 @@ export namespace CoreTypes {
|
||||
}
|
||||
|
||||
export type BackgroundRepeatType = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';
|
||||
export module BackgroundRepeat {
|
||||
export namespace BackgroundRepeat {
|
||||
export const repeat: BackgroundRepeatType = 'repeat';
|
||||
export const repeatX: BackgroundRepeatType = 'repeat-x';
|
||||
export const repeatY: BackgroundRepeatType = 'repeat-y';
|
||||
@@ -254,26 +257,26 @@ export namespace CoreTypes {
|
||||
|
||||
let animation: typeof animationModule;
|
||||
|
||||
export module AnimationCurve {
|
||||
export namespace AnimationCurve {
|
||||
export const ease = 'ease';
|
||||
export const easeIn = 'easeIn';
|
||||
export const easeOut = 'easeOut';
|
||||
export const easeInOut = 'easeInOut';
|
||||
export const linear = 'linear';
|
||||
export const spring = 'spring';
|
||||
export function cubicBezier(x1: number, y1: number, x2: number, y2: number): Object {
|
||||
export function cubicBezier(x1: number, y1: number, x2: number, y2: number) {
|
||||
animation = animation || require('../ui/animation');
|
||||
|
||||
return new animation.CubicBezierAnimationCurve(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
export module StatusBarStyle {
|
||||
export namespace StatusBarStyle {
|
||||
export const light = 'light';
|
||||
export const dark = 'dark';
|
||||
}
|
||||
|
||||
export module SystemAppearance {
|
||||
export namespace SystemAppearance {
|
||||
export const light = 'light';
|
||||
export const dark = 'dark';
|
||||
}
|
||||
|
||||
@@ -460,6 +460,7 @@ function parseArgumentsList<T>(text: string, start: number, argument: (value: st
|
||||
return { start, end, value };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
for (let index = 0; true; index++) {
|
||||
const arg = argument(text, end, index);
|
||||
if (!arg) {
|
||||
|
||||
@@ -95,7 +95,7 @@ export class ObservableArray<T> extends Observable {
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (let item of this._array) {
|
||||
for (const item of this._array) {
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,22 +291,24 @@ export class Observable implements ObservableDefinition {
|
||||
}
|
||||
for (let i = observers.length - 1; i >= 0; i--) {
|
||||
const entry = observers[i];
|
||||
if (entry.once) {
|
||||
observers.splice(i, 1);
|
||||
}
|
||||
if (entry) {
|
||||
if (entry.once) {
|
||||
observers.splice(i, 1);
|
||||
}
|
||||
|
||||
let returnValue;
|
||||
if (entry.thisArg) {
|
||||
returnValue = entry.callback.apply(entry.thisArg, [data]);
|
||||
} else {
|
||||
returnValue = entry.callback(data);
|
||||
}
|
||||
let returnValue;
|
||||
if (entry.thisArg) {
|
||||
returnValue = entry.callback.apply(entry.thisArg, [data]);
|
||||
} else {
|
||||
returnValue = entry.callback(data);
|
||||
}
|
||||
|
||||
// This ensures errors thrown inside asynchronous functions do not get swallowed
|
||||
if (returnValue && returnValue instanceof Promise) {
|
||||
returnValue.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
// This ensures errors thrown inside asynchronous functions do not get swallowed
|
||||
if (returnValue && returnValue instanceof Promise) {
|
||||
returnValue.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ export function initGlobal() {
|
||||
}
|
||||
}
|
||||
|
||||
declare var jest: any;
|
||||
declare const jest: any;
|
||||
function isTestingEnv() {
|
||||
return typeof jest !== 'undefined';
|
||||
}
|
||||
|
||||
3
packages/core/index.d.ts
vendored
3
packages/core/index.d.ts
vendored
@@ -105,7 +105,7 @@ export type { InstrumentationMode, TimerInfo } from './profiling';
|
||||
export { encoding } from './text';
|
||||
export * from './trace';
|
||||
export * from './ui';
|
||||
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, escapeRegexSymbols, convertString, dismissSoftInput, dismissKeyboard, queueMacrotask, queueGC, throttle, debounce, dataSerialize, dataDeserialize, copyToClipboard, getFileExtension } from './utils';
|
||||
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, escapeRegexSymbols, convertString, dismissSoftInput, dismissKeyboard, queueMacrotask, queueGC, throttle, debounce, dataSerialize, dataDeserialize, copyToClipboard, getFileExtension, isEmoji } from './utils';
|
||||
import { SDK_VERSION } from './utils/constants';
|
||||
import { ClassInfo, getClass, getBaseClasses, getClassInfo, isBoolean, isDefined, isFunction, isNullOrUndefined, isNumber, isObject, isString, isUndefined, toUIString, verifyCallback, numberHasDecimals, numberIs64Bit } from './utils/types';
|
||||
export declare const Utils: {
|
||||
@@ -163,5 +163,6 @@ export declare const Utils: {
|
||||
dismissSoftInput: typeof dismissSoftInput;
|
||||
dismissKeyboard: typeof dismissKeyboard;
|
||||
copyToClipboard: typeof copyToClipboard;
|
||||
isEmoji: typeof isEmoji;
|
||||
};
|
||||
export { XmlParser, ParserEventType, ParserEvent } from './xml';
|
||||
|
||||
@@ -137,7 +137,7 @@ export * from './trace';
|
||||
|
||||
export * from './ui';
|
||||
|
||||
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, queueMacrotask, queueGC, debounce, throttle, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, RESOURCE_PREFIX, FILE_PREFIX, escapeRegexSymbols, convertString, dismissSoftInput, dismissKeyboard, dataDeserialize, dataSerialize, copyToClipboard, getFileExtension } from './utils';
|
||||
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, queueMacrotask, queueGC, debounce, throttle, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, RESOURCE_PREFIX, FILE_PREFIX, escapeRegexSymbols, convertString, dismissSoftInput, dismissKeyboard, dataDeserialize, dataSerialize, copyToClipboard, getFileExtension, isEmoji } from './utils';
|
||||
import { SDK_VERSION } from './utils/constants';
|
||||
import { ClassInfo, getClass, getBaseClasses, getClassInfo, isBoolean, isDefined, isFunction, isNullOrUndefined, isNumber, isObject, isString, isUndefined, toUIString, verifyCallback, numberHasDecimals, numberIs64Bit } from './utils/types';
|
||||
|
||||
@@ -199,6 +199,7 @@ export const Utils = {
|
||||
dismissSoftInput,
|
||||
dismissKeyboard,
|
||||
copyToClipboard,
|
||||
isEmoji,
|
||||
};
|
||||
|
||||
export { XmlParser, ParserEventType, ParserEvent } from './xml';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nativescript/core",
|
||||
"version": "8.4.2",
|
||||
"version": "8.4.7",
|
||||
"description": "A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.",
|
||||
"main": "index",
|
||||
"types": "index.d.ts",
|
||||
@@ -47,6 +47,7 @@
|
||||
"@nativescript/hook": "~2.0.0",
|
||||
"acorn": "^8.7.0",
|
||||
"css-tree": "^1.1.2",
|
||||
"emoji-regex": "^10.2.1",
|
||||
"reduce-css-calc": "^2.1.7",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"CoreFoundation.CFError:*",
|
||||
"CoreFoundation.CFNumber:*",
|
||||
"CoreFoundation.CFRunLoop:*",
|
||||
|
||||
"CoreFoundation.CFCGTypes:",
|
||||
|
||||
"CoreGraphics.*:*",
|
||||
|
||||
"CoreText.CTFontManager:*",
|
||||
|
||||
@@ -49,8 +49,11 @@
|
||||
|
||||
BOOL actualItalic = result.fontDescriptor.symbolicTraits & UIFontDescriptorTraitItalic;
|
||||
if ([[font valueForKey:@"isItalic"] boolValue] && !actualItalic) {
|
||||
#if TARGET_OS_MACCATALYST
|
||||
#else
|
||||
// The font we got is not actually italic so emulate that with a matrix
|
||||
result = [UIFont fontWithDescriptor:[descriptor fontDescriptorWithMatrix:CGAffineTransformMake(1, 0, 0.2, 1, 0, 0)] size:size];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check if the resolved font has the correct font-family
|
||||
|
||||
@@ -22,13 +22,14 @@ export class ActionBarBase extends View implements ActionBarDefinition {
|
||||
public effectiveContentInsetLeft: number;
|
||||
public effectiveContentInsetRight: number;
|
||||
|
||||
get navigationButton(): NavigationButton {
|
||||
return this._navigationButton;
|
||||
}
|
||||
disposeNativeView() {
|
||||
this._actionItems = null;
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
get navigationButton(): NavigationButton {
|
||||
return this._navigationButton;
|
||||
}
|
||||
set navigationButton(value: NavigationButton) {
|
||||
if (this._navigationButton !== value) {
|
||||
if (this._navigationButton) {
|
||||
|
||||
@@ -177,7 +177,9 @@ export class ActionBar extends ActionBarBase {
|
||||
}
|
||||
|
||||
public disposeNativeView() {
|
||||
(<any>this.nativeViewProtected).menuItemClickListener.owner = null;
|
||||
if ((<any>this.nativeViewProtected)?.menuItemClickListener) {
|
||||
(<any>this.nativeViewProtected).menuItemClickListener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ export class Button extends ButtonBase {
|
||||
}
|
||||
|
||||
public disposeNativeView() {
|
||||
if (this.nativeViewProtected) {
|
||||
if ((<any>this.nativeViewProtected)?.clickListener) {
|
||||
(<any>this.nativeViewProtected).clickListener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
|
||||
@@ -21,9 +21,8 @@ export class Button extends ButtonBase {
|
||||
|
||||
public initNativeView(): void {
|
||||
super.initNativeView();
|
||||
const nativeView = this.nativeViewProtected;
|
||||
this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this));
|
||||
nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
|
||||
this.nativeViewProtected.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
|
||||
}
|
||||
|
||||
public disposeNativeView(): void {
|
||||
|
||||
@@ -51,8 +51,8 @@ const logicalOperators = {
|
||||
const expressionParsers = {
|
||||
'ArrayExpression': (expression: ASTExpression, model, isBackConvert: boolean, changedModel) => {
|
||||
const parsed = [];
|
||||
for (let element of expression.elements) {
|
||||
let value = convertExpressionToValue(element, model, isBackConvert, changedModel);
|
||||
for (const element of expression.elements) {
|
||||
const value = convertExpressionToValue(element, model, isBackConvert, changedModel);
|
||||
element.type == 'SpreadElement' ? parsed.push(...value) : parsed.push(value);
|
||||
}
|
||||
return parsed;
|
||||
@@ -116,8 +116,8 @@ const expressionParsers = {
|
||||
}
|
||||
|
||||
const parsedArgs = [];
|
||||
for (let argument of expression.arguments) {
|
||||
let value = convertExpressionToValue(argument, model, isBackConvert, changedModel);
|
||||
for (const argument of expression.arguments) {
|
||||
const value = convertExpressionToValue(argument, model, isBackConvert, changedModel);
|
||||
argument.type == 'SpreadElement' ? parsedArgs.push(...value) : parsedArgs.push(value);
|
||||
}
|
||||
return expression.optional ? callback?.(...parsedArgs) : callback(...parsedArgs);
|
||||
@@ -181,8 +181,8 @@ const expressionParsers = {
|
||||
'NewExpression': (expression: ASTExpression, model, isBackConvert: boolean, changedModel) => {
|
||||
const callback = convertExpressionToValue(expression.callee, model, isBackConvert, changedModel);
|
||||
const parsedArgs = [];
|
||||
for (let argument of expression.arguments) {
|
||||
let value = convertExpressionToValue(argument, model, isBackConvert, changedModel);
|
||||
for (const argument of expression.arguments) {
|
||||
const value = convertExpressionToValue(argument, model, isBackConvert, changedModel);
|
||||
argument.type == 'SpreadElement' ? parsedArgs.push(...value) : parsedArgs.push(value);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ const expressionParsers = {
|
||||
},
|
||||
'ObjectExpression': (expression: ASTExpression, model, isBackConvert: boolean, changedModel) => {
|
||||
const parsedObject = {};
|
||||
for (let property of expression.properties) {
|
||||
for (const property of expression.properties) {
|
||||
const value = convertExpressionToValue(property, model, isBackConvert, changedModel);
|
||||
Object.assign(parsedObject, value);
|
||||
}
|
||||
@@ -217,7 +217,7 @@ const expressionParsers = {
|
||||
const length = expression.quasis.length;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
let q = expression.quasis[i];
|
||||
const q = expression.quasis[i];
|
||||
parsedText += convertExpressionToValue(q, model, isBackConvert, changedModel);
|
||||
if (!q.tail) {
|
||||
parsedText += convertExpressionToValue(expression.expressions[i], model, isBackConvert, changedModel);
|
||||
@@ -262,7 +262,7 @@ export function parseExpression(expressionText: string): ASTExpression {
|
||||
if (expression == null) {
|
||||
const program: any = parse(expressionText, { ecmaVersion: 2020 });
|
||||
const statements = program.body;
|
||||
for (let statement of statements) {
|
||||
for (const statement of statements) {
|
||||
if (statement.type == 'ExpressionStatement') {
|
||||
expression = statement.expression;
|
||||
break;
|
||||
|
||||
@@ -415,7 +415,7 @@ export class Binding {
|
||||
}
|
||||
|
||||
// Clear added props
|
||||
for (let prop of addedProps) {
|
||||
for (const prop of addedProps) {
|
||||
delete context[prop];
|
||||
}
|
||||
addedProps.length = 0;
|
||||
|
||||
@@ -430,14 +430,6 @@ export class View extends ViewCommon {
|
||||
|
||||
@profile
|
||||
public onUnloaded() {
|
||||
if (this.touchListenerIsSet) {
|
||||
this.touchListenerIsSet = false;
|
||||
if (this.nativeViewProtected) {
|
||||
this.nativeViewProtected.setOnTouchListener(null);
|
||||
this.nativeViewProtected.setClickable(this._isClickable);
|
||||
}
|
||||
}
|
||||
|
||||
this._manager = null;
|
||||
this._rootManager = null;
|
||||
super.onUnloaded();
|
||||
@@ -474,7 +466,6 @@ export class View extends ViewCommon {
|
||||
public initNativeView(): void {
|
||||
super.initNativeView();
|
||||
this._isClickable = this.nativeViewProtected.isClickable();
|
||||
|
||||
if (this.needsOnLayoutChangeListener()) {
|
||||
this.setOnLayoutChangeListener();
|
||||
}
|
||||
@@ -485,16 +476,24 @@ export class View extends ViewCommon {
|
||||
}
|
||||
|
||||
public disposeNativeView(): void {
|
||||
super.disposeNativeView();
|
||||
|
||||
if (this.touchListenerIsSet) {
|
||||
this.touchListenerIsSet = false;
|
||||
if (this.nativeViewProtected) {
|
||||
this.nativeViewProtected.setOnTouchListener(null);
|
||||
}
|
||||
}
|
||||
if (this.layoutChangeListenerIsSet) {
|
||||
this.layoutChangeListenerIsSet = false;
|
||||
this.nativeViewProtected.removeOnLayoutChangeListener(this.layoutChangeListener);
|
||||
if (this.nativeViewProtected) {
|
||||
this.nativeViewProtected.removeOnLayoutChangeListener(this.layoutChangeListener);
|
||||
this.layoutChangeListener = null;
|
||||
}
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
setOnTouchListener() {
|
||||
if (!this.nativeViewProtected || !this.hasGestureObservers()) {
|
||||
if (this.touchListenerIsSet || !this.nativeViewProtected || !this.hasGestureObservers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -479,12 +479,14 @@ export class View extends ViewCommon implements ViewDefinition {
|
||||
} else {
|
||||
//use CSS & attribute width & height if option is not provided
|
||||
const handler = () => {
|
||||
const w = <number>(this.width || this.style.width);
|
||||
const h = <number>(this.height || this.style.height);
|
||||
if (this.viewController) {
|
||||
const w = <number>(this.width || this.style.width);
|
||||
const h = <number>(this.height || this.style.height);
|
||||
|
||||
//TODO: only numeric value is supported, percentage value is not supported like Android
|
||||
if (w > 0 && h > 0) {
|
||||
controller.preferredContentSize = CGSizeMake(w, h);
|
||||
//TODO: only numeric value is supported, percentage value is not supported like Android
|
||||
if (w > 0 && h > 0) {
|
||||
this.viewController.preferredContentSize = CGSizeMake(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
this.off(View.loadedEvent, handler);
|
||||
|
||||
@@ -80,6 +80,8 @@ class UILayoutViewController extends UIViewController {
|
||||
right: 0,
|
||||
});
|
||||
this.additionalSafeAreaInsets = additionalInsets;
|
||||
} else {
|
||||
this.additionalSafeAreaInsets = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,9 @@ export class DatePicker extends DatePickerBase {
|
||||
if (this.timePicker) {
|
||||
this.timePicker.disposeNativeView();
|
||||
}
|
||||
(<any>this.nativeViewProtected).listener.owner = null;
|
||||
if ((<any>this.nativeViewProtected)?.listener) {
|
||||
(<any>this.nativeViewProtected).listener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
newInputType = android.text.InputType.TYPE_CLASS_NUMBER;
|
||||
break;
|
||||
|
||||
default:
|
||||
default: {
|
||||
const inputType = +value;
|
||||
if (!isNaN(inputType)) {
|
||||
newInputType = inputType;
|
||||
@@ -237,6 +237,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
newInputType = android.text.InputType.TYPE_CLASS_TEXT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._setInputType(newInputType);
|
||||
@@ -269,6 +270,15 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
case 'password':
|
||||
newOptions = 'password'; // android.view.View.AUTOFILL_HINT_PASSWORD
|
||||
break;
|
||||
case 'newPassword':
|
||||
newOptions = 'newPassword'; // android.view.View.AUTOFILL_HINT_NEW_PASSWORD
|
||||
break;
|
||||
case 'newUsername':
|
||||
newOptions = 'newUsername'; // android.view.View.AUTOFILL_HINT_NEW_USERNAME
|
||||
break;
|
||||
case 'oneTimeCode':
|
||||
newOptions = '2faAppOTPCode'; // android.view.View.AUTOFILL_HINT_2FA_APP_OTP
|
||||
break;
|
||||
case 'none':
|
||||
newOptions = null;
|
||||
break;
|
||||
|
||||
@@ -60,7 +60,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
newKeyboardType = UIKeyboardType.NumberPad;
|
||||
break;
|
||||
|
||||
default:
|
||||
default: {
|
||||
const kt = +value;
|
||||
if (!isNaN(kt)) {
|
||||
newKeyboardType = <UIKeyboardType>kt;
|
||||
@@ -68,6 +68,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
newKeyboardType = UIKeyboardType.Default;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.nativeTextViewProtected.keyboardType = newKeyboardType;
|
||||
@@ -96,11 +97,19 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
case 'password':
|
||||
newTextContentType = UITextContentTypePassword;
|
||||
break;
|
||||
case 'newPassword':
|
||||
newTextContentType = UITextContentTypeNewPassword;
|
||||
break;
|
||||
case 'oneTimeCode':
|
||||
newTextContentType = UITextContentTypeOneTimeCode;
|
||||
break;
|
||||
case 'none':
|
||||
newTextContentType = null;
|
||||
default:
|
||||
break;
|
||||
default: {
|
||||
newTextContentType = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.nativeTextViewProtected.textContentType = newTextContentType;
|
||||
@@ -146,7 +155,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
case 'send':
|
||||
newValue = UIReturnKeyType.Send;
|
||||
break;
|
||||
default:
|
||||
default: {
|
||||
const rkt = +value;
|
||||
if (!isNaN(rkt)) {
|
||||
newValue = <UIKeyboardType>rkt;
|
||||
@@ -154,6 +163,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
newValue = UIKeyboardType.Default;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.nativeTextViewProtected.returnKeyType = newValue;
|
||||
|
||||
@@ -439,7 +439,7 @@ export class Frame extends FrameBase {
|
||||
const newFragmentTag = `fragment${fragmentId}[${navDepth}]`;
|
||||
const newFragment = this.createFragment(newEntry, newFragmentTag);
|
||||
const transaction = manager.beginTransaction();
|
||||
let animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false;
|
||||
const animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false;
|
||||
// NOTE: Don't use transition for the initial navigation (same as on iOS)
|
||||
// On API 21+ transition won't be triggered unless there was at least one
|
||||
// layout pass so we will wait forever for transitionCompleted handler...
|
||||
|
||||
@@ -84,7 +84,7 @@ export class Frame extends FrameBase {
|
||||
}
|
||||
|
||||
let navigationTransition: NavigationTransition;
|
||||
let animated = this.currentPage ? this._getIsAnimatedNavigation(backstackEntry.entry) : false;
|
||||
const animated = this.currentPage ? this._getIsAnimatedNavigation(backstackEntry.entry) : false;
|
||||
if (animated) {
|
||||
navigationTransition = this._getNavigationTransition(backstackEntry.entry);
|
||||
if (navigationTransition) {
|
||||
@@ -118,7 +118,9 @@ export class Frame extends FrameBase {
|
||||
if (!this._currentEntry) {
|
||||
// Update action-bar with disabled animations before the initial navigation.
|
||||
this._updateActionBar(backstackEntry.resolvedPage, true);
|
||||
this.pushViewControllerAnimated(viewController, animated);
|
||||
// Core defaults modalPresentationStyle to 1 for standard frame navigation
|
||||
// for all others, it's modal presentation
|
||||
this.pushViewControllerAnimated(viewController, animated, this._ios?.controller?.modalPresentationStyle !== 1);
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write(`${this}.pushViewControllerAnimated(${viewController}, ${animated}); depth = ${navDepth}`, Trace.categories.Navigation);
|
||||
}
|
||||
@@ -180,13 +182,14 @@ export class Frame extends FrameBase {
|
||||
}
|
||||
}
|
||||
|
||||
private pushViewControllerAnimated(viewController: UIViewController, animated: boolean) {
|
||||
let transitionCoordinator = this._ios.controller.transitionCoordinator;
|
||||
if (transitionCoordinator) {
|
||||
private pushViewControllerAnimated(viewController: UIViewController, animated: boolean, isModal: boolean) {
|
||||
const transitionCoordinator = this._ios.controller.transitionCoordinator;
|
||||
if (!isModal && transitionCoordinator) {
|
||||
transitionCoordinator.animateAlongsideTransitionCompletion(null, () => {
|
||||
this._ios.controller.pushViewControllerAnimated(viewController, animated);
|
||||
});
|
||||
} else {
|
||||
// modal should always push immediately without transition coordinator
|
||||
this._ios.controller.pushViewControllerAnimated(viewController, animated);
|
||||
}
|
||||
}
|
||||
@@ -307,7 +310,16 @@ export class Frame extends FrameBase {
|
||||
}
|
||||
|
||||
public _onNavigatingTo(backstackEntry: BackstackEntry, isBack: boolean) {
|
||||
super._onNavigatingTo(backstackEntry, isBack);
|
||||
// for now to not break iOS events chain (calling navigation events from controller delegates)
|
||||
// we dont call super(which would also trigger events) but only notify the frame of the navigation
|
||||
// though it means events are not triggered at the same time (lifecycle) on iOS / Android
|
||||
this.notify({
|
||||
eventName: Page.navigatingToEvent,
|
||||
object: this,
|
||||
isBack,
|
||||
entry: backstackEntry,
|
||||
fromEntry: this._currentEntry,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ export class Image extends ImageBase {
|
||||
}
|
||||
|
||||
public disposeNativeView() {
|
||||
(<any>this.nativeViewProtected).listener.owner = null;
|
||||
if ((<any>this.nativeViewProtected)?.listener) {
|
||||
(<any>this.nativeViewProtected).listener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,13 +39,12 @@ export class Image extends ImageBase {
|
||||
}
|
||||
|
||||
public disposeNativeView(): void {
|
||||
super.disposeNativeView();
|
||||
|
||||
if (this.nativeViewProtected?.image) {
|
||||
this.nativeViewProtected.image = null;
|
||||
}
|
||||
|
||||
this.disposeImageSource();
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
private setTintColor(value: Color) {
|
||||
|
||||
@@ -78,15 +78,15 @@ export class ItemSpec extends Observable implements ItemSpecDefinition {
|
||||
private _value: number;
|
||||
private _unitType: GridUnitType;
|
||||
|
||||
constructor() {
|
||||
constructor(...args) {
|
||||
super();
|
||||
|
||||
if (arguments.length === 0) {
|
||||
if (args.length === 0) {
|
||||
this._value = 1;
|
||||
this._unitType = GridUnitType.STAR;
|
||||
} else if (arguments.length === 2) {
|
||||
const value = arguments[0];
|
||||
const type = arguments[1];
|
||||
const value = args[0];
|
||||
const type = args[1];
|
||||
if (typeof value === 'number' && typeof type === 'string') {
|
||||
if (value < 0 || isNaN(value) || !isFinite(value)) {
|
||||
throw new Error(`Value should not be negative, NaN or Infinity: ${value}`);
|
||||
@@ -381,9 +381,9 @@ rowSpanProperty.register(View);
|
||||
|
||||
export type GridUnitType = 'pixel' | 'star' | 'auto';
|
||||
export namespace GridUnitType {
|
||||
export const PIXEL: 'pixel' = 'pixel';
|
||||
export const STAR: 'star' = 'star';
|
||||
export const AUTO: 'auto' = 'auto';
|
||||
export const PIXEL = 'pixel';
|
||||
export const STAR = 'star';
|
||||
export const AUTO = 'auto';
|
||||
export const isValid = makeValidator<GridUnitType>(PIXEL, STAR, AUTO);
|
||||
export const parse = makeParser<GridUnitType>(isValid);
|
||||
}
|
||||
|
||||
@@ -16,17 +16,19 @@ export class RootLayout extends RootLayoutBase {
|
||||
super.insertChild(view, atIndex);
|
||||
if (!view.hasGestureObservers()) {
|
||||
// block tap events from going through to layers behind the view
|
||||
view.nativeViewProtected.setOnTouchListener(
|
||||
new android.view.View.OnTouchListener({
|
||||
onTouch: function (view, event) {
|
||||
return true;
|
||||
},
|
||||
})
|
||||
);
|
||||
if (view.nativeViewProtected) {
|
||||
view.nativeViewProtected.setOnTouchListener(
|
||||
new android.view.View.OnTouchListener({
|
||||
onTouch: function (view, event) {
|
||||
return true;
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
removeChild(view: View): void {
|
||||
if (view.hasGestureObservers()) {
|
||||
if (view.hasGestureObservers() && view.nativeViewProtected) {
|
||||
view.nativeViewProtected.setOnTouchListener(null);
|
||||
}
|
||||
super.removeChild(view);
|
||||
@@ -109,7 +111,7 @@ export class RootLayout extends RootLayoutBase {
|
||||
backgroundColorAnimator.addUpdateListener(
|
||||
new android.animation.ValueAnimator.AnimatorUpdateListener({
|
||||
onAnimationUpdate(animator: android.animation.ValueAnimator) {
|
||||
let argb = (<java.lang.Integer>animator.getAnimatedValue()).intValue();
|
||||
const argb = (<java.lang.Integer>animator.getAnimatedValue()).intValue();
|
||||
view.backgroundColor = new Color(argb);
|
||||
},
|
||||
})
|
||||
|
||||
@@ -131,8 +131,12 @@ export class ListPicker extends ListPickerBase {
|
||||
|
||||
public disposeNativeView() {
|
||||
const nativeView = this.nativeViewProtected;
|
||||
(<any>nativeView).formatter.owner = null;
|
||||
(<any>nativeView).valueChangedListener.owner = null;
|
||||
if ((<any>nativeView)?.formatter) {
|
||||
(<any>nativeView).formatter.owner = null;
|
||||
}
|
||||
if ((<any>nativeView)?.valueChangedListener) {
|
||||
(<any>nativeView).valueChangedListener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ export class ListPicker extends ListPickerBase {
|
||||
|
||||
initNativeView() {
|
||||
super.initNativeView();
|
||||
const nativeView = this.nativeViewProtected;
|
||||
nativeView.dataSource = this._dataSource = ListPickerDataSource.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.dataSource = this._dataSource = ListPickerDataSource.initWithOwner(new WeakRef(this));
|
||||
this._delegate = ListPickerDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
}
|
||||
|
||||
public disposeNativeView() {
|
||||
@@ -33,17 +33,6 @@ export class ListPicker extends ListPickerBase {
|
||||
return this.nativeViewProtected;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this.ios.delegate = this._delegate;
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this.ios.delegate = null;
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
[selectedIndexProperty.getDefault](): number {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -153,8 +153,12 @@ export class ListView extends ListViewBase {
|
||||
public disposeNativeView() {
|
||||
const nativeView = this.nativeViewProtected;
|
||||
nativeView.setAdapter(null);
|
||||
(<any>nativeView).itemClickListener.owner = null;
|
||||
(<any>nativeView).adapter.owner = null;
|
||||
if ((<any>nativeView).itemClickListener) {
|
||||
(<any>nativeView).itemClickListener.owner = null;
|
||||
}
|
||||
if ((<any>nativeView).adapter) {
|
||||
(<any>nativeView).adapter.owner = null;
|
||||
}
|
||||
this.clearRealizedCells();
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
@@ -287,11 +287,6 @@ export class ListView extends ListViewBase {
|
||||
this.ios.delegate = this._delegate;
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this.ios.delegate = null;
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
get ios(): UITableView {
|
||||
return this.nativeViewProtected;
|
||||
|
||||
@@ -74,6 +74,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() {
|
||||
@@ -84,6 +85,7 @@ class UIViewControllerImpl extends UIViewController {
|
||||
}
|
||||
private finishRunningLayout() {
|
||||
this._isRunningLayout--;
|
||||
this.didFirstLayout = true;
|
||||
}
|
||||
private runLayout(cb: () => void) {
|
||||
try {
|
||||
@@ -98,6 +100,7 @@ class UIViewControllerImpl extends UIViewController {
|
||||
const controller = <UIViewControllerImpl>UIViewControllerImpl.new();
|
||||
controller._owner = owner;
|
||||
controller._isRunningLayout = 0;
|
||||
controller.didFirstLayout = false;
|
||||
|
||||
return controller;
|
||||
}
|
||||
@@ -118,6 +121,13 @@ class UIViewControllerImpl extends UIViewController {
|
||||
}
|
||||
|
||||
const frame = this.navigationController ? (<any>this.navigationController).owner : null;
|
||||
const newEntry = this[ENTRY];
|
||||
|
||||
// Don't raise event if currentPage was showing modal page.
|
||||
if (!owner._presentedViewController && newEntry && (!frame || frame.currentPage !== owner)) {
|
||||
const isBack = isBackNavigationTo(owner, newEntry);
|
||||
owner.onNavigatingTo(newEntry.entry.context, isBack, newEntry.entry.bindingContext);
|
||||
}
|
||||
|
||||
if (frame) {
|
||||
if (!owner.parent) {
|
||||
@@ -269,7 +279,7 @@ class UIViewControllerImpl extends UIViewController {
|
||||
|
||||
public viewSafeAreaInsetsDidChange(): void {
|
||||
super.viewSafeAreaInsetsDidChange();
|
||||
if (this.isRunningLayout) {
|
||||
if (this.isRunningLayout || !this.didFirstLayout) {
|
||||
return;
|
||||
}
|
||||
const owner = this._owner?.deref();
|
||||
@@ -325,6 +335,8 @@ class UIViewControllerImpl extends UIViewController {
|
||||
right: 0,
|
||||
});
|
||||
this.additionalSafeAreaInsets = additionalInsets;
|
||||
} else {
|
||||
this.additionalSafeAreaInsets = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,31 +129,17 @@ export class ScrollView extends ScrollViewBase {
|
||||
}
|
||||
|
||||
protected attachNative() {
|
||||
const that = new WeakRef(this);
|
||||
if (this.orientation === 'vertical') {
|
||||
this.scrollChangeHandler = new androidx.core.widget.NestedScrollView.OnScrollChangeListener({
|
||||
onScrollChange(view, scrollX, scrollY) {
|
||||
const owner: ScrollView = that?.get();
|
||||
if (owner) {
|
||||
owner.notify({
|
||||
object: owner,
|
||||
eventName: ScrollView.scrollEvent,
|
||||
scrollX: layout.toDeviceIndependentPixels(scrollX),
|
||||
scrollY: layout.toDeviceIndependentPixels(scrollY),
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
this.nativeView.setOnScrollChangeListener(this.scrollChangeHandler);
|
||||
} else {
|
||||
if (!this.handler) {
|
||||
const that = new WeakRef(this);
|
||||
this.handler = new android.view.ViewTreeObserver.OnScrollChangedListener({
|
||||
onScrollChanged: function () {
|
||||
const owner: ScrollView = that?.get();
|
||||
const owner: ScrollView = that.get();
|
||||
if (owner) {
|
||||
owner._onScrollChanged();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
this.nativeViewProtected.getViewTreeObserver().addOnScrollChangedListener(this.handler);
|
||||
}
|
||||
}
|
||||
@@ -181,14 +167,8 @@ export class ScrollView extends ScrollViewBase {
|
||||
}
|
||||
|
||||
protected dettachNative() {
|
||||
if (this.handler) {
|
||||
this.nativeViewProtected?.getViewTreeObserver().removeOnScrollChangedListener(this.handler);
|
||||
this.handler = null;
|
||||
}
|
||||
if (this.scrollChangeHandler) {
|
||||
this.nativeView?.setOnScrollChangeListener(null);
|
||||
this.scrollChangeHandler = null;
|
||||
}
|
||||
this.nativeViewProtected.getViewTreeObserver().removeOnScrollChangedListener(this.handler);
|
||||
this.handler = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,7 @@ export class ScrollView extends ScrollViewBase {
|
||||
private _delegate: UIScrollViewDelegateImpl;
|
||||
|
||||
public createNativeView() {
|
||||
const view = UIScrollView.new();
|
||||
|
||||
return view;
|
||||
return UIScrollView.new();
|
||||
}
|
||||
|
||||
initNativeView() {
|
||||
@@ -51,18 +49,31 @@ export class ScrollView extends ScrollViewBase {
|
||||
this._setNativeClipToBounds();
|
||||
}
|
||||
|
||||
disposeNativeView() {
|
||||
this.dettachNative();
|
||||
this._delegate = null;
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
_setNativeClipToBounds() {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
}
|
||||
// Always set clipsToBounds for scroll-view
|
||||
this.nativeViewProtected.clipsToBounds = true;
|
||||
}
|
||||
|
||||
protected attachNative() {
|
||||
this._delegate = UIScrollViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
if (!this._delegate) {
|
||||
this._delegate = UIScrollViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
}
|
||||
}
|
||||
|
||||
protected dettachNative() {
|
||||
this.nativeViewProtected.delegate = null;
|
||||
if (this.nativeViewProtected) {
|
||||
this.nativeViewProtected.delegate = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected updateScrollBarVisibility(value) {
|
||||
|
||||
@@ -41,10 +41,9 @@ export abstract class ScrollViewBase extends ContentView implements ScrollViewDe
|
||||
this.attach();
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
super.onUnloaded();
|
||||
|
||||
public disposeNativeView() {
|
||||
this.dettach();
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
private attach() {
|
||||
|
||||
@@ -150,8 +150,12 @@ export class SearchBar extends SearchBarBase {
|
||||
|
||||
public disposeNativeView() {
|
||||
const nativeView: any = this.nativeViewProtected;
|
||||
nativeView.closeListener.owner = null;
|
||||
nativeView.queryTextListener.owner = null;
|
||||
if (nativeView.closeListener) {
|
||||
nativeView.closeListener.owner = null;
|
||||
}
|
||||
if (nativeView.queryTextListener) {
|
||||
nativeView.queryTextListener.owner = null;
|
||||
}
|
||||
this._searchPlate = null;
|
||||
this._searchTextView = null;
|
||||
super.disposeNativeView();
|
||||
|
||||
@@ -82,6 +82,7 @@ export class SearchBar extends SearchBarBase {
|
||||
initNativeView() {
|
||||
super.initNativeView();
|
||||
this._delegate = UISearchBarDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
}
|
||||
|
||||
disposeNativeView() {
|
||||
@@ -89,16 +90,6 @@ export class SearchBar extends SearchBarBase {
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this.ios.delegate = this._delegate;
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this.ios.delegate = null;
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
public dismissSoftInput() {
|
||||
(<UIResponder>this.ios).resignFirstResponder();
|
||||
}
|
||||
|
||||
@@ -238,7 +238,9 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
|
||||
public disposeNativeView() {
|
||||
const nativeView: any = this.nativeViewProtected;
|
||||
nativeView.listener.owner = null;
|
||||
if (nativeView?.listener) {
|
||||
nativeView.listener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -736,7 +736,12 @@ function drawBoxShadow(nativeView: NativeScriptUIView, view: View, boxShadow: CS
|
||||
);
|
||||
|
||||
// this should match the view's border radius
|
||||
const cornerRadius = Length.toDevicePixels(<CoreTypes.LengthType>view.style.borderRadius, 0.0);
|
||||
let cornerRadius: number;
|
||||
if (typeof view.style.borderRadius !== 'number') {
|
||||
cornerRadius = Length.toDevicePixels(<CoreTypes.LengthType>view.style.borderRadius, 0.0);
|
||||
} else {
|
||||
cornerRadius = view.style.borderRadius;
|
||||
}
|
||||
|
||||
// apply spreadRadius by expanding shadow layer bounds
|
||||
// prettier-ignore
|
||||
|
||||
@@ -734,6 +734,7 @@ function normalizeTransformation({ property, value }: Transformation): Transform
|
||||
}
|
||||
|
||||
function convertTransformValue(property: string, stringValue: string): TransformationValue {
|
||||
/* eslint-disable prefer-const */
|
||||
let [x, y, z] = stringValue.split(',').map(parseFloat);
|
||||
if (property === 'translate') {
|
||||
y ??= IDENTITY_TRANSFORMATION.translate.y;
|
||||
|
||||
@@ -52,7 +52,9 @@ export class Switch extends SwitchBase {
|
||||
|
||||
public disposeNativeView() {
|
||||
const nativeView: any = this.nativeViewProtected;
|
||||
nativeView.listener.owner = null;
|
||||
if (nativeView.listener) {
|
||||
nativeView.listener.owner = null;
|
||||
}
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -350,8 +350,8 @@ export class TabViewItem extends TabViewItemBase {
|
||||
}
|
||||
|
||||
public disposeNativeView(): void {
|
||||
super.disposeNativeView();
|
||||
(<TabViewItemDefinition>this).canBeLoaded = false;
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
public createNativeView() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { hintProperty, placeholderColorProperty, _updateCharactersInRangeReplace
|
||||
import { CoreTypes } from '../../core-types';
|
||||
import { Color } from '../../color';
|
||||
import { colorProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty } from '../styling/style-properties';
|
||||
import { layout } from '../../utils';
|
||||
import { layout, isEmoji } from '../../utils';
|
||||
import { profile } from '../../profiling';
|
||||
|
||||
export * from './text-field-common';
|
||||
@@ -123,6 +123,7 @@ export class TextField extends TextFieldBase {
|
||||
initNativeView() {
|
||||
super.initNativeView();
|
||||
this._delegate = UITextFieldDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
}
|
||||
|
||||
disposeNativeView() {
|
||||
@@ -130,17 +131,6 @@ export class TextField extends TextFieldBase {
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this.ios.delegate = this._delegate;
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this.ios.delegate = null;
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
get ios(): UITextField {
|
||||
return this.nativeViewProtected;
|
||||
@@ -200,7 +190,10 @@ export class TextField extends TextFieldBase {
|
||||
}
|
||||
|
||||
if (this.updateTextTrigger === 'textChanged') {
|
||||
const shouldReplaceString = (textField.secureTextEntry && this.firstEdit) || delta > 1;
|
||||
// 1. secureTextEntry with firstEdit should not replace
|
||||
// 2. emoji's should not replace value
|
||||
// 3. convenient keyboard shortcuts should not replace value (eg, '.com')
|
||||
const shouldReplaceString = (textField.secureTextEntry && this.firstEdit) || (delta > 1 && !isEmoji(replacementString) && delta !== replacementString.length);
|
||||
if (shouldReplaceString) {
|
||||
textProperty.nativeValueChange(this, replacementString);
|
||||
} else {
|
||||
|
||||
@@ -106,6 +106,7 @@ export class TextView extends TextViewBaseCommon {
|
||||
initNativeView() {
|
||||
super.initNativeView();
|
||||
this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeTextViewProtected.delegate = this._delegate;
|
||||
}
|
||||
|
||||
disposeNativeView() {
|
||||
@@ -113,17 +114,6 @@ export class TextView extends TextViewBaseCommon {
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this.nativeTextViewProtected.delegate = this._delegate;
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this.nativeTextViewProtected.delegate = null;
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
get ios(): UITextView {
|
||||
return this.nativeViewProtected;
|
||||
|
||||
@@ -29,8 +29,7 @@ function initializeWebViewClient(): void {
|
||||
|
||||
// Handle schemes like mailto, tel, etc
|
||||
if (!android.webkit.URLUtil.isNetworkUrl(url)) {
|
||||
openUrl(url);
|
||||
return true;
|
||||
return openUrl(url);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -124,10 +123,12 @@ export class WebView extends WebViewBase {
|
||||
public disposeNativeView() {
|
||||
const nativeView = this.nativeViewProtected;
|
||||
if (nativeView) {
|
||||
if ((<any>nativeView).client) {
|
||||
(<any>nativeView).client.owner = null;
|
||||
}
|
||||
nativeView.destroy();
|
||||
}
|
||||
|
||||
(<any>nativeView).client.owner = null;
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -202,18 +202,16 @@ export class WebView extends WebViewBase {
|
||||
this._delegate = WKNavigationDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this._scrollDelegate = UIScrollViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this._uiDelegate = WKUIDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.ios.navigationDelegate = this._delegate;
|
||||
this.ios.scrollView.delegate = this._scrollDelegate;
|
||||
this.ios.UIDelegate = this._uiDelegate;
|
||||
this.nativeViewProtected.navigationDelegate = this._delegate;
|
||||
this.nativeViewProtected.scrollView.delegate = this._scrollDelegate;
|
||||
this.nativeViewProtected.UIDelegate = this._uiDelegate;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
super.onUnloaded();
|
||||
disposeNativeView() {
|
||||
this._delegate = null;
|
||||
this._scrollDelegate = null;
|
||||
this._uiDelegate = null;
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
@@ -222,48 +220,48 @@ export class WebView extends WebViewBase {
|
||||
}
|
||||
|
||||
public stopLoading() {
|
||||
this.ios.stopLoading();
|
||||
this.nativeViewProtected.stopLoading();
|
||||
}
|
||||
|
||||
public _loadUrl(src: string) {
|
||||
if (src.startsWith('file:///')) {
|
||||
const cachePath = src.substring(0, src.lastIndexOf('/'));
|
||||
this.ios.loadFileURLAllowingReadAccessToURL(NSURL.URLWithString(src), NSURL.URLWithString(cachePath));
|
||||
this.nativeViewProtected.loadFileURLAllowingReadAccessToURL(NSURL.URLWithString(src), NSURL.URLWithString(cachePath));
|
||||
} else {
|
||||
this.ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src)));
|
||||
this.nativeViewProtected.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src)));
|
||||
}
|
||||
}
|
||||
|
||||
public _loadData(content: string) {
|
||||
this.ios.loadHTMLStringBaseURL(content, NSURL.alloc().initWithString(`file:///${knownFolders.currentApp().path}/`));
|
||||
this.nativeViewProtected.loadHTMLStringBaseURL(content, NSURL.alloc().initWithString(`file:///${knownFolders.currentApp().path}/`));
|
||||
}
|
||||
|
||||
get canGoBack(): boolean {
|
||||
return this.ios.canGoBack;
|
||||
return this.nativeViewProtected.canGoBack;
|
||||
}
|
||||
|
||||
get canGoForward(): boolean {
|
||||
return this.ios.canGoForward;
|
||||
return this.nativeViewProtected.canGoForward;
|
||||
}
|
||||
|
||||
public goBack() {
|
||||
this.ios.goBack();
|
||||
this.nativeViewProtected.goBack();
|
||||
}
|
||||
|
||||
public goForward() {
|
||||
this.ios.goForward();
|
||||
this.nativeViewProtected.goForward();
|
||||
}
|
||||
|
||||
public reload() {
|
||||
this.ios.reload();
|
||||
this.nativeViewProtected.reload();
|
||||
}
|
||||
|
||||
[disableZoomProperty.setNative](value: boolean) {
|
||||
if (!value && typeof this._minimumZoomScale === 'number' && typeof this._maximumZoomScale === 'number' && typeof this._zoomScale === 'number') {
|
||||
if (this.ios.scrollView) {
|
||||
this.ios.scrollView.minimumZoomScale = this._minimumZoomScale;
|
||||
this.ios.scrollView.maximumZoomScale = this._maximumZoomScale;
|
||||
this.ios.scrollView.zoomScale = this._zoomScale;
|
||||
if (this.nativeViewProtected?.scrollView) {
|
||||
this.nativeViewProtected.scrollView.minimumZoomScale = this._minimumZoomScale;
|
||||
this.nativeViewProtected.scrollView.maximumZoomScale = this._maximumZoomScale;
|
||||
this.nativeViewProtected.scrollView.zoomScale = this._zoomScale;
|
||||
this._minimumZoomScale = undefined;
|
||||
this._maximumZoomScale = undefined;
|
||||
this._zoomScale = undefined;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as types from './types';
|
||||
import { dispatchToMainThread, dispatchToUIThread, isMainThread } from './mainthread-helper';
|
||||
import { sanitizeModuleName } from '../ui/builder/module-name-sanitizer';
|
||||
import emojiRegex from 'emoji-regex';
|
||||
|
||||
import { GC } from './index';
|
||||
|
||||
@@ -158,11 +159,11 @@ export function debounce(fn: any, delay = 300) {
|
||||
};
|
||||
}
|
||||
|
||||
export function throttle(fn: any, delay = 300) {
|
||||
export function throttle(fn: Function, delay = 300) {
|
||||
let waiting = false;
|
||||
return function () {
|
||||
return function (...args) {
|
||||
if (!waiting) {
|
||||
fn.apply(this, arguments);
|
||||
fn.apply(this, args);
|
||||
waiting = true;
|
||||
setTimeout(function () {
|
||||
waiting = false;
|
||||
@@ -203,3 +204,9 @@ export function queueGC(delay = 900, useThrottle?: boolean) {
|
||||
debouncedGC.get(delay)();
|
||||
}
|
||||
}
|
||||
|
||||
export function isEmoji(value: string): boolean {
|
||||
// TODO: In a future runtime update, we can switch to using Unicode Property Escapes:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
|
||||
return emojiRegex().test(value);
|
||||
}
|
||||
|
||||
@@ -23,11 +23,10 @@ export function openUrl(location: string): boolean {
|
||||
try {
|
||||
const intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(location.trim()));
|
||||
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
context.startActivity(intent);
|
||||
} catch (e) {
|
||||
// We Don't do anything with an error. We just output it
|
||||
Trace.write('Error in OpenURL', Trace.categories.Error, Trace.messageType.error);
|
||||
// We don't do anything with an error. We just output it
|
||||
Trace.write(`Failed to start activity for handling URL: ${location}`, Trace.categories.Error, Trace.messageType.error);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,9 +34,10 @@ export function dataDeserialize(nativeData?: any) {
|
||||
}
|
||||
case 'org.json.JSONObject': {
|
||||
store = {};
|
||||
let i = nativeData.keys();
|
||||
const i = nativeData.keys();
|
||||
let key;
|
||||
while (i.hasNext()) {
|
||||
let key = i.next();
|
||||
key = i.next();
|
||||
store[key] = dataDeserialize(nativeData.get(key));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -36,8 +36,8 @@ export function dataDeserialize(nativeData?: any) {
|
||||
case 'NSNull':
|
||||
return null;
|
||||
case 'NSMutableDictionary':
|
||||
case 'NSDictionary':
|
||||
let obj = {};
|
||||
case 'NSDictionary': {
|
||||
const obj = {};
|
||||
const length = nativeData.count;
|
||||
const keysArray = nativeData.allKeys as NSArray<any>;
|
||||
for (let i = 0; i < length; i++) {
|
||||
@@ -45,14 +45,16 @@ export function dataDeserialize(nativeData?: any) {
|
||||
obj[nativeKey] = dataDeserialize(nativeData.objectForKey(nativeKey));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
case 'NSMutableArray':
|
||||
case 'NSArray':
|
||||
let array = [];
|
||||
case 'NSArray': {
|
||||
const array = [];
|
||||
const len = nativeData.count;
|
||||
for (let i = 0; i < len; i++) {
|
||||
array[i] = dataDeserialize(nativeData.objectAtIndex(i));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
default:
|
||||
return nativeData;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nativescript/webpack",
|
||||
"version": "5.0.12",
|
||||
"version": "5.0.13",
|
||||
"private": false,
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
|
||||
@@ -34,7 +34,7 @@ export class PlatformSuffixPlugin {
|
||||
}
|
||||
|
||||
apply(compiler: any) {
|
||||
const platformRE = new RegExp(`\.${this.platform}\.`);
|
||||
const platformRE = new RegExp(`\\.${this.platform}\\.`);
|
||||
|
||||
// require.context
|
||||
compiler.hooks.contextModuleFactory.tap(id, (cmf) => {
|
||||
|
||||
@@ -48,7 +48,7 @@ npx nx run core:test --watch
|
||||
|
||||
### Isolate tests by name
|
||||
|
||||
Run a single test by it's decribe name, for example to run just the `xml/index.spec.ts`, the describe block is named `XmlParser` therefore:
|
||||
Run a single test by it's describe name, for example to run just the `xml/index.spec.ts`, the describe block is named `XmlParser` therefore:
|
||||
|
||||
```
|
||||
npx nx run core:test --watch -t 'XmlParser'
|
||||
|
||||
Reference in New Issue
Block a user