1 /*
2 * Copyright (C) 2023-2025 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 "pasteboard_web_controller.h"
17
18 #include <regex>
19
20 #include "file_uri.h"
21 #include "pasteboard_common.h"
22 #include "uri_permission_manager_client.h"
23 #include "pasteboard_hilog.h"
24
25 namespace {
26 constexpr const char *IMG_TAG_PATTERN = "<img.*?>";
27 constexpr const char *IMG_TAG_SRC_PATTERN = "src=(['\"])(.*?)\\1";
28 constexpr const char *IMG_TAG_SRC_HEAD = "src=\"";
29 constexpr const char *IMG_LOCAL_URI = "file:///";
30 constexpr const char *IMG_LOCAL_PATH = "://";
31 constexpr const char *FILE_SCHEME_PREFIX = "file://";
32
33 constexpr uint32_t FOUR_BYTES = 4;
34 constexpr uint32_t EIGHT_BIT = 8;
35 constexpr int32_t DOCS_LOCAL_PATH_SUBSTR_START_INDEX = 1;
36
37 struct Cmp {
operator ()__anon8401e5a50111::Cmp38 bool operator()(const uint32_t &lhs, const uint32_t &rhs) const
39 {
40 return lhs > rhs;
41 }
42 };
43 } // namespace
44
45 namespace OHOS {
46 namespace MiscServices {
47
48 // static
GetInstance()49 PasteboardWebController &PasteboardWebController::GetInstance()
50 {
51 static PasteboardWebController instance;
52 return instance;
53 }
54
SplitWebviewPasteData(PasteData & pasteData)55 bool PasteboardWebController::SplitWebviewPasteData(PasteData &pasteData)
56 {
57 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "start");
58 auto hasExtraRecord = false;
59 for (const auto &record : pasteData.AllRecords()) {
60 if (record->GetRecordId() == record->GetFrom()) {
61 continue;
62 }
63 auto htmlEntry = record->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
64 if (htmlEntry == nullptr) {
65 continue;
66 }
67 std::shared_ptr<std::string> html = htmlEntry->ConvertToHtml();
68 if (html == nullptr || html->empty()) {
69 continue;
70 }
71 std::vector<std::shared_ptr<PasteDataRecord>> extraUriRecords = SplitHtml2Records(html, record->GetRecordId());
72 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "split html, recordId=%{public}u, uri count=%{public}zu",
73 record->GetRecordId(), extraUriRecords.size());
74 if (extraUriRecords.empty()) {
75 continue;
76 }
77 hasExtraRecord = true;
78 for (const auto &item : extraUriRecords) {
79 pasteData.AddRecord(item);
80 }
81 record->SetFrom(record->GetRecordId());
82 }
83 if (hasExtraRecord) {
84 pasteData.SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
85 }
86 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "end");
87 return hasExtraRecord;
88 }
89
SetWebviewPasteData(PasteData & pasteData,const std::string & bundleName)90 void PasteboardWebController::SetWebviewPasteData(PasteData &pasteData, const std::string &bundleName)
91 {
92 if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
93 return;
94 }
95 for (auto &item : pasteData.AllRecords()) {
96 if (item->GetUri() == nullptr || item->GetFrom() == 0 || item->GetRecordId() == item->GetFrom()) {
97 continue;
98 }
99 std::shared_ptr<Uri> uri = item->GetUri();
100 std::string puri = uri->ToString();
101 if (puri.substr(0, strlen(IMG_LOCAL_URI)) == PasteData::IMG_LOCAL_URI &&
102 puri.find(FILE_SCHEME_PREFIX + PasteData::PATH_SHARE) == std::string::npos) {
103 std::string path = uri->GetPath();
104 std::string newUriStr = "";
105 if (path.substr(0, PasteData::DOCS_LOCAL_TAG.size()) == PasteData::DOCS_LOCAL_TAG) {
106 newUriStr = FILE_SCHEME_PREFIX;
107 newUriStr += path.substr(DOCS_LOCAL_PATH_SUBSTR_START_INDEX);
108 } else {
109 newUriStr = FILE_SCHEME_PREFIX;
110 newUriStr += bundleName + path;
111 }
112 item->SetUri(std::make_shared<OHOS::Uri>(newUriStr));
113 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "uri: %{private}s -> %{private}s", puri.c_str(),
114 newUriStr.c_str());
115 }
116 }
117 }
118
CheckAppUriPermission(PasteData & pasteData)119 void PasteboardWebController::CheckAppUriPermission(PasteData &pasteData)
120 {
121 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "enter");
122 std::vector<std::string> uris;
123 std::vector<size_t> indexs;
124 std::vector<bool> checkResults;
125 for (size_t i = 0; i < pasteData.GetRecordCount(); i++) {
126 auto item = pasteData.GetRecordAt(i);
127 if (item == nullptr || item->GetOriginUri() == nullptr) {
128 continue;
129 }
130 auto uri = item->GetOriginUri()->ToString();
131 uris.emplace_back(uri);
132 indexs.emplace_back(i);
133 }
134 if (uris.empty()) {
135 return;
136 }
137 size_t offset = 0;
138 size_t length = uris.size();
139 size_t count = PasteData::URI_BATCH_SIZE;
140 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "loop for CheckUriAuthorization, uri count=%{public}zu", uris.size());
141 while (length > offset) {
142 if (length - offset < PasteData::URI_BATCH_SIZE) {
143 count = length - offset;
144 }
145 auto sendValues = std::vector<std::string>(uris.begin() + offset, uris.begin() + offset + count);
146 std::vector<bool> ret = AAFwk::UriPermissionManagerClient::GetInstance().CheckUriAuthorization(
147 sendValues, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, pasteData.GetTokenId());
148 checkResults.insert(checkResults.end(), ret.begin(), ret.end());
149 offset += count;
150 }
151 if (checkResults.size() != indexs.size()) {
152 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "check uri authorization fail");
153 return;
154 }
155 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "loop for SetGrantUriPermission");
156 for (size_t i = 0; i < indexs.size(); i++) {
157 auto item = pasteData.GetRecordAt(indexs[i]);
158 if (item == nullptr || item->GetOriginUri() == nullptr) {
159 continue;
160 }
161 item->SetGrantUriPermission(checkResults[i]);
162 }
163 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "leave");
164 }
165
RefreshUri(std::shared_ptr<PasteDataRecord> & record,const std::string & targetBundle)166 void PasteboardWebController::RefreshUri(std::shared_ptr<PasteDataRecord> &record, const std::string &targetBundle)
167 {
168 PASTEBOARD_CHECK_AND_RETURN_LOGD(record->GetUri() != nullptr, PASTEBOARD_MODULE_COMMON,
169 "id=%{public}u, uri is null", record->GetRecordId());
170 PASTEBOARD_CHECK_AND_RETURN_LOGD(record->GetFrom() != 0 && record->GetFrom() != record->GetRecordId(),
171 PASTEBOARD_MODULE_COMMON, "id=%{public}u, from=%{public}u", record->GetRecordId(), record->GetFrom());
172
173 std::shared_ptr<Uri> uri = record->GetUri();
174 std::string puri = uri->ToString();
175 std::string realUri = puri;
176 if (puri.substr(0, strlen(FILE_SCHEME_PREFIX)) == FILE_SCHEME_PREFIX) {
177 AppFileService::ModuleFileUri::FileUri fileUri(puri);
178 std::string realPath = PasteBoardCommon::IsPasteboardService() ? fileUri.GetRealPathBySA(targetBundle) :
179 fileUri.GetRealPath();
180 realUri = FILE_SCHEME_PREFIX;
181 realUri += realPath;
182 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "uri: %{private}s -> %{private}s", puri.c_str(), realUri.c_str());
183 }
184 if (realUri.find(PasteData::DISTRIBUTEDFILES_TAG) != std::string::npos) {
185 record->SetConvertUri(realUri);
186 } else {
187 record->SetUri(std::make_shared<OHOS::Uri>(realUri));
188 }
189 }
190
RetainUri(PasteData & pasteData)191 void PasteboardWebController::RetainUri(PasteData &pasteData)
192 {
193 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "start");
194 if (!pasteData.IsLocalPaste()) {
195 return;
196 }
197 // clear convert uri
198 for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
199 auto record = pasteData.GetRecordAt(i);
200 if (record != nullptr) {
201 record->SetConvertUri("");
202 }
203 }
204 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "end");
205 }
206
RebuildWebviewPasteData(PasteData & pasteData,const std::string & targetBundle)207 void PasteboardWebController::RebuildWebviewPasteData(PasteData &pasteData, const std::string &targetBundle)
208 {
209 if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
210 return;
211 }
212 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "rebuild start, record count=%{public}zu", pasteData.GetRecordCount());
213 auto justSplitHtml = false;
214 auto details = std::make_shared<Details>();
215 std::string textContent;
216 for (auto &item : pasteData.AllRecords()) {
217 justSplitHtml = justSplitHtml || item->GetFrom() > 0;
218 if (!item->GetTextContent().empty() && textContent.empty()) {
219 details = item->GetDetails();
220 textContent = item->GetTextContent();
221 }
222 RefreshUri(item, targetBundle);
223 }
224 if (justSplitHtml) {
225 MergeExtraUris2Html(pasteData);
226 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Rebuild webview PasteData end, merged uris into html.");
227 return;
228 }
229 if (pasteData.GetPrimaryHtml() == nullptr) {
230 return;
231 }
232
233 auto webData = std::make_shared<PasteData>(pasteData);
234 RebuildHtml(webData);
235 PasteDataRecord::Builder builder(MIMETYPE_TEXT_HTML);
236 std::shared_ptr<PasteDataRecord> pasteDataRecord = builder.SetMimeType(MIMETYPE_TEXT_HTML).
237 SetPlainText(pasteData.GetPrimaryText()).SetHtmlText(webData->GetPrimaryHtml()).Build();
238 if (details) {
239 pasteDataRecord->SetDetails(*details);
240 }
241 pasteDataRecord->SetUDType(UDMF::HTML);
242 pasteDataRecord->SetTextContent(textContent);
243 webData->AddRecord(pasteDataRecord);
244 std::size_t recordCnt = webData->GetRecordCount();
245 if (recordCnt >= 1) {
246 webData->RemoveRecordAt(recordCnt - 1);
247 }
248 pasteData = *webData;
249 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Rebuild end, record count=%{public}zu", pasteData.GetRecordCount());
250 }
251
SplitHtml2Records(const std::shared_ptr<std::string> & html,uint32_t recordId)252 std::vector<std::shared_ptr<PasteDataRecord>> PasteboardWebController::SplitHtml2Records(
253 const std::shared_ptr<std::string> &html, uint32_t recordId) noexcept
254 {
255 std::vector<std::pair<std::string, uint32_t>> matchVec = SplitHtmlWithImgLabel(html);
256 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "matchVec size: %{public}zu", matchVec.size());
257 if (matchVec.empty()) {
258 return {};
259 }
260 std::map<std::string, std::vector<uint8_t>> imgSrcMap = SplitHtmlWithImgSrcLabel(matchVec);
261 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "imgSrcMap size: %{public}zu", imgSrcMap.size());
262 return BuildPasteDataRecords(imgSrcMap, recordId);
263 }
264
MergeExtraUris2Html(PasteData & data)265 void PasteboardWebController::MergeExtraUris2Html(PasteData &data)
266 {
267 auto recordGroups = GroupRecordWithFrom(data);
268 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "recordGroups size: %{public}zu", recordGroups.size());
269 for (auto &recordGroup : recordGroups) {
270 ReplaceHtmlRecordContentByExtraUris(recordGroup.second);
271 }
272 RemoveExtraUris(data);
273 }
274
RebuildHtml(std::shared_ptr<PasteData> pasteData)275 std::shared_ptr<std::string> PasteboardWebController::RebuildHtml(std::shared_ptr<PasteData> pasteData) noexcept
276 {
277 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(pasteData != nullptr, nullptr, PASTEBOARD_MODULE_COMMON, "pasteData is null");
278 std::vector<std::shared_ptr<PasteDataRecord>> pasteDataRecords = pasteData->AllRecords();
279 std::shared_ptr<std::string> htmlData;
280 std::map<uint32_t, std::pair<std::string, std::string>, Cmp> replaceUris;
281
282 for (const auto &item : pasteDataRecords) {
283 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(item != nullptr, nullptr,
284 PASTEBOARD_MODULE_COMMON, "item is null");
285 std::shared_ptr<std::string> html = item->GetHtmlText();
286 if (html != nullptr) {
287 htmlData = html;
288 }
289 std::shared_ptr<OHOS::Uri> uri = item->GetUri();
290 std::shared_ptr<MiscServices::MineCustomData> customData = item->GetCustomData();
291 if (uri == nullptr || customData == nullptr) {
292 continue;
293 }
294 std::map<std::string, std::vector<uint8_t>> customItemData = customData->GetItemData();
295 for (const auto &itemData : customItemData) {
296 for (uint32_t i = 0; i < itemData.second.size(); i += FOUR_BYTES) {
297 uint32_t offset = static_cast<uint32_t>(itemData.second[i]) |
298 static_cast<uint32_t>(itemData.second[i + 1] << 8) |
299 static_cast<uint32_t>(itemData.second[i + 2] << 16) |
300 static_cast<uint32_t>(itemData.second[i + 3] << 24);
301 replaceUris[offset] = std::make_pair(uri->ToString(), itemData.first);
302 }
303 }
304 }
305
306 RemoveAllRecord(pasteData);
307 for (auto &replaceUri : replaceUris) {
308 htmlData->replace(replaceUri.first, replaceUri.second.second.size(), replaceUri.second.first);
309 }
310 pasteData->AddHtmlRecord(*htmlData);
311 return htmlData;
312 }
313
SplitHtmlWithImgLabel(const std::shared_ptr<std::string> html)314 std::vector<std::pair<std::string, uint32_t>> PasteboardWebController::SplitHtmlWithImgLabel(
315 const std::shared_ptr<std::string> html) noexcept
316 {
317 std::smatch results;
318 std::string pattern(IMG_TAG_PATTERN);
319 std::regex reg(pattern);
320 std::string::const_iterator iterStart = html->begin();
321 std::string::const_iterator iterEnd = html->end();
322 std::vector<std::pair<std::string, uint32_t>> matchVec;
323
324 try {
325 while (std::regex_search(iterStart, iterEnd, results, reg)) {
326 std::string tmp = results[0];
327 iterStart = results[0].second;
328 uint32_t offset = static_cast<uint32_t>(results[0].first - html->begin());
329
330 matchVec.emplace_back(tmp, offset);
331 }
332 } catch (std::regex_error &e) {
333 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "Regex error !");
334 }
335
336 return matchVec;
337 }
338
SplitHtmlWithImgSrcLabel(const std::vector<std::pair<std::string,uint32_t>> & matchVec)339 std::map<std::string, std::vector<uint8_t>> PasteboardWebController::SplitHtmlWithImgSrcLabel(
340 const std::vector<std::pair<std::string, uint32_t>> &matchVec) noexcept
341 {
342 std::map<std::string, std::vector<uint8_t>> res;
343 std::smatch match;
344 std::regex re(IMG_TAG_SRC_PATTERN);
345 for (const auto &node : matchVec) {
346 std::string::const_iterator iterStart = node.first.begin();
347 std::string::const_iterator iterEnd = node.first.end();
348
349 while (std::regex_search(iterStart, iterEnd, match, re)) {
350 std::string tmp = match[0];
351 iterStart = match[0].second;
352 uint32_t offset = static_cast<uint32_t>(match[0].first - node.first.begin());
353 tmp = tmp.substr(strlen(IMG_TAG_SRC_HEAD));
354 tmp.pop_back();
355 if (!IsLocalURI(tmp)) {
356 continue;
357 }
358 offset += strlen(IMG_TAG_SRC_HEAD) + node.second;
359 for (uint32_t i = 0; i < FOUR_BYTES; i++) {
360 res[tmp].emplace_back((offset >> (EIGHT_BIT * i)) & 0xff);
361 }
362 }
363 }
364 return res;
365 }
366
BuildPasteDataRecords(const std::map<std::string,std::vector<uint8_t>> & imgSrcMap,uint32_t recordId)367 std::vector<std::shared_ptr<PasteDataRecord>> PasteboardWebController::BuildPasteDataRecords(
368 const std::map<std::string, std::vector<uint8_t>> &imgSrcMap, uint32_t recordId) noexcept
369 {
370 std::vector<std::shared_ptr<PasteDataRecord>> records;
371 for (const auto &item : imgSrcMap) {
372 PasteDataRecord::Builder builder(MiscServices::MIMETYPE_TEXT_URI);
373 auto uri = std::make_shared<OHOS::Uri>(item.first);
374 builder.SetUri(uri);
375 auto customData = std::make_shared<MiscServices::MineCustomData>();
376 customData->AddItemData(item.first, item.second);
377 builder.SetCustomData(customData);
378 auto record = builder.Build();
379 record->SetFrom(recordId);
380 records.push_back(record);
381 }
382 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Build extra records size: %{public}zu", records.size());
383 return records;
384 }
385
RemoveRecordById(PasteData & pasteData,uint32_t recordId)386 void PasteboardWebController::RemoveRecordById(PasteData &pasteData, uint32_t recordId) noexcept
387 {
388 for (uint32_t i = 0; i < pasteData.GetRecordCount(); i++) {
389 if (pasteData.GetRecordAt(i)->GetRecordId() == recordId) {
390 if (pasteData.RemoveRecordAt(i)) {
391 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON,
392 "WebClipboardController RemoveRecord success, i=%{public}u", i);
393 return;
394 }
395 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_COMMON,
396 "WebClipboardController RemoveRecord failed, i=%{public}u", i);
397 }
398 }
399 }
400
RemoveAllRecord(std::shared_ptr<PasteData> pasteData)401 void PasteboardWebController::RemoveAllRecord(std::shared_ptr<PasteData> pasteData) noexcept
402 {
403 PASTEBOARD_CHECK_AND_RETURN_LOGE(pasteData != nullptr, PASTEBOARD_MODULE_COMMON, "pasteData is null");
404 std::size_t recordCount = pasteData->GetRecordCount();
405 for (uint32_t i = 0; i < recordCount; i++) {
406 if (!pasteData->RemoveRecordAt(0)) {
407 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "WebClipboardController RemoveRecord failed, i=%{public}u", i);
408 }
409 }
410 }
411
IsLocalURI(std::string & uri)412 bool PasteboardWebController::IsLocalURI(std::string &uri) noexcept
413 {
414 return uri.substr(0, strlen(IMG_LOCAL_URI)) == std::string(IMG_LOCAL_URI) ||
415 uri.find(IMG_LOCAL_PATH) == std::string::npos;
416 }
417
UpdateHtmlRecord(std::shared_ptr<PasteDataRecord> & htmlRecord,std::shared_ptr<std::string> & htmlData)418 void PasteboardWebController::UpdateHtmlRecord(
419 std::shared_ptr<PasteDataRecord> &htmlRecord, std::shared_ptr<std::string> &htmlData)
420 {
421 if (htmlRecord == nullptr || htmlData == nullptr) {
422 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "htmlRecord or htmlData is null");
423 return;
424 }
425 auto entry = htmlRecord->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
426 if (entry == nullptr) {
427 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "entry is null");
428 return;
429 }
430 auto entryValue = entry->GetValue();
431 if (std::holds_alternative<std::string>(entryValue)) {
432 entry->SetValue(*htmlData);
433 } else if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
434 auto object = std::get<std::shared_ptr<Object>>(entryValue);
435 auto newObject = std::make_shared<Object>();
436 newObject->value_ = object->value_;
437 newObject->value_[UDMF::HTML_CONTENT] = *htmlData;
438 entry->SetValue(newObject);
439 }
440 htmlRecord->AddEntryByMimeType(MIMETYPE_TEXT_HTML, entry);
441 htmlRecord->SetFrom(0);
442 }
443
ReplaceHtmlRecordContentByExtraUris(std::vector<std::shared_ptr<PasteDataRecord>> & records)444 void PasteboardWebController::ReplaceHtmlRecordContentByExtraUris(
445 std::vector<std::shared_ptr<PasteDataRecord>> &records)
446 {
447 std::shared_ptr<PasteDataRecord> htmlRecord = nullptr;
448 std::shared_ptr<std::string> htmlData;
449 std::map<uint32_t, std::pair<std::string, std::string>, Cmp> replaceUris;
450 for (const auto &item : records) {
451 auto htmlEntry = item->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
452 if (htmlEntry != nullptr) {
453 auto html = htmlEntry->ConvertToHtml();
454 if (html != nullptr && !html->empty()) {
455 htmlData = html;
456 htmlRecord = item;
457 continue;
458 }
459 }
460 std::shared_ptr<OHOS::Uri> uri = item->GetUri();
461 std::shared_ptr<MiscServices::MineCustomData> customData = item->GetCustomData();
462 if (!uri || !customData) {
463 continue;
464 }
465 std::map<std::string, std::vector<uint8_t>> customItemData = customData->GetItemData();
466 for (auto &itemData : customItemData) {
467 for (uint32_t i = 0; i < itemData.second.size(); i += FOUR_BYTES) {
468 uint32_t offset = static_cast<uint32_t>(itemData.second[i]) |
469 static_cast<uint32_t>(itemData.second[i + 1] << 8) |
470 static_cast<uint32_t>(itemData.second[i + 2] << 16) |
471 static_cast<uint32_t>(itemData.second[i + 3] << 24);
472 replaceUris[offset] = std::make_pair(uri->ToString(), itemData.first);
473 }
474 }
475 }
476 if (htmlData == nullptr) {
477 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_COMMON, "htmlData is nullptr");
478 return;
479 }
480
481 for (const auto &replaceUri : replaceUris) {
482 htmlData->replace(replaceUri.first, replaceUri.second.second.size(), replaceUri.second.first);
483 }
484 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "replace uri count: %{public}zu", replaceUris.size());
485 if (htmlRecord != nullptr) {
486 UpdateHtmlRecord(htmlRecord, htmlData);
487 }
488 }
489
GroupRecordWithFrom(PasteData & data)490 std::map<std::uint32_t, std::vector<std::shared_ptr<PasteDataRecord>>> PasteboardWebController::GroupRecordWithFrom(
491 PasteData &data)
492 {
493 std::map<std::uint32_t, std::vector<std::shared_ptr<PasteDataRecord>>> groupMap;
494 for (const auto &record : data.AllRecords()) {
495 if (record->GetFrom() == 0) {
496 continue;
497 }
498 auto item = groupMap.find(record->GetFrom());
499 auto value = item != groupMap.end() ? item->second : std::vector<std::shared_ptr<PasteDataRecord>>();
500 value.emplace_back(record);
501 groupMap.insert_or_assign(record->GetFrom(), value);
502 }
503 return groupMap;
504 }
505
RemoveExtraUris(PasteData & data)506 void PasteboardWebController::RemoveExtraUris(PasteData &data)
507 {
508 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Before remove record count: %{public}zu", data.AllRecords().size());
509 for (const auto &record : data.AllRecords()) {
510 if (record->GetFrom() > 0 && record->GetMimeType() == MIMETYPE_TEXT_URI) {
511 RemoveRecordById(data, record->GetRecordId());
512 }
513 }
514 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "After remove record count: %{public}zu", data.AllRecords().size());
515 }
516 } // namespace MiscServices
517 } // namespace OHOS
518