1 // PukiWiki - Yet another WikiWikiWeb clone.
4 // 2017 PukiWiki Development Team
5 // License: GPL v2 or (at your option) any later version
7 // PukiWiki JavaScript client script
8 if (window.addEventListener) {
9 window.addEventListener('DOMContentLoaded', function() {
10 if (!Array.prototype.indexOf || !document.createDocumentFragment) {
13 var headReText = '([\\s\\b]|^)';
14 var tailReText = '\\b';
15 var _siteList = getSiteListFromBody();
16 function ticketToLink(keyText) {
17 var siteList = getSiteList();
18 for (var i = 0; i < siteList.length; i++) {
19 var site = siteList[i];
20 var m = keyText.match(site.re);
22 var title = site.title;
25 title = title.replace(/\$1/g, ticketKey);
28 url: site.base_url + m[3],
35 function regexEscape(key) {
36 return key.replace(/[\-\.]/g, function (m) {
40 function setupSites(siteList) {
41 for (var i = 0, length = siteList.length; i < length; i++) {
42 var site = siteList[i];
46 reText = '(' + regexEscape(site.key) + '):' + '([A-Z][A-Z0-9_]+-\\d+)';
49 reText = '(' + regexEscape(site.key) + '):' + '(\\d+)';
52 reText = '(' + regexEscape(site.key) + '):' + '([0-9a-f]{7,40})';
58 site.re = new RegExp(headReText + reText + tailReText);
61 function getSiteList() {
64 function getSiteListFromBody() {
66 var defRoot = document.querySelector('.pukiwiki-ticketlink-def');
70 var siteNodes = defRoot.querySelectorAll('.pukiwiki-ticketlink-site');
71 Array.prototype.forEach.call(siteNodes, function (e) {
72 var siteInfoText = e.dataset && e.dataset.site;
73 if (!siteInfoText) return;
74 var info = textToSiteInfo(siteInfoText);
82 function textToSiteInfo(siteDef) {
83 if (!siteDef) return null;
84 var info = JSON.parse(siteDef);
85 if (info && info.key && info.type && info.base_url) {
90 function startsWith(s, searchString) {
91 if (String.prototype.startsWith) {
92 return s.startsWith(searchString);
94 return s.substr(0, searchString.length) === searchString;
96 function getRegex(list) {
98 for (var i = 0, length = list.length; i < length; i++) {
99 if (reText.length > 0) {
102 reText += list[i].reText;
104 return new RegExp(headReText + '(' + reText + ')' + tailReText);
106 function makeTicketLink(element) {
107 var siteList = getSiteList();
108 if (!siteList || siteList.length === 0) {
111 var re = getRegex(siteList);
112 var f, m, text = element.nodeValue;
113 while (m = text.match(re)) {
114 // m[1]: head, m[2]: keyText
115 f || (f = document.createDocumentFragment());
116 if (m.index > 0 || m[1].length > 0) {
117 f.appendChild(document.createTextNode(text.substr(0, m.index) + m[1]));
119 var a = document.createElement('a');
120 a.textContent = m[2];
121 var linkInfo = ticketToLink(a.textContent);
122 a.href = linkInfo.url;
123 a.title = linkInfo.title;
125 text = text.substr(m.index + m[0].length);
128 text.length > 0 && f.appendChild(document.createTextNode(text));
129 element.parentNode.replaceChild(f, element)
132 var ignoreTags = ['A', 'INPUT', 'TEXTAREA', 'BUTTON',
133 'SCRIPT', 'FRAME', 'IFRAME'];
134 function walkElement(element) {
135 var e = element.firstChild;
137 if (e.nodeType == 3 && e.nodeValue &&
138 e.nodeValue.length > 5 && /\S/.test(e.nodeValue)) {
139 var next = e.nextSibling;
143 if (e.nodeType == 1 && ignoreTags.indexOf(e.tagName) == -1) {
150 var target = document.getElementById('body');