timeline_setter 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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");
|