summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llurlentry.cpp81
-rw-r--r--indra/llui/llurlentry.h28
-rw-r--r--indra/llui/llurlregistry.cpp7
-rw-r--r--indra/llui/tests/llurlentry_test.cpp72
4 files changed, 97 insertions, 91 deletions
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 85f9064115..c20212c375 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -339,54 +339,75 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
///
-/// LLUrlEntryEvent Describes a Second Life event Url, e.g.,
-/// secondlife:///app/event/700727/about
+/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
+/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
-LLUrlEntryEvent::LLUrlEntryEvent()
+LLUrlEntryParcel::LLUrlEntryParcel()
{
- mPattern = boost::regex("secondlife:///app/event/[\\da-f-]+/about",
+ mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about",
boost::regex::perl|boost::regex::icase);
- mMenuName = "menu_url_event.xml";
- mTooltip = LLTrans::getString("TooltipEventUrl");
+ mMenuName = "menu_url_parcel.xml";
+ mTooltip = LLTrans::getString("TooltipParcelUrl");
}
-std::string LLUrlEntryEvent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
return unescapeUrl(url);
}
-///
-/// LLUrlEntryClassified Describes a Second Life classified Url, e.g.,
-/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about
-///
-LLUrlEntryClassified::LLUrlEntryClassified()
+//
+// LLUrlEntryPlace Describes secondlife:///<location> URLs
+//
+LLUrlEntryPlace::LLUrlEntryPlace()
{
- mPattern = boost::regex("secondlife:///app/classified/[\\da-f-]+/about",
+ mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
boost::regex::perl|boost::regex::icase);
- mMenuName = "menu_url_classified.xml";
- mTooltip = LLTrans::getString("TooltipClassifiedUrl");
+ mMenuName = "menu_url_slurl.xml";
+ mTooltip = LLTrans::getString("TooltipSLURL");
}
-std::string LLUrlEntryClassified::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+std::string LLUrlEntryPlace::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
- return unescapeUrl(url);
-}
+ //
+ // we handle SLURLs in the following formats:
+ // - secondlife://Place/X/Y/Z
+ // - secondlife://Place/X/Y
+ //
+ LLURI uri(url);
+ std::string location = unescapeUrl(uri.hostName());
+ LLSD path_array = uri.pathArray();
+ S32 path_parts = path_array.size();
+ if (path_parts == 3)
+ {
+ // handle slurl with (X,Y,Z) coordinates
+ std::string x = path_array[0];
+ std::string y = path_array[1];
+ std::string z = path_array[2];
+ return location + " (" + x + "," + y + "," + z + ")";
+ }
+ else if (path_parts == 2)
+ {
+ // handle slurl with (X,Y) coordinates
+ std::string x = path_array[0];
+ std::string y = path_array[1];
+ return location + " (" + x + "," + y + ")";
+ }
-///
-/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
-/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
-///
-LLUrlEntryParcel::LLUrlEntryParcel()
-{
- mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about",
- boost::regex::perl|boost::regex::icase);
- mMenuName = "menu_url_parcel.xml";
- mTooltip = LLTrans::getString("TooltipParcelUrl");
+ return url;
}
-std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+std::string LLUrlEntryPlace::getLocation(const std::string &url) const
{
- return unescapeUrl(url);
+ // return the part of the Url after secondlife:// part
+ const std::string search_string = "://";
+ size_t pos = url.find(search_string);
+ if (pos == std::string::npos)
+ {
+ return "";
+ }
+
+ pos += search_string.size();
+ return url.substr(pos, url.size() - pos);
}
//
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index f3e76dbec0..54053872df 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -170,36 +170,26 @@ private:
};
///
-/// LLUrlEntryEvent Describes a Second Life event Url, e.g.,
-/// secondlife:///app/event/700727/about
-///
-class LLUrlEntryEvent : public LLUrlEntryBase
-{
-public:
- LLUrlEntryEvent();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
-};
-
-///
-/// LLUrlEntryClassified Describes a Second Life classified Url, e.g.,
-/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about
+/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
+/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
-class LLUrlEntryClassified : public LLUrlEntryBase
+class LLUrlEntryParcel : public LLUrlEntryBase
{
public:
- LLUrlEntryClassified();
+ LLUrlEntryParcel();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
};
///
-/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
-/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
+/// LLUrlEntryPlace Describes a Second Life location Url, e.g.,
+/// secondlife:///Ahern/50/50/50
///
-class LLUrlEntryParcel : public LLUrlEntryBase
+class LLUrlEntryPlace : public LLUrlEntryBase
{
public:
- LLUrlEntryParcel();
+ LLUrlEntryPlace();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getLocation(const std::string &url) const;
};
///
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 938375ad13..f2d340deb7 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -49,11 +49,10 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryHTTPLabel());
registerUrl(new LLUrlEntryAgent());
registerUrl(new LLUrlEntryGroup());
- registerUrl(new LLUrlEntryEvent());
- registerUrl(new LLUrlEntryClassified());
registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport());
registerUrl(new LLUrlEntryObjectIM());
+ registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
}
@@ -118,8 +117,8 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
{
- // test for the trivial case of no text and get out fast
- if (text.empty())
+ // avoid costly regexes if there is clearly no URL in the text
+ if (text.find("://") == std::string::npos)
{
return false;
}
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 610ee3349b..1e7a0f7f2c 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -308,56 +308,52 @@ namespace tut
void object::test<6>()
{
//
- // test LLUrlEntryEvent - secondlife://app/event Urls
+ // test LLUrlEntryPlace - secondlife://<location> URLs
//
- LLUrlEntryEvent url;
+ LLUrlEntryPlace url;
boost::regex r = url.getPattern();
- testRegex("Invalid Event Url", r,
- "secondlife:///app/event/FOO/about",
+ testRegex("no valid slurl [1]", r,
+ "secondlife://Ahern/FOO/50/",
"");
- testRegex("Event Url ", r,
- "secondlife:///app/event/700727/about",
- "secondlife:///app/event/700727/about");
+ testRegex("Ahern (50,50,50) [1]", r,
+ "secondlife://Ahern/50/50/50/",
+ "secondlife://Ahern/50/50/50/");
- testRegex("Event Url in text", r,
- "XXX secondlife:///app/event/700727/about XXX",
- "secondlife:///app/event/700727/about");
+ testRegex("Ahern (50,50,50) [2]", r,
+ "XXX secondlife://Ahern/50/50/50/ XXX",
+ "secondlife://Ahern/50/50/50/");
- testRegex("Event Url multicase", r,
- "XXX secondlife:///APP/Event/700727/about XXX",
- "secondlife:///APP/Event/700727/about");
- }
+ testRegex("Ahern (50,50,50) [3]", r,
+ "XXX secondlife://Ahern/50/50/50 XXX",
+ "secondlife://Ahern/50/50/50");
- template<> template<>
- void object::test<7>()
- {
- //
- // test LLUrlEntryClassified - secondlife://app/classified Urls
- //
- LLUrlEntryClassified url;
- boost::regex r = url.getPattern();
+ testRegex("Ahern (50,50,50) multicase", r,
+ "XXX SecondLife://Ahern/50/50/50/ XXX",
+ "SecondLife://Ahern/50/50/50/");
- testRegex("Invalid Classified Url", r,
- "secondlife:///app/classified/00128854-XXXX-5649-7ca6-5dfaa7514ab2/about",
- "");
+ testRegex("Ahern (50,50) [1]", r,
+ "XXX secondlife://Ahern/50/50/ XXX",
+ "secondlife://Ahern/50/50/");
- testRegex("Classified Url ", r,
- "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about",
- "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about");
+ testRegex("Ahern (50,50) [2]", r,
+ "XXX secondlife://Ahern/50/50 XXX",
+ "secondlife://Ahern/50/50");
- testRegex("Classified Url in text", r,
- "XXX secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about XXX",
- "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about");
+ // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
+ testRegex("SLURL with brackets", r,
+ "XXX secondlife://Burning%20Life%20(Hyper)/27/210/30 XXX",
+ "secondlife://Burning%20Life%20(Hyper)/27/210/30");
- testRegex("Classified Url multicase", r,
- "XXX secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About XXX",
- "secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About");
+ // DEV-35459: SLURLs and teleport Links not parsed properly
+ testRegex("SLURL with quote", r,
+ "XXX secondlife://A'ksha%20Oasis/41/166/701 XXX",
+ "secondlife://A'ksha%20Oasis/41/166/701");
}
template<> template<>
- void object::test<8>()
+ void object::test<7>()
{
//
// test LLUrlEntryParcel - secondlife://app/parcel Urls
@@ -382,7 +378,7 @@ namespace tut
"secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About");
}
template<> template<>
- void object::test<9>()
+ void object::test<8>()
{
//
// test LLUrlEntryTeleport - secondlife://app/teleport URLs
@@ -458,7 +454,7 @@ namespace tut
}
template<> template<>
- void object::test<10>()
+ void object::test<9>()
{
//
// test LLUrlEntrySL - general secondlife:// URLs
@@ -496,7 +492,7 @@ namespace tut
}
template<> template<>
- void object::test<11>()
+ void object::test<10>()
{
//
// test LLUrlEntrySLLabel - general secondlife:// URLs with labels