feat:Input add beforeTextChange API

This commit is contained in:
pengfei.zhou 2021-06-11 17:47:06 +08:00 committed by osborn
parent e528630f71
commit 9fed9e431c
11 changed files with 95 additions and 2 deletions

View File

@ -31,6 +31,8 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
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.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
@ -40,6 +42,7 @@ import org.json.JSONObject;
import java.util.LinkedList;
import pub.doric.DoricContext;
import pub.doric.async.AsyncResult;
import pub.doric.extension.bridge.DoricMethod;
import pub.doric.extension.bridge.DoricPlugin;
import pub.doric.extension.bridge.DoricPromise;
@ -50,10 +53,11 @@ import pub.doric.extension.bridge.DoricPromise;
* @CreateDate: 2019-12-06
*/
@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 String onTextChangeId;
private String onFocusChangeId;
private String beforeTextChangeId;
public InputNode(DoricContext doricContext) {
super(doricContext);
@ -67,6 +71,7 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
editText.setOnFocusChangeListener(this);
editText.setBackground(null);
editText.setGravity(Gravity.START | Gravity.TOP);
editText.setFilters(new InputFilter[]{this});
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);
}
break;
case "beforeTextChange":
if (prop.isString()) {
beforeTextChangeId = prop.asString().value();
} else {
beforeTextChangeId = null;
}
break;
case "onTextChange":
if (prop.isString()) {
onTextChangeId = prop.asString().value();
@ -312,4 +324,25 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
mInputMethodManager.hideSoftInputFromWindow(mView.getWindowToken(), 0);
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 : "";
}
}

View File

@ -20,6 +20,7 @@
// Created by on 2019/12/11.
//
#import <JavaScriptCore/JavaScriptCore.h>
#import "DoricInputNode.h"
#import "DoricUtil.h"
#import "DoricPromise.h"
@ -76,6 +77,7 @@ @interface DoricInputNode () <UITextViewDelegate>
@property(nonatomic, copy) onFocusChangeBlock onFocusChange;
@property(nonatomic, copy) onSubmitEditingBlock onSubmitEditing;
@property(nonatomic, strong) NSNumber *maxLength;
@property(nonatomic, copy) NSString *beforeTextChangeFuncId;
@end
@implementation DoricInputNode
@ -116,6 +118,8 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
} else {
view.textContainer.maximumNumberOfLines = 0;
}
} else if ([name isEqualToString:@"beforeTextChange"]) {
self.beforeTextChangeFuncId = prop;
} else if ([name isEqualToString:@"hintText"]) {
view.placeholderLabel.text = (NSString *) prop;
} else if ([name isEqualToString:@"hintTextColor"]) {
@ -283,6 +287,22 @@ - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range r
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;
}

View File

@ -2860,6 +2860,10 @@ var Input = /** @class */ (function (_super) {
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "beforeTextChange", void 0);
return Input;
}(View));
exports.InputType = void 0;

View File

@ -2224,6 +2224,10 @@ __decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "beforeTextChange", void 0);
exports.InputType = void 0;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

View File

@ -3745,6 +3745,10 @@ __decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "beforeTextChange", void 0);
exports.InputType = void 0;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

6
doric-js/index.d.ts vendored
View File

@ -784,6 +784,12 @@ declare module 'doric/lib/src/widget/input' {
editable?: boolean;
returnKeyType?: ReturnKeyType;
onSubmitEditing?: (text: string) => void;
beforeTextChange?: (change: {
editing: string;
start: number;
length: number;
replacement: string;
}) => boolean;
getText(context: BridgeContext): Promise<string>;
setSelection(context: BridgeContext, start: number, end?: number): Promise<any>;
getSelection(context: BridgeContext): Promise<{

View File

@ -26,6 +26,12 @@ export declare class Input extends View {
editable?: boolean;
returnKeyType?: ReturnKeyType;
onSubmitEditing?: (text: string) => void;
beforeTextChange?: (change: {
editing: string;
start: number;
length: number;
replacement: string;
}) => boolean;
getText(context: BridgeContext): Promise<string>;
setSelection(context: BridgeContext, start: number, end?: number): Promise<any>;
getSelection(context: BridgeContext): Promise<{

View File

@ -115,6 +115,10 @@ __decorate([
Property,
__metadata("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
__decorate([
Property,
__metadata("design:type", Function)
], Input.prototype, "beforeTextChange", void 0);
export var InputType;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

View File

@ -75,6 +75,14 @@ export class Input extends View {
@Property
onSubmitEditing?: (text: string) => void
@Property
beforeTextChange?: (change: {
editing: string,
start: number,
length: number,
replacement: string,
}) => boolean
getText(context: BridgeContext) {
return this.nativeChannel(context, 'getText')() as Promise<string>
}

View File

@ -3799,6 +3799,10 @@ __decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "beforeTextChange", void 0);
exports.InputType = void 0;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

File diff suppressed because one or more lines are too long