forked from darth-cheney/Grantnotes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
grantnotes.js
155 lines (126 loc) · 4.57 KB
/
grantnotes.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*********************
* Grantnotes 2.0 *
* ECMG *
*********************/
// License: This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the License, or (at
// your option) any later version. This program is distributed in the hope
// that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
var grantnotes = function(text, footbar, optArgs) {
if(optArgs) {
if (optArgs.breakpoint) {
var breakpoint = optArgs.breakpoint;
}
if (optArgs.breakpoint_action) {
var breakpoint_action = optArgs.breakpoint_action;
}
if (optArgs.animate) {
var animate = true;
}
if (typeof(optArgs.note_container == "object")) {
var note_container = optArgs.note_container;
} else if (optArgs.note_container == "string") {
var note_container = $(optArgs.note_container);
}
if (optArgs.ref_id) {
var refID = optArgs.ref_id;
}
if (optArgs.foot_id) {
var footID = optArgs.foot_id;
}
}
function Footnote(reference, text, footbar, note_count) {
// Constructed variables
this.number = note_count;
this.refID = 'ref' + note_count;
this.footID = 'foot' + note_count;
this.reference = reference;
// Make changes to the in-text <sup> elements.
// If a number exists within the <sup>, use it. Otherwise make one automagically
var note_char;
if(!reference.text()) {
note_char = this.number;
} else {
note_char = reference.text();
reference.text('');
};
reference.prepend('<a href="#' + this.footID + '">' + note_char + '</a>');
// Find the footnote text and create a .footnote div
footbar.append($('<div class="footnote" id="' + this.footID + '"></div>'));
this.element = $('div#' + this.footID + '.footnote'); // a jQuery object representing the newly created div.footnote
this.element.append($('<sup>' + note_char + '</sup>'));
this.element.append(text.find('span.footnote-text').filter(':first'));
// Make the footnote absolutely positioned, and also hide it
this.element.css({
position: 'absolute',
opacity: '0'
});
// Methods
this.getHeight = function() { // returns calculated height of footnote div
return this.element.outerHeight(true);
};
this.refAbsPosition = function() { // returns pos of in-text ref relative to document
return this.reference.offset().top;
};
this.barPosition = function() { // returns the position of footnote div relative to footbar
return this.element.position().top;
};
this.setPosition = function(num) {
this.element.css('top', num + 'px');
};
this.getBottom = function() {
return this.barPosition() + this.getHeight();
};
}
function getFootbarOffset() {
return footbar.offset().top;
}
this.positionFootnotes = function(noteArray, footbar_offset) {
// Loop through the array of footnotes and position them appropriately
var notes_length = noteArray.length;
for (var i = 0; i < notes_length; i ++) {
var footnote = noteArray[i];
var ref_pos = footnote.refAbsPosition();
var total_offset = ref_pos - footbar_offset;
if(total_offset >= 0 && total_offset > prev_bottom) {
footnote.setPosition(total_offset);
} else if (total_offset <= prev_bottom) {
footnote.setPosition(prev_bottom + 10); // +10 for some padding
} else {
footnote.setPosition(0);
}
prev_bottom = footnote.getBottom();
footnote.element.animate({
opacity: '1'
}, 400);
}
}
// Main
var note_count = 1;
var prev_bottom = 0; // Updates with bottom of the previous footnote when looping.
var noteArray = new Array(); // An array to store the notes as we create them
var footbar_offset = getFootbarOffset();
// Make sure that footbar is explicitly set to relative positioning
footbar.css('position', 'relative');
// Find each <sup> within the text and create a new Footnote for each
text.find('sup').each(function(){
var reference = $(this);
var footnote = new Footnote(reference, text, footbar, note_count);
noteArray.push(footnote);
note_count = note_count + 1;
});
// This delay helps smooth over browser inconsistencies in loading/rendering (needs work)
$(window).load(function(){
setTimeout(function(){
this.positionFootnotes(noteArray, footbar_offset);
}, 200);
});
// Bind the positioning function to any window resizing
/* NEEDS TO BE FIXED
$(window).resize(function() {
this.positionFootnotes(noteArray, footbar_offset);
}); */
}