Skip to content

Commit 42fc4ac

Browse files
authored
feat(ios): textfield option to disable iOS autofill strong password handling (NativeScript#8348)
* feat(ios): textfield option to disable autofill strong password handling * chore: api change report
1 parent 8ab0e72 commit 42fc4ac

4 files changed

Lines changed: 80 additions & 64 deletions

File tree

api-reports/NativeScript.api.md

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -878,45 +878,45 @@ export interface GestureEventData extends EventData {
878878

879879
// @public
880880
export interface GestureEventDataWithState extends GestureEventData {
881-
// (undocumented)
882-
state: number;
881+
// (undocumented)
882+
state: number;
883883
}
884884

885885
// @public
886886
export class GesturesObserver {
887-
constructor(target: View, callback: (args: GestureEventData) => void, context: any);
887+
constructor(target: View, callback: (args: GestureEventData) => void, context: any);
888888

889-
androidOnTouchEvent: (motionEvent: any /* android.view.MotionEvent */) => void;
889+
androidOnTouchEvent: (motionEvent: any /* android.view.MotionEvent */) => void;
890890

891-
callback: (args: GestureEventData) => void;
891+
callback: (args: GestureEventData) => void;
892892

893-
context: any;
893+
context: any;
894894

895-
disconnect();
895+
disconnect();
896896

897-
observe(type: GestureTypes);
897+
observe(type: GestureTypes);
898898

899-
type: GestureTypes;
899+
type: GestureTypes;
900900
}
901901

902902
// @public
903903
export enum GestureStateTypes {
904-
began,
905-
cancelled,
906-
changed,
907-
ended
904+
began,
905+
cancelled,
906+
changed,
907+
ended
908908
}
909909

910910
// @public
911911
export enum GestureTypes {
912-
doubleTap,
913-
longPress,
914-
pan,
915-
pinch,
916-
rotation,
917-
swipe,
918-
tap,
919-
touch
912+
doubleTap,
913+
longPress,
914+
pan,
915+
pinch,
916+
rotation,
917+
swipe,
918+
tap,
919+
touch
920920
}
921921

922922
// @public
@@ -1011,49 +1011,49 @@ export const Http: {
10111011

10121012
// @public
10131013
export interface HttpContent {
1014-
raw: any;
1014+
raw: any;
10151015

1016-
toArrayBuffer: () => ArrayBuffer;
1016+
toArrayBuffer: () => ArrayBuffer;
10171017

1018-
toFile: (destinationFilePath?: string) => File;
1018+
toFile: (destinationFilePath?: string) => File;
10191019

1020-
toImage: () => Promise<ImageSource>;
1020+
toImage: () => Promise<ImageSource>;
10211021

1022-
toJSON: (encoding?: HttpResponseEncoding) => any;
1022+
toJSON: (encoding?: HttpResponseEncoding) => any;
10231023

1024-
toString: (encoding?: HttpResponseEncoding) => string;
1024+
toString: (encoding?: HttpResponseEncoding) => string;
10251025
}
10261026

10271027
// @public
10281028
export interface HttpRequestOptions {
1029-
content?: string | FormData | ArrayBuffer;
1029+
content?: string | FormData | ArrayBuffer;
10301030

1031-
dontFollowRedirects?: boolean;
1031+
dontFollowRedirects?: boolean;
10321032

1033-
headers?: any;
1033+
headers?: any;
10341034

1035-
method: string;
1035+
method: string;
10361036

1037-
timeout?: number;
1037+
timeout?: number;
10381038

1039-
url: string;
1039+
url: string;
10401040
}
10411041

10421042
// @public
10431043
export interface HttpResponse {
1044-
content?: HttpContent;
1044+
content?: HttpContent;
10451045

1046-
headers: Headers;
1046+
headers: Headers;
10471047

1048-
statusCode: number;
1048+
statusCode: number;
10491049
}
10501050

10511051
// @public (undocumented)
10521052
export enum HttpResponseEncoding {
1053-
// (undocumented)
1054-
GBK,
1055-
// (undocumented)
1056-
UTF8
1053+
// (undocumented)
1054+
GBK,
1055+
// (undocumented)
1056+
UTF8
10571057
}
10581058

10591059
// @public
@@ -1642,10 +1642,10 @@ export class Page extends ContentView {
16421642

16431643
// @public
16441644
export interface PanGestureEventData extends GestureEventDataWithState {
1645-
// (undocumented)
1646-
deltaX: number;
1647-
// (undocumented)
1648-
deltaY: number;
1645+
// (undocumented)
1646+
deltaX: number;
1647+
// (undocumented)
1648+
deltaY: number;
16491649
}
16501650

16511651
// @public
@@ -1694,14 +1694,14 @@ export module path {
16941694

16951695
// @public
16961696
export interface PinchGestureEventData extends GestureEventDataWithState {
1697-
// (undocumented)
1698-
getFocusX(): number;
1697+
// (undocumented)
1698+
getFocusX(): number;
16991699

1700-
// (undocumented)
1701-
getFocusY(): number;
1700+
// (undocumented)
1701+
getFocusY(): number;
17021702

1703-
// (undocumented)
1704-
scale: number;
1703+
// (undocumented)
1704+
scale: number;
17051705
}
17061706

17071707
// @public
@@ -1765,8 +1765,8 @@ export class Repeater extends CustomLayoutView {
17651765

17661766
// @public
17671767
export interface RotationGestureEventData extends GestureEventDataWithState {
1768-
// (undocumented)
1769-
rotation: number;
1768+
// (undocumented)
1769+
rotation: number;
17701770
}
17711771

17721772
// @public
@@ -2172,16 +2172,16 @@ export class Style extends Observable {
21722172

21732173
// @public
21742174
export enum SwipeDirection {
2175-
down,
2176-
left,
2177-
right,
2178-
up
2175+
down,
2176+
left,
2177+
right,
2178+
up
21792179
}
21802180

21812181
// @public
21822182
export interface SwipeGestureEventData extends GestureEventData {
2183-
// (undocumented)
2184-
direction: SwipeDirection;
2183+
// (undocumented)
2184+
direction: SwipeDirection;
21852185
}
21862186

21872187
// @public
@@ -2424,10 +2424,9 @@ export class TabViewItem extends ViewBase {
24242424
// @public
24252425
export interface TapGestureEventData extends GestureEventData {
24262426
getPointerCount(): number;
2427-
24282427
getX(): number;
2429-
24302428
getY(): number;
2429+
24312430
}
24322431

24332432
// @public
@@ -2508,6 +2507,8 @@ export class TextField extends EditableTextBase {
25082507
public static returnPressEvent: string;
25092508

25102509
secure: boolean;
2510+
2511+
secureWithoutAutofill: boolean;
25112512
}
25122513

25132514
// @public
@@ -2552,10 +2553,10 @@ export interface TimerInfo {
25522553

25532554
// @public
25542555
export interface TouchGestureEventData extends TapGestureEventData {
2555-
action: "up" | "move" | "down" | "cancel";
2556-
// Warning: (ae-forgotten-export) The symbol "Pointer" needs to be exported by the entry point index.d.ts
2557-
getActivePointers(): Array<Pointer>;
2558-
getAllPointers(): Array<Pointer>;
2556+
action: "up" | "move" | "down" | "cancel";
2557+
// Warning: (ae-forgotten-export) The symbol "Pointer" needs to be exported by the entry point index.d.ts
2558+
getActivePointers(): Array<Pointer>;
2559+
getAllPointers(): Array<Pointer>;
25592560
}
25602561

25612562
// @public (undocumented)

nativescript-core/ui/text-field/text-field-common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export class TextFieldBase extends EditableTextBase implements TextFieldDefiniti
88
public static returnPressEvent = "returnPress";
99
public secure: boolean;
1010
public closeOnReturn: boolean;
11+
// iOS only (to avoid 12+ suggested strong password handling)
12+
public secureWithoutAutofill: boolean;
1113
}
1214

1315
TextFieldBase.prototype.recycleNativeView = "auto";

nativescript-core/ui/text-field/text-field.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ export class TextField extends EditableTextBase {
3232
* Gets or sets if a text field should dismiss on return.
3333
*/
3434
closeOnReturn: boolean;
35+
36+
/**
37+
* iOS only (to avoid 12+ auto suggested strong password handling)
38+
*/
39+
secureWithoutAutofill: boolean;
3540
}

nativescript-core/ui/text-field/text-field.ios.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
7878
public textFieldShouldChangeCharactersInRangeReplacementString(textField: UITextField, range: NSRange, replacementString: string): boolean {
7979
const owner = this._owner.get();
8080
if (owner) {
81+
if (owner.secureWithoutAutofill && !textField.secureTextEntry) {
82+
/**
83+
* Helps avoid iOS 12+ autofill strong password suggestion prompt
84+
* Discussed in several circles but for example:
85+
* https://github.com/expo/expo/issues/2571#issuecomment-473347380
86+
*/
87+
textField.secureTextEntry = true;
88+
}
8189
const delta = replacementString.length - range.length;
8290
if (delta > 0) {
8391
if (textField.text.length + delta > owner.maxLength) {

0 commit comments

Comments
 (0)