feat:Input add beforeTextChange API
This commit is contained in:
parent
e528630f71
commit
9fed9e431c
@ -31,6 +31,8 @@ import android.view.inputmethod.InputMethodManager;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.github.pengfeizhou.jscore.ArchiveException;
|
||||||
|
import com.github.pengfeizhou.jscore.JSDecoder;
|
||||||
import com.github.pengfeizhou.jscore.JSONBuilder;
|
import com.github.pengfeizhou.jscore.JSONBuilder;
|
||||||
import com.github.pengfeizhou.jscore.JSObject;
|
import com.github.pengfeizhou.jscore.JSObject;
|
||||||
import com.github.pengfeizhou.jscore.JSValue;
|
import com.github.pengfeizhou.jscore.JSValue;
|
||||||
@ -40,6 +42,7 @@ import org.json.JSONObject;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
|
import pub.doric.async.AsyncResult;
|
||||||
import pub.doric.extension.bridge.DoricMethod;
|
import pub.doric.extension.bridge.DoricMethod;
|
||||||
import pub.doric.extension.bridge.DoricPlugin;
|
import pub.doric.extension.bridge.DoricPlugin;
|
||||||
import pub.doric.extension.bridge.DoricPromise;
|
import pub.doric.extension.bridge.DoricPromise;
|
||||||
@ -50,10 +53,11 @@ import pub.doric.extension.bridge.DoricPromise;
|
|||||||
* @CreateDate: 2019-12-06
|
* @CreateDate: 2019-12-06
|
||||||
*/
|
*/
|
||||||
@DoricPlugin(name = "Input")
|
@DoricPlugin(name = "Input")
|
||||||
public class InputNode extends ViewNode<EditText> implements TextWatcher, View.OnFocusChangeListener {
|
public class InputNode extends ViewNode<EditText> implements TextWatcher, View.OnFocusChangeListener, InputFilter {
|
||||||
private final InputMethodManager mInputMethodManager;
|
private final InputMethodManager mInputMethodManager;
|
||||||
private String onTextChangeId;
|
private String onTextChangeId;
|
||||||
private String onFocusChangeId;
|
private String onFocusChangeId;
|
||||||
|
private String beforeTextChangeId;
|
||||||
|
|
||||||
public InputNode(DoricContext doricContext) {
|
public InputNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
@ -67,6 +71,7 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
|
|||||||
editText.setOnFocusChangeListener(this);
|
editText.setOnFocusChangeListener(this);
|
||||||
editText.setBackground(null);
|
editText.setBackground(null);
|
||||||
editText.setGravity(Gravity.START | Gravity.TOP);
|
editText.setGravity(Gravity.START | Gravity.TOP);
|
||||||
|
editText.setFilters(new InputFilter[]{this});
|
||||||
return editText;
|
return editText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +121,13 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
|
|||||||
view.setInputType(view.getInputType() & ~InputType.TYPE_TEXT_FLAG_MULTI_LINE);
|
view.setInputType(view.getInputType() & ~InputType.TYPE_TEXT_FLAG_MULTI_LINE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "beforeTextChange":
|
||||||
|
if (prop.isString()) {
|
||||||
|
beforeTextChangeId = prop.asString().value();
|
||||||
|
} else {
|
||||||
|
beforeTextChangeId = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "onTextChange":
|
case "onTextChange":
|
||||||
if (prop.isString()) {
|
if (prop.isString()) {
|
||||||
onTextChangeId = prop.asString().value();
|
onTextChangeId = prop.asString().value();
|
||||||
@ -312,4 +324,25 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
|
|||||||
mInputMethodManager.hideSoftInputFromWindow(mView.getWindowToken(), 0);
|
mInputMethodManager.hideSoftInputFromWindow(mView.getWindowToken(), 0);
|
||||||
promise.resolve();
|
promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
|
||||||
|
if (TextUtils.isEmpty(beforeTextChangeId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AsyncResult<JSDecoder> asyncResult = callJSResponse(beforeTextChangeId,
|
||||||
|
new JSONBuilder()
|
||||||
|
.put("start", "")
|
||||||
|
.put("length", "")
|
||||||
|
.put("text", "")
|
||||||
|
.toJSONObject());
|
||||||
|
JSDecoder jsDecoder = asyncResult.synchronous().get();
|
||||||
|
boolean ret = true;
|
||||||
|
try {
|
||||||
|
ret = jsDecoder.bool();
|
||||||
|
} catch (ArchiveException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return ret ? null : "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
// Created by 姜腾 on 2019/12/11.
|
// Created by 姜腾 on 2019/12/11.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#import <JavaScriptCore/JavaScriptCore.h>
|
||||||
#import "DoricInputNode.h"
|
#import "DoricInputNode.h"
|
||||||
#import "DoricUtil.h"
|
#import "DoricUtil.h"
|
||||||
#import "DoricPromise.h"
|
#import "DoricPromise.h"
|
||||||
@ -76,6 +77,7 @@ @interface DoricInputNode () <UITextViewDelegate>
|
|||||||
@property(nonatomic, copy) onFocusChangeBlock onFocusChange;
|
@property(nonatomic, copy) onFocusChangeBlock onFocusChange;
|
||||||
@property(nonatomic, copy) onSubmitEditingBlock onSubmitEditing;
|
@property(nonatomic, copy) onSubmitEditingBlock onSubmitEditing;
|
||||||
@property(nonatomic, strong) NSNumber *maxLength;
|
@property(nonatomic, strong) NSNumber *maxLength;
|
||||||
|
@property(nonatomic, copy) NSString *beforeTextChangeFuncId;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricInputNode
|
@implementation DoricInputNode
|
||||||
@ -116,6 +118,8 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
|
|||||||
} else {
|
} else {
|
||||||
view.textContainer.maximumNumberOfLines = 0;
|
view.textContainer.maximumNumberOfLines = 0;
|
||||||
}
|
}
|
||||||
|
} else if ([name isEqualToString:@"beforeTextChange"]) {
|
||||||
|
self.beforeTextChangeFuncId = prop;
|
||||||
} else if ([name isEqualToString:@"hintText"]) {
|
} else if ([name isEqualToString:@"hintText"]) {
|
||||||
view.placeholderLabel.text = (NSString *) prop;
|
view.placeholderLabel.text = (NSString *) prop;
|
||||||
} else if ([name isEqualToString:@"hintTextColor"]) {
|
} else if ([name isEqualToString:@"hintTextColor"]) {
|
||||||
@ -283,6 +287,22 @@ - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range r
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.beforeTextChangeFuncId) {
|
||||||
|
DoricAsyncResult *asyncResult = [self
|
||||||
|
pureCallJSResponse:self.beforeTextChangeFuncId,
|
||||||
|
@{
|
||||||
|
@"editing": textView.text,
|
||||||
|
@"start": @(range.location),
|
||||||
|
@"length": @(range.length),
|
||||||
|
@"replacement": text,
|
||||||
|
},
|
||||||
|
nil];
|
||||||
|
NSNumber *ret = [asyncResult waitUntilResult:^(JSValue *model) {
|
||||||
|
return [model toNumber];
|
||||||
|
}];
|
||||||
|
return [ret boolValue];
|
||||||
|
}
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2860,6 +2860,10 @@ var Input = /** @class */ (function (_super) {
|
|||||||
Property,
|
Property,
|
||||||
__metadata$3("design:type", Function)
|
__metadata$3("design:type", Function)
|
||||||
], Input.prototype, "onSubmitEditing", void 0);
|
], Input.prototype, "onSubmitEditing", void 0);
|
||||||
|
__decorate$3([
|
||||||
|
Property,
|
||||||
|
__metadata$3("design:type", Function)
|
||||||
|
], Input.prototype, "beforeTextChange", void 0);
|
||||||
return Input;
|
return Input;
|
||||||
}(View));
|
}(View));
|
||||||
exports.InputType = void 0;
|
exports.InputType = void 0;
|
||||||
|
@ -2224,6 +2224,10 @@ __decorate$3([
|
|||||||
Property,
|
Property,
|
||||||
__metadata$3("design:type", Function)
|
__metadata$3("design:type", Function)
|
||||||
], Input.prototype, "onSubmitEditing", void 0);
|
], Input.prototype, "onSubmitEditing", void 0);
|
||||||
|
__decorate$3([
|
||||||
|
Property,
|
||||||
|
__metadata$3("design:type", Function)
|
||||||
|
], Input.prototype, "beforeTextChange", void 0);
|
||||||
exports.InputType = void 0;
|
exports.InputType = void 0;
|
||||||
(function (InputType) {
|
(function (InputType) {
|
||||||
InputType[InputType["Default"] = 0] = "Default";
|
InputType[InputType["Default"] = 0] = "Default";
|
||||||
|
@ -3745,6 +3745,10 @@ __decorate$3([
|
|||||||
Property,
|
Property,
|
||||||
__metadata$3("design:type", Function)
|
__metadata$3("design:type", Function)
|
||||||
], Input.prototype, "onSubmitEditing", void 0);
|
], Input.prototype, "onSubmitEditing", void 0);
|
||||||
|
__decorate$3([
|
||||||
|
Property,
|
||||||
|
__metadata$3("design:type", Function)
|
||||||
|
], Input.prototype, "beforeTextChange", void 0);
|
||||||
exports.InputType = void 0;
|
exports.InputType = void 0;
|
||||||
(function (InputType) {
|
(function (InputType) {
|
||||||
InputType[InputType["Default"] = 0] = "Default";
|
InputType[InputType["Default"] = 0] = "Default";
|
||||||
|
6
doric-js/index.d.ts
vendored
6
doric-js/index.d.ts
vendored
@ -784,6 +784,12 @@ declare module 'doric/lib/src/widget/input' {
|
|||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
returnKeyType?: ReturnKeyType;
|
returnKeyType?: ReturnKeyType;
|
||||||
onSubmitEditing?: (text: string) => void;
|
onSubmitEditing?: (text: string) => void;
|
||||||
|
beforeTextChange?: (change: {
|
||||||
|
editing: string;
|
||||||
|
start: number;
|
||||||
|
length: number;
|
||||||
|
replacement: string;
|
||||||
|
}) => boolean;
|
||||||
getText(context: BridgeContext): Promise<string>;
|
getText(context: BridgeContext): Promise<string>;
|
||||||
setSelection(context: BridgeContext, start: number, end?: number): Promise<any>;
|
setSelection(context: BridgeContext, start: number, end?: number): Promise<any>;
|
||||||
getSelection(context: BridgeContext): Promise<{
|
getSelection(context: BridgeContext): Promise<{
|
||||||
|
6
doric-js/lib/src/widget/input.d.ts
vendored
6
doric-js/lib/src/widget/input.d.ts
vendored
@ -26,6 +26,12 @@ export declare class Input extends View {
|
|||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
returnKeyType?: ReturnKeyType;
|
returnKeyType?: ReturnKeyType;
|
||||||
onSubmitEditing?: (text: string) => void;
|
onSubmitEditing?: (text: string) => void;
|
||||||
|
beforeTextChange?: (change: {
|
||||||
|
editing: string;
|
||||||
|
start: number;
|
||||||
|
length: number;
|
||||||
|
replacement: string;
|
||||||
|
}) => boolean;
|
||||||
getText(context: BridgeContext): Promise<string>;
|
getText(context: BridgeContext): Promise<string>;
|
||||||
setSelection(context: BridgeContext, start: number, end?: number): Promise<any>;
|
setSelection(context: BridgeContext, start: number, end?: number): Promise<any>;
|
||||||
getSelection(context: BridgeContext): Promise<{
|
getSelection(context: BridgeContext): Promise<{
|
||||||
|
@ -115,6 +115,10 @@ __decorate([
|
|||||||
Property,
|
Property,
|
||||||
__metadata("design:type", Function)
|
__metadata("design:type", Function)
|
||||||
], Input.prototype, "onSubmitEditing", void 0);
|
], Input.prototype, "onSubmitEditing", void 0);
|
||||||
|
__decorate([
|
||||||
|
Property,
|
||||||
|
__metadata("design:type", Function)
|
||||||
|
], Input.prototype, "beforeTextChange", void 0);
|
||||||
export var InputType;
|
export var InputType;
|
||||||
(function (InputType) {
|
(function (InputType) {
|
||||||
InputType[InputType["Default"] = 0] = "Default";
|
InputType[InputType["Default"] = 0] = "Default";
|
||||||
|
@ -75,6 +75,14 @@ export class Input extends View {
|
|||||||
@Property
|
@Property
|
||||||
onSubmitEditing?: (text: string) => void
|
onSubmitEditing?: (text: string) => void
|
||||||
|
|
||||||
|
@Property
|
||||||
|
beforeTextChange?: (change: {
|
||||||
|
editing: string,
|
||||||
|
start: number,
|
||||||
|
length: number,
|
||||||
|
replacement: string,
|
||||||
|
}) => boolean
|
||||||
|
|
||||||
getText(context: BridgeContext) {
|
getText(context: BridgeContext) {
|
||||||
return this.nativeChannel(context, 'getText')() as Promise<string>
|
return this.nativeChannel(context, 'getText')() as Promise<string>
|
||||||
}
|
}
|
||||||
|
4
doric-web/dist/index.js
vendored
4
doric-web/dist/index.js
vendored
@ -3799,6 +3799,10 @@ __decorate$3([
|
|||||||
Property,
|
Property,
|
||||||
__metadata$3("design:type", Function)
|
__metadata$3("design:type", Function)
|
||||||
], Input.prototype, "onSubmitEditing", void 0);
|
], Input.prototype, "onSubmitEditing", void 0);
|
||||||
|
__decorate$3([
|
||||||
|
Property,
|
||||||
|
__metadata$3("design:type", Function)
|
||||||
|
], Input.prototype, "beforeTextChange", void 0);
|
||||||
exports.InputType = void 0;
|
exports.InputType = void 0;
|
||||||
(function (InputType) {
|
(function (InputType) {
|
||||||
InputType[InputType["Default"] = 0] = "Default";
|
InputType[InputType["Default"] = 0] = "Default";
|
||||||
|
2
doric-web/dist/index.js.map
vendored
2
doric-web/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user