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.pngBinary files differ new 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" /> | 
