diff options
-rw-r--r-- | indra/llui/llurlentry.cpp | 81 | ||||
-rw-r--r-- | indra/llui/llurlentry.h | 28 | ||||
-rw-r--r-- | indra/llui/llurlregistry.cpp | 7 | ||||
-rw-r--r-- | indra/llui/tests/llurlentry_test.cpp | 72 |
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 |