1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_RICHEDITOR_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_RICHEDITOR_H
18 
19 #include "core/components_ng/pattern/rich_editor/rich_editor_event_hub.h"
20 #include "core/components_ng/pattern/rich_editor/rich_editor_model.h"
21 #include "core/components_ng/pattern/text_field/text_field_model.h"
22 #include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h"
23 
24 namespace OHOS::Ace::Framework {
25 class JSRichEditor : public JSContainerBase {
26 public:
27     static void Create(const JSCallbackInfo& info);
28     static void JSBind(BindingTarget globalObj);
29     static void SetOnReady(const JSCallbackInfo& args);
30     static void SetOnSelect(const JSCallbackInfo& args);
31     static void SetOnSelectionChange(const JSCallbackInfo& args);
32     static void SetAboutToIMEInput(const JSCallbackInfo& args);
33     static void SetOnIMEInputComplete(const JSCallbackInfo& args);
34     static void SetOnDidIMEInput(const JSCallbackInfo& args);
35     static void SetAboutToDelete(const JSCallbackInfo& args);
36     static void SetOnDeleteComplete(const JSCallbackInfo& args);
37     static void SetCustomKeyboard(const JSCallbackInfo& args);
38     static JSRef<JSVal> CreateJsAboutToIMEInputObj(const NG::RichEditorInsertValue& insertValue);
39     static JSRef<JSVal> CreateJsOnIMEInputComplete(const NG::RichEditorAbstractSpanResult& textSpanResult);
40     static JSRef<JSVal> CreateJsOnDidIMEInput(const TextRange& textRange);
41     static JSRef<JSVal> CreateJsAboutToDelet(const NG::RichEditorDeleteValue& deleteValue);
42     static void SetChangeTextSpans(
43         JSRef<JSArray>& jsArray, const std::vector<NG::RichEditorAbstractSpanResult>& spanList);
44     static JSRef<JSVal> CreateJsOnWillChange(const NG::RichEditorChangeValue& changeValue);
45     static JSRef<JSVal> CreateJsOnDidChange(const std::vector<NG::RichEditorAbstractSpanResult>& spanList);
46     static void JsClip(const JSCallbackInfo& info);
47     static void JsFocusable(const JSCallbackInfo& info);
48     static void SetCopyOptions(const JSCallbackInfo& info);
49     static void BindSelectionMenu(const JSCallbackInfo& info);
50     static void SetOnPaste(const JSCallbackInfo& info);
51     static void SetPlaceholder(const JSCallbackInfo& info);
52     static void JsEnableDataDetector(const JSCallbackInfo& info);
53     static void JsEnablePreviewText(const JSCallbackInfo& info);
54     static void JsDataDetectorConfig(const JSCallbackInfo& info);
55     static void SetOnWillChange(const JSCallbackInfo& info);
56     static void SetOnDidChange(const JSCallbackInfo& info);
57     static void SetOnCut(const JSCallbackInfo& info);
58     static void SetOnCopy(const JSCallbackInfo& info);
59     static JSRef<JSObject> CreateJSSpanResultObject(const ResultObject& resultObject);
60     static JSRef<JSVal> CreateJSSelection(const SelectionInfo& selectInfo);
61     static JSRef<JSVal> CreateJSSelectionRange(const SelectionRangeInfo& selectRange);
62     static JSRef<JSObject> CreateJSTextStyleResult(const TextStyleResult& textStyleResult);
63     static JSRef<JSObject> CreateJSParagraphStyle(const TextStyleResult& textStyleResult);
64     static JSRef<JSObject> CreateJSSymbolSpanStyleResult(const SymbolSpanStyle& symbolSpanStyle);
65     static JSRef<JSObject> CreateJSValueResource(const RefPtr<ResourceObject>& valueResource);
66     static JSRef<JSObject> CreateJSLayoutStyle(const ImageStyleResult& imageStyleResult);
67     static JSRef<JSObject> CreateJSImageStyleResult(const ImageStyleResult& imageStyleResult);
68     static JSRef<JSObject> CreateParagraphStyleResult(const ParagraphInfo& info);
69     static JSRef<JSVal> CreateJSTextCommonEvent(NG::TextCommonEvent& event);
70     static void SetCaretColor(const JSCallbackInfo& info);
71     static void SetOnEditingChange(const JSCallbackInfo& args);
72     static void SetSelectedBackgroundColor(const JSCallbackInfo& info);
73     static void SetEnterKeyType(const JSCallbackInfo& info);
74     static void CreateJsRichEditorCommonEvent(const JSCallbackInfo& info);
75     static void SetOnSubmit(const JSCallbackInfo& info);
76     static Local<JSValueRef> JsKeepEditableState(panda::JsiRuntimeCallInfo* info);
77     static std::optional<NG::BorderRadiusProperty> ParseBorderRadiusAttr(JsiRef<JSVal> args);
78     static std::optional<NG::MarginProperty> ParseMarginAttr(JsiRef<JSVal> marginAttr);
79     static CalcDimension ParseLengthMetrics(const JSRef<JSObject>& obj);
80     static void EditMenuOptions(const JSCallbackInfo& info);
81     static void SetEnableKeyboardOnFocus(const JSCallbackInfo& info);
82     static void SetEnableHapticFeedback(const JSCallbackInfo& info);
83     static JSRef<JSArray> CreateJsTextShadowObjectArray(const TextStyleResult& textStyleResult);
84     static JSRef<JSArray> CreateJsTextShadowObjectArray(const std::vector<Shadow>& textShadows);
85     static void SetBarState(const JSCallbackInfo& info);
86 private:
87     static void CreateTextStyleObj(JSRef<JSObject>& textStyleObj, const NG::RichEditorAbstractSpanResult& spanResult);
88     static void CreateImageStyleObj(JSRef<JSObject>& imageStyleObj, JSRef<JSObject>& spanResultObj,
89         const NG::RichEditorAbstractSpanResult& spanResult);
90     static JSRef<JSArray> CreateJSDeleteSpans(const NG::RichEditorDeleteValue& deleteValue);
91     static void ParseUserGesture(
92         const JSCallbackInfo& args, UserGestureOptions& gestureOption, const std::string& spanType);
93     static void ParseJsFont(const JSRef<JSObject>& fontObject, Font& font);
94     static void SetTextChangeSpanResult(JSRef<JSObject>& resultObj,
95         const NG::RichEditorAbstractSpanResult& spanResult);
96     static void SetImageChangeSpanResult(JSRef<JSObject>& resultObj,
97         const NG::RichEditorAbstractSpanResult& spanResult);
98     static void SetSymbolChangeSpanResult(JSRef<JSObject>& resultObj,
99         const NG::RichEditorAbstractSpanResult& spanResult);
100     static void SetJSSpanResultObject(JSRef<JSObject>& resultObj, const ResultObject& resultObject);
101     static void SetJSDeleteSpan(JSRef<JSObject>& spanResultObj, const NG::RichEditorAbstractSpanResult& it);
102 };
103 
104 class JSRichEditorBaseController : public Referenced {
105 public:
SetController(const RefPtr<RichEditorBaseControllerBase> & controller)106     void SetController(const RefPtr<RichEditorBaseControllerBase>& controller)
107     {
108         controllerWeak_ = controller;
109     }
110 
111     void SetCaretOffset(const JSCallbackInfo& args);
112     void GetCaretOffset(const JSCallbackInfo& args);
113     void SetTypingStyle(const JSCallbackInfo& info);
114     void ParseJsTextStyle(
115         const JSRef<JSObject>& styleObject, TextStyle& style, struct UpdateSpanStyle& updateSpanStyle);
116     void ParseJsLineHeightLetterSpacingTextStyle(const JSRef<JSObject>& styleObject, TextStyle& style,
117         struct UpdateSpanStyle& updateSpanStyle, bool isSupportPercent = true);
118     void ParseJsFontFeatureTextStyle(const JSRef<JSObject>& styleObject, TextStyle& style,
119         struct UpdateSpanStyle& updateSpanStyle);
120     void GetTypingStyle(const JSCallbackInfo& info);
121     void CloseSelectionMenu();
122     void IsEditing(const JSCallbackInfo& args);
123     void StopEditing();
124     void SetSelection(const JSCallbackInfo& args);
125     bool FontSizeRangeIsNegative(const CalcDimension& size);
126     void GetLayoutManager(const JSCallbackInfo& args);
127     void GetPreviewTextInfo(const JSCallbackInfo& args);
128 
SetInstanceId(int32_t id)129     void SetInstanceId(int32_t id)
130     {
131         instanceId_ = id;
132     }
133 
SetStyledStringMode(bool isStyledStringMode)134     void SetStyledStringMode(bool isStyledStringMode)
135     {
136         isStyledStringMode_ = isStyledStringMode;
137     }
138 
IsStyledStringMode()139     bool IsStyledStringMode()
140     {
141         return isStyledStringMode_;
142     }
143 
144 protected:
145     int32_t instanceId_ = INSTANCE_ID_UNDEFINED;
146     WeakPtr<RichEditorBaseControllerBase> controllerWeak_;
147     struct UpdateSpanStyle typingStyle_;
148     bool isStyledStringMode_ = false;
149     static JSRef<JSObject> CreateTypingStyleResult(const struct UpdateSpanStyle& typingStyle);
150     void ParseTextDecoration(
151         const JSRef<JSObject>& styleObject, TextStyle& style, struct UpdateSpanStyle& updateSpanStyle);
152     void ParseTextShadow(
153         const JSRef<JSObject>& styleObject, TextStyle& style, struct UpdateSpanStyle& updateSpanStyle);
154     JSRef<JSObject> JSObjectCast(JSRef<JSVal> jsValue);
155     void ParseJsSelectionOptions(const JSCallbackInfo& args, std::optional<SelectionOptions>& options);
156     JSRef<JSObject> CreateJSPreviewTextInfo(const PreviewTextInfo& info);
157 };
158 
159 class JSRichEditorController final : public JSRichEditorBaseController {
160 public:
161     JSRichEditorController() = default;
162     ~JSRichEditorController() override = default;
163 
164     static void JSBind(BindingTarget globalObj);
165 
Constructor(const JSCallbackInfo & args)166     static void Constructor(const JSCallbackInfo& args)
167     {
168         auto controller = Referenced::MakeRefPtr<JSRichEditorController>();
169         controller->SetStyledStringMode(false);
170         controller->IncRefCount();
171         args.SetReturnValue(Referenced::RawPtr(controller));
172     }
173 
Destructor(JSRichEditorController * controller)174     static void Destructor(JSRichEditorController* controller)
175     {
176         if (controller != nullptr) {
177             controller->DecRefCount();
178         }
179     }
180 
181     void AddImageSpan(const JSCallbackInfo& args);
182     void AddTextSpan(const JSCallbackInfo& args);
183     void AddSymbolSpan(const JSCallbackInfo& args);
184     void AddPlaceholderSpan(const JSCallbackInfo& args);
185     void ParseOptions(const JSCallbackInfo& args, SpanOptionBase& placeholderSpan);
186     void DeleteSpans(const JSCallbackInfo& args);
187     ImageSpanAttribute ParseJsImageSpanAttribute(JSRef<JSObject> imageAttribute);
188     void ParseJsSymbolSpanStyle(
189         const JSRef<JSObject>& styleObject, TextStyle& style, struct UpdateSpanStyle& updateSpanStyle);
190     ImageSpanOptions CreateJsImageOptions(const JSCallbackInfo& args);
191     void UpdateSpanStyle(const JSCallbackInfo& info);
192     void UpdateParagraphStyle(const JSCallbackInfo& info);
193     void GetSpansInfo(const JSCallbackInfo& args);
194     void GetParagraphsInfo(const JSCallbackInfo& args);
195     void GetSelection(const JSCallbackInfo& args);
196     void ToStyledString(const JSCallbackInfo& args);
197     void FromStyledString(const JSCallbackInfo& args);
198 
199 private:
200     static void ParseUserGesture(
201         const JSCallbackInfo& args, UserGestureOptions& gestureOption, const std::string& spanType);
202     static void ParseUserClickEvent(const JSCallbackInfo& args, const JSRef<JSObject>& gestureObj,
203         UserGestureOptions& gestureOption, const std::string& spanType);
204     static void ParseUserMouseOption(
205         const JSCallbackInfo& args, UserMouseOptions& mouseOption, const std::string& spanType);
206     bool ParseParagraphStyle(const JSRef<JSObject>& styleObject, struct UpdateParagraphStyle& style);
207     bool IsPixelMap(const JSRef<JSVal>& jsValue);
208     bool IsDrawable(const JSRef<JSVal>& jsValue);
209     static JSRef<JSVal> CreateJSSpansInfo(const SelectionInfo& info);
210     static JSRef<JSVal> CreateJSParagraphsInfo(const std::vector<ParagraphInfo>& info);
211     static void ParseWordBreakParagraphStyle(const JSRef<JSObject>& styleObject, struct UpdateParagraphStyle& style);
212     static void ParseTextAlignParagraphStyle(const JSRef<JSObject>& styleObject, struct UpdateParagraphStyle& style);
213     bool CheckImageSource(std::string assetSrc);
214 
215     ACE_DISALLOW_COPY_AND_MOVE(JSRichEditorController);
216     struct UpdateSpanStyle updateSpanStyle_;
217     static void ParseLineBreakStrategyParagraphStyle(
218         const JSRef<JSObject>& styleObject, struct UpdateParagraphStyle& style);
219 };
220 
221 class JSRichEditorStyledStringController final : public JSRichEditorBaseController {
222 public:
223     JSRichEditorStyledStringController() = default;
224     ~JSRichEditorStyledStringController() override = default;
225 
226     static void JSBind(BindingTarget globalObj);
227 
Constructor(const JSCallbackInfo & args)228     static void Constructor(const JSCallbackInfo& args)
229     {
230         auto controller = Referenced::MakeRefPtr<JSRichEditorStyledStringController>();
231         controller->SetStyledStringMode(true);
232         controller->IncRefCount();
233         args.SetReturnValue(Referenced::RawPtr(controller));
234     }
235 
Destructor(JSRichEditorStyledStringController * controller)236     static void Destructor(JSRichEditorStyledStringController* controller)
237     {
238         if (controller != nullptr) {
239             controller->DecRefCount();
240         }
241     }
242 
243     void GetSelection(const JSCallbackInfo& args);
244     void SetStyledString(const JSCallbackInfo& args);
245     void GetStyledString(const JSCallbackInfo& args);
246     void OnContentChanged(const JSCallbackInfo& args);
247 
248 private:
249     void SetOnWillChange(const JSCallbackInfo& args);
250     void SetOnDidChange(const JSCallbackInfo& args);
251     static JSRef<JSVal> CreateJsOnWillChange(const NG::StyledStringChangeValue& changeValue);
252     ACE_DISALLOW_COPY_AND_MOVE(JSRichEditorStyledStringController);
253 };
254 } // namespace OHOS::Ace::Framework
255 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_RICHEDITOR_H
256