• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "core/components_ng/pattern/text/span/mutable_span_string.h"
17 
18 #include "core/text/text_emoji_processor.h"
19 
20 namespace OHOS::Ace {
21 namespace {
GetWStringLength(const std::u16string & str)22 int32_t GetWStringLength(const std::u16string& str)
23 {
24     return static_cast<int32_t>(str.length());
25 }
26 } // namespace
27 
28 const std::vector<SpanType> specailTypes = { SpanType::Image, SpanType::CustomSpan };
29 
SplitSpansByNewLine()30 void MutableSpanString::SplitSpansByNewLine()
31 {
32     for (auto it = spans_.begin(); it != spans_.end();) {
33         it = SplitSpansAndForward(it);
34     }
35 }
36 
RemoveSpans(int32_t start,int32_t length,bool removeSpecialSpan)37 void MutableSpanString::RemoveSpans(int32_t start, int32_t length, bool removeSpecialSpan)
38 {
39     if (!CheckRange(start, length)) {
40         return;
41     }
42     auto end = start + length;
43     length = end - start;
44     std::list<SpanType> typeList;
45     auto iter = typeList.begin();
46     for (auto& it : spansMap_) {
47         auto spanKey = it.first;
48         if (spanKey != SpanType::CustomSpan && spanKey != SpanType::Image) {
49             iter = typeList.insert(iter, spanKey);
50         }
51     }
52     for (const auto& spanKey : typeList) {
53         if (spanKey != SpanType::CustomSpan && spanKey != SpanType::Image) {
54             RemoveSpan(start, length, spanKey);
55         }
56     }
57     if (removeSpecialSpan) {
58         RemoveSpecialSpans(start, length);
59     }
60 }
61 
RemoveSpecialSpans(int32_t start,int32_t length)62 void MutableSpanString::RemoveSpecialSpans(int32_t start, int32_t length)
63 {
64     if (!CheckRange(start, length)) {
65         return;
66     }
67     auto end = start + length;
68     length = end - start;
69     std::list<RefPtr<SpanBase>> spanBaseList;
70     auto iter = spanBaseList.begin();
71     for (const auto& type : specailTypes) {
72         auto spans = spansMap_[type];
73         for (const auto& span : spans) {
74             auto spanIndex = span->GetStartIndex();
75             if (start <= spanIndex && spanIndex < end) {
76                 iter = spanBaseList.insert(iter, span);
77             }
78         }
79     }
80     spanBaseList.sort(
81         [](const RefPtr<SpanBase>& a, const RefPtr<SpanBase>& b) { return a->GetStartIndex() < b->GetStartIndex(); });
82     for (const auto& span : spanBaseList) {
83         auto index = span->GetStartIndex();
84         RemoveSpan(index, 1, span->GetSpanType());
85     }
86 }
87 
ReplaceSpan(int32_t start,int32_t length,const RefPtr<SpanBase> & span)88 void MutableSpanString::ReplaceSpan(int32_t start, int32_t length, const RefPtr<SpanBase>& span)
89 {
90     if (!CheckRange(start, length)) {
91         return;
92     }
93     auto end = start + length;
94     length = end - start;
95     if (IsSpecialNode(span)) {
96         RemoveSpans(start, length);
97         AddSpan(span->GetSubSpan(start, start + length));
98         return;
99     }
100     std::list<std::pair<int32_t, int32_t>> indexList;
101     GetNormalTypesVector(indexList, start, length);
102     std::list<int32_t> specialList;
103     GetSpecialTypesVector(specialList, start, length);
104     for (const auto& pair : indexList) {
105         auto startIndex = pair.first;
106         auto secondIndex = pair.second;
107         RemoveSpans(startIndex, secondIndex);
108     }
109     for (const auto& index : specialList) {
110         RemoveSpans(index, 1, false);
111     }
112     AddSpan(span->GetSubSpan(start, start + length));
113 }
114 
ApplyReplaceStringToSpans(int32_t start,int32_t length,const std::u16string & other,SpanStringOperation op)115 void MutableSpanString::ApplyReplaceStringToSpans(
116     int32_t start, int32_t length, const std::u16string& other, SpanStringOperation op)
117 {
118     int32_t end = start + length;
119     for (auto it = spans_.begin(); it != spans_.end();) {
120         auto intersection = (*it)->GetIntersectionInterval({ start, end });
121         if (!intersection) {
122             ++it;
123             continue;
124         }
125         it = HandleSpanOperation(it, start, length, other, op, intersection.value());
126     }
127 }
128 
HandleSpanOperation(std::list<RefPtr<NG::SpanItem>>::iterator it,int32_t start,int32_t length,const std::u16string & other,SpanStringOperation op,const std::pair<int32_t,int32_t> & intersection)129 std::list<RefPtr<NG::SpanItem>>::iterator MutableSpanString::HandleSpanOperation(
130     std::list<RefPtr<NG::SpanItem>>::iterator it, int32_t start, int32_t length,
131     const std::u16string& other, SpanStringOperation op, const std::pair<int32_t, int32_t>& intersection)
132 {
133     auto end = start + length;
134     auto spanItemStart = (*it)->interval.first;
135     auto spanItemEnd = (*it)->interval.second;
136     auto wContent = (*it)->content;
137 
138     if (spanItemStart == start && op == SpanStringOperation::REPLACE) {
139         if ((*it)->spanItemType == SpanItemType::IMAGE || (*it)->spanItemType == SpanItemType::CustomSpan) {
140             auto newSpan = MakeRefPtr<NG::SpanItem>();
141             newSpan->UpdateContent(other);
142             newSpan->interval.first = spanItemStart;
143             newSpan->interval.second = GetWStringLength(newSpan->content) + spanItemStart;
144             it = spans_.erase(it);
145             it = spans_.insert(it, newSpan);
146         } else {
147             (*it)->UpdateContent(other + GetWideStringSubstr(wContent, length));
148             (*it)->interval.second = GetWStringLength((*it)->content) + spanItemStart;
149         }
150         ++it;
151         return it;
152     }
153 
154     if (spanItemStart == intersection.first && spanItemEnd == intersection.second) {
155         return spans_.erase(it);
156     }
157 
158     if (spanItemStart < intersection.first && intersection.second < spanItemEnd && op == SpanStringOperation::REMOVE) {
159         auto newSpan = (*it)->GetSameStyleSpanItem();
160         (*it)->interval = { spanItemStart, start };
161         (*it)->UpdateContent(wContent.substr(0, start - spanItemStart));
162         newSpan->interval = { end, spanItemEnd };
163         newSpan->UpdateContent(wContent.substr(end - spanItemStart, spanItemEnd - end));
164         ++it;
165         spans_.insert(it, newSpan);
166         return it;
167     }
168 
169     if (intersection.first > spanItemStart) {
170         if (op == SpanStringOperation::REMOVE) {
171             (*it)->UpdateContent(wContent.substr(0, start - spanItemStart));
172             (*it)->interval.second = start;
173         } else {
174             (*it)->UpdateContent(GetWideStringSubstr(wContent, 0, start - spanItemStart) + other +
175                                                     GetWideStringSubstr(wContent, end - spanItemStart));
176             (*it)->interval.second = std::max(end, spanItemEnd);
177         }
178     } else {
179         (*it)->UpdateContent(GetWideStringSubstr(wContent, end - spanItemStart));
180         (*it)->interval.first = end;
181     }
182     return ++it;
183 }
184 
ApplyReplaceStringToSpanBase(int32_t start,int32_t length,const std::u16string & other,SpanStringOperation op)185 void MutableSpanString::ApplyReplaceStringToSpanBase(
186     int32_t start, int32_t length, const std::u16string& other, SpanStringOperation op)
187 {
188     int32_t end = start + length;
189     for (auto& iter : spansMap_) {
190         if (spansMap_.find(iter.first) == spansMap_.end()) {
191             spansMap_[iter.first] = {};
192         }
193         auto spans = spansMap_[iter.first];
194         ProcessSpanBaseList(spans, start, end, other, op, iter.first);
195         spansMap_[iter.first] = spans;
196     }
197 }
198 
ProcessSpanBaseList(std::list<RefPtr<SpanBase>> & spans,int32_t start,int32_t end,const std::u16string & other,SpanStringOperation op,SpanType spanType)199 void MutableSpanString::ProcessSpanBaseList(std::list<RefPtr<SpanBase>>& spans, int32_t start,
200     int32_t end, const std::u16string& other, SpanStringOperation op, SpanType spanType)
201 {
202     for (auto it = spans.begin(); it != spans.end();) {
203         auto spanStart = (*it)->GetStartIndex();
204         auto spanEnd = (*it)->GetEndIndex();
205         auto intersection = (*it)->GetIntersectionInterval({ start, end });
206         if (!intersection) {
207             ++it;
208             continue;
209         }
210         if (spanStart == start && op == SpanStringOperation::REPLACE) {
211             if (spanType == SpanType::Image || spanType == SpanType::CustomSpan) {
212                 it = spans.erase(it);
213                 continue;
214             }
215             auto newLength = other.length();
216             if (end < spanEnd) {
217                 newLength += static_cast<size_t>(spanEnd - end);
218             }
219             (*it)->UpdateEndIndex(newLength + spanStart);
220             ++it;
221             continue;
222         }
223         if (intersection->first == spanStart && intersection->second == spanEnd) {
224             it = spans.erase(it);
225             continue;
226         }
227         if (spanStart < intersection->first && intersection->second < spanEnd &&
228             op == SpanStringOperation::REMOVE) {
229             auto newSpan = (*it)->GetSubSpan(end, spanEnd);
230             (*it)->UpdateEndIndex(start);
231             ++it;
232             spans.insert(it, newSpan);
233             continue;
234         }
235         auto newEnd = (op != SpanStringOperation::REMOVE) ? std::max(end, spanEnd) : start;
236         if (intersection->first > spanStart) {
237             (*it)->UpdateEndIndex(newEnd);
238         } else {
239             (*it)->UpdateStartIndex(intersection->second);
240         }
241         ++it;
242     }
243 }
244 
ReplaceString(int32_t start,int32_t length,const std::u16string & other)245 void MutableSpanString::ReplaceString(int32_t start, int32_t length, const std::u16string& other)
246 {
247     if (!CheckRange(start, length)) {
248         return;
249     }
250     auto end = start + length;
251     length = end - start;
252     SpanStringOperation op = SpanStringOperation::REPLACE;
253     auto otherLength = other.length();
254     if (otherLength == 0) {
255         op = SpanStringOperation::REMOVE;
256     }
257     auto text = GetU16string();
258     SetString(text.substr(0, start) + other + text.substr(end));
259     ApplyReplaceStringToSpans(start, length, other, op);
260     ApplyReplaceStringToSpanBase(start, length, other, op);
261     UpdateSpansWithOffset(start, otherLength - length);
262     UpdateSpanMapWithOffset(start, otherLength - length);
263     SplitSpansByNewLine();
264     KeepSpansOrder();
265 }
266 
UpdateSpansAndSpanMapWithOffsetAfterInsert(int32_t start,int32_t offset,bool useFrontStyle)267 void MutableSpanString::UpdateSpansAndSpanMapWithOffsetAfterInsert(int32_t start, int32_t offset, bool useFrontStyle)
268 {
269     for (auto& span : spans_) {
270         if (span->interval.first > start || (span->interval.first == start && useFrontStyle)) {
271             span->interval.first += offset;
272         }
273         if (span->interval.second > start || (span->interval.second == start && useFrontStyle)) {
274             span->interval.second += offset;
275         }
276     }
277     for (auto& iter : spansMap_) {
278         if (spansMap_.find(iter.first) == spansMap_.end()) {
279             continue;
280         }
281         auto spans = spansMap_[iter.first];
282         for (auto& span : spans) {
283             if (span->GetStartIndex() > start || (span->GetStartIndex() == start && useFrontStyle)) {
284                 span->UpdateStartIndex(span->GetStartIndex() + offset);
285             }
286             if (span->GetEndIndex() > start || (span->GetEndIndex() == start && useFrontStyle)) {
287                 span->UpdateEndIndex(span->GetEndIndex() + offset);
288             }
289         }
290         spansMap_[iter.first] = spans;
291     }
292 }
293 
InsertUseFrontStyle(int32_t start)294 bool MutableSpanString::InsertUseFrontStyle(int32_t start)
295 {
296     if (start == GetLength()) {
297         return true;
298     }
299     for (auto& iter : spansMap_) {
300         if (spansMap_.find(iter.first) == spansMap_.end()) {
301             continue;
302         }
303         auto spans = spansMap_[iter.first];
304         for (auto& span : spans) {
305             if (span->GetStartIndex() <= start - 1 && span->GetEndIndex() > start - 1) {
306                 return true;
307             }
308         }
309     }
310     return false;
311 }
312 
InsertString(int32_t start,const std::u16string & other)313 void MutableSpanString::InsertString(int32_t start, const std::u16string& other)
314 {
315     auto len = GetLength();
316     if (other.length() == 0 || start > len) {
317         return;
318     }
319     auto isAround = IsInsertAroundSpecialNode(start);
320     if (isAround != AroundSpecialNode::NONE) {
321         InsertStringAroundSpecialNode(start, other, isAround);
322         NotifySpanWatcher();
323         return;
324     }
325     bool useFrontStyle = InsertUseFrontStyle(start);
326     auto text = GetU16string();
327     text = GetWideStringSubstr(text, 0, start) + other + GetWideStringSubstr(text, start);
328     SetString(text);
329     auto otherLength = other.length();
330     if (len == 0) {
331         spans_.clear();
332         auto spanItem = MakeRefPtr<NG::SpanItem>();
333         spanItem->UpdateContent(other);
334         spanItem->interval = { 0, otherLength };
335         spans_.emplace_back(spanItem);
336         NotifySpanWatcher();
337         return;
338     }
339     for (auto& span : spans_) {
340         auto spanItemStart = span->interval.first;
341         auto spanItemEnd = span->interval.second;
342         if (start == 0 && spanItemStart == 0) {
343             span->UpdateContent(other + span->content);
344             break;
345         }
346         if (start - 1 >= spanItemStart && start - 1 < spanItemEnd && useFrontStyle) {
347             span->UpdateContent(GetWideStringSubstr(span->content, 0, start - spanItemStart) + other +
348                 GetWideStringSubstr(span->content, start - spanItemStart));
349             break;
350         }
351         if (start >= spanItemStart && start < spanItemEnd) {
352             span->UpdateContent(GetWideStringSubstr(span->content, 0, start - spanItemStart) + other +
353                 GetWideStringSubstr(span->content, start - spanItemStart));
354             break;
355         }
356     }
357     UpdateSpansAndSpanMapWithOffsetAfterInsert(start, otherLength, useFrontStyle);
358     SplitSpansByNewLine();
359     KeepSpansOrder();
360     NotifySpanWatcher();
361 }
362 
RemoveString(int32_t start,int32_t length)363 void MutableSpanString::RemoveString(int32_t start, int32_t length)
364 {
365     auto end = start + length;
366     ReplaceString(start, end - start, u"");
367     NotifySpanWatcher();
368 }
369 
RemoveSpecialpanText()370 void MutableSpanString::RemoveSpecialpanText()
371 {
372     std::list<int32_t> indexList;
373     GetSpecialTypesVector(indexList, 0, GetLength());
374     int32_t count = 0;
375     for (const auto& index : indexList) {
376         text_.erase(index - count, 1);
377         ++count;
378     }
379 }
380 
ClearAllSpans()381 void MutableSpanString::ClearAllSpans()
382 {
383     RemoveSpecialpanText();
384     spansMap_.clear();
385     spans_.clear();
386     spans_.emplace_back(GetDefaultSpanItem(text_));
387     SplitSpansByNewLine();
388 }
389 
KeepSpansOrder()390 void MutableSpanString::KeepSpansOrder()
391 {
392     for (auto& it : spansMap_) {
393         auto spans = spansMap_[it.first];
394         SortSpans(spans);
395         MergeIntervals(spans);
396         spansMap_[it.first] = spans;
397     }
398 }
399 
ReplaceSpanString(int32_t start,int32_t length,const RefPtr<SpanString> & spanString)400 void MutableSpanString::ReplaceSpanString(int32_t start, int32_t length, const RefPtr<SpanString>& spanString)
401 {
402     if (length < 0 || start + length > GetLength()) {
403         return;
404     }
405     auto end = start + length;
406     length = end - start;
407     if (length != 0) {
408         RemoveString(start, length);
409     }
410     InsertSpanString(start, spanString);
411 }
412 
UpdateSpanAndSpanMapAfterInsertSpanString(int32_t start,int32_t offset)413 void MutableSpanString::UpdateSpanAndSpanMapAfterInsertSpanString(int32_t start, int32_t offset)
414 {
415     for (auto& span : spans_) {
416         if (span->interval.first >= start) {
417             span->interval.first += offset;
418         }
419         if (span->interval.second > start) {
420             span->interval.second += offset;
421         }
422     }
423 }
424 
ApplyInsertSpanStringToSpans(int32_t start,const RefPtr<SpanString> & spanString)425 void MutableSpanString::ApplyInsertSpanStringToSpans(int32_t start, const RefPtr<SpanString>& spanString)
426 {
427     auto offset = spanString->GetLength();
428     for (auto it = spans_.begin(); it != spans_.end(); ++it) {
429         auto spanItemStart = (*it)->interval.first;
430         auto spanItemEnd = (*it)->interval.second;
431         if (spanItemEnd < start || spanItemStart > start) {
432             continue;
433         }
434         if (spanItemEnd != start) {
435             auto newSpanItem = (*it)->GetSameStyleSpanItem();
436             newSpanItem->interval.first = start + offset;
437             newSpanItem->interval.second = spanItemEnd;
438             auto wStr = (*it)->content;
439             newSpanItem->UpdateContent(GetWideStringSubstr(wStr, start - spanItemStart));
440             (*it)->interval.second = start;
441             (*it)->UpdateContent(GetWideStringSubstr(wStr, 0, start - spanItemStart));
442             ++it;
443             it = spans_.insert(it, newSpanItem);
444         } else {
445             ++it;
446         }
447         auto otherSpans = spanString->GetSpanItems();
448         for (auto rit = otherSpans.rbegin(); rit != otherSpans.rend(); ++rit) {
449             auto newSpanItem = (*rit)->GetSameStyleSpanItem();
450             newSpanItem->interval.first = (*rit)->interval.first + start;
451             newSpanItem->interval.second = (*rit)->interval.second + start;
452             newSpanItem->UpdateContent((*rit)->content);
453             it = spans_.insert(it, newSpanItem);
454         }
455         break;
456     }
457 }
458 
ApplyInsertSpanStringToSpanBase(int32_t start,const RefPtr<SpanString> & spanString)459 void MutableSpanString::ApplyInsertSpanStringToSpanBase(int32_t start, const RefPtr<SpanString>& spanString)
460 {
461     auto offset = spanString->GetLength();
462     auto otherSpansMap = spanString->GetSpansMap();
463     for (auto& iter : spansMap_) {
464         auto spans = spansMap_[iter.first];
465         for (auto it = spans.begin(); it != spans.end(); ++it) {
466             auto spanItemStart = (*it)->GetStartIndex();
467             auto spanItemEnd = (*it)->GetEndIndex();
468             if (spanItemStart >= start) {
469                 (*it)->UpdateStartIndex(spanItemStart + offset);
470                 (*it)->UpdateEndIndex(spanItemEnd + offset);
471             } else if (spanItemStart < start && start < spanItemEnd) {
472                 auto newSpanItem = (*it)->GetSubSpan(start + offset, spanItemEnd + offset);
473                 (*it)->UpdateEndIndex(start);
474                 ++it;
475                 it = spans.insert(it, newSpanItem);
476             }
477         }
478         spansMap_[iter.first] = spans;
479     }
480 
481     for (auto& iter : otherSpansMap) {
482         auto spans = spansMap_[iter.first];
483         auto otherSpans = otherSpansMap[iter.first];
484         for (auto& spanBase : otherSpans) {
485             auto newSpanItem = spanBase->GetSubSpan(spanBase->GetStartIndex() + start, spanBase->GetEndIndex() + start);
486             spans.emplace_back(newSpanItem);
487         }
488         spansMap_[iter.first] = spans;
489     }
490 }
491 
InsertSpanString(int32_t start,const RefPtr<SpanString> & spanString)492 void MutableSpanString::InsertSpanString(int32_t start, const RefPtr<SpanString>& spanString)
493 {
494     auto len = GetLength();
495     if (start > len || spanString->GetLength() == 0) {
496         return;
497     }
498     auto offset = spanString->GetLength();
499     SetString(GetWideStringSubstr(GetU16string(), 0, start) + spanString->GetU16string() +
500         GetWideStringSubstr(GetU16string(), start));
501     UpdateSpanAndSpanMapAfterInsertSpanString(start, offset);
502     if (start == 0 || start == len) {
503         if (len == 0) {
504             spans_.clear();
505         }
506         auto it = start == 0 ? spans_.begin() : spans_.end();
507         auto otherSpans = spanString->GetSpanItems();
508         for (auto rit = otherSpans.rbegin(); rit != otherSpans.rend(); ++rit) {
509             auto newSpanItem = (*rit)->GetSameStyleSpanItem();
510             newSpanItem->interval.first = (*rit)->interval.first + start;
511             newSpanItem->interval.second = (*rit)->interval.second + start;
512             newSpanItem->UpdateContent((*rit)->content);
513             it = spans_.insert(it, newSpanItem);
514         }
515     } else {
516         ApplyInsertSpanStringToSpans(start, spanString);
517     }
518     ApplyInsertSpanStringToSpanBase(start, spanString);
519     KeepSpansOrder();
520     NotifySpanWatcher();
521 }
522 
AppendSpanString(const RefPtr<SpanString> & spanString)523 void MutableSpanString::AppendSpanString(const RefPtr<SpanString>& spanString)
524 {
525     InsertSpanString(GetLength(), spanString);
526 }
527 
IsInsertAroundSpecialNode(int32_t start)528 AroundSpecialNode MutableSpanString::IsInsertAroundSpecialNode(int32_t start)
529 {
530     AroundSpecialNode res = AroundSpecialNode::NONE;
531     if (spansMap_.find(SpanType::Image) == spansMap_.end() && spansMap_.find(SpanType::CustomSpan) == spansMap_.end()) {
532         return res;
533     }
534 
535     for (const auto& type : specailTypes) {
536         auto specialSpans = spansMap_[type];
537         for (const auto& span : specialSpans) {
538             if (span->GetEndIndex() == start) {
539                 res = (res == AroundSpecialNode::NONE || res == AroundSpecialNode::AFTER) ? AroundSpecialNode::AFTER
540                                                                                           : AroundSpecialNode::BETWEEN;
541             }
542             if (span->GetStartIndex() == start) {
543                 res = (res == AroundSpecialNode::NONE || res == AroundSpecialNode::BEFORE) ? AroundSpecialNode::BEFORE
544                                                                                            : AroundSpecialNode::BETWEEN;
545             }
546         }
547     }
548     return res;
549 }
550 
InsertStringAroundSpecialNode(int32_t start,const std::u16string & str,AroundSpecialNode aroundMode)551 void MutableSpanString::InsertStringAroundSpecialNode(
552     int32_t start, const std::u16string& str, AroundSpecialNode aroundMode)
553 {
554     auto iter = spans_.begin();
555     auto step = GetStepsByPosition(start);
556     RefPtr<NG::SpanItem> spanItem = MakeRefPtr<NG::SpanItem>();
557     std::advance(iter, step);
558     if (aroundMode == AroundSpecialNode::BEFORE && step >= 1) {
559         auto iter2 = spans_.begin();
560         std::advance(iter2, step - 1);
561         spanItem = (*iter2)->GetSameStyleSpanItem();
562     } else if (aroundMode == AroundSpecialNode::AFTER && iter != spans_.end()) {
563         spanItem = (*iter)->GetSameStyleSpanItem();
564     }
565     int32_t length = static_cast<int32_t>(str.length());
566     spanItem->UpdateContent(str);
567     spanItem->interval.first = start;
568     spanItem->interval.second = start + length;
569     auto beforeStr = GetWideStringSubstr(GetU16string(), 0, start);
570     auto afterStr = GetWideStringSubstr(GetU16string(), start);
571     SetString(beforeStr + str + afterStr);
572     iter = spans_.insert(iter, spanItem);
573     ++iter;
574     for (; iter != spans_.end(); ++iter) {
575         (*iter)->interval.first += length;
576         (*iter)->interval.second += length;
577     }
578 
579     SplitSpansByNewLine();
580 
581     for (auto& mapIter : spansMap_) {
582         if (spansMap_.find(mapIter.first) == spansMap_.end()) {
583             continue;
584         }
585         auto spans = spansMap_[mapIter.first];
586         for (auto& span : spans) {
587             if (span->GetStartIndex() > start ||
588                 (span->GetStartIndex() == start && aroundMode != AroundSpecialNode::AFTER)) {
589                 span->UpdateStartIndex(span->GetStartIndex() + length);
590                 span->UpdateEndIndex(span->GetEndIndex() + length);
591             }
592         }
593         spansMap_[mapIter.first] = spans;
594     }
595 }
596 
IsSpeicalNode(int32_t location,SpanType speicalType)597 bool MutableSpanString::IsSpeicalNode(int32_t location, SpanType speicalType)
598 {
599     if (spansMap_.find(speicalType) == spansMap_.end()) {
600         return false;
601     }
602     auto speicalList = spansMap_[speicalType];
603     for (const auto& speicalNode : speicalList) {
604         if (speicalNode->GetStartIndex() == location) {
605             return true;
606         }
607 
608         if (speicalNode->GetStartIndex() > location) {
609             return false;
610         }
611     }
612     return false;
613 }
614 
SetSpanWatcher(const WeakPtr<SpanWatcher> & watcher)615 void MutableSpanString::SetSpanWatcher(const WeakPtr<SpanWatcher>& watcher)
616 {
617     watcher_ = watcher;
618 }
619 
NotifySpanWatcher()620 void MutableSpanString::NotifySpanWatcher()
621 {
622     if (spans_.empty()) {
623         spans_.emplace_back(GetDefaultSpanItem(u""));
624     }
625     auto watcher = watcher_.Upgrade();
626     if (watcher) {
627         watcher->UpdateSpanItems(spans_);
628     }
629 }
630 } // namespace OHOS::Ace