Skip to content
Snippets Groups Projects
Commit abda07fb authored by Vadim ProductEngine's avatar Vadim ProductEngine
Browse files

STORM-796 FIXED Implemented rendering /app/region/ SLapps into human-readable strings.

Example: secondlife:///app/region/Ahern/10/20/30/ is displayed as "Ahern (10,20,30)".
parent 73962e21
No related branches found
No related tags found
No related merge requests found
...@@ -805,6 +805,69 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const ...@@ -805,6 +805,69 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
return ::getStringAfterToken(url, "://"); return ::getStringAfterToken(url, "://");
} }
//
// LLUrlEntryRegion Describes secondlife:///app/region/REGION_NAME/X/Y/Z URLs, e.g.
// secondlife:///app/region/Ahern/128/128/0
//
LLUrlEntryRegion::LLUrlEntryRegion()
{
mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");
}
std::string LLUrlEntryRegion::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
//
// we handle SLURLs in the following formats:
// - secondlife:///app/region/Place/X/Y/Z
// - secondlife:///app/region/Place/X/Y
// - secondlife:///app/region/Place/X
// - secondlife:///app/region/Place
//
LLSD path_array = LLURI(url).pathArray();
S32 path_parts = path_array.size();
if (path_parts < 3) // no region name
{
llwarns << "Failed to parse url [" << url << "]" << llendl;
return url;
}
std::string label = unescapeUrl(path_array[2]); // region name
if (path_parts > 3) // secondlife:///app/region/Place/X
{
std::string x = path_array[3];
label += " (" + x;
if (path_parts > 4) // secondlife:///app/region/Place/X/Y
{
std::string y = path_array[4];
label += "," + y;
if (path_parts > 5) // secondlife:///app/region/Place/X/Y/Z
{
std::string z = path_array[5];
label = label + "," + z;
}
}
label += ")";
}
return label;
}
std::string LLUrlEntryRegion::getLocation(const std::string &url) const
{
LLSD path_array = LLURI(url).pathArray();
std::string region_name = unescapeUrl(path_array[2]);
return region_name;
}
// //
// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g., // LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
// secondlife:///app/teleport/Ahern/50/50/50/ // secondlife:///app/teleport/Ahern/50/50/50/
......
...@@ -301,6 +301,18 @@ class LLUrlEntryPlace : public LLUrlEntryBase ...@@ -301,6 +301,18 @@ class LLUrlEntryPlace : public LLUrlEntryBase
/*virtual*/ std::string getLocation(const std::string &url) const; /*virtual*/ std::string getLocation(const std::string &url) const;
}; };
///
/// LLUrlEntryRegion Describes a Second Life location Url, e.g.,
/// secondlife:///app/region/Ahern/128/128/0
///
class LLUrlEntryRegion : public LLUrlEntryBase
{
public:
LLUrlEntryRegion();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getLocation(const std::string &url) const;
};
/// ///
/// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g., /// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
/// secondlife:///app/teleport/Ahern/50/50/50/ /// secondlife:///app/teleport/Ahern/50/50/50/
......
...@@ -54,6 +54,7 @@ LLUrlRegistry::LLUrlRegistry() ...@@ -54,6 +54,7 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryGroup());
registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport()); registerUrl(new LLUrlEntryTeleport());
registerUrl(new LLUrlEntryRegion());
registerUrl(new LLUrlEntryWorldMap()); registerUrl(new LLUrlEntryWorldMap());
registerUrl(new LLUrlEntryObjectIM()); registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace()); registerUrl(new LLUrlEntryPlace());
......
...@@ -103,6 +103,45 @@ namespace tut ...@@ -103,6 +103,45 @@ namespace tut
ensure_equals(testname, url, expected); ensure_equals(testname, url, expected);
} }
void dummyCallback(const std::string &url, const std::string &label, const std::string& icon)
{
}
void testLabel(const std::string &testname, LLUrlEntryBase &entry,
const char *text, const std::string &expected)
{
boost::regex regex = entry.getPattern();
std::string label = "";
boost::cmatch result;
bool found = boost::regex_search(text, result, regex);
if (found)
{
S32 start = static_cast<U32>(result[0].first - text);
S32 end = static_cast<U32>(result[0].second - text);
std::string url = std::string(text+start, end-start);
label = entry.getLabel(url, dummyCallback);
}
ensure_equals(testname, label, expected);
}
void testLocation(const std::string &testname, LLUrlEntryBase &entry,
const char *text, const std::string &expected)
{
boost::regex regex = entry.getPattern();
std::string location = "";
boost::cmatch result;
bool found = boost::regex_search(text, result, regex);
if (found)
{
S32 start = static_cast<U32>(result[0].first - text);
S32 end = static_cast<U32>(result[0].second - text);
std::string url = std::string(text+start, end-start);
location = entry.getLocation(url);
}
ensure_equals(testname, location, expected);
}
template<> template<> template<> template<>
void object::test<1>() void object::test<1>()
{ {
...@@ -697,4 +736,114 @@ namespace tut ...@@ -697,4 +736,114 @@ namespace tut
"<nolink>My Object</nolink>", "<nolink>My Object</nolink>",
"My Object"); "My Object");
} }
template<> template<>
void object::test<13>()
{
//
// test LLUrlEntryRegion - secondlife:///app/region/<location> URLs
//
LLUrlEntryRegion url;
// Regex tests.
testRegex("no valid region", url,
"secondlife:///app/region/",
"");
testRegex("invalid coords", url,
"secondlife:///app/region/Korea2/a/b/c",
"secondlife:///app/region/Korea2/"); // don't count invalid coords
testRegex("Ahern (50,50,50) [1]", url,
"secondlife:///app/region/Ahern/50/50/50/",
"secondlife:///app/region/Ahern/50/50/50/");
testRegex("Ahern (50,50,50) [2]", url,
"XXX secondlife:///app/region/Ahern/50/50/50/ XXX",
"secondlife:///app/region/Ahern/50/50/50/");
testRegex("Ahern (50,50,50) [3]", url,
"XXX secondlife:///app/region/Ahern/50/50/50 XXX",
"secondlife:///app/region/Ahern/50/50/50");
testRegex("Ahern (50,50,50) multicase", url,
"XXX secondlife:///app/region/Ahern/50/50/50/ XXX",
"secondlife:///app/region/Ahern/50/50/50/");
testRegex("Ahern (50,50) [1]", url,
"XXX secondlife:///app/region/Ahern/50/50/ XXX",
"secondlife:///app/region/Ahern/50/50/");
testRegex("Ahern (50,50) [2]", url,
"XXX secondlife:///app/region/Ahern/50/50 XXX",
"secondlife:///app/region/Ahern/50/50");
// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
testRegex("Region with brackets", url,
"XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",
"secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30");
// DEV-35459: SLURLs and teleport Links not parsed properly
testRegex("Region with quote", url,
"XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX",
"secondlife:///app/region/A%27ksha%20Oasis/41/166/701");
// Rendering tests.
testLabel("Render /app/region/Ahern/50/50/50/", url,
"secondlife:///app/region/Ahern/50/50/50/",
"Ahern (50,50,50)");
testLabel("Render /app/region/Ahern/50/50/50", url,
"secondlife:///app/region/Ahern/50/50/50",
"Ahern (50,50,50)");
testLabel("Render /app/region/Ahern/50/50/", url,
"secondlife:///app/region/Ahern/50/50/",
"Ahern (50,50)");
testLabel("Render /app/region/Ahern/50/50", url,
"secondlife:///app/region/Ahern/50/50",
"Ahern (50,50)");
testLabel("Render /app/region/Ahern/50/", url,
"secondlife:///app/region/Ahern/50/",
"Ahern (50)");
testLabel("Render /app/region/Ahern/50", url,
"secondlife:///app/region/Ahern/50",
"Ahern (50)");
testLabel("Render /app/region/Ahern/", url,
"secondlife:///app/region/Ahern/",
"Ahern");
testLabel("Render /app/region/Ahern/ within context", url,
"XXX secondlife:///app/region/Ahern/ XXX",
"Ahern");
testLabel("Render /app/region/Ahern", url,
"secondlife:///app/region/Ahern",
"Ahern");
testLabel("Render /app/region/Ahern within context", url,
"XXX secondlife:///app/region/Ahern XXX",
"Ahern");
testLabel("Render /app/region/Product%20Engine/", url,
"secondlife:///app/region/Product%20Engine/",
"Product Engine");
testLabel("Render /app/region/Product%20Engine", url,
"secondlife:///app/region/Product%20Engine",
"Product Engine");
// Location parsing texts.
testLocation("Location /app/region/Ahern/50/50/50/", url,
"secondlife:///app/region/Ahern/50/50/50/",
"Ahern");
testLocation("Location /app/region/Product%20Engine", url,
"secondlife:///app/region/Product%20Engine",
"Product Engine");
}
} }
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