@apollohg/react-native-rich-text-editor 2.0.3 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +8 -3
- package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +5 -1
- package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +1 -1
- package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +3 -2
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +196 -8
- package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +7 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +1 -0
- package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +48 -9
- package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +17 -4
- package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +83 -25
- package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +28 -14
- package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +5 -1
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +5 -1
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +141 -40
- package/dist/EditorStyleSheetNormalization.js +37 -0
- package/dist/EditorStyleSheetTypes.d.ts +22 -1
- package/dist/EditorTheme.js +4 -1
- package/dist/index.d.ts +1 -1
- package/dist/useRichTextEditorCommands.js +1 -6
- package/ios/EditorCore.xcframework/Info.plist +5 -5
- package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
- package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
- package/ios/EditorLayoutManager.swift +2 -4
- package/ios/EditorStyleSheet.swift +77 -11
- package/ios/EditorTextView+Commands.swift +1 -1
- package/ios/EditorTextView+Selection.swift +5 -2
- package/ios/EditorTextView.swift +5 -2
- package/ios/EditorTheme.swift +3 -1
- package/ios/EditorV2Adapter+Commands.swift +10 -0
- package/ios/EditorV2Shadow.swift +4 -0
- package/ios/RenderBridge+Atoms.swift +15 -6
- package/ios/RenderBridge+Style.swift +59 -17
- package/ios/RenderBridge.swift +19 -16
- package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +31 -13
- package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +17 -2
- package/ios/Viewer/CoreTextProseLayoutEngine.swift +39 -21
- package/package.json +3 -3
- package/rust/android/arm64-v8a/libeditor_core.so +0 -0
- package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
- package/rust/android/x86/libeditor_core.so +0 -0
- package/rust/android/x86_64/libeditor_core.so +0 -0
- package/src/EditorStyleSheetNormalization.ts +50 -0
- package/src/EditorStyleSheetTypes.ts +51 -6
- package/src/EditorTheme.ts +5 -1
- package/src/index.ts +1 -0
- package/src/useRichTextEditorCommands.tsx +1 -7
|
@@ -6,7 +6,12 @@ import android.graphics.Path
|
|
|
6
6
|
import android.graphics.RectF
|
|
7
7
|
import android.text.style.ReplacementSpan
|
|
8
8
|
|
|
9
|
-
internal fun resolvedCheckboxStyle(
|
|
9
|
+
internal fun resolvedCheckboxStyle(
|
|
10
|
+
sheet: EditorStyleSheet,
|
|
11
|
+
checked: Boolean,
|
|
12
|
+
ancestors: List<String> = emptyList()
|
|
13
|
+
): EditorElementStyle {
|
|
14
|
+
val resolved = sheet.resolveElement("taskCheckbox", ancestors)
|
|
10
15
|
val base = EditorElementStyle(
|
|
11
16
|
EditorTextStyle(),
|
|
12
17
|
EditorBoxStyle(
|
|
@@ -16,8 +21,8 @@ internal fun resolvedCheckboxStyle(sheet: EditorStyleSheet, checked: Boolean): E
|
|
|
16
21
|
size = 18f,
|
|
17
22
|
gap = 6f
|
|
18
23
|
)
|
|
19
|
-
.mergedWith(
|
|
20
|
-
return if (checked) base.mergedWith(
|
|
24
|
+
.mergedWith(resolved)
|
|
25
|
+
return if (checked) base.mergedWith(resolved?.checked) else base
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
internal fun drawCheckbox(
|
|
@@ -75,7 +75,11 @@ internal fun EditorEditText.applyThemeImpl(theme: EditorTheme?) {
|
|
|
75
75
|
background =
|
|
76
76
|
EditorBoxDrawable(it.box("content").scaled(resources.displayMetrics.density))
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
val content = theme?.styleSheet?.box("content", emptyList())?.outerInset
|
|
79
|
+
applyContentInsets(
|
|
80
|
+
content?.let { EditorContentInsets(it.top, it.right, it.bottom, it.left) }
|
|
81
|
+
?: theme?.contentInsets
|
|
82
|
+
)
|
|
79
83
|
if (hasLiveEditor()) {
|
|
80
84
|
val previousScrollX = scrollX
|
|
81
85
|
val previousScrollY = scrollY
|
|
@@ -22,7 +22,7 @@ internal fun EditorEditText.performToolbarToggleListImpl(listType: String, isAct
|
|
|
22
22
|
val update = if (isActive) {
|
|
23
23
|
driver.unwrapFromList(selection.first, selection.second)
|
|
24
24
|
} else {
|
|
25
|
-
driver.
|
|
25
|
+
driver.applyListType(listType, selection.first, selection.second)
|
|
26
26
|
}
|
|
27
27
|
update?.let { applyUpdateJSON(it) }
|
|
28
28
|
}
|
|
@@ -81,7 +81,8 @@ internal fun EditorElementStyle.mergedWith(other: EditorElementStyle?): EditorEl
|
|
|
81
81
|
internal fun resolvedMentionStyle(
|
|
82
82
|
base: EditorTextStyle,
|
|
83
83
|
theme: EditorTheme?,
|
|
84
|
-
local: EditorMentionTheme
|
|
84
|
+
local: EditorMentionTheme?,
|
|
85
|
+
ancestors: List<String> = emptyList()
|
|
85
86
|
): EditorElementStyle {
|
|
86
87
|
var result = EditorElementStyle(
|
|
87
88
|
base,
|
|
@@ -91,7 +92,7 @@ internal fun resolvedMentionStyle(
|
|
|
91
92
|
corners = EditorCorners(6f, 6f, 6f, 6f)
|
|
92
93
|
)
|
|
93
94
|
)
|
|
94
|
-
.mergedWith(theme?.styleSheet?.
|
|
95
|
+
.mergedWith(theme?.styleSheet?.resolveElement("mention", ancestors))
|
|
95
96
|
listOf(theme?.mentions?.node, local?.node).forEach { node ->
|
|
96
97
|
if (node != null) {
|
|
97
98
|
result = result.copy(
|
|
@@ -71,13 +71,32 @@ data class EditorElementStyle(
|
|
|
71
71
|
val declaredProperties: Set<String> = emptySet()
|
|
72
72
|
)
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
private data class EditorStyleRule(val path: List<String>, val style: JSONObject)
|
|
75
|
+
|
|
76
|
+
class EditorStyleSheet private constructor(
|
|
77
|
+
val styles: Map<String, EditorElementStyle>,
|
|
78
|
+
private val rules: List<EditorStyleRule> = emptyList()
|
|
79
|
+
) {
|
|
75
80
|
operator fun get(element: String): EditorElementStyle? = styles[canonicalElement(element)]
|
|
76
81
|
|
|
77
|
-
fun
|
|
82
|
+
fun resolveElement(
|
|
78
83
|
element: String,
|
|
79
|
-
ancestors: List<String> = emptyList()
|
|
80
|
-
|
|
84
|
+
ancestors: List<String> = emptyList()
|
|
85
|
+
): EditorElementStyle? {
|
|
86
|
+
val name = canonicalMark(canonicalElement(element))
|
|
87
|
+
val matches = matchingRules(name, ancestors)
|
|
88
|
+
val existing = this[name]
|
|
89
|
+
if (matches.isEmpty()) return existing
|
|
90
|
+
var result = existing ?: decodeElement(JSONObject(), defaultBox(name))
|
|
91
|
+
for (rule in matches) {
|
|
92
|
+
result = result.overlaidWith(decodeElement(rule.style, result.box), rule.style)
|
|
93
|
+
}
|
|
94
|
+
return result
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
internal fun resolveBaseText(
|
|
98
|
+
element: String,
|
|
99
|
+
ancestors: List<String> = emptyList()
|
|
81
100
|
): EditorTextStyle {
|
|
82
101
|
val name = canonicalElement(element)
|
|
83
102
|
var result = EditorTextStyle().mergedWith(this["text"]?.text)
|
|
@@ -85,18 +104,54 @@ class EditorStyleSheet private constructor(val styles: Map<String, EditorElement
|
|
|
85
104
|
ancestors.forEach {
|
|
86
105
|
result = result.mergedWith(this[it]?.text?.copy(backgroundColor = null))
|
|
87
106
|
}
|
|
88
|
-
|
|
107
|
+
return result.mergedWith(this[name]?.text?.copy(backgroundColor = null))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
fun resolveText(
|
|
111
|
+
element: String,
|
|
112
|
+
ancestors: List<String> = emptyList(),
|
|
113
|
+
marks: List<String> = emptyList()
|
|
114
|
+
): EditorTextStyle {
|
|
115
|
+
val name = canonicalElement(element)
|
|
116
|
+
var result = resolveBaseText(name, ancestors)
|
|
117
|
+
matchingRules(name, ancestors).forEach {
|
|
118
|
+
result =
|
|
119
|
+
result.mergedWith(EditorTextStyle.fromJson(it.style)?.copy(backgroundColor = null))
|
|
120
|
+
}
|
|
89
121
|
val active = marks.map(::canonicalMark).toSet()
|
|
90
122
|
listOf("inlineCode", "bold", "italic", "link", "underline", "strike").filter {
|
|
91
123
|
it in active
|
|
92
124
|
}.forEach {
|
|
93
125
|
result = result.mergedWith(semanticText(it)).mergedWith(this[it]?.text)
|
|
126
|
+
matchingRules(it, ancestors + name).forEach { rule ->
|
|
127
|
+
result = result.mergedWith(EditorTextStyle.fromJson(rule.style))
|
|
128
|
+
}
|
|
94
129
|
}
|
|
95
130
|
return result
|
|
96
131
|
}
|
|
97
132
|
|
|
98
|
-
fun box(element: String): EditorBoxStyle =
|
|
99
|
-
|
|
133
|
+
fun box(element: String): EditorBoxStyle = box(element, emptyList())
|
|
134
|
+
|
|
135
|
+
fun box(element: String, ancestors: List<String>): EditorBoxStyle {
|
|
136
|
+
var result = this[element]?.box ?: defaultBox(canonicalElement(element))
|
|
137
|
+
for (rule in matchingRules(element, ancestors)) {
|
|
138
|
+
result = decodeElement(rule.style, result).box
|
|
139
|
+
}
|
|
140
|
+
return result
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
internal fun hasMatchingRuleProperty(
|
|
144
|
+
element: String,
|
|
145
|
+
ancestors: List<String>,
|
|
146
|
+
property: String
|
|
147
|
+
): Boolean = matchingRules(element, ancestors).any { it.style.has(property) }
|
|
148
|
+
|
|
149
|
+
private fun matchingRules(element: String, ancestors: List<String>): List<EditorStyleRule> {
|
|
150
|
+
val chain = (ancestors + element).map { canonicalMark(canonicalElement(it)) }
|
|
151
|
+
return rules.filter { rule ->
|
|
152
|
+
rule.path.size <= chain.size && chain.takeLast(rule.path.size) == rule.path
|
|
153
|
+
}
|
|
154
|
+
}
|
|
100
155
|
|
|
101
156
|
companion object {
|
|
102
157
|
internal fun decodeTheme(root: JSONObject): EditorTheme? {
|
|
@@ -110,7 +165,8 @@ class EditorStyleSheet private constructor(val styles: Map<String, EditorElement
|
|
|
110
165
|
val sheet = EditorStyleSheet(
|
|
111
166
|
values.keys().asSequence().associateWith { name ->
|
|
112
167
|
decodeElement(values.getJSONObject(name), defaultBox(name))
|
|
113
|
-
}
|
|
168
|
+
},
|
|
169
|
+
decodeRules(root)
|
|
114
170
|
)
|
|
115
171
|
val content = sheet.box("content").outerInset
|
|
116
172
|
val marker = sheet["listMarker"]
|
|
@@ -160,6 +216,27 @@ class EditorStyleSheet private constructor(val styles: Map<String, EditorElement
|
|
|
160
216
|
)
|
|
161
217
|
}
|
|
162
218
|
|
|
219
|
+
private fun decodeRules(root: JSONObject): List<EditorStyleRule> {
|
|
220
|
+
val values = root.optJSONArray("rules") ?: return emptyList()
|
|
221
|
+
return buildList {
|
|
222
|
+
for (index in 0 until values.length()) {
|
|
223
|
+
val entry = values.optJSONObject(index) ?: continue
|
|
224
|
+
val pathValues = entry.optJSONArray("path") ?: continue
|
|
225
|
+
if (pathValues.length() == 0) continue
|
|
226
|
+
val path = mutableListOf<String>()
|
|
227
|
+
for (pathIndex in 0 until pathValues.length()) {
|
|
228
|
+
val raw = pathValues.opt(pathIndex) as? String ?: break
|
|
229
|
+
val name = canonicalMark(canonicalElement(raw))
|
|
230
|
+
if (name !in STYLE_NAMES) break
|
|
231
|
+
path.add(name)
|
|
232
|
+
}
|
|
233
|
+
if (path.size != pathValues.length()) continue
|
|
234
|
+
val style = entry.optJSONObject("style") ?: continue
|
|
235
|
+
add(EditorStyleRule(path.toList(), style))
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
163
240
|
internal fun decodeElement(
|
|
164
241
|
json: JSONObject,
|
|
165
242
|
fallback: EditorBoxStyle = EditorBoxStyle()
|
|
@@ -211,6 +288,117 @@ class EditorStyleSheet private constructor(val styles: Map<String, EditorElement
|
|
|
211
288
|
}
|
|
212
289
|
}
|
|
213
290
|
|
|
291
|
+
private val STYLE_NAMES = setOf(
|
|
292
|
+
"content", "text", "paragraph", "h1", "h2", "h3", "h4", "h5", "h6",
|
|
293
|
+
"blockquote", "codeBlock", "bulletList", "orderedList", "taskList", "listItem",
|
|
294
|
+
"taskItem", "listMarker", "taskCheckbox", "horizontalRule", "image", "link",
|
|
295
|
+
"inlineCode", "bold", "italic", "underline", "strike", "mention", "placeholder"
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
private fun EditorElementStyle.overlaidWith(
|
|
299
|
+
other: EditorElementStyle,
|
|
300
|
+
raw: JSONObject? = null
|
|
301
|
+
): EditorElementStyle {
|
|
302
|
+
val keys = other.declaredProperties
|
|
303
|
+
fun sides(prefix: String, current: EditorEdges, next: EditorEdges, suffix: String = "") =
|
|
304
|
+
EditorEdges(
|
|
305
|
+
if ("${prefix}Top$suffix" in keys) next.top else current.top,
|
|
306
|
+
if ("${prefix}Right$suffix" in keys) next.right else current.right,
|
|
307
|
+
if ("${prefix}Bottom$suffix" in keys) next.bottom else current.bottom,
|
|
308
|
+
if ("${prefix}Left$suffix" in keys) next.left else current.left
|
|
309
|
+
)
|
|
310
|
+
val nextChecked = if ("checked" in keys) {
|
|
311
|
+
other.checked?.let {
|
|
312
|
+
(checked ?: EditorElementStyle(EditorTextStyle(), box)).overlaidWith(
|
|
313
|
+
it,
|
|
314
|
+
raw?.optJSONObject("checked")
|
|
315
|
+
)
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
checked
|
|
319
|
+
}
|
|
320
|
+
val nextOrdered = if ("ordered" in keys) {
|
|
321
|
+
other.ordered?.let { next ->
|
|
322
|
+
val current = ordered ?: EditorOrderedListMarkerTheme()
|
|
323
|
+
val orderedJson = raw?.optJSONObject("ordered")
|
|
324
|
+
EditorOrderedListMarkerTheme(
|
|
325
|
+
schemes = if (orderedJson?.has("schemes") ==
|
|
326
|
+
true
|
|
327
|
+
) {
|
|
328
|
+
next.schemes
|
|
329
|
+
} else {
|
|
330
|
+
current.schemes
|
|
331
|
+
},
|
|
332
|
+
suffix = if (orderedJson?.has("suffix") == true) next.suffix else current.suffix
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
ordered
|
|
337
|
+
}
|
|
338
|
+
return copy(
|
|
339
|
+
text = text.mergedWith(other.text),
|
|
340
|
+
box = box.copy(
|
|
341
|
+
backgroundColor = if ("backgroundColor" in keys) {
|
|
342
|
+
other.box.backgroundColor
|
|
343
|
+
} else {
|
|
344
|
+
box.backgroundColor
|
|
345
|
+
},
|
|
346
|
+
padding = sides("padding", box.padding, other.box.padding),
|
|
347
|
+
margin = sides("margin", box.margin, other.box.margin),
|
|
348
|
+
border = sides("border", box.border, other.box.border, "Width"),
|
|
349
|
+
borderColors = listOf("Top", "Right", "Bottom", "Left").mapIndexed { index, side ->
|
|
350
|
+
if ("border${side}Color" in keys) {
|
|
351
|
+
other.box.borderColors[index]
|
|
352
|
+
} else {
|
|
353
|
+
box.borderColors[index]
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
corners = EditorCorners(
|
|
357
|
+
if ("borderTopLeftRadius" in
|
|
358
|
+
keys
|
|
359
|
+
) {
|
|
360
|
+
other.box.corners.topLeft
|
|
361
|
+
} else {
|
|
362
|
+
box.corners.topLeft
|
|
363
|
+
},
|
|
364
|
+
if ("borderTopRightRadius" in
|
|
365
|
+
keys
|
|
366
|
+
) {
|
|
367
|
+
other.box.corners.topRight
|
|
368
|
+
} else {
|
|
369
|
+
box.corners.topRight
|
|
370
|
+
},
|
|
371
|
+
if ("borderBottomRightRadius" in keys) {
|
|
372
|
+
other.box.corners.bottomRight
|
|
373
|
+
} else {
|
|
374
|
+
box.corners.bottomRight
|
|
375
|
+
},
|
|
376
|
+
if ("borderBottomLeftRadius" in keys) {
|
|
377
|
+
other.box.corners.bottomLeft
|
|
378
|
+
} else {
|
|
379
|
+
box.corners.bottomLeft
|
|
380
|
+
}
|
|
381
|
+
),
|
|
382
|
+
borderStyle = if ("borderStyle" in keys) other.box.borderStyle else box.borderStyle
|
|
383
|
+
),
|
|
384
|
+
indent = if ("indent" in keys) other.indent else indent,
|
|
385
|
+
baseIndentMultiplier = if ("baseIndentMultiplier" in keys) {
|
|
386
|
+
other.baseIndentMultiplier
|
|
387
|
+
} else {
|
|
388
|
+
baseIndentMultiplier
|
|
389
|
+
},
|
|
390
|
+
scale = if ("scale" in keys) other.scale else scale,
|
|
391
|
+
gap = if ("gap" in keys) other.gap else gap,
|
|
392
|
+
ordered = nextOrdered,
|
|
393
|
+
checked = nextChecked,
|
|
394
|
+
resizeMode = if ("resizeMode" in keys) other.resizeMode else resizeMode,
|
|
395
|
+
size = if ("size" in keys) other.size else size,
|
|
396
|
+
checkColor = if ("checkColor" in keys) other.checkColor else checkColor,
|
|
397
|
+
height = if ("height" in keys) other.height else height,
|
|
398
|
+
declaredProperties = declaredProperties + keys
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
|
|
214
402
|
internal fun canonicalElement(name: String): String = when (name) {
|
|
215
403
|
"bullet_list" -> "bulletList"
|
|
216
404
|
"ordered_list" -> "orderedList"
|
|
@@ -870,6 +870,13 @@ internal class EditorV2Adapter private constructor(
|
|
|
870
870
|
override fun toggleBlockquote(anchor: Int, head: Int): String? =
|
|
871
871
|
commandAtSelection(JSONObject().put("type", "toggleBlockquote"), anchor, head)
|
|
872
872
|
|
|
873
|
+
override fun applyListType(listType: String, anchor: Int, head: Int): String? =
|
|
874
|
+
commandAtSelection(
|
|
875
|
+
JSONObject().put("type", "applyListType").put("listType", listType),
|
|
876
|
+
anchor,
|
|
877
|
+
head
|
|
878
|
+
)
|
|
879
|
+
|
|
873
880
|
override fun wrapInList(listType: String, anchor: Int, head: Int): String? {
|
|
874
881
|
val itemType = EditorNodeTypes.listItemType(listType)
|
|
875
882
|
return commandAtSelection(
|
|
@@ -66,6 +66,7 @@ internal interface EditorV2Driver {
|
|
|
66
66
|
fun toggleHeading(level: Int, anchor: Int, head: Int): String?
|
|
67
67
|
fun toggleCodeBlock(anchor: Int, head: Int): String?
|
|
68
68
|
fun toggleBlockquote(anchor: Int, head: Int): String?
|
|
69
|
+
fun applyListType(listType: String, anchor: Int, head: Int): String?
|
|
69
70
|
fun wrapInList(listType: String, anchor: Int, head: Int): String?
|
|
70
71
|
fun unwrapFromList(anchor: Int, head: Int): String?
|
|
71
72
|
fun indentListItem(anchor: Int, head: Int): String?
|
|
@@ -83,7 +83,9 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
83
83
|
val selectedSpan = editorView?.selectedImageSpanForResize()
|
|
84
84
|
if (currentGeometry?.docPos != nextGeometry.docPos ||
|
|
85
85
|
dragState?.span?.let { it !== selectedSpan } == true
|
|
86
|
-
)
|
|
86
|
+
) {
|
|
87
|
+
cancelActiveResize()
|
|
88
|
+
}
|
|
87
89
|
currentGeometry = nextGeometry
|
|
88
90
|
visibility = VISIBLE
|
|
89
91
|
bringToFront()
|
|
@@ -138,7 +140,10 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
138
140
|
fixedHeightPx = geometry.rect.height() - span.currentSizePx().second,
|
|
139
141
|
maximumWidthPx = editorView?.maximumImageWidthPx() ?: geometry.rect.width(),
|
|
140
142
|
previewRect = RectF(geometry.rect),
|
|
141
|
-
previewContentSize = span.currentSizePx().let {
|
|
143
|
+
previewContentSize = span.currentSizePx().let {
|
|
144
|
+
it.first.toFloat() to
|
|
145
|
+
it.second.toFloat()
|
|
146
|
+
}
|
|
142
147
|
)
|
|
143
148
|
parent?.requestDisallowInterceptTouchEvent(true)
|
|
144
149
|
return true
|
|
@@ -163,7 +168,9 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
163
168
|
)
|
|
164
169
|
}
|
|
165
170
|
editorView?.restoreImageResizePreview(state.span)
|
|
166
|
-
} else
|
|
171
|
+
} else {
|
|
172
|
+
editorView?.restoreImageResizePreview(state.span)
|
|
173
|
+
}
|
|
167
174
|
dragState = null
|
|
168
175
|
parent?.requestDisallowInterceptTouchEvent(false)
|
|
169
176
|
post { refresh() }
|
|
@@ -188,7 +195,9 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
188
195
|
originalContentSize.first,
|
|
189
196
|
originalContentSize.second
|
|
190
197
|
)
|
|
191
|
-
)
|
|
198
|
+
) {
|
|
199
|
+
return
|
|
200
|
+
}
|
|
192
201
|
state.previewRect = RectF(state.originalRect)
|
|
193
202
|
state.previewContentSize = originalContentSize
|
|
194
203
|
currentGeometry = boundEditor.selectedImageGeometry()
|
|
@@ -209,7 +218,14 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
209
218
|
maximumWidthPx = state.maximumWidthPx
|
|
210
219
|
)
|
|
211
220
|
val boundEditor = editorView ?: return
|
|
212
|
-
if (!boundEditor.previewImageResize(
|
|
221
|
+
if (!boundEditor.previewImageResize(
|
|
222
|
+
state.span,
|
|
223
|
+
contentSize.first,
|
|
224
|
+
contentSize.second
|
|
225
|
+
)
|
|
226
|
+
) {
|
|
227
|
+
return
|
|
228
|
+
}
|
|
213
229
|
state.previewRect = RectF(nextRect)
|
|
214
230
|
state.previewContentSize = contentSize
|
|
215
231
|
currentGeometry = boundEditor.selectedImageGeometry()
|
|
@@ -324,10 +340,33 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
324
340
|
val visualWidth = width + fixedWidthPx
|
|
325
341
|
val visualHeight = height + fixedHeightPx
|
|
326
342
|
val rect = when (corner) {
|
|
327
|
-
Corner.TOP_LEFT -> RectF(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
343
|
+
Corner.TOP_LEFT -> RectF(
|
|
344
|
+
anchor.x - visualWidth,
|
|
345
|
+
anchor.y - visualHeight,
|
|
346
|
+
anchor.x,
|
|
347
|
+
anchor.y
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
Corner.TOP_RIGHT -> RectF(
|
|
351
|
+
anchor.x,
|
|
352
|
+
anchor.y - visualHeight,
|
|
353
|
+
anchor.x + visualWidth,
|
|
354
|
+
anchor.y
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
Corner.BOTTOM_LEFT -> RectF(
|
|
358
|
+
anchor.x - visualWidth,
|
|
359
|
+
anchor.y,
|
|
360
|
+
anchor.x,
|
|
361
|
+
anchor.y + visualHeight
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
Corner.BOTTOM_RIGHT -> RectF(
|
|
365
|
+
anchor.x,
|
|
366
|
+
anchor.y,
|
|
367
|
+
anchor.x + visualWidth,
|
|
368
|
+
anchor.y + visualHeight
|
|
369
|
+
)
|
|
331
370
|
}
|
|
332
371
|
return rect to (width to height)
|
|
333
372
|
}
|
|
@@ -285,9 +285,9 @@ internal fun RenderBridge.calculateIndent(
|
|
|
285
285
|
density: Float
|
|
286
286
|
): Float {
|
|
287
287
|
theme?.styleSheet?.let { sheet ->
|
|
288
|
-
val lists = blockStack.filter { it.listContext != null }
|
|
289
|
-
return lists.mapIndexed { index,
|
|
290
|
-
val context =
|
|
288
|
+
val lists = blockStack.withIndex().filter { it.value.listContext != null }
|
|
289
|
+
return lists.mapIndexed { index, entry ->
|
|
290
|
+
val context = entry.value.listContext!!
|
|
291
291
|
val name = if (context.optString("kind") ==
|
|
292
292
|
"task"
|
|
293
293
|
) {
|
|
@@ -297,7 +297,20 @@ internal fun RenderBridge.calculateIndent(
|
|
|
297
297
|
} else {
|
|
298
298
|
"bulletList"
|
|
299
299
|
}
|
|
300
|
-
val
|
|
300
|
+
val prefix = blockStack.take(entry.index)
|
|
301
|
+
val containerIndex = prefix.indexOfLast { canonicalElement(it.nodeType) == name }
|
|
302
|
+
val style = sheet.resolveElement(
|
|
303
|
+
name,
|
|
304
|
+
prefix.take(
|
|
305
|
+
if (containerIndex >=
|
|
306
|
+
0
|
|
307
|
+
) {
|
|
308
|
+
containerIndex
|
|
309
|
+
} else {
|
|
310
|
+
prefix.size
|
|
311
|
+
}
|
|
312
|
+
).map { it.nodeType }
|
|
313
|
+
)
|
|
301
314
|
(style?.indent ?: LayoutConstants.INDENT_PER_DEPTH) *
|
|
302
315
|
(if (index == 0) style?.baseIndentMultiplier ?: 1f else 1f) *
|
|
303
316
|
density
|