123b3eb3cSopenharmony_ci/* 223b3eb3cSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License. 523b3eb3cSopenharmony_ci * You may obtain a copy of the License at 623b3eb3cSopenharmony_ci * 723b3eb3cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 823b3eb3cSopenharmony_ci * 923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and 1323b3eb3cSopenharmony_ci * limitations under the License. 1423b3eb3cSopenharmony_ci */ 1523b3eb3cSopenharmony_ci 1623b3eb3cSopenharmony_ci#include "adapter/ohos/osal/resource_theme_style.h" 1723b3eb3cSopenharmony_ci 1823b3eb3cSopenharmony_ci#include <regex> 1923b3eb3cSopenharmony_ci#include <set> 2023b3eb3cSopenharmony_ci 2123b3eb3cSopenharmony_cinamespace OHOS::Ace { 2223b3eb3cSopenharmony_cinamespace { 2323b3eb3cSopenharmony_ciconstexpr char COLOR_VALUE_PREFIX[] = "$color:"; 2423b3eb3cSopenharmony_ciconstexpr char MEDIA_VALUE_PREFIX[] = "/"; 2523b3eb3cSopenharmony_ciconstexpr char REF_ATTR_VALUE_KEY_WORD[] = "?theme:"; 2623b3eb3cSopenharmony_ci 2723b3eb3cSopenharmony_ciconstexpr char RES_TAG[] = "resource:///"; 2823b3eb3cSopenharmony_ci// resource manager hap for system resource 2923b3eb3cSopenharmony_ciconstexpr char RES_HAP_PREFIX[] = "ohos.global.systemres"; 3023b3eb3cSopenharmony_ci#ifdef PREVIEW 3123b3eb3cSopenharmony_ciconstexpr char RES_PATH_TAG[] = "file://"; 3223b3eb3cSopenharmony_ci// resource manager hap absolute path, as resource manager api don't return 3323b3eb3cSopenharmony_ciconstexpr char RES_HAP_PATH[] = "../resources/"; 3423b3eb3cSopenharmony_ci#else 3523b3eb3cSopenharmony_ciconstexpr char RES_PATH_TAG[] = "file:///"; 3623b3eb3cSopenharmony_ci// resource manager hap absolute path, as resource manager api don't return 3723b3eb3cSopenharmony_ciconstexpr char RES_HAP_PATH[] = "/data/storage/el1/bundle/ohos.global.systemres/ohos.global.systemres/assets/"; 3823b3eb3cSopenharmony_ci#endif 3923b3eb3cSopenharmony_ci 4023b3eb3cSopenharmony_ciconst std::string DIMENSION_PATTERN = R"(^([+-]?\d+(\.\d+)?)(px|fp|lpx|vp|%)?)"; 4123b3eb3cSopenharmony_ciconstexpr int32_t WAIT_FOR_TIME = 50; 4223b3eb3cSopenharmony_cistatic const std::set<std::string> stringAttrs = { 4323b3eb3cSopenharmony_ci "attribute_text_font_family_regular", 4423b3eb3cSopenharmony_ci "attribute_text_font_family_medium", 4523b3eb3cSopenharmony_ci "description_current_location", 4623b3eb3cSopenharmony_ci "description_add_location", 4723b3eb3cSopenharmony_ci "description_select_location", 4823b3eb3cSopenharmony_ci "description_share_location", 4923b3eb3cSopenharmony_ci "description_send_location", 5023b3eb3cSopenharmony_ci "description_locating", 5123b3eb3cSopenharmony_ci "description_location", 5223b3eb3cSopenharmony_ci "description_send_current_location", 5323b3eb3cSopenharmony_ci "description_relocation", 5423b3eb3cSopenharmony_ci "description_punch_in", 5523b3eb3cSopenharmony_ci "description_current_position", 5623b3eb3cSopenharmony_ci "description_paste", 5723b3eb3cSopenharmony_ci "description_download", 5823b3eb3cSopenharmony_ci "description_download_file", 5923b3eb3cSopenharmony_ci "description_save", 6023b3eb3cSopenharmony_ci "description_save_image", 6123b3eb3cSopenharmony_ci "description_save_file", 6223b3eb3cSopenharmony_ci "description_download_and_share", 6323b3eb3cSopenharmony_ci "description_receive", 6423b3eb3cSopenharmony_ci "description_continue_to_receive", 6523b3eb3cSopenharmony_ci "description_save_to_gallery", 6623b3eb3cSopenharmony_ci "description_export_to_gallery", 6723b3eb3cSopenharmony_ci "description_quick_save_to_gallery", 6823b3eb3cSopenharmony_ci "description_quick_resave_to_gallery", 6923b3eb3cSopenharmony_ci "draggable", 7023b3eb3cSopenharmony_ci "divider_shadow_enable", 7123b3eb3cSopenharmony_ci "camera_input", 7223b3eb3cSopenharmony_ci "menu_bg_blur_effect_enable", 7323b3eb3cSopenharmony_ci "menu_double_border_enable", 7423b3eb3cSopenharmony_ci "section_unfocus_effect_enable", 7523b3eb3cSopenharmony_ci "section_unfocus_color", 7623b3eb3cSopenharmony_ci "sheet_type", 7723b3eb3cSopenharmony_ci "multiple_dialog_display", 7823b3eb3cSopenharmony_ci "menu_expand_display", 7923b3eb3cSopenharmony_ci "popup_double_border_enable", 8023b3eb3cSopenharmony_ci "dialog_expand_display", 8123b3eb3cSopenharmony_ci "show_password_directly", 8223b3eb3cSopenharmony_ci "textfield_show_handle", 8323b3eb3cSopenharmony_ci "dialog_radius_level10", 8423b3eb3cSopenharmony_ci "dialog_icon_primary", 8523b3eb3cSopenharmony_ci "dialog_font_primary", 8623b3eb3cSopenharmony_ci "menu_has_filter", 8723b3eb3cSopenharmony_ci "calendar_picker_dialog_button_transparent", 8823b3eb3cSopenharmony_ci "calendar_picker_dialog_divider_transparent", 8923b3eb3cSopenharmony_ci "textfield_accessibility_property_clear", 9023b3eb3cSopenharmony_ci "textfield_accessibility_show_password", 9123b3eb3cSopenharmony_ci "textfield_accessibility_hide_password", 9223b3eb3cSopenharmony_ci "rich_editor_show_handle", 9323b3eb3cSopenharmony_ci "text_show_handle", 9423b3eb3cSopenharmony_ci "textfield_show_password_button", 9523b3eb3cSopenharmony_ci "textfield_hide_password_button", 9623b3eb3cSopenharmony_ci "textfield_has_showed_password", 9723b3eb3cSopenharmony_ci "textfield_has_hidden_password", 9823b3eb3cSopenharmony_ci "calendar_picker_mon", 9923b3eb3cSopenharmony_ci "calendar_picker_tue", 10023b3eb3cSopenharmony_ci "calendar_picker_wed", 10123b3eb3cSopenharmony_ci "calendar_picker_thu", 10223b3eb3cSopenharmony_ci "calendar_picker_fri", 10323b3eb3cSopenharmony_ci "calendar_picker_sat", 10423b3eb3cSopenharmony_ci "calendar_picker_sun", 10523b3eb3cSopenharmony_ci "slider_accessibility_selected", 10623b3eb3cSopenharmony_ci "slider_accessibility_unselected", 10723b3eb3cSopenharmony_ci "slider_accessibility_unselectedDesc", 10823b3eb3cSopenharmony_ci "slider_accessibility_disabledDesc", 10923b3eb3cSopenharmony_ci "textfield_writting_bundle_name", 11023b3eb3cSopenharmony_ci "textfield_writting_ability_name", 11123b3eb3cSopenharmony_ci "rich_editor_writting_bundle_name", 11223b3eb3cSopenharmony_ci "rich_editor_writting_ability_name", 11323b3eb3cSopenharmony_ci "textfield_writting_is_support", 11423b3eb3cSopenharmony_ci "rich_editor_writting_is_support", 11523b3eb3cSopenharmony_ci "ai_write_menu_name", 11623b3eb3cSopenharmony_ci "textfield_accessibility_clear", 11723b3eb3cSopenharmony_ci "pass_point" 11823b3eb3cSopenharmony_ci}; 11923b3eb3cSopenharmony_ci 12023b3eb3cSopenharmony_civoid ParseNumberUnit(const std::string& value, std::string& number, std::string& unit) 12123b3eb3cSopenharmony_ci{ 12223b3eb3cSopenharmony_ci std::regex regex(DIMENSION_PATTERN); 12323b3eb3cSopenharmony_ci std::smatch results; 12423b3eb3cSopenharmony_ci if (std::regex_search(value, results, regex)) { 12523b3eb3cSopenharmony_ci number = results[1]; 12623b3eb3cSopenharmony_ci // The unit is in the 3rd sub-match. If the value doesn't have unit, 12723b3eb3cSopenharmony_ci // the 3rd match result is empty. 12823b3eb3cSopenharmony_ci unit = results[3]; 12923b3eb3cSopenharmony_ci } 13023b3eb3cSopenharmony_ci} 13123b3eb3cSopenharmony_ci 13223b3eb3cSopenharmony_ciDimensionUnit ParseDimensionUnit(const std::string& unit) 13323b3eb3cSopenharmony_ci{ 13423b3eb3cSopenharmony_ci if (unit == "px") { 13523b3eb3cSopenharmony_ci return DimensionUnit::PX; 13623b3eb3cSopenharmony_ci } else if (unit == "fp") { 13723b3eb3cSopenharmony_ci return DimensionUnit::FP; 13823b3eb3cSopenharmony_ci } else if (unit == "lpx") { 13923b3eb3cSopenharmony_ci return DimensionUnit::LPX; 14023b3eb3cSopenharmony_ci } else if (unit == "%") { 14123b3eb3cSopenharmony_ci return DimensionUnit::PERCENT; 14223b3eb3cSopenharmony_ci } else { 14323b3eb3cSopenharmony_ci return DimensionUnit::VP; 14423b3eb3cSopenharmony_ci } 14523b3eb3cSopenharmony_ci} 14623b3eb3cSopenharmony_ci} 14723b3eb3cSopenharmony_ci 14823b3eb3cSopenharmony_civoid ResourceThemeStyle::ParseContent() 14923b3eb3cSopenharmony_ci{ 15023b3eb3cSopenharmony_ci for (auto& [attrName, attrValue] : rawAttrs_) { 15123b3eb3cSopenharmony_ci if (attrName.empty() || attrValue.empty()) { 15223b3eb3cSopenharmony_ci continue; 15323b3eb3cSopenharmony_ci } 15423b3eb3cSopenharmony_ci if (stringAttrs.find(attrName) != stringAttrs.end()) { 15523b3eb3cSopenharmony_ci // string 15623b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::STRING, .value = attrValue }; 15723b3eb3cSopenharmony_ci continue; 15823b3eb3cSopenharmony_ci } 15923b3eb3cSopenharmony_ci if (attrValue.front() == '#' || attrValue.find(COLOR_VALUE_PREFIX) != std::string::npos) { 16023b3eb3cSopenharmony_ci // color 16123b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::COLOR, .value = Color::FromString(attrValue) }; 16223b3eb3cSopenharmony_ci } else if (attrValue.find(MEDIA_VALUE_PREFIX) != std::string::npos) { 16323b3eb3cSopenharmony_ci OnParseResourceMedia(attrName, attrValue); 16423b3eb3cSopenharmony_ci } else if (attrValue.find(REF_ATTR_VALUE_KEY_WORD) != std::string::npos) { 16523b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::REFERENCE_ATTR, .value = attrValue }; 16623b3eb3cSopenharmony_ci } else { 16723b3eb3cSopenharmony_ci // int & double & dimension 16823b3eb3cSopenharmony_ci std::string number; 16923b3eb3cSopenharmony_ci std::string unit; 17023b3eb3cSopenharmony_ci ParseNumberUnit(attrValue, number, unit); 17123b3eb3cSopenharmony_ci if (number.empty()) { 17223b3eb3cSopenharmony_ci continue; 17323b3eb3cSopenharmony_ci } else if (!unit.empty()) { 17423b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::DIMENSION, 17523b3eb3cSopenharmony_ci .value = Dimension(std::atof(number.c_str()), ParseDimensionUnit(unit)) }; 17623b3eb3cSopenharmony_ci } else if (number.find(".") == std::string::npos) { 17723b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::INT, .value = std::atoi(number.c_str()) }; 17823b3eb3cSopenharmony_ci } else { 17923b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::DOUBLE, .value = std::atof(number.c_str()) }; 18023b3eb3cSopenharmony_ci } 18123b3eb3cSopenharmony_ci } 18223b3eb3cSopenharmony_ci } 18323b3eb3cSopenharmony_ci OnParseStyle(); 18423b3eb3cSopenharmony_ci} 18523b3eb3cSopenharmony_ci 18623b3eb3cSopenharmony_civoid ResourceThemeStyle::OnParseStyle() 18723b3eb3cSopenharmony_ci{ 18823b3eb3cSopenharmony_ci for (auto& [patternName, patternMap]: patternAttrs_) { 18923b3eb3cSopenharmony_ci auto patternStyle = AceType::MakeRefPtr<ResourceThemeStyle>(resAdapter_); 19023b3eb3cSopenharmony_ci patternStyle->SetName(patternName); 19123b3eb3cSopenharmony_ci patternStyle->parentStyle_ = AceType::WeakClaim(this); 19223b3eb3cSopenharmony_ci patternStyle->rawAttrs_ = patternMap; 19323b3eb3cSopenharmony_ci patternStyle->ParseContent(); 19423b3eb3cSopenharmony_ci attributes_[patternName] = { .type = ThemeConstantsType::PATTERN, 19523b3eb3cSopenharmony_ci .value = RefPtr<ThemeStyle>(std::move(patternStyle)) }; 19623b3eb3cSopenharmony_ci } 19723b3eb3cSopenharmony_ci} 19823b3eb3cSopenharmony_ci 19923b3eb3cSopenharmony_civoid ResourceThemeStyle::OnParseResourceMedia(const std::string& attrName, const std::string& attrValue) 20023b3eb3cSopenharmony_ci{ 20123b3eb3cSopenharmony_ci std::string mediaPath; 20223b3eb3cSopenharmony_ci if (SystemProperties::GetUnZipHap()) { 20323b3eb3cSopenharmony_ci mediaPath = RES_PATH_TAG; 20423b3eb3cSopenharmony_ci if (attrValue.find(RES_HAP_PREFIX) == std::string::npos) { 20523b3eb3cSopenharmony_ci mediaPath.append(RES_HAP_PATH); 20623b3eb3cSopenharmony_ci } 20723b3eb3cSopenharmony_ci#ifdef PREVIEW 20823b3eb3cSopenharmony_ci auto pos = attrValue.find(MEDIA_VALUE_PREFIX); 20923b3eb3cSopenharmony_ci if (pos == std::string::npos) { 21023b3eb3cSopenharmony_ci return; 21123b3eb3cSopenharmony_ci } 21223b3eb3cSopenharmony_ci mediaPath += attrValue.substr(pos + 1); 21323b3eb3cSopenharmony_ci#else 21423b3eb3cSopenharmony_ci mediaPath += attrValue; 21523b3eb3cSopenharmony_ci#endif 21623b3eb3cSopenharmony_ci } else { 21723b3eb3cSopenharmony_ci // hap is not unzip, should use resource name to read file 21823b3eb3cSopenharmony_ci auto pos = attrValue.find_last_of(MEDIA_VALUE_PREFIX); 21923b3eb3cSopenharmony_ci if (pos == std::string::npos) { 22023b3eb3cSopenharmony_ci LOGW("resource media invalid:[%{public}s, %{public}s]", attrName.c_str(), attrValue.c_str()); 22123b3eb3cSopenharmony_ci return; 22223b3eb3cSopenharmony_ci } 22323b3eb3cSopenharmony_ci mediaPath = std::string(RES_TAG) + attrValue.substr(pos + 1); 22423b3eb3cSopenharmony_ci } 22523b3eb3cSopenharmony_ci attributes_[attrName] = { .type = ThemeConstantsType::STRING, .value = mediaPath }; 22623b3eb3cSopenharmony_ci} 22723b3eb3cSopenharmony_ci 22823b3eb3cSopenharmony_civoid ResourceThemeStyle::CheckThemeStyleLoaded(const std::string& patternName) 22923b3eb3cSopenharmony_ci{ 23023b3eb3cSopenharmony_ci if (!CheckThemeStyle(patternName)) { 23123b3eb3cSopenharmony_ci return; 23223b3eb3cSopenharmony_ci } 23323b3eb3cSopenharmony_ci if (future_.valid()) { 23423b3eb3cSopenharmony_ci future_.wait_until(std::chrono::system_clock::now() + std::chrono::milliseconds(WAIT_FOR_TIME)); 23523b3eb3cSopenharmony_ci } 23623b3eb3cSopenharmony_ci} 23723b3eb3cSopenharmony_ci} // namespace OHOS::Ace 238