Federated wiki collects context for links based on sites mentioned on the page. This context is consulted when a link is clicked.
We redefine the meaning of clicking a link from what is expected in hypertext as defined by html or even earlier dialects of wiki. We'll follow linking from one refresh cycle through to the same cycle of the next page.
We assemble from page content a list of sites to be probed to find the best version of an internal link. We probe because the most desirable site might not be online or might not have the desired page. In this case we try the next most desirable site, and so on.
# Context
We embed the page fetching resolution context in each link as a title that can be viewed with hover.
view => ward.asia.wiki.org => ward.fed.wiki.org
See Storage Name for words that appear in place of sites.
The refresh.cycle defers this embedding to each plugin that might render links. Plugins can create well formatted links by further delegating to the core resolve module. You can see this in the paragraph module that resolves the most ordinary of items.
$item.append "<p>#{resolve.resolveLinks(text)}</p>"
Dynamically loaded plugins have access to the resolve module through the wiki global. The wiki-plugin-markdown still performs a similar append.
$item.append " <p> #{wiki.resolveLinks item.text, expand} </p> "
We say links are resolved when we decide exactly which sites should be probed should a link be clicked. Resolving depends on the resolution context assembled in the refresh.cycle and passed quietly to the resolve module.
Try finding links with interesting hovers. Inspect their representation in the dom to see how resolution has treated them.
The resolveLinks function operates in three steps. First, links are found using both the single and double square bracket notation. Second, the caller can transform the remaining text by whatever markup rules it might have. Third, the resolved links are inserted back into the expanded text.
Try adding console.log statements to resolve in order to see each of these steps applied.
# Click
The user is free to click any link no matter when it was rendered. We have more options now than we once did for recovering the proper context. A quick hack that persists is to parse the context out of the link title.
.delegate '.internal', 'click', (e) -> name = $(e.target).data 'pageName' pageHandler.context = $(e.target).attr('title').split(' => ') page = $(e.target).parents('.page') link.doInternalLink name, page
This slightly simplified delegate definition is found with many more in the legacy module bootstrap code. The link module assumes responsibility for completing the click once the important parameters have been identified.
Try single stepping link processing from this handler until refresh.cycle is called to render the new page.
Other callers to doInternalLink include visualizations which find their particulars from very different data structures that they manage.
Common code in link ensures common linking behavior among plugins that choose to use it. It also provides one more sneak path to pass a resolution context between modules, in this case to the pageHandler that is about to be asked to find the desired page.
# Reflection
Internal links are made complicated by the need to search in very specific places for the loosely linked json from which the new page can be rendered.
All plugins are expected to respect the same square bracket notation. Various core modules cooperate to make this easy to do if not easy to understand.