Added: URL #fragment navigation.
This commit is contained in:
parent
9014aa6fad
commit
d3625364c6
2 changed files with 114 additions and 5 deletions
|
@ -343,6 +343,10 @@ namespace NLGUI
|
||||||
|
|
||||||
// Current URL
|
// Current URL
|
||||||
std::string _URL;
|
std::string _URL;
|
||||||
|
// Fragment from loading url
|
||||||
|
std::string _UrlFragment;
|
||||||
|
std::map<std::string,NLGUI::CInterfaceElement *> _Anchors;
|
||||||
|
std::vector<std::string> _AnchorName;
|
||||||
|
|
||||||
// Current DOMAIN
|
// Current DOMAIN
|
||||||
bool _TrustedDomain;
|
bool _TrustedDomain;
|
||||||
|
@ -378,6 +382,7 @@ namespace NLGUI
|
||||||
bool _IgnoreText;
|
bool _IgnoreText;
|
||||||
// the script to execute
|
// the script to execute
|
||||||
std::string _LuaScript;
|
std::string _LuaScript;
|
||||||
|
bool _LuaHrefHack;
|
||||||
|
|
||||||
bool _Object;
|
bool _Object;
|
||||||
std::string _ObjectScript;
|
std::string _ObjectScript;
|
||||||
|
@ -673,6 +678,8 @@ namespace NLGUI
|
||||||
// search if the action / params match the url. look recurs into procedures
|
// search if the action / params match the url. look recurs into procedures
|
||||||
bool actionLaunchUrlRecurs(const std::string &ah, const std::string ¶ms, const std::string &url);
|
bool actionLaunchUrlRecurs(const std::string &ah, const std::string ¶ms, const std::string &url);
|
||||||
|
|
||||||
|
void registerAnchor(CInterfaceElement* elm);
|
||||||
|
|
||||||
// Browse undo and redo
|
// Browse undo and redo
|
||||||
enum {MaxUrlUndoRedo= 256};
|
enum {MaxUrlUndoRedo= 256};
|
||||||
std::string _BrowseUndoButton;
|
std::string _BrowseUndoButton;
|
||||||
|
@ -683,7 +690,8 @@ namespace NLGUI
|
||||||
std::deque<std::string> _BrowseUndo;
|
std::deque<std::string> _BrowseUndo;
|
||||||
std::deque<std::string> _BrowseRedo;
|
std::deque<std::string> _BrowseRedo;
|
||||||
void pushUrlUndoRedo(const std::string &url);
|
void pushUrlUndoRedo(const std::string &url);
|
||||||
void doBrowse(const char *url);
|
void doBrowse(const char *url, bool force = false);
|
||||||
|
void doBrowseAnchor(const std::string &anchor);
|
||||||
void updateUndoRedoButtons();
|
void updateUndoRedoButtons();
|
||||||
void updateRefreshButton();
|
void updateRefreshButton();
|
||||||
|
|
||||||
|
|
|
@ -700,12 +700,26 @@ namespace NLGUI
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
|
#define registerAnchorName(prefix) \
|
||||||
|
{\
|
||||||
|
if (present[prefix##_ID] && value[prefix##_ID]) \
|
||||||
|
_AnchorName.push_back(value[prefix##_ID]); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
|
||||||
void CGroupHTML::addLink (uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value)
|
void CGroupHTML::addLink (uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value)
|
||||||
{
|
{
|
||||||
if (_Browsing)
|
if (_Browsing)
|
||||||
{
|
{
|
||||||
if (element_number == HTML_A)
|
if (element_number == HTML_A)
|
||||||
{
|
{
|
||||||
|
registerAnchorName(MY_HTML_A);
|
||||||
|
|
||||||
|
// #fragment works with both ID and NAME so register both
|
||||||
|
if (present[MY_HTML_A_NAME] && value[MY_HTML_A_NAME])
|
||||||
|
_AnchorName.push_back(value[MY_HTML_A_NAME]);
|
||||||
|
|
||||||
if (present[MY_HTML_A_HREF] && value[MY_HTML_A_HREF])
|
if (present[MY_HTML_A_HREF] && value[MY_HTML_A_HREF])
|
||||||
{
|
{
|
||||||
string suri = value[MY_HTML_A_HREF];
|
string suri = value[MY_HTML_A_HREF];
|
||||||
|
@ -716,7 +730,7 @@ namespace NLGUI
|
||||||
else
|
else
|
||||||
_Link.push_back ("");
|
_Link.push_back ("");
|
||||||
}
|
}
|
||||||
else if (_TrustedDomain && suri[0] == '#')
|
else if (_TrustedDomain && suri[0] == '#' && _LuaHrefHack)
|
||||||
{
|
{
|
||||||
// Direct url (hack for lua beginElement)
|
// Direct url (hack for lua beginElement)
|
||||||
_Link.push_back (suri.substr(1));
|
_Link.push_back (suri.substr(1));
|
||||||
|
@ -1043,6 +1057,8 @@ namespace NLGUI
|
||||||
|
|
||||||
case HTML_DIV:
|
case HTML_DIV:
|
||||||
{
|
{
|
||||||
|
registerAnchorName(MY_HTML_DIV);
|
||||||
|
|
||||||
if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME])
|
if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME])
|
||||||
_DivName = value[MY_HTML_DIV_NAME];
|
_DivName = value[MY_HTML_DIV_NAME];
|
||||||
|
|
||||||
|
@ -1208,36 +1224,42 @@ namespace NLGUI
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HTML_H1:
|
case HTML_H1:
|
||||||
|
registerAnchorName(MY_HTML_H1);
|
||||||
newParagraph(PBeginSpace);
|
newParagraph(PBeginSpace);
|
||||||
_FontSize.push_back(H1FontSize);
|
_FontSize.push_back(H1FontSize);
|
||||||
_TextColor.push_back(H1Color);
|
_TextColor.push_back(H1Color);
|
||||||
_GlobalColor.push_back(H1ColorGlobalColor);
|
_GlobalColor.push_back(H1ColorGlobalColor);
|
||||||
break;
|
break;
|
||||||
case HTML_H2:
|
case HTML_H2:
|
||||||
|
registerAnchorName(MY_HTML_H2);
|
||||||
newParagraph(PBeginSpace);
|
newParagraph(PBeginSpace);
|
||||||
_FontSize.push_back(H2FontSize);
|
_FontSize.push_back(H2FontSize);
|
||||||
_TextColor.push_back(H2Color);
|
_TextColor.push_back(H2Color);
|
||||||
_GlobalColor.push_back(H2ColorGlobalColor);
|
_GlobalColor.push_back(H2ColorGlobalColor);
|
||||||
break;
|
break;
|
||||||
case HTML_H3:
|
case HTML_H3:
|
||||||
|
registerAnchorName(MY_HTML_H3);
|
||||||
newParagraph(PBeginSpace);
|
newParagraph(PBeginSpace);
|
||||||
_FontSize.push_back(H3FontSize);
|
_FontSize.push_back(H3FontSize);
|
||||||
_TextColor.push_back(H3Color);
|
_TextColor.push_back(H3Color);
|
||||||
_GlobalColor.push_back(H3ColorGlobalColor);
|
_GlobalColor.push_back(H3ColorGlobalColor);
|
||||||
break;
|
break;
|
||||||
case HTML_H4:
|
case HTML_H4:
|
||||||
|
registerAnchorName(MY_HTML_H4);
|
||||||
newParagraph(PBeginSpace);
|
newParagraph(PBeginSpace);
|
||||||
_FontSize.push_back(H4FontSize);
|
_FontSize.push_back(H4FontSize);
|
||||||
_TextColor.push_back(H4Color);
|
_TextColor.push_back(H4Color);
|
||||||
_GlobalColor.push_back(H4ColorGlobalColor);
|
_GlobalColor.push_back(H4ColorGlobalColor);
|
||||||
break;
|
break;
|
||||||
case HTML_H5:
|
case HTML_H5:
|
||||||
|
registerAnchorName(MY_HTML_H5);
|
||||||
newParagraph(PBeginSpace);
|
newParagraph(PBeginSpace);
|
||||||
_FontSize.push_back(H5FontSize);
|
_FontSize.push_back(H5FontSize);
|
||||||
_TextColor.push_back(H5Color);
|
_TextColor.push_back(H5Color);
|
||||||
_GlobalColor.push_back(H5ColorGlobalColor);
|
_GlobalColor.push_back(H5ColorGlobalColor);
|
||||||
break;
|
break;
|
||||||
case HTML_H6:
|
case HTML_H6:
|
||||||
|
registerAnchorName(MY_HTML_H6);
|
||||||
newParagraph(PBeginSpace);
|
newParagraph(PBeginSpace);
|
||||||
_FontSize.push_back(H6FontSize);
|
_FontSize.push_back(H6FontSize);
|
||||||
_TextColor.push_back(H6Color);
|
_TextColor.push_back(H6Color);
|
||||||
|
@ -1604,6 +1626,8 @@ namespace NLGUI
|
||||||
break;
|
break;
|
||||||
case HTML_TABLE:
|
case HTML_TABLE:
|
||||||
{
|
{
|
||||||
|
registerAnchorName(MY_HTML_TABLE);
|
||||||
|
|
||||||
// Get cells parameters
|
// Get cells parameters
|
||||||
getCellsParameters (MY_HTML_TABLE, false);
|
getCellsParameters (MY_HTML_TABLE, false);
|
||||||
|
|
||||||
|
@ -2024,6 +2048,7 @@ namespace NLGUI
|
||||||
// init
|
// init
|
||||||
_TrustedDomain = false;
|
_TrustedDomain = false;
|
||||||
_ParsingLua = false;
|
_ParsingLua = false;
|
||||||
|
_LuaHrefHack = false;
|
||||||
_IgnoreText = false;
|
_IgnoreText = false;
|
||||||
_BrowseNextTime = false;
|
_BrowseNextTime = false;
|
||||||
_PostNextTime = false;
|
_PostNextTime = false;
|
||||||
|
@ -2035,6 +2060,7 @@ namespace NLGUI
|
||||||
_LI = false;
|
_LI = false;
|
||||||
_SelectOption = false;
|
_SelectOption = false;
|
||||||
_GroupListAdaptor = NULL;
|
_GroupListAdaptor = NULL;
|
||||||
|
_UrlFragment.clear();
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
CWidgetManager::getInstance()->registerClockMsgTarget(this);
|
CWidgetManager::getInstance()->registerClockMsgTarget(this);
|
||||||
|
@ -3087,11 +3113,11 @@ namespace NLGUI
|
||||||
void CGroupHTML::refresh()
|
void CGroupHTML::refresh()
|
||||||
{
|
{
|
||||||
if (!_URL.empty())
|
if (!_URL.empty())
|
||||||
doBrowse(_URL.c_str());
|
doBrowse(_URL.c_str(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
void CGroupHTML::doBrowse(const char *url)
|
void CGroupHTML::doBrowse(const char *url, bool force)
|
||||||
{
|
{
|
||||||
// Stop previous browse
|
// Stop previous browse
|
||||||
if (_Browsing)
|
if (_Browsing)
|
||||||
|
@ -3111,8 +3137,29 @@ namespace NLGUI
|
||||||
nlwarning("(%s) Browsing URL : '%s'", _Id.c_str(), url);
|
nlwarning("(%s) Browsing URL : '%s'", _Id.c_str(), url);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
CUrlParser uri(url);
|
||||||
|
if (uri.hash.size() > 0)
|
||||||
|
{
|
||||||
|
// Anchor to scroll after page has loaded
|
||||||
|
_UrlFragment = uri.hash;
|
||||||
|
|
||||||
|
uri.inherit(_URL);
|
||||||
|
uri.hash.clear();
|
||||||
|
|
||||||
|
// compare urls and see if we only navigating to new anchor
|
||||||
|
if (!force && _URL == uri.toString())
|
||||||
|
{
|
||||||
|
// scroll happens in updateCoords()
|
||||||
|
invalidateCoords();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_UrlFragment.clear();
|
||||||
|
|
||||||
// go
|
// go
|
||||||
_URL = url;
|
_URL = uri.toString();
|
||||||
_Connecting = false;
|
_Connecting = false;
|
||||||
_BrowseNextTime = true;
|
_BrowseNextTime = true;
|
||||||
|
|
||||||
|
@ -3177,6 +3224,13 @@ namespace NLGUI
|
||||||
void CGroupHTML::updateCoords()
|
void CGroupHTML::updateCoords()
|
||||||
{
|
{
|
||||||
CGroupScrollText::updateCoords();
|
CGroupScrollText::updateCoords();
|
||||||
|
|
||||||
|
// all elements are in their correct place, tell scrollbar to scroll to anchor
|
||||||
|
if (!_Browsing && !_UrlFragment.empty())
|
||||||
|
{
|
||||||
|
doBrowseAnchor(_UrlFragment);
|
||||||
|
_UrlFragment.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
@ -3228,6 +3282,25 @@ namespace NLGUI
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
|
void CGroupHTML::registerAnchor(CInterfaceElement* elm)
|
||||||
|
{
|
||||||
|
if (_AnchorName.size() > 0)
|
||||||
|
{
|
||||||
|
for(uint32 i=0; i < _AnchorName.size(); ++i)
|
||||||
|
{
|
||||||
|
// filter out duplicates and register only first
|
||||||
|
if (!_AnchorName[i].empty() && _Anchors.count(_AnchorName[i]) == 0)
|
||||||
|
{
|
||||||
|
_Anchors[_AnchorName[i]] = elm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_AnchorName.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
|
||||||
void CGroupHTML::addString(const ucstring &str)
|
void CGroupHTML::addString(const ucstring &str)
|
||||||
{
|
{
|
||||||
ucstring tmpStr = str;
|
ucstring tmpStr = str;
|
||||||
|
@ -3381,6 +3454,8 @@ namespace NLGUI
|
||||||
newLink->setModulateGlobalColor(getGlobalColor());
|
newLink->setModulateGlobalColor(getGlobalColor());
|
||||||
// newLink->setLineAtBottom (true);
|
// newLink->setLineAtBottom (true);
|
||||||
|
|
||||||
|
registerAnchor(newLink);
|
||||||
|
|
||||||
if (getA() && !newLink->Link.empty())
|
if (getA() && !newLink->Link.empty())
|
||||||
{
|
{
|
||||||
getParagraph()->addChildLink(newLink);
|
getParagraph()->addChildLink(newLink);
|
||||||
|
@ -3666,6 +3741,8 @@ namespace NLGUI
|
||||||
_TR.clear();
|
_TR.clear();
|
||||||
_Forms.clear();
|
_Forms.clear();
|
||||||
_Groups.clear();
|
_Groups.clear();
|
||||||
|
_Anchors.clear();
|
||||||
|
_AnchorName.clear();
|
||||||
_CellParams.clear();
|
_CellParams.clear();
|
||||||
_Title = false;
|
_Title = false;
|
||||||
_TextArea = false;
|
_TextArea = false;
|
||||||
|
@ -3747,6 +3824,8 @@ namespace NLGUI
|
||||||
_Paragraph = NULL;
|
_Paragraph = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerAnchor(group);
|
||||||
|
|
||||||
if (!_DivName.empty())
|
if (!_DivName.empty())
|
||||||
{
|
{
|
||||||
group->setName(_DivName);
|
group->setName(_DivName);
|
||||||
|
@ -4355,6 +4434,22 @@ namespace NLGUI
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
|
void CGroupHTML::doBrowseAnchor(const std::string &anchor)
|
||||||
|
{
|
||||||
|
CInterfaceElement *pIE = _Anchors.find(anchor)->second;
|
||||||
|
if (pIE)
|
||||||
|
{
|
||||||
|
// hotspot depends on vertical/horizontal scrollbar
|
||||||
|
CCtrlScroll *pSB = getScrollBar();
|
||||||
|
if (pSB)
|
||||||
|
{
|
||||||
|
pSB->ensureVisible(pIE, Hotspot_Tx, Hotspot_Tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
|
||||||
void CGroupHTML::draw ()
|
void CGroupHTML::draw ()
|
||||||
{
|
{
|
||||||
CGroupScrollText::draw ();
|
CGroupScrollText::draw ();
|
||||||
|
@ -4762,7 +4857,13 @@ namespace NLGUI
|
||||||
|
|
||||||
beginElement(element_number, present, value);
|
beginElement(element_number, present, value);
|
||||||
if (element_number == HTML_A)
|
if (element_number == HTML_A)
|
||||||
|
{
|
||||||
|
// ingame lua scripts from browser are using <a href="#http://..."> url scheme
|
||||||
|
// reason unknown
|
||||||
|
_LuaHrefHack = true;
|
||||||
addLink(element_number, present, value);
|
addLink(element_number, present, value);
|
||||||
|
_LuaHrefHack = false;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue