2012-01-15 13:29:16 +00:00
|
|
|
/*\
|
|
|
|
title: js/macros/link.js
|
|
|
|
|
2012-04-03 16:07:38 +00:00
|
|
|
Implements the link macro.
|
|
|
|
|
|
|
|
A special callback function is used to massage links according to the needs of the host platform.
|
|
|
|
|
|
|
|
The linkMassager is stored in the `linkMassager` property of the store object. It is a function
|
|
|
|
that takes a `linkInfo` structure as the only parameter. It contains a hashmap of information
|
|
|
|
as follows:
|
|
|
|
|
|
|
|
{
|
2012-04-07 10:32:41 +00:00
|
|
|
to: the target of the link
|
2012-04-03 16:07:38 +00:00
|
|
|
space: an optional space associated with the link
|
|
|
|
isExternal: true if the link has been determined to be an external link by the default heuristics
|
|
|
|
isMissing: true if a non-external link references a missing tiddler
|
2012-04-07 11:10:46 +00:00
|
|
|
attributes: a hashmap of HTML attributes to add to the `<a>` tag
|
|
|
|
suppressLink: see below
|
2012-04-03 16:07:38 +00:00
|
|
|
}
|
|
|
|
|
2012-04-07 11:10:46 +00:00
|
|
|
The link massager is called with the `attributes` hashmap initialised as follows:
|
|
|
|
|
|
|
|
{
|
2012-04-07 13:28:50 +00:00
|
|
|
class: an array of strings representing the CSS classes to be applied to the link. The default classes are already applieda according to whether the heuristics decide the tiddler is external or missing
|
2012-04-07 11:10:46 +00:00
|
|
|
href: the href to be used in the link (defaults to the unencoded value of the `to` parameter)
|
|
|
|
}
|
|
|
|
|
2012-04-07 13:28:50 +00:00
|
|
|
Note that the member `class` cannot be referred to with JavaScript dot syntax: use `linkInfo.attributes["class"]` rather than `linkInfo.attributes.class`.
|
|
|
|
|
2012-04-07 11:10:46 +00:00
|
|
|
The linkMassager can modify the `classes` and `href` fields as required, and add additional HTML attributes, such as the `target` attribute.
|
|
|
|
|
|
|
|
The linkMassager can cause the link to be suppressed by setting the `linkInfo.suppressLink` to `true`. The content of the link will still be displayed.
|
2012-04-03 16:07:38 +00:00
|
|
|
|
2012-01-15 13:29:16 +00:00
|
|
|
\*/
|
|
|
|
(function(){
|
|
|
|
|
2012-02-02 18:00:42 +00:00
|
|
|
/*jslint node: true, browser: true */
|
2012-01-15 13:29:16 +00:00
|
|
|
"use strict";
|
|
|
|
|
2012-02-16 20:38:10 +00:00
|
|
|
var Renderer = require("../Renderer.js").Renderer;
|
2012-01-15 13:29:16 +00:00
|
|
|
|
2012-04-07 10:32:41 +00:00
|
|
|
var isLinkExternal = function(to) {
|
2012-02-09 13:36:46 +00:00
|
|
|
var externalRegExp = /(?:file|http|https|mailto|ftp|irc|news|data):[^\s'"]+(?:\/|\b)/i;
|
2012-04-07 10:32:41 +00:00
|
|
|
return externalRegExp.test(to);
|
2012-02-09 13:36:46 +00:00
|
|
|
};
|
|
|
|
|
2012-01-15 13:29:16 +00:00
|
|
|
exports.macro = {
|
|
|
|
name: "link",
|
|
|
|
params: {
|
2012-04-07 10:32:41 +00:00
|
|
|
to: {byName: "default", type: "tiddler", skinny: true},
|
2012-04-03 16:07:38 +00:00
|
|
|
space: {byName: true, type: "text"}
|
2012-01-15 13:29:16 +00:00
|
|
|
},
|
2012-02-02 18:00:42 +00:00
|
|
|
events: {
|
2012-02-21 21:57:30 +00:00
|
|
|
click: function(event) {
|
2012-04-07 10:32:41 +00:00
|
|
|
if(isLinkExternal(this.params.to)) {
|
2012-02-09 13:36:46 +00:00
|
|
|
event.target.setAttribute("target","_blank");
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
var navEvent = document.createEvent("Event");
|
|
|
|
navEvent.initEvent("tw-navigate",true,true);
|
2012-04-07 10:32:41 +00:00
|
|
|
navEvent.navigateTo = this.params.to;
|
2012-02-16 20:38:10 +00:00
|
|
|
event.target.dispatchEvent(navEvent);
|
2012-02-09 13:36:46 +00:00
|
|
|
event.preventDefault();
|
|
|
|
return false;
|
|
|
|
}
|
2012-02-02 18:00:42 +00:00
|
|
|
}
|
|
|
|
},
|
2012-02-21 21:57:30 +00:00
|
|
|
execute: function() {
|
2012-04-03 16:07:38 +00:00
|
|
|
// Assemble the information about the link
|
|
|
|
var linkInfo = {
|
2012-04-07 10:32:41 +00:00
|
|
|
to: this.params.to,
|
2012-04-03 16:07:38 +00:00
|
|
|
space: this.params.space
|
|
|
|
};
|
|
|
|
// Generate the default link characteristics
|
2012-04-07 10:32:41 +00:00
|
|
|
linkInfo.isExternal = isLinkExternal(linkInfo.to);
|
2012-04-03 16:07:38 +00:00
|
|
|
if(!linkInfo.isExternal) {
|
2012-04-07 10:32:41 +00:00
|
|
|
linkInfo.isMissing = !this.store.tiddlerExists(linkInfo.to);
|
2012-04-03 16:07:38 +00:00
|
|
|
}
|
2012-04-07 11:10:46 +00:00
|
|
|
linkInfo.attributes = {
|
|
|
|
href: linkInfo.to
|
|
|
|
};
|
2012-04-03 16:07:38 +00:00
|
|
|
// Generate the default classes for the link
|
2012-04-07 13:28:50 +00:00
|
|
|
linkInfo.attributes["class"] = ["tw-tiddlylink"];
|
2012-04-03 16:07:38 +00:00
|
|
|
if(linkInfo.isExternal) {
|
2012-04-07 13:28:50 +00:00
|
|
|
linkInfo.attributes["class"].push("tw-tiddlylink-external");
|
2012-02-09 13:36:46 +00:00
|
|
|
} else {
|
2012-04-07 13:28:50 +00:00
|
|
|
linkInfo.attributes["class"].push("tw-tiddlylink-internal");
|
2012-04-03 16:07:38 +00:00
|
|
|
if(linkInfo.isMissing) {
|
2012-04-07 13:28:50 +00:00
|
|
|
linkInfo.attributes["class"].push("tw-tiddlylink-missing");
|
2012-02-09 13:36:46 +00:00
|
|
|
} else {
|
2012-04-07 13:28:50 +00:00
|
|
|
linkInfo.attributes["class"].push("tw-tiddlylink-resolves");
|
2012-02-09 13:36:46 +00:00
|
|
|
}
|
|
|
|
}
|
2012-04-03 16:07:38 +00:00
|
|
|
// Invoke the link massager if defined
|
|
|
|
if(this.store.linkMassager) {
|
|
|
|
this.store.linkMassager(linkInfo);
|
|
|
|
}
|
2012-04-07 11:10:46 +00:00
|
|
|
// Create the link
|
|
|
|
var content;
|
|
|
|
if(linkInfo.suppressLink) {
|
|
|
|
content = this.cloneChildren();
|
|
|
|
} else {
|
|
|
|
content = [Renderer.ElementNode("a",linkInfo.attributes,this.cloneChildren())];
|
|
|
|
}
|
2012-02-16 20:38:10 +00:00
|
|
|
for(var t=0; t<content.length; t++) {
|
2012-03-29 13:30:22 +00:00
|
|
|
content[t].execute(this.parents,this.tiddlerTitle);
|
2012-02-16 20:38:10 +00:00
|
|
|
}
|
|
|
|
return content;
|
2012-01-15 13:29:16 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
})();
|