-
-
Notifications
You must be signed in to change notification settings - Fork 721
/
refs.js
130 lines (112 loc) · 3.59 KB
/
refs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
function isCitation( href ) {
return href.indexOf("#cite_note") > -1;
}
function isEndnote( href ) {
return href.indexOf("#endnote_") > -1;
}
function isReference( href ) {
return href.indexOf("#ref_") > -1;
}
function goDown( element ) {
return element.getElementsByTagName( "A" )[0];
}
/**
* Skip over whitespace but not other elements
*/
function skipOverWhitespace( skipFunc ) {
return (function(element) {
do {
element = skipFunc( element );
if (element && element.nodeType == Node.TEXT_NODE) {
if (element.textContent.match(/^\s+$/)) {
// Ignore empty whitespace
continue;
} else {
break;
}
} else {
// found an element or ran out
break;
}
} while (true);
return element;
});
}
var goLeft = skipOverWhitespace( function( element ) {
return element.previousSibling;
});
var goRight = skipOverWhitespace( function( element ) {
return element.nextSibling;
});
function hasCitationLink( element ) {
try {
return isCitation( goDown( element ).getAttribute( "href" ) );
} catch (e) {
return false;
}
}
function collectRefText( sourceNode ) {
var href = sourceNode.getAttribute( "href" );
var targetId = href.slice(1);
var targetNode = document.getElementById( targetId );
if ( targetNode === null ) {
/*global console */
console.log("reference target not found: " + targetId);
return "";
}
// preferably without the back link
var refTexts = targetNode.getElementsByClassName( "reference-text" );
if ( refTexts.length > 0 ) {
targetNode = refTexts[0];
}
return targetNode.innerHTML;
}
function collectRefLink( sourceNode ) {
var node = sourceNode;
while (!node.classList || !node.classList.contains('reference')) {
node = node.parentNode;
if (!node) {
return '';
}
}
return node.id;
}
function sendNearbyReferences( sourceNode ) {
var refsIndex = 0;
var refs = [];
var linkId = [];
var linkText = [];
var curNode = sourceNode;
// handle clicked ref:
refs.push( collectRefText( curNode ) );
linkId.push( collectRefLink( curNode ) );
linkText.push( curNode.textContent );
// go left:
curNode = sourceNode.parentElement;
while ( hasCitationLink( goLeft( curNode ) ) ) {
refsIndex += 1;
curNode = goLeft( curNode );
refs.unshift( collectRefText( goDown ( curNode ) ) );
linkId.unshift( collectRefLink( curNode ) );
linkText.unshift( curNode.textContent );
}
// go right:
curNode = sourceNode.parentElement;
while ( hasCitationLink( goRight( curNode ) ) ) {
curNode = goRight( curNode );
refs.push( collectRefText( goDown ( curNode ) ) );
linkId.push( collectRefLink( curNode ) );
linkText.push( curNode.textContent );
}
// Special handling for references
window.webkit.messageHandlers.referenceClicked.postMessage({
"refs": refs,
"refsIndex": refsIndex,
"linkId": linkId,
"linkText": linkText
});
}
exports.isEndnote = isEndnote;
exports.isReference = isReference;
exports.isCitation = isCitation;
exports.sendNearbyReferences = sendNearbyReferences;