diff options
-rwxr-xr-x | indra/llui/lltextbase.cpp | 70 | ||||
-rwxr-xr-x | indra/llui/lltextutil.cpp | 91 | ||||
-rwxr-xr-x | indra/llui/lltextutil.h | 29 | ||||
-rwxr-xr-x | indra/llui/llurlentry.cpp | 30 | ||||
-rwxr-xr-x | indra/llui/llurlentry.h | 17 | ||||
-rwxr-xr-x | indra/llui/llurlmatch.cpp | 6 | ||||
-rwxr-xr-x | indra/llui/llurlmatch.h | 6 | ||||
-rwxr-xr-x | indra/llui/llurlregistry.cpp | 7 | ||||
-rw-r--r-- | indra/newview/skins/default/textures/icons/hand.png | bin | 0 -> 957 bytes | |||
-rwxr-xr-x | indra/newview/skins/default/textures/textures.xml | 2 |
10 files changed, 191 insertions, 67 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8395e74715..fee271b943 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -44,8 +44,6 @@ #include "llwindow.h" #include <boost/bind.hpp> -#include "uriparser/Uri.h" - const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds const S32 CURSOR_THICKNESS = 2; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. @@ -2021,60 +2019,7 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name) static LLTrace::BlockTimerStatHandle FTM_PARSE_HTML("Parse HTML"); -S32 LLTextBase::normalizeUri(std::string& uri_string) -{ - UriParserStateA state; - UriUriA uri; - state.uri = &uri; - - S32 res = uriParseUriA(&state, uri_string.c_str()); - - if (!res) - { - if (uri.scheme.afterLast - uri.scheme.first > 0) - { - res = uriNormalizeSyntaxExA(&uri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); - if (!res) - { - S32 chars_required; - res = uriToStringCharsRequiredA(&uri, &chars_required); - - if (!res) - { - chars_required++; - std::vector<char> label_buf(chars_required); - res = uriToStringA(&label_buf[0], &uri, chars_required, NULL); - - if (!res) - { - uri_string = &label_buf[0]; - } - } - } - } - else if (uri_string.find_first_of('.') != std::string::npos) - { - static bool recursive_call = false; - - // allow only single level recursive call - if (!recursive_call) - { - recursive_call = true; - - // force uri to be with scheme and try to normalize - std::string uri_with_scheme = "http://"; - uri_with_scheme += uri_string; - normalizeUri(uri_with_scheme); - uri_string = uri_with_scheme.substr(7); - recursive_call = false; - } - } - } - - uriFreeUriMembersA(&uri); - return res; -} void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params) { @@ -2113,8 +2058,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para appendAndHighlightText(subtext, part, style_params); } + // add icon before url if need + LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted()); + std::string label = match.getLabel(); - normalizeUri(label); + LLTextUtil::normalizeUri(label); // output the styled Url appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly()); @@ -2124,14 +2072,12 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para { segment_set_t::iterator it = getSegIterContaining(getLength()-1); if (it != mSegments.end()) - { - LLTextSegmentPtr segment = *it; - segment->setToolTip(match.getTooltip()); - } + { + LLTextSegmentPtr segment = *it; + segment->setToolTip(match.getTooltip()); + } } - LLTextUtil::processUrlMatch(&match,this,isContentTrusted()); - // move on to the rest of the text after the Url if (end < (S32)text.length()) { diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp index fff04b34f2..b67daf427b 100755 --- a/indra/llui/lltextutil.cpp +++ b/indra/llui/lltextutil.cpp @@ -30,6 +30,8 @@ #include "lltextbox.h" #include "llurlmatch.h" +#include "uriparser/Uri.h" + boost::function<bool(LLUrlMatch*,LLTextBase*)> LLTextUtil::TextHelpers::iconCallbackCreationFunction = 0; void LLTextUtil::textboxSetHighlightedVal(LLTextBox *txtbox, const LLStyle::Params& normal_style, const std::string& text, const std::string& hl) @@ -104,4 +106,93 @@ bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool i return false; } +static void textRangeToString(UriTextRangeA& textRange, std::string& str) +{ + S32 len = textRange.afterLast - textRange.first; + if (len) + { + str = textRange.first; + str = str.substr(0, len); + } +} + +S32 LLTextUtil::normalizeUri(std::string& uri_string, Uri * urip/* = NULL*/) +{ + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + + S32 res = uriParseUriA(&state, uri_string.c_str()); + + if (!res) + { + S32 len = uri.scheme.afterLast - uri.scheme.first; + + if (len > 0) + { + res = uriNormalizeSyntaxExA(&uri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); + + if (!res) + { + S32 chars_required; + res = uriToStringCharsRequiredA(&uri, &chars_required); + + if (!res) + { + chars_required++; + std::vector<char> label_buf(chars_required); + res = uriToStringA(&label_buf[0], &uri, chars_required, NULL); + + if (!res) + { + uri_string = &label_buf[0]; + } + } + } + + // fill urip if requested + if (urip) + { + textRangeToString(uri.scheme, urip->scheme); + textRangeToString(uri.hostText, urip->host); + textRangeToString(uri.portText, urip->port); + textRangeToString(uri.query, urip->query); + textRangeToString(uri.fragment, urip->fragment); + + UriPathSegmentA * pathHead = uri.pathHead; + while (pathHead) + { + std::string partOfPath; + textRangeToString(pathHead->text, partOfPath); + + urip->path += '/'; + urip->path += partOfPath; + + pathHead = pathHead->next; + } + } + } + else if (uri_string.find_first_of('.') != std::string::npos) + { + static bool recursive_call = false; + + // allow only single level recursive call + if (!recursive_call) + { + recursive_call = true; + + // force uri to be with scheme and try to normalize + std::string uri_with_scheme = "http://"; + uri_with_scheme += uri_string; + normalizeUri(uri_with_scheme, urip); + uri_string = uri_with_scheme.substr(7); + recursive_call = false; + } + } + } + + uriFreeUriMembersA(&uri); + return res; +} + // EOF diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h index 798f14d086..176b4ba071 100755 --- a/indra/llui/lltextutil.h +++ b/indra/llui/lltextutil.h @@ -64,7 +64,34 @@ namespace LLTextUtil */ const std::string& formatPhoneNumber(const std::string& phone_str); - bool processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted); + /** + * Adds icon before url if need. + * + * @param[in] match an object with results of matching + * @param[in] text_base pointer to UI text object + * @param[in] is_content_trusted true if context is trusted + * @return reference to string with formatted phone number + */ + bool processUrlMatch(LLUrlMatch* match, LLTextBase* text_base, bool is_content_trusted); + + typedef struct + { + std::string scheme; + std::string host; + std::string port; + std::string path; + std::string query; + std::string fragment; + } Uri; + + /** + * Translates uri's host name and scheme to lowercase + * + * @param[in, out] uri_string string with original uri + * @param[out] uri receives parts of uri + * @return 0 on success, error code otherwise + */ + S32 normalizeUri(std::string& uri_string, Uri * uri = NULL); class TextHelpers { diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index be583c83d8..3ebf06eefa 100755 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -35,6 +35,7 @@ #include "llavatarnamecache.h" #include "llcachename.h" #include "lltrans.h" +#include "lltextutil.h" #include "lluicolortable.h" #include "message.h" @@ -342,6 +343,35 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const } // +// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com urls to substitute icon 'hand.png' before link +// +LLUrlEntrySeconlifeURL::LLUrlEntrySeconlifeURL() +{ + mPattern = boost::regex("\\b(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com\\S*", + boost::regex::perl|boost::regex::icase); + + mIcon = "Hand"; + mMenuName = "menu_url_http.xml"; +} + +std::string LLUrlEntrySeconlifeURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + std::string local_url(url); + + LLTextUtil::Uri uri; + LLTextUtil::normalizeUri(local_url, &uri); + + return uri.host; +} + +std::string LLUrlEntrySeconlifeURL::getTooltip(const std::string &url) const +{ + std::string local_url(url); + LLTextUtil::normalizeUri(local_url); + return local_url; +} + +// // LLUrlEntryAgent Describes a Second Life agent Url, e.g., // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index ffcd45dfde..f75d773803 100755 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -96,6 +96,8 @@ public: /// Should this link text be underlined only when mouse is hovered over it? virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } + virtual bool isTrusted() const { return false; } + virtual LLUUID getID(const std::string &string) const { return LLUUID::null; } bool isLinkDisabled() const; @@ -168,6 +170,21 @@ public: }; /// +/// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com Urls +/// +class LLUrlEntrySeconlifeURL : public LLUrlEntryBase +{ +public: + LLUrlEntrySeconlifeURL(); + virtual bool isTrusted() const { return true; } + virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + virtual std::string getTooltip(const std::string &url) const; + +private: + std::string mLabel; +}; + +/// /// LLUrlEntryAgent Describes a Second Life agent Url, e.g., /// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about class LLUrlEntryAgent : public LLUrlEntryBase diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index c1f1382a9f..016d1ca92d 100755 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -37,7 +37,8 @@ LLUrlMatch::LLUrlMatch() : mIcon(""), mMenuName(""), mLocation(""), - mUnderlineOnHoverOnly(false) + mUnderlineOnHoverOnly(false), + mTrusted(false) { } @@ -45,7 +46,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLStyle::Params& style, const std::string &menu, const std::string &location, - const LLUUID& id, bool underline_on_hover_only) + const LLUUID& id, bool underline_on_hover_only, bool trusted) { mStart = start; mEnd = end; @@ -59,4 +60,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mLocation = location; mID = id; mUnderlineOnHoverOnly = underline_on_hover_only; + mTrusted = trusted; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index 2818f45207..9f8960b32f 100755 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -80,12 +80,15 @@ public: /// Should this link text be underlined only when mouse is hovered over it? bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; } + /// Return true if Url is trusted. + bool isTrusted() const { return mTrusted; } + /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLStyle::Params& style, const std::string &menu, const std::string &location, const LLUUID& id, - bool underline_on_hover_only = false ); + bool underline_on_hover_only = false, bool trusted = false ); const LLUUID& getID() const { return mID; } private: @@ -100,6 +103,7 @@ private: LLUUID mID; LLStyle::Params mStyle; bool mUnderlineOnHoverOnly; + bool mTrusted; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index ef0789e0e4..462b3d6979 100755 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -44,6 +44,10 @@ LLUrlRegistry::LLUrlRegistry() mUrlEntryIcon = new LLUrlEntryIcon(); registerUrl(mUrlEntryIcon); registerUrl(new LLUrlEntrySLURL()); + + // decorated links for host names like: secondlife.com and lindenlab.com + registerUrl(new LLUrlEntrySeconlifeURL()); + registerUrl(new LLUrlEntryHTTP()); mUrlEntryHTTPLabel = new LLUrlEntryHTTPLabel(); registerUrl(mUrlEntryHTTPLabel); @@ -212,7 +216,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getMenuName(), match_entry->getLocation(url), match_entry->getID(url), - match_entry->underlineOnHoverOnly(url)); + match_entry->underlineOnHoverOnly(url), + match_entry->isTrusted()); return true; } diff --git a/indra/newview/skins/default/textures/icons/hand.png b/indra/newview/skins/default/textures/icons/hand.png Binary files differnew file mode 100644 index 0000000000..41b9600da6 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/hand.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 46698b3949..8fdc770009 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -229,6 +229,8 @@ with the same filename but different name <texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" /> <texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" /> + <texture name="Hand" file_name="icons/hand.png" preload="false" /> + <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" /> <texture name="Hierarchy_View_Disabled" file_name="icons/Hierarchy_View_Disabled.png" preload="false" /> |