diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index fa91490036..24cab99373 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2700,6 +2700,12 @@ void LLTextBase::appendTextImpl(const std::string& new_text, const LLStyle::Para
if (tooltip_required)
{
setLastSegmentToolTip(match.getTooltip());
+ // Preview real URLs of bracket links
+ if (match.getLabeledLinkMasked())
+ {
+ setLastSegmentProminentUrlTooltip(match.getLabel(), match.getLabeledLinkTrusted());
+ }
+ //
}
// show query part of url with gray color only for LLUrlEntryHTTP url entries
@@ -2763,6 +2769,18 @@ void LLTextBase::setLastSegmentToolTip(const std::string &tooltip)
}
}
+// Preview real URLs of bracket links
+void LLTextBase::setLastSegmentProminentUrlTooltip(const std::string &label, bool trusted)
+{
+ segment_set_t::iterator it = getSegIterContaining(getLength()-1);
+ if (it != mSegments.end())
+ {
+ LLTextSegmentPtr segment = *it;
+ segment->setProminentUrlTooltip(label, trusted);
+ }
+}
+//
+
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
@@ -4150,6 +4168,41 @@ bool LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask)
bool LLNormalTextSegment::handleToolTip(S32 x, S32 y, MASK mask)
{
+ // Preview real URLs of bracket links
+ // Bypasses the BasicUITooltips preference and the normal hover delay on purpose
+ if (mForceProminentUrlTooltip && !mTooltip.empty())
+ {
+ LLToolTip::Params params;
+ params.font(LLFontGL::getFontSansSerifBig());
+ params.delay_time(0.f);
+ params.wrap(true);
+ params.max_width(700);
+ LLUIColorTable& colors = LLUIColorTable::instance();
+
+ if (mProminentUrlTrusted)
+ {
+ params.styled_message.add().text(LLTrans::getString("FSChatLinkTagTrusted") + " ").style.color(colors.getColor("LindenChatColor", LLColor4::green));
+ }
+ else
+ {
+ params.styled_message.add().text(LLTrans::getString("FSChatLinkTagUntrusted") + " ").style.color(colors.getColor("MutedChatColor", LLColor4::grey));
+ }
+
+ if (!mProminentUrlLabel.empty())
+ {
+ params.styled_message.add().text(mProminentUrlLabel + "\n").style.color(LLColor4::white);
+ }
+ else
+ {
+ params.styled_message.add().text("\n");
+ }
+
+ params.styled_message.add().text(mTooltip).style.color(colors.getColor("HTMLLinkColor", LLColor4::blue));
+ LLToolTipMgr::instance().show(params);
+ return true;
+ }
+ //
+
std::string msg;
// do we have a tooltip for a loaded keyword (for script editor)?
if (mToken && !mToken->getToolTip().empty())
@@ -4179,6 +4232,15 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
mTooltip = tooltip;
}
+// Preview real URLs of bracket links
+void LLNormalTextSegment::setProminentUrlTooltip(const std::string& label, bool trusted)
+{
+ mForceProminentUrlTooltip = true;
+ mProminentUrlLabel = label;
+ mProminentUrlTrusted = trusted;
+}
+//
+
// virtual
LLTextSegmentPtr LLNormalTextSegment::clone(LLTextBase& target) const
{
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 4947d52a5a..da78ff71ed 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -99,6 +99,7 @@ public:
virtual void setToken( LLKeywordToken* token );
virtual LLKeywordToken* getToken() const;
virtual void setToolTip(const std::string& tooltip);
+ virtual void setProminentUrlTooltip(const std::string& label, bool trusted) { } // Preview real URLs of bracket links
virtual void dump() const;
// LLMouseHandler interface
@@ -151,6 +152,7 @@ public:
/*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; }
/*virtual*/ LLKeywordToken* getToken() const { return mToken; }
/*virtual*/ void setToolTip(const std::string& tooltip);
+ /*virtual*/ void setProminentUrlTooltip(const std::string& label, bool trusted); // Preview real URLs of bracket links
/*virtual*/ void dump() const;
/*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
@@ -174,6 +176,11 @@ protected:
S32 mFontHeight;
LLKeywordToken* mToken;
std::string mTooltip;
+ // Preview real URLs of bracket links
+ bool mForceProminentUrlTooltip { false };
+ bool mProminentUrlTrusted { false };
+ std::string mProminentUrlLabel;
+ //
boost::signals2::connection mImageLoadedConnection;
bool mCanEdit { true };
@@ -506,6 +513,7 @@ public:
const LLWString& getWlabel() { return mLabel.getWString();}
void setLastSegmentToolTip(const std::string &tooltip);
+ void setLastSegmentProminentUrlTooltip(const std::string &label, bool trusted); // Preview real URLs of bracket links
/**
* If label is set, draws text label (which is LLLabelTextSegment)
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index 103f04a854..ef749ac53c 100644
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
@@ -39,7 +39,11 @@ LLUrlMatch::LLUrlMatch() :
mLocation(""),
mUnderline(e_underline::UNDERLINE_ALWAYS),
mTrusted(false),
- mSkipProfileIcon(false)
+ mSkipProfileIcon(false),
+ // Preview real URLs of bracket links
+ mLabeledLinkMasked(false),
+ mLabeledLinkTrusted(false)
+ //
{
}
@@ -68,4 +72,8 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std
mSkipProfileIcon = skip_icon;
// Store matched text
mMatchedText = matched_text;
+ // Preview real URLs of bracket links
+ mLabeledLinkMasked = false;
+ mLabeledLinkTrusted = false;
+ //
}
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index 2a32ac1f19..80817b52c3 100644
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
@@ -89,6 +89,13 @@ public:
bool getSkipProfileIcon() const { return mSkipProfileIcon; }
+ // Preview real URLs of bracket links
+ bool getLabeledLinkMasked() const { return mLabeledLinkMasked; }
+ void setLabeledLinkMasked(bool masked) { mLabeledLinkMasked = masked; }
+ bool getLabeledLinkTrusted() const { return mLabeledLinkTrusted; }
+ void setLabeledLinkTrusted(bool trusted) { mLabeledLinkTrusted = trusted; }
+ //
+
/// 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& query, const std::string &tooltip, const std::string &icon,
@@ -117,6 +124,10 @@ private:
e_underline mUnderline;
bool mTrusted;
bool mSkipProfileIcon;
+ // Preview real URLs of bracket links
+ bool mLabeledLinkMasked { false };
+ bool mLabeledLinkTrusted { false };
+ //
};
#endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 176afb57f7..b6aebbd9b1 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -254,15 +254,6 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
continue;
}
- // Option to disable square-bracket links (intentionally ignores secondlife:// and hop://)
- static LLUICachedControl sDisableLabeledLinks("FSDisableLabeledChatLinks", false);
- static LLUICachedControl sDisableLabeledLinksNearby("FSDisableLabeledChatLinksNearbyChat", false);
- if (!is_content_trusted && (mUrlEntryHTTPLabel == *it) && (is_nearby_chat ? sDisableLabeledLinksNearby : sDisableLabeledLinks))
- {
- continue;
- }
- //
-
LLUrlEntryBase *url_entry = *it;
U32 start = 0, end = 0;
@@ -346,6 +337,31 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getUnderline(url),
match_entry->isTrusted(),
match_entry->getSkipProfileIcon(url));
+
+ // Preview real URLs of bracket links
+ static LLUICachedControl sDisableLabeledLinks("FSDisableLabeledChatLinks", false);
+ static LLUICachedControl sDisableLabeledLinksNearby("FSDisableLabeledChatLinksNearbyChat", false);
+ if (!is_content_trusted && (match_entry == mUrlEntryHTTPLabel) && (is_nearby_chat ? sDisableLabeledLinksNearby : sDisableLabeledLinks) && match.getLabel() != match.getUrl())
+ {
+ match.setLabeledLinkMasked(true);
+ if (mUrlEntryTrustedUrl)
+ {
+ U32 trusted_start = 0, trusted_end = 0;
+ const std::string& real_url = match.getUrl();
+ bool url_trusted = matchRegex(real_url.c_str(), mUrlEntryTrustedUrl->getPattern(), trusted_start, trusted_end) && (trusted_start == 0);
+ if (!url_trusted)
+ {
+ const std::string slashed_url = real_url + "/";
+ url_trusted = matchRegex(slashed_url.c_str(), mUrlEntryTrustedUrl->getPattern(), trusted_start, trusted_end) && (trusted_start == 0);
+ }
+ if (url_trusted)
+ {
+ match.setLabeledLinkTrusted(true);
+ }
+ }
+ }
+ //
+
return true;
}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f6b23882a0..2570c4fb90 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -19658,7 +19658,7 @@ Change of this parameter will affect the layout of buttons in notification toast
FSDisableLabeledChatLinks