Skip to content
Snippets Groups Projects
Commit 7cd1020f authored by Martin Reddy's avatar Martin Reddy
Browse files

DEV-39188: Removed the custom support for secondlife:///app/events and

secondlife:///app/classifieds URLs because we do not have handlers for
these SLAPPs in 2.0.

Added support for secondlife://<location/<x>/<y>/<z> URLs, in addition
to the http://slurl.com SLURLs.

Also optimized LLUrlRegistry:findUrl() so that it avoids lots of
expensive regex calls when there is no URL in the text.
parent 1d985532
No related branches found
No related tags found
No related merge requests found
...@@ -339,54 +339,75 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa ...@@ -339,54 +339,75 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
} }
/// ///
/// LLUrlEntryEvent Describes a Second Life event Url, e.g., /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/event/700727/about /// 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); boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_event.xml"; mMenuName = "menu_url_parcel.xml";
mTooltip = LLTrans::getString("TooltipEventUrl"); 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); return unescapeUrl(url);
} }
/// //
/// LLUrlEntryClassified Describes a Second Life classified Url, e.g., // LLUrlEntryPlace Describes secondlife:///<location> URLs
/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about //
/// LLUrlEntryPlace::LLUrlEntryPlace()
LLUrlEntryClassified::LLUrlEntryClassified()
{ {
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); boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_classified.xml"; mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipClassifiedUrl"); 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 + ")";
}
/// return url;
/// 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");
} }
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);
} }
// //
......
...@@ -170,36 +170,26 @@ private: ...@@ -170,36 +170,26 @@ private:
}; };
/// ///
/// LLUrlEntryEvent Describes a Second Life event Url, e.g., /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/event/700727/about /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/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
/// ///
class LLUrlEntryClassified : public LLUrlEntryBase class LLUrlEntryParcel : public LLUrlEntryBase
{ {
public: public:
LLUrlEntryClassified(); LLUrlEntryParcel();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
}; };
/// ///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., /// LLUrlEntryPlace Describes a Second Life location Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about /// secondlife:///Ahern/50/50/50
/// ///
class LLUrlEntryParcel : public LLUrlEntryBase class LLUrlEntryPlace : public LLUrlEntryBase
{ {
public: public:
LLUrlEntryParcel(); LLUrlEntryPlace();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getLocation(const std::string &url) const;
}; };
/// ///
......
...@@ -49,11 +49,10 @@ LLUrlRegistry::LLUrlRegistry() ...@@ -49,11 +49,10 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryHTTPLabel()); registerUrl(new LLUrlEntryHTTPLabel());
registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryAgent());
registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryGroup());
registerUrl(new LLUrlEntryEvent());
registerUrl(new LLUrlEntryClassified());
registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport()); registerUrl(new LLUrlEntryTeleport());
registerUrl(new LLUrlEntryObjectIM()); registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntrySL()); registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel()); registerUrl(new LLUrlEntrySLLabel());
} }
...@@ -118,8 +117,8 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en ...@@ -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) bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
{ {
// test for the trivial case of no text and get out fast // avoid costly regexes if there is clearly no URL in the text
if (text.empty()) if (text.find("://") == std::string::npos)
{ {
return false; return false;
} }
......
...@@ -308,56 +308,52 @@ namespace tut ...@@ -308,56 +308,52 @@ namespace tut
void object::test<6>() void object::test<6>()
{ {
// //
// test LLUrlEntryEvent - secondlife://app/event Urls // test LLUrlEntryPlace - secondlife://<location> URLs
// //
LLUrlEntryEvent url; LLUrlEntryPlace url;
boost::regex r = url.getPattern(); boost::regex r = url.getPattern();
testRegex("Invalid Event Url", r, testRegex("no valid slurl [1]", r,
"secondlife:///app/event/FOO/about", "secondlife://Ahern/FOO/50/",
""); "");
testRegex("Event Url ", r, testRegex("Ahern (50,50,50) [1]", r,
"secondlife:///app/event/700727/about", "secondlife://Ahern/50/50/50/",
"secondlife:///app/event/700727/about"); "secondlife://Ahern/50/50/50/");
testRegex("Event Url in text", r, testRegex("Ahern (50,50,50) [2]", r,
"XXX secondlife:///app/event/700727/about XXX", "XXX secondlife://Ahern/50/50/50/ XXX",
"secondlife:///app/event/700727/about"); "secondlife://Ahern/50/50/50/");
testRegex("Event Url multicase", r, testRegex("Ahern (50,50,50) [3]", r,
"XXX secondlife:///APP/Event/700727/about XXX", "XXX secondlife://Ahern/50/50/50 XXX",
"secondlife:///APP/Event/700727/about"); "secondlife://Ahern/50/50/50");
}
template<> template<> testRegex("Ahern (50,50,50) multicase", r,
void object::test<7>() "XXX SecondLife://Ahern/50/50/50/ XXX",
{ "SecondLife://Ahern/50/50/50/");
//
// test LLUrlEntryClassified - secondlife://app/classified Urls
//
LLUrlEntryClassified url;
boost::regex r = url.getPattern();
testRegex("Invalid Classified Url", r, testRegex("Ahern (50,50) [1]", r,
"secondlife:///app/classified/00128854-XXXX-5649-7ca6-5dfaa7514ab2/about", "XXX secondlife://Ahern/50/50/ XXX",
""); "secondlife://Ahern/50/50/");
testRegex("Classified Url ", r, testRegex("Ahern (50,50) [2]", r,
"secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about", "XXX secondlife://Ahern/50/50 XXX",
"secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about"); "secondlife://Ahern/50/50");
testRegex("Classified Url in text", r, // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
"XXX secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about XXX", testRegex("SLURL with brackets", r,
"secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about"); "XXX secondlife://Burning%20Life%20(Hyper)/27/210/30 XXX",
"secondlife://Burning%20Life%20(Hyper)/27/210/30");
testRegex("Classified Url multicase", r, // DEV-35459: SLURLs and teleport Links not parsed properly
"XXX secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About XXX", testRegex("SLURL with quote", r,
"secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About"); "XXX secondlife://A'ksha%20Oasis/41/166/701 XXX",
"secondlife://A'ksha%20Oasis/41/166/701");
} }
template<> template<> template<> template<>
void object::test<8>() void object::test<7>()
{ {
// //
// test LLUrlEntryParcel - secondlife://app/parcel Urls // test LLUrlEntryParcel - secondlife://app/parcel Urls
...@@ -382,7 +378,7 @@ namespace tut ...@@ -382,7 +378,7 @@ namespace tut
"secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About"); "secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About");
} }
template<> template<> template<> template<>
void object::test<9>() void object::test<8>()
{ {
// //
// test LLUrlEntryTeleport - secondlife://app/teleport URLs // test LLUrlEntryTeleport - secondlife://app/teleport URLs
...@@ -458,7 +454,7 @@ namespace tut ...@@ -458,7 +454,7 @@ namespace tut
} }
template<> template<> template<> template<>
void object::test<10>() void object::test<9>()
{ {
// //
// test LLUrlEntrySL - general secondlife:// URLs // test LLUrlEntrySL - general secondlife:// URLs
...@@ -496,7 +492,7 @@ namespace tut ...@@ -496,7 +492,7 @@ namespace tut
} }
template<> template<> template<> template<>
void object::test<11>() void object::test<10>()
{ {
// //
// test LLUrlEntrySLLabel - general secondlife:// URLs with labels // test LLUrlEntrySLLabel - general secondlife:// URLs with labels
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment