Using UrlHistoryList do display history list (on urientry edition).
[profile/tv/apps/web/browser.git] / services / QuickAccess / UrlHistoryList / UrlMatchesStyler.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "UrlMatchesStyler.h"
18
19 namespace tizen_browser {
20 namespace base_ui {
21
22 UrlMatchesStyler::UrlMatchesStyler() :
23                 TAG_WHOLE_URL("<align=left><color=" + FONT_COLOR_NORMAL + "><font_size="+FONT_SIZE+">"),
24                 TAG_WHOLE_URL_CLOSE("</color></font></align>"),
25                 TAG_HIGHLIGHT("<hilight>"),
26                 TAG_HIGHLIGHT_CLOSE(closeTag(TAG_HIGHLIGHT)),
27                 TAG_COLOR("<color=" + FONT_COLOR_HIGHLIGHT + ">"),
28                 TAG_COLOR_CLOSE(closeTag(TAG_COLOR)),
29                 TAG_COMPLETE(TAG_HIGHLIGHT + TAG_COLOR),
30                 TAG_COMPLETE_CLOSE(TAG_HIGHLIGHT_CLOSE + TAG_COLOR_CLOSE),
31                 TAGS_COMPLETE_LEN(TAG_COMPLETE.length() + TAG_COMPLETE_CLOSE.length()) {
32 }
33
34 UrlMatchesStyler::~UrlMatchesStyler() {
35 }
36
37 string UrlMatchesStyler::closeTag(const string& tag) const {
38         string closedTag(tag);
39         return string(closedTag.insert(1, "/"));
40 }
41
42 string UrlMatchesStyler::getUrlHighlightedMatches(const string& styledUrl,
43                 const string& highlightingKeywords) const {
44         vector < string > keywords;
45         splitKeywordsString(highlightingKeywords, keywords);
46
47         int_pairs rangesHighlight;
48         for (auto key : keywords) {
49                 fillOccuranceRanges(styledUrl, key, rangesHighlight);
50         }
51
52         int_pairs mergedRangesHighlight;
53         mergeRanges(rangesHighlight, mergedRangesHighlight);
54         return getTaggedString(styledUrl, mergedRangesHighlight);
55 }
56
57 void UrlMatchesStyler::splitKeywordsString(const string& keywordsString,
58                 vector<string>& resultKeywords) const {
59         boost::algorithm::split(resultKeywords, keywordsString,
60                         boost::is_any_of("\t "), boost::token_compress_on);
61         // remove empty elements
62         for (auto it = resultKeywords.begin(); it != resultKeywords.end();) {
63                 if ((*it).empty()) {
64                         it = resultKeywords.erase(it);
65                 } else {
66                         ++it;
67                 }
68         }
69 }
70
71 void UrlMatchesStyler::fillOccuranceRanges(const string& _checkedString,
72                 const string& _searchedMatch, int_pairs& resultRanges) const {
73         if (_checkedString.empty() || _searchedMatch.empty())
74                 return;
75
76         string checkedString(_checkedString);
77         string searchedMatch(_searchedMatch);
78         boost::algorithm::to_lower(checkedString);
79         boost::algorithm::to_lower(searchedMatch);
80
81         int len = searchedMatch.length();
82         vector<int> positions;
83         getMatchesPositions(checkedString, searchedMatch, positions);
84         for (auto pos : positions) {
85                 resultRanges.push_back( { pos, pos + len - 1 });
86         }
87 }
88
89 void UrlMatchesStyler::getMatchesPositions(const string& checkedString,
90                 const string& searchedMatch, vector<int>& resultPositions) const {
91         boost::regex match_regex(searchedMatch);
92         for (auto it = boost::sregex_iterator(checkedString.begin(),
93                         checkedString.end(), match_regex); it != boost::sregex_iterator();
94                         ++it) {
95                 resultPositions.push_back(it->position());
96         }
97 }
98
99 void UrlMatchesStyler::mergeRanges(int_pairs& ranges, int_pairs& result) const {
100         if (ranges.size() == 0)
101                 return;
102         sort(ranges.begin(), ranges.end());
103
104         auto current = *(ranges.begin());
105         for (auto it = ranges.begin() + 1; it != ranges.end(); ++it) {
106                 if (current.second >= it->first) {
107                         current.second = max(current.second, it->second);
108                 } else {
109                         result.push_back(current);
110                         current = *it;
111                 }
112         }
113         result.push_back(current);
114 }
115
116 string UrlMatchesStyler::getTaggedString(const string& strToHighlight,
117                 const int_pairs& ranges) const {
118         string strResult(strToHighlight);
119         int insertOffset = 0;
120         for (auto pair : ranges) {
121                 strResult.insert(pair.second + insertOffset + 1, TAG_COMPLETE_CLOSE);
122                 strResult.insert(pair.first + insertOffset, TAG_COMPLETE);
123                 insertOffset += TAGS_COMPLETE_LEN;
124         }
125         strResult.insert(strResult.length(), TAG_WHOLE_URL_CLOSE);
126         strResult.insert(0, TAG_WHOLE_URL);
127         return strResult;
128 }
129
130 } /* namespace base_ui */
131 } /* namespace tizen_browser */