timeline_setter 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/doc.markdown +15 -4
- data/doc/timeline-setter.html +79 -94
- data/documentation/TimelineSetter/CLI.html +59 -9
- data/documentation/TimelineSetter/Parser.html +1 -1
- data/documentation/TimelineSetter/Timeline.html +1 -1
- data/documentation/TimelineSetter.html +1 -1
- data/documentation/_index.html +1 -1
- data/documentation/file.README.html +1 -1
- data/documentation/index.html +1 -1
- data/documentation/method_list.html +13 -5
- data/documentation/top-level-namespace.html +1 -1
- data/index.html +3 -2
- data/lib/timeline_setter/cli.rb +6 -2
- data/lib/timeline_setter/timeline.rb +1 -1
- data/lib/timeline_setter/version.rb +1 -1
- data/public/javascripts/timeline-setter.js +83 -87
- data/public/stylesheets/timeline-setter.css +5 -7
- data/spec/test_data.csv +4 -1
- data/templates/timeline-markup.erb +3 -3
- data/timeline_setter.gemspec +2 -2
- metadata +4 -4
@@ -237,6 +237,27 @@ A new instance of CLI.
|
|
237
237
|
|
238
238
|
|
239
239
|
|
240
|
+
<span class="summary_desc"><div class='inline'></div></span>
|
241
|
+
|
242
|
+
</li>
|
243
|
+
|
244
|
+
|
245
|
+
<li class="public ">
|
246
|
+
<span class="summary_signature">
|
247
|
+
|
248
|
+
<a href="#timeline_page_path-instance_method" title="#timeline_page_path (instance method)">- (Object) <strong>timeline_page_path</strong> </a>
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
</span>
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
|
240
261
|
<span class="summary_desc"><div class='inline'></div></span>
|
241
262
|
|
242
263
|
</li>
|
@@ -308,10 +329,6 @@ A new instance of CLI
|
|
308
329
|
<pre class="lines">
|
309
330
|
|
310
331
|
|
311
|
-
68
|
312
|
-
69
|
313
|
-
70
|
314
|
-
71
|
315
332
|
72
|
316
333
|
73
|
317
334
|
74
|
@@ -323,17 +340,21 @@ A new instance of CLI
|
|
323
340
|
80
|
324
341
|
81
|
325
342
|
82
|
326
|
-
83
|
343
|
+
83
|
344
|
+
84
|
345
|
+
85
|
346
|
+
86
|
347
|
+
87</pre>
|
327
348
|
</td>
|
328
349
|
<td>
|
329
|
-
<pre class="code"><span class="info file"># File 'lib/timeline_setter/cli.rb', line
|
350
|
+
<pre class="code"><span class="info file"># File 'lib/timeline_setter/cli.rb', line 72</span>
|
330
351
|
|
331
352
|
<span class='def def kw'>def</span> <span class='compile! fid id'>compile!</span>
|
332
353
|
<span class='if if kw'>if</span> <span class='@options ivar id'>@options</span><span class='lbrack token'>[</span><span class='symbol val'>:assets</span><span class='rbrack token'>]</span>
|
333
354
|
<span class='FileUtils constant id'>FileUtils</span><span class='dot token'>.</span><span class='cp_r identifier id'>cp_r</span><span class='lparen token'>(</span><span class='Dir constant id'>Dir</span><span class='dot token'>.</span><span class='glob identifier id'>glob</span><span class='lparen token'>(</span><span class='dstring node'>"#{TimelineSetter::ROOT}/public/*"</span><span class='rparen token'>)</span><span class='comma token'>,</span> <span class='outdir identifier id'>outdir</span><span class='rparen token'>)</span>
|
334
355
|
<span class='end end kw'>end</span>
|
335
356
|
|
336
|
-
<span class='File constant id'>File</span><span class='dot token'>.</span><span class='open identifier id'>open</span><span class='lparen token'>(</span><span class='
|
357
|
+
<span class='File constant id'>File</span><span class='dot token'>.</span><span class='open identifier id'>open</span><span class='lparen token'>(</span><span class='timeline_page_path identifier id'>timeline_page_path</span><span class='comma token'>,</span> <span class='string val'>'w+'</span><span class='rparen token'>)</span> <span class='do do kw'>do</span> <span class='bitor op'>|</span><span class='doc identifier id'>doc</span><span class='bitor op'>|</span>
|
337
358
|
<span class='doc identifier id'>doc</span><span class='dot token'>.</span><span class='write identifier id'>write</span> <span class='html identifier id'>html</span>
|
338
359
|
<span class='end end kw'>end</span>
|
339
360
|
|
@@ -341,7 +362,7 @@ A new instance of CLI
|
|
341
362
|
|
342
363
|
<span class='if if kw'>if</span> <span class='@options ivar id'>@options</span><span class='lbrack token'>[</span><span class='symbol val'>:open</span><span class='rbrack token'>]</span>
|
343
364
|
<span class='puts identifier id'>puts</span> <span class='string val'>"== Opening ..."</span>
|
344
|
-
<span class='dxstring node'>%x
|
365
|
+
<span class='dxstring node'>%x[ open #{timeline_page_path} ]</span>
|
345
366
|
<span class='end end kw'>end</span>
|
346
367
|
<span class='end end kw'>end</span>
|
347
368
|
</pre>
|
@@ -559,6 +580,35 @@ A new instance of CLI
|
|
559
580
|
</td>
|
560
581
|
</tr>
|
561
582
|
</table>
|
583
|
+
</div>
|
584
|
+
|
585
|
+
<div class="method_details ">
|
586
|
+
<p class="signature " id="timeline_page_path-instance_method">
|
587
|
+
|
588
|
+
- (<tt>Object</tt>) <strong>timeline_page_path</strong>
|
589
|
+
|
590
|
+
|
591
|
+
|
592
|
+
</p><table class="source_code">
|
593
|
+
<tr>
|
594
|
+
<td>
|
595
|
+
<pre class="lines">
|
596
|
+
|
597
|
+
|
598
|
+
68
|
599
|
+
69
|
600
|
+
70</pre>
|
601
|
+
</td>
|
602
|
+
<td>
|
603
|
+
<pre class="code"><span class="info file"># File 'lib/timeline_setter/cli.rb', line 68</span>
|
604
|
+
|
605
|
+
<span class='def def kw'>def</span> <span class='timeline_page_path identifier id'>timeline_page_path</span>
|
606
|
+
<span class='File constant id'>File</span><span class='dot token'>.</span><span class='join identifier id'>join</span><span class='lparen token'>(</span><span class='outdir identifier id'>outdir</span><span class='comma token'>,</span> <span class='string val'>'timeline.html'</span><span class='rparen token'>)</span>
|
607
|
+
<span class='end end kw'>end</span>
|
608
|
+
</pre>
|
609
|
+
</td>
|
610
|
+
</tr>
|
611
|
+
</table>
|
562
612
|
</div>
|
563
613
|
|
564
614
|
</div>
|
@@ -566,7 +616,7 @@ A new instance of CLI
|
|
566
616
|
</div>
|
567
617
|
|
568
618
|
<div id="footer">
|
569
|
-
Generated on
|
619
|
+
Generated on Wed Apr 6 10:07:07 2011 by
|
570
620
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
571
621
|
0.6.5 (ruby-1.8.7).
|
572
622
|
</div>
|
@@ -276,7 +276,7 @@ Returns the value of attribute events
|
|
276
276
|
</div>
|
277
277
|
|
278
278
|
<div id="footer">
|
279
|
-
Generated on
|
279
|
+
Generated on Wed Apr 6 10:07:08 2011 by
|
280
280
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
281
281
|
0.6.5 (ruby-1.8.7).
|
282
282
|
</div>
|
@@ -504,7 +504,7 @@ the events hash to JSON to stick into our HTML.
|
|
504
504
|
</div>
|
505
505
|
|
506
506
|
<div id="footer">
|
507
|
-
Generated on
|
507
|
+
Generated on Wed Apr 6 10:07:08 2011 by
|
508
508
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
509
509
|
0.6.5 (ruby-1.8.7).
|
510
510
|
</div>
|
@@ -103,7 +103,7 @@
|
|
103
103
|
</div>
|
104
104
|
|
105
105
|
<div id="footer">
|
106
|
-
Generated on
|
106
|
+
Generated on Wed Apr 6 10:07:08 2011 by
|
107
107
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
108
108
|
0.6.5 (ruby-1.8.7).
|
109
109
|
</div>
|
data/documentation/_index.html
CHANGED
@@ -123,7 +123,7 @@
|
|
123
123
|
</div>
|
124
124
|
|
125
125
|
<div id="footer">
|
126
|
-
Generated on
|
126
|
+
Generated on Wed Apr 6 10:07:06 2011 by
|
127
127
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
128
128
|
0.6.5 (ruby-1.8.7).
|
129
129
|
</div>
|
data/documentation/index.html
CHANGED
@@ -61,17 +61,17 @@
|
|
61
61
|
|
62
62
|
|
63
63
|
<li class="r1 ">
|
64
|
-
<span class='object_link'><a href="TimelineSetter/
|
64
|
+
<span class='object_link'><a href="TimelineSetter/CLI.html#initialize-instance_method" title="TimelineSetter::CLI#initialize (method)">#initialize</a></span>
|
65
65
|
|
66
|
-
<small>TimelineSetter::
|
66
|
+
<small>TimelineSetter::CLI</small>
|
67
67
|
|
68
68
|
</li>
|
69
69
|
|
70
70
|
|
71
71
|
<li class="r2 ">
|
72
|
-
<span class='object_link'><a href="TimelineSetter/
|
72
|
+
<span class='object_link'><a href="TimelineSetter/Timeline.html#initialize-instance_method" title="TimelineSetter::Timeline#initialize (method)">#initialize</a></span>
|
73
73
|
|
74
|
-
<small>TimelineSetter::
|
74
|
+
<small>TimelineSetter::Timeline</small>
|
75
75
|
|
76
76
|
</li>
|
77
77
|
|
@@ -133,6 +133,14 @@
|
|
133
133
|
|
134
134
|
|
135
135
|
<li class="r2 ">
|
136
|
+
<span class='object_link'><a href="TimelineSetter/CLI.html#timeline_page_path-instance_method" title="TimelineSetter::CLI#timeline_page_path (method)">#timeline_page_path</a></span>
|
137
|
+
|
138
|
+
<small>TimelineSetter::CLI</small>
|
139
|
+
|
140
|
+
</li>
|
141
|
+
|
142
|
+
|
143
|
+
<li class="r1 ">
|
136
144
|
<span class='object_link'><a href="TimelineSetter/Timeline.html#tmpl-instance_method" title="TimelineSetter::Timeline#tmpl (method)">#tmpl</a></span>
|
137
145
|
|
138
146
|
<small>TimelineSetter::Timeline</small>
|
@@ -140,7 +148,7 @@
|
|
140
148
|
</li>
|
141
149
|
|
142
150
|
|
143
|
-
<li class="
|
151
|
+
<li class="r2 ">
|
144
152
|
<span class='object_link'><a href="TimelineSetter/Timeline.html#to_json-instance_method" title="TimelineSetter::Timeline#to_json (method)">#to_json</a></span>
|
145
153
|
|
146
154
|
<small>TimelineSetter::Timeline</small>
|
data/index.html
CHANGED
@@ -180,7 +180,7 @@ supporting assets if applicable) within the current directory.</p>
|
|
180
180
|
|
181
181
|
<p>TimelineSetter looks for certain column names in your CSV file in order to
|
182
182
|
generate a timeline. All columns are required, though as you’ll see, some of
|
183
|
-
them can be left blank. Here’s a summary of each column and its significance:</p>
|
183
|
+
them can be left blank (see a <a href="https://github.com/propublica/timeline-setter/blob/master/spec/test_data.csv">sample CSV</a>). Here’s a summary of each column and its significance:</p>
|
184
184
|
|
185
185
|
<p><a id="date-csv"></a></p>
|
186
186
|
|
@@ -230,7 +230,7 @@ best not to assign a name.</p>
|
|
230
230
|
<p>Any arbitrary HTML that will be inserted above <code>description</code>. This
|
231
231
|
field may contain image tags, YouTube tags, etc. — nearly everything except
|
232
232
|
<code><script></code> tags. If you choose to use JavaScript, you must do it inside an
|
233
|
-
iframe and call that iframe inside this field.</p>
|
233
|
+
iframe and call that iframe inside this field. <strong>Note</strong>: If you put an image or iframe in this field, make sure to set <code>height</code> and <code>width</code> attributes, or the card may not extend around the image.</p>
|
234
234
|
|
235
235
|
<p><a id="deployment"></a></p>
|
236
236
|
|
@@ -343,6 +343,7 @@ Feb. 21, 1952 and Jan. 26, 1957, as shown
|
|
343
343
|
|
344
344
|
<ul>
|
345
345
|
<li>In the Wild: <a href="http://www.propublica.org/special/tbi-psycho-platoon-timeline">ProPublica: How One Blast Affected Five Soldiers</a></li>
|
346
|
+
<li>In the Wild: <a href="http://www.talkingpointsmemo.com/interactive/2011/04/the-wisconsin-union-struggle-timeline.php">TPM: The Wisconsin Union Struggle Timeline</a></li>
|
346
347
|
</ul>
|
347
348
|
|
348
349
|
|
data/lib/timeline_setter/cli.rb
CHANGED
@@ -63,13 +63,17 @@ module TimelineSetter
|
|
63
63
|
def outdir
|
64
64
|
@options[:output] ? @options[:output] : "#{`pwd`.strip}/"
|
65
65
|
end
|
66
|
+
|
67
|
+
def timeline_page_path
|
68
|
+
File.join(outdir, 'timeline.html')
|
69
|
+
end
|
66
70
|
|
67
71
|
def compile!
|
68
72
|
if @options[:assets]
|
69
73
|
FileUtils.cp_r(Dir.glob("#{TimelineSetter::ROOT}/public/*"), outdir)
|
70
74
|
end
|
71
75
|
|
72
|
-
File.open(
|
76
|
+
File.open(timeline_page_path, 'w+') do |doc|
|
73
77
|
doc.write html
|
74
78
|
end
|
75
79
|
|
@@ -77,7 +81,7 @@ module TimelineSetter
|
|
77
81
|
|
78
82
|
if @options[:open]
|
79
83
|
puts "== Opening ..."
|
80
|
-
%x
|
84
|
+
%x[ open #{timeline_page_path} ]
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
@@ -10,7 +10,7 @@ module TimelineSetter
|
|
10
10
|
# Convert human dates to timestamps, sort the hash by timestamp, and
|
11
11
|
# convert the events hash to JSON to stick into our HTML.
|
12
12
|
def to_json
|
13
|
-
@events.
|
13
|
+
@events.each {|r| r[:timestamp] = Time.parse(r[:date]).to_i * 1000 }
|
14
14
|
@events.to_json
|
15
15
|
end
|
16
16
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
|
22
22
|
// Invoke all callbacks registered to the object with `bind`.
|
23
23
|
obj.trigger = function(){
|
24
|
-
if(!this._callbacks) return;
|
24
|
+
if (!this._callbacks) return;
|
25
25
|
for(var i = 0; callback = this._callbacks[i]; i++)
|
26
26
|
callback.apply(this, arguments);
|
27
27
|
};
|
@@ -37,9 +37,9 @@
|
|
37
37
|
// message passing. So each registered callback first checks to see if the
|
38
38
|
// event fired matches the event it is listening for.
|
39
39
|
obj.move = function(e){
|
40
|
-
if(!e.type === "move" || !e.deltaX) return;
|
40
|
+
if (!e.type === "move" || !e.deltaX) return;
|
41
41
|
|
42
|
-
if(_.isUndefined(this.currOffset)) this.currOffset = 0;
|
42
|
+
if (_.isUndefined(this.currOffset)) this.currOffset = 0;
|
43
43
|
this.currOffset += e.deltaX;
|
44
44
|
this.el.css({"left" : this.currOffset});
|
45
45
|
};
|
@@ -48,7 +48,7 @@
|
|
48
48
|
// in order to zoom the Timeline all that's needed is to increase or decrease
|
49
49
|
// the percentage width.
|
50
50
|
obj.zoom = function(e){
|
51
|
-
if(!e.type === "zoom") return;
|
51
|
+
if (!e.type === "zoom") return;
|
52
52
|
this.el.css({ "width": e.width });
|
53
53
|
};
|
54
54
|
};
|
@@ -60,7 +60,7 @@
|
|
60
60
|
|
61
61
|
// Check to see if we're on a mobile device.
|
62
62
|
var touchInit = 'ontouchstart' in document;
|
63
|
-
if(touchInit) jQuery.event.props.push("touches");
|
63
|
+
if (touchInit) jQuery.event.props.push("touches");
|
64
64
|
|
65
65
|
// The `draggable` plugin tracks changes in X offsets due to mouse movement
|
66
66
|
// or finger gestures and proxies associated events on a particular element.
|
@@ -78,7 +78,7 @@
|
|
78
78
|
|
79
79
|
// The user is interacting; capture the offset and trigger a `dragging` event.
|
80
80
|
function mousemove(e){
|
81
|
-
if(!drag) return;
|
81
|
+
if (!drag) return;
|
82
82
|
e.preventDefault();
|
83
83
|
e.type = "dragging";
|
84
84
|
e = _.extend(e, {
|
@@ -90,13 +90,13 @@
|
|
90
90
|
|
91
91
|
// We're done tracking the movement set drag back to `null` for the next event.
|
92
92
|
function mouseup(e){
|
93
|
-
if(!drag) return;
|
93
|
+
if (!drag) return;
|
94
94
|
drag = null;
|
95
95
|
e.type = "dragend";
|
96
96
|
obj.el.trigger(e);
|
97
97
|
};
|
98
98
|
|
99
|
-
if(!touchInit) {
|
99
|
+
if (!touchInit) {
|
100
100
|
// Bind on mouse events if we have a mouse...
|
101
101
|
obj.el.bind("mousedown", mousedown);
|
102
102
|
|
@@ -130,7 +130,7 @@
|
|
130
130
|
function mousewheel(e){
|
131
131
|
e.preventDefault();
|
132
132
|
var delta = (e.wheelDelta || -e.detail);
|
133
|
-
if(safari){
|
133
|
+
if (safari){
|
134
134
|
var negative = delta < 0 ? -1 : 1;
|
135
135
|
delta = Math.log(Math.abs(delta)) * negative * 2;
|
136
136
|
};
|
@@ -288,7 +288,7 @@
|
|
288
288
|
var events = Array.prototype.slice.call(arguments, 2);
|
289
289
|
_.each(events, function(ev){
|
290
290
|
origin.bind(function(e){
|
291
|
-
if(e.type === ev && listener[ev])
|
291
|
+
if (e.type === ev && listener[ev])
|
292
292
|
listener[ev](e);
|
293
293
|
});
|
294
294
|
});
|
@@ -302,7 +302,7 @@
|
|
302
302
|
// Simple function to strip suffixes like `"px"` and return a clean integer for
|
303
303
|
// use.
|
304
304
|
var cleanNumber = function(str){
|
305
|
-
return parseInt(str.replace(/^[^+\-\d]?([+\-]
|
305
|
+
return parseInt(str.replace(/^[^+\-\d]?([+\-]?\d+)?.*$/, "$1"), 10);
|
306
306
|
};
|
307
307
|
|
308
308
|
// Zero pad a number less than 10 and return a 2 digit value.
|
@@ -362,7 +362,7 @@
|
|
362
362
|
// takes a json array of card representations and then builds series, calculates
|
363
363
|
// intervals `sync`s the `Bar` and `CardContainer` objects and triggers the
|
364
364
|
// `render` event.
|
365
|
-
var Timeline = TimelineSetter.Timeline = function(data) {
|
365
|
+
var Timeline = TimelineSetter.Timeline = function(data) {
|
366
366
|
data = data.sort(function(a, b){ return a.timestamp - b.timestamp; });
|
367
367
|
this.bySid = {};
|
368
368
|
this.series = [];
|
@@ -394,12 +394,13 @@
|
|
394
394
|
// in the `bySid` object add it. Then add a card to the `Series` and extend
|
395
395
|
// the global `bounds`.
|
396
396
|
add : function(card){
|
397
|
-
if(!(card.series in this.bySid)){
|
397
|
+
if (!(card.series in this.bySid)){
|
398
398
|
this.bySid[card.series] = new Series(card, this);
|
399
399
|
this.series.push(this.bySid[card.series]);
|
400
400
|
}
|
401
401
|
var series = this.bySid[card.series];
|
402
402
|
series.add(card);
|
403
|
+
|
403
404
|
this.bounds.extend(series.max());
|
404
405
|
this.bounds.extend(series.min());
|
405
406
|
}
|
@@ -441,11 +442,11 @@
|
|
441
442
|
var pOffset = parent.offset().left;
|
442
443
|
var offset = this.el.offset().left;
|
443
444
|
var width = this.el.width();
|
444
|
-
if(_.isUndefined(e.deltaX)) e.deltaX = 0;
|
445
|
+
if (_.isUndefined(e.deltaX)) e.deltaX = 0;
|
445
446
|
|
446
|
-
if(offset + width + e.deltaX < pOffset + parent.width())
|
447
|
+
if (offset + width + e.deltaX < pOffset + parent.width())
|
447
448
|
e.deltaX = (pOffset + parent.width()) - (offset + width);
|
448
|
-
if(offset + e.deltaX > pOffset)
|
449
|
+
if (offset + e.deltaX > pOffset)
|
449
450
|
e.deltaX = pOffset - offset;
|
450
451
|
|
451
452
|
e.type = "move";
|
@@ -543,8 +544,8 @@
|
|
543
544
|
// Create and append the label to `.TS-series_nav_container` and bind up
|
544
545
|
// `hideNotches` and `showNotches`.
|
545
546
|
render : function(e){
|
546
|
-
if(!e.type === "render") return;
|
547
|
-
if(this.name.length === 0) return;
|
547
|
+
if (!e.type === "render") return;
|
548
|
+
if (this.name.length === 0) return;
|
548
549
|
this.el = $(this.template(this));
|
549
550
|
$(".TS-series_nav_container").append(this.el);
|
550
551
|
this.el.toggle(this.hideNotches, this.showNotches);
|
@@ -567,12 +568,13 @@
|
|
567
568
|
this.timestamp = card.timestamp;
|
568
569
|
this.attributes = card;
|
569
570
|
this.attributes.topcolor = series.color;
|
571
|
+
|
570
572
|
this.template = template("#TS-card_tmpl");
|
571
573
|
this.ntemplate = template("#TS-notch_tmpl");
|
572
|
-
_.bindAll(this, "render", "activate", "
|
574
|
+
_.bindAll(this, "render", "activate", "flip", "setPermalink", "toggleNotch");
|
573
575
|
this.series.bind(this.toggleNotch);
|
574
576
|
this.series.timeline.bind(this.render);
|
575
|
-
this.series.timeline.bar.bind(this.
|
577
|
+
this.series.timeline.bar.bind(this.flip);
|
576
578
|
this.id = [
|
577
579
|
this.get('timestamp'),
|
578
580
|
this.get('description').split(/ /)[0].replace(/[^a-zA-Z\-]/g,"")
|
@@ -594,7 +596,7 @@
|
|
594
596
|
// `Bar` and binds a click handler so it can be activated. if the `Card`'s id
|
595
597
|
// is currently selected via `window.location.hash` it's activated.
|
596
598
|
render : function(e){
|
597
|
-
if(!e.type === "render") return;
|
599
|
+
if (!e.type === "render") return;
|
598
600
|
this.offset = this.series.timeline.bounds.project(this.timestamp, 100);
|
599
601
|
var html = this.ntemplate(this.attributes);
|
600
602
|
this.notch = $(html).css({"left": this.offset + "%"});
|
@@ -603,55 +605,36 @@
|
|
603
605
|
if (history.get() === this.id) this.activate();
|
604
606
|
},
|
605
607
|
|
606
|
-
// As the `Bar` moves
|
608
|
+
// As the `Bar` moves the current card checks to see if it's outside the viewport,
|
607
609
|
// if it is the card is flipped so as to be visible for the longest period
|
608
|
-
// of time.
|
609
|
-
|
610
|
-
if (e.type !== "move" || !this.el) return;
|
611
|
-
var
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
610
|
+
// of time. The magic number here (7) is half the width of the css arrow.
|
611
|
+
flip : function(e) {
|
612
|
+
if (e.type !== "move" || !this.el || !this.el.is(":visible")) return;
|
613
|
+
var rightEdge = this.$(".TS-item").offset().left + this.$(".TS-item").width();
|
614
|
+
var tRightEdge = $("#timeline_setter").offset().left + $("#timeline_setter").width();
|
615
|
+
var margin = this.el.css("margin-left") === this.originalMargin;
|
616
|
+
var flippable = this.$(".TS-item").width() < $("#timeline_setter").width() / 2;
|
617
|
+
var offTimeline = this.el.position().left - this.$(".TS-item").width() < 0;
|
618
|
+
|
619
|
+
// If the card's right edge is more than the timeline's right edge and
|
620
|
+
// it's never been flipped before and it won't go off the timeline when
|
621
|
+
// flipped. We'll flip it.
|
622
|
+
if (tRightEdge - rightEdge < 0 && margin && !offTimeline) {
|
623
|
+
this.el.css({"margin-left": -(this.$(".TS-item").width() + 7)});
|
624
|
+
this.$(".TS-css_arrow").css({"left" : this.$(".TS-item").width()});
|
625
|
+
// Otherwise, if the card is off the left side of the timeline and we have
|
626
|
+
// flipped it before and the card's width is less than half of the width
|
627
|
+
// of the whole timeline, we'll flip it to the default position.
|
628
|
+
} else if (this.el.offset().left - $("#timeline_setter").offset().left < 0 && !margin && flippable) {
|
629
|
+
this.el.css({"margin-left": this.originalMargin});
|
630
|
+
this.$(".TS-css_arrow").css({"left": 0});
|
621
631
|
}
|
622
632
|
},
|
623
633
|
|
624
|
-
// A utility function to suss out whether the card is fully viewable.
|
625
|
-
cardOffset : function() {
|
626
|
-
if (!this.el) return { onBarEdge : false };
|
627
|
-
|
628
|
-
var that = this;
|
629
|
-
var item = this.el.children(".TS-item");
|
630
|
-
var currentMargin = this.el.css("margin-left");
|
631
|
-
var timeline = $("#timeline_setter");
|
632
|
-
var right = (this.el.offset().left + item.width()) - (timeline.offset().left + timeline.width());
|
633
|
-
var left = (this.el.offset().left) - timeline.offset().left;
|
634
|
-
|
635
|
-
return {
|
636
|
-
item : item,
|
637
|
-
onBarEdge : (right > 0 && currentMargin === that.originalMargin) ?
|
638
|
-
'right' :
|
639
|
-
(left < 0 && that.el.css("margin-left") !== that.originalMargin) ?
|
640
|
-
'default' :
|
641
|
-
(left < 0 && that.el.css("margin-left") === that.originalMargin) ?
|
642
|
-
'left' :
|
643
|
-
false
|
644
|
-
};
|
645
|
-
},
|
646
|
-
|
647
634
|
// The first time a card is activated it renders its `template` and appends
|
648
|
-
// its element to the `Bar`. After doing so it
|
649
|
-
//
|
650
|
-
//
|
651
|
-
// if that is less than the `.TS-item_year` element's width, `.TS-item_label`
|
652
|
-
// gets `.TS-item_year`s width. Which is a funny way of saying, if you'd
|
653
|
-
// like to set the width of the card as a whole, fiddle with `.TS-item_year`s
|
654
|
-
// width.
|
635
|
+
// its element to the `Bar`. After doing so it sets the width if `.TS-item_label`
|
636
|
+
// and moves the `Bar` if its element outside the visible portion of the
|
637
|
+
// timeline.
|
655
638
|
activate : function(e){
|
656
639
|
this.hideActiveCard();
|
657
640
|
if (!this.el) {
|
@@ -660,36 +643,47 @@
|
|
660
643
|
$("#TS-card_scroller_inner").append(this.el);
|
661
644
|
this.originalMargin = this.el.css("margin-left");
|
662
645
|
this.el.delegate(".TS-permalink", "click", this.setPermalink);
|
646
|
+
// Reactivate if there are images in the html so we can recalculate
|
647
|
+
// widths and position accordingly.
|
648
|
+
this.$("img").load(this.activate);
|
663
649
|
}
|
664
|
-
|
665
650
|
this.el.show().addClass(("TS-card_active"));
|
666
|
-
|
651
|
+
this.notch.addClass("TS-notch_active");
|
652
|
+
this.setWidth();
|
653
|
+
|
654
|
+
// In the case that the card is outside the bounds the wrong way when
|
655
|
+
// it's flipped, we'll take care of it here before we move the actual
|
656
|
+
// card.
|
657
|
+
this.flip($.Event("move"));
|
658
|
+
this.move();
|
659
|
+
},
|
660
|
+
|
661
|
+
// For Internet Explorer each card sets the width of` .TS-item_label` to
|
662
|
+
// the maximum width of the card's children, or if that is less than the
|
663
|
+
// `.TS-item_year` element's width, `.TS-item_label` gets `.TS-item_year`s
|
664
|
+
// width. Which is a funny way of saying, if you'd like to set the width of
|
665
|
+
// the card as a whole, fiddle with `.TS-item_year`s width.
|
666
|
+
setWidth : function(){
|
667
667
|
var max = _.max(_.toArray(this.$(".TS-item_user_html").children()), function(el){ return $(el).width(); });
|
668
|
-
if($(max).width() > this.$(".TS-item_year").width()){
|
668
|
+
if ($(max).width() > this.$(".TS-item_year").width()) {
|
669
669
|
this.$(".TS-item_label").css("width", $(max).width());
|
670
670
|
} else {
|
671
671
|
this.$(".TS-item_label").css("width", this.$(".TS-item_year").width());
|
672
672
|
}
|
673
|
-
|
674
|
-
this.moveBarWithCard();
|
675
|
-
this.notch.addClass("TS-notch_active");
|
676
673
|
},
|
677
674
|
|
678
|
-
// Move the `Bar` if the
|
679
|
-
|
675
|
+
// Move the `Bar` if the card is outside the visible region on activation.
|
676
|
+
move : function() {
|
680
677
|
var e = $.Event('moving');
|
681
|
-
var
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
e.deltaX = (this.cardOffset().item.width());
|
690
|
-
this.series.timeline.bar.moving(e);
|
678
|
+
var offset = this.$(".TS-item").offset();
|
679
|
+
var toffset = $("#timeline_setter").offset();
|
680
|
+
if (offset.left < toffset.left) {
|
681
|
+
e.deltaX = toffset.left - offset.left + cleanNumber(this.$(".TS-item").css("padding-left"));
|
682
|
+
this.series.timeline.bar.moving(e);
|
683
|
+
} else if (offset.left + this.$(".TS-item").outerWidth() > toffset.left + $("#timeline_setter").width()) {
|
684
|
+
e.deltaX = toffset.left + $("#timeline_setter").width() - (offset.left + this.$(".TS-item").outerWidth());
|
685
|
+
this.series.timeline.bar.moving(e);
|
691
686
|
}
|
692
|
-
this.position($.Event('move'));
|
693
687
|
},
|
694
688
|
|
695
689
|
// The click handler to set the current hash to the `Card`'s id.
|
@@ -705,10 +699,10 @@
|
|
705
699
|
|
706
700
|
// An event listener to toggle this notche on and off via `Series`.
|
707
701
|
toggleNotch : function(e){
|
708
|
-
switch(e.type) {
|
702
|
+
switch (e.type) {
|
709
703
|
case "hideNotch":
|
710
704
|
this.notch.hide().removeClass("TS-notch_active").addClass("TS-series_inactive");
|
711
|
-
if(this.el) this.el.hide();
|
705
|
+
if (this.el) this.el.hide();
|
712
706
|
return;
|
713
707
|
case "showNotch":
|
714
708
|
this.notch.removeClass("TS-series_inactive").show();
|
@@ -782,7 +776,7 @@
|
|
782
776
|
} else {
|
783
777
|
el = (curCardIdx > 0 ? notches.eq(curCardIdx - 1) : false);
|
784
778
|
}
|
785
|
-
if(!el) return;
|
779
|
+
if (!el) return;
|
786
780
|
el.trigger("click");
|
787
781
|
}
|
788
782
|
});
|
@@ -799,7 +793,9 @@
|
|
799
793
|
// and binding to `"keydown"`.
|
800
794
|
Timeline.boot = function(data) {
|
801
795
|
$(function(){
|
796
|
+
|
802
797
|
TimelineSetter.timeline = new Timeline(data);
|
798
|
+
|
803
799
|
new Zoom("in");
|
804
800
|
new Zoom("out");
|
805
801
|
var chooseNext = new Chooser("next");
|