alongslide 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjhiZDM3YTNiNWYyYWI0N2IzNGIwNGU1ZmEyOWMyZjkyZTg1NjZiYQ==
4
+ NDM0ODFhYTU3OTQ2OGY1ODQwYzU4M2FlYzc3N2UxNDRlZmJiYjYxNQ==
5
5
  data.tar.gz: !binary |-
6
- YmMxZGM2YWJlMzQwYjRkYjc2Y2E3YmM1MTM1M2Q2NjFiYWNmY2ZjYg==
6
+ YWU4YjgzNWM5MDYzMWZkNjhlZjc2YzJjNTBiNzdiNTRkZDU3ZGE2OQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTNjZGZiNDA0YzJhYjc0NDEzYmFiNThiOTUwM2JjYjhhMjFmNDJmYTNhOWRl
10
- MjYyZmNkYWMwZWMwZDBiNjk1NDFmNzhhM2QxZTAwODE3YzQwYzM4MmMyNjlh
11
- MTBmZTU5MjU5ZTcwYmI4NTZhMDhjNGI0ZTc1OWFlNDA2MTg1Y2Q=
9
+ NDMxZTU3YzJlMjRmMTc2NmIxYThjNDhlZDAwYjNjZmNiZWNmMmNmMzFjOGZl
10
+ ODM0MTcwMTUwZTgxY2QxMWE3NGEwN2UwYTkyMjI3ZDIyZGFiYTYyODRhMjgw
11
+ MDdlYWZjOGYwZGViZDRhYTM0OTQ5NjQ0YTc5ODBjZWFjMGIyNGU=
12
12
  data.tar.gz: !binary |-
13
- YWE3MjYxZDQyMGZiYWIwNTM3NmIzMmVhODEyMWIwNzBhYzI0MmY5NWE1NjFj
14
- NmRjNzY5MDZlZWY4YTczMjZjYTRmZDIwNDdlZDc4MDk2MTRlMmViYjQyZGE4
15
- NmNjYWE1YmNmN2QxMWZhNjcwNmI5NzMzNDFlODk0ZWRhNjlkY2I=
13
+ Y2FjZjZhMzUyYmJmNzNjOGJiZjZhMTIwNTcwOWZmMjlmMWU3NjZlMGYyZDcz
14
+ YzE0NTdkNDhiNDk2YmYzMzA1OTYwNWQwMTZjNDExZGJiNTkwOTc3MDEzY2Qy
15
+ MDczY2Y5NzNiODkwNmQxMGNhZDcxMjVlMGY0YWUyYTEzMDQ4OGY=
data/alongslide.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'alongslide'
3
- gem.version = '0.9.9'
3
+ gem.version = '0.9.10'
4
4
 
5
5
  gem.summary = "Create dynamic web layouts with an extended Markdown syntax"
6
6
  gem.description = "Create dynamic web layouts with an extended Markdown syntax"
@@ -1,9 +1,9 @@
1
- #
1
+ #
2
2
  # alongslide.cofee: Central init, pull in submodules.
3
- #
3
+ #
4
4
  # Copyright 2013 Canopy Canopy Canopy, Inc.
5
5
  # Authors Adam Florin & Anthony Tran
6
- #
6
+ #
7
7
  class Alongslide
8
8
 
9
9
  panels : {}
@@ -12,12 +12,14 @@ class Alongslide
12
12
  parser : null
13
13
  layout : null
14
14
  scrolling : null
15
+ state : null
15
16
 
16
17
  constructor: (options= {}) ->
17
- @source = $(options.source) ? $('#content .raw')
18
- @frames = $(options.to) ? $('#frames')
19
- @regionCls = options.regionCls ? 'column'
20
- @marginTop = options.marginTop ? 0
18
+ @source = $(options.source) ? $('#content .raw')
19
+ @frames = $(options.to) ? $('#frames')
20
+ @regionCls = options.regionCls ? 'column'
21
+ @marginTop = options.marginTop ? 0
22
+ @panelNames = {}
21
23
 
22
24
  RegionFlow::init()
23
25
 
@@ -33,20 +35,25 @@ class Alongslide
33
35
  backgrounds: @backgrounds
34
36
  panels: @panels
35
37
  regionCls: @regionCls
38
+ panelNames: @panelNames
36
39
 
37
40
  # init scrolling
38
41
  @scrolling = new @Scrolling
39
42
  frames: @frames
40
43
 
44
+ # init broswer history
45
+ @state = new @State
46
+ panelNames: @panelNames
47
+
41
48
 
42
49
  # Render flowing layout and scroll behavior.
43
- #
50
+ #
44
51
  # Force use of CSS Regions polyfill. (Don't trust native browser support
45
52
  # while W3C draft is under active development.)
46
- #
53
+ #
47
54
  # @param frameAspect - bounding box computed by FixedAspect
48
55
  # @param postRenderCallback - to be called when layout returns
49
- #
56
+ #
50
57
  render: (postRenderCallback) ->
51
58
  frameAspect = FixedAspect.prototype.fitFrame(@layout.FRAME_WIDTH, @marginTop)
52
59
  @layout.render (lastFramePosition) =>
@@ -65,7 +72,7 @@ class Alongslide
65
72
  postRenderCallback()
66
73
 
67
74
  # Refresh Skrollr only on resize events, as it's fast.
68
- #
75
+ #
69
76
  refresh: ->
70
77
  frameAspect = FixedAspect.prototype.fitFrame(@layout.FRAME_WIDTH, @marginTop)
71
78
  @scrolling.render(frameAspect, @lastFramePosition)
@@ -80,7 +87,7 @@ class Alongslide
80
87
 
81
88
 
82
89
  # Create footnotes
83
- #
90
+ #
84
91
  # Sanitize Markdown generated HTML
85
92
  applyFootnotes: ->
86
93
  # For each footnote in the article
@@ -107,7 +114,7 @@ class Alongslide
107
114
  $footnote.fadeIn(150)
108
115
  false
109
116
 
110
- $footnote.on "mouseleave click", (e) ->
117
+ $footnote.on "mouseleave click", (e) ->
111
118
  setTimeout ( ()-> $footnote.fadeOut(150) ), 100
112
119
  false
113
120
 
@@ -124,5 +131,5 @@ class Alongslide
124
131
 
125
132
 
126
133
  # Make global
127
- #
134
+ #
128
135
  window.Alongslide = Alongslide
@@ -1,61 +1,61 @@
1
- #
1
+ #
2
2
  # alongslide.coffee: Re-format HTML into horizontally-scrolling elements
3
3
  # which scroll at different rates.
4
- #
4
+ #
5
5
  # Use CSS Regions polyfill for text flowing, and skrollr for scroll positioning.
6
- #
6
+ #
7
7
  # Copyright 2013 Canopy Canopy Canopy, Inc.
8
8
  # Authors Adam Florin & Anthony Tran
9
- #
9
+ #
10
10
  class Alongslide::Layout
11
11
 
12
12
  # For parsing pinned panel directives.
13
- #
13
+ #
14
14
  HORIZONTAL_EDGES: ["left", "right"]
15
- VERTICAL_EDGES: ["top", "bottom"]
16
- EDGES: @::HORIZONTAL_EDGES.concat @::VERTICAL_EDGES
17
- SIZES: ["one-third", "half", "two-thirds"]
18
- ALIGNMENTS: @::EDGES.concat 'fullscreen'
15
+ VERTICAL_EDGES : ["top", "bottom"]
16
+ EDGES : @::HORIZONTAL_EDGES.concat @::VERTICAL_EDGES
17
+ SIZES : ["one-third", "half", "two-thirds"]
18
+ ALIGNMENTS : @::EDGES.concat 'fullscreen'
19
19
 
20
20
  # Keys to ALS position data attributes
21
- IN_POINT_KEY: 'als-in-position'
21
+ IN_POINT_KEY : 'als-in-position'
22
22
  OUT_POINT_KEY: 'als-out-position'
23
23
 
24
24
  # Corresponds to $fixed-frame-width in alongslide.sass
25
25
  FRAME_WIDTH: 980
26
26
 
27
27
  # Pixel width of each frame == screen width.
28
- #
28
+ #
29
29
  frameWidth: $(window).width()
30
30
 
31
31
  # Switch to true for verbose debugging. Plus constants for indent level.
32
- #
33
- debug: false
32
+ #
33
+ debug : false
34
34
  SUPER_FRAME_LEVEL: 1
35
- FRAME_LEVEL: 2
36
- SUB_FRAME_LEVEL: 3
37
-
38
- #
39
- #
35
+ FRAME_LEVEL : 2
36
+ SUB_FRAME_LEVEL : 3
37
+
38
+ #
39
+ #
40
40
  constructor: (options = {}) ->
41
- {@frames, @flowNames, @backgrounds, @panels, @regionCls, @sourceLength} = options
41
+ {@frames, @flowNames, @backgrounds, @panels, @regionCls, @sourceLength, @panelNames} = options
42
42
 
43
43
  # Main entrypoint for asynchronous chain of render calls.
44
- #
44
+ #
45
45
  # @param postRenderCallback - to be called when layout is 100% complete
46
- #
46
+ #
47
47
  render: (@postRenderCallback) ->
48
48
  @reset()
49
49
  @writeBackgrounds()
50
50
  @layout()
51
-
51
+
52
52
  # Flow text into columns, using regionFlow as a CSS regions polyfill.
53
- #
53
+ #
54
54
  # Loop through each flow (= section), then each frame, then each column.
55
- #
55
+ #
56
56
  # This is all done asynchronously so that DOM can update itself periodically
57
57
  # (namely for layout progress updates).
58
- #
58
+ #
59
59
  layout: =>
60
60
  @startTime = new Date
61
61
  @log "Beginning layout"
@@ -67,7 +67,7 @@ class Alongslide::Layout
67
67
 
68
68
  # Render one section (a.k.a. one "flow" in CSSRegions parlance),
69
69
  # one frame at a time, asynchronously.
70
- #
70
+ #
71
71
  renderSection: ->
72
72
  flowName = @flowNames[@currentFlowIndex]
73
73
 
@@ -82,13 +82,13 @@ class Alongslide::Layout
82
82
  @renderFrame(flowName)
83
83
 
84
84
  # Render one frame and its containing columns.
85
- #
85
+ #
86
86
  # When frame is done, trigger (asynchronously) either next frame or next section.
87
- #
87
+ #
88
88
  # Note that normally we check _second-to-last_ column for directives,
89
89
  # as last column contains overflow. Once flow is complete, though,
90
90
  # check the last column--and remove it if it contains nothing but directives.
91
- #
91
+ #
92
92
  renderFrame: (flowName, frame, lastColumn) ->
93
93
  frame = @findOrBuildNextFlowFrame frame
94
94
 
@@ -143,20 +143,20 @@ class Alongslide::Layout
143
143
  setTimeout((=> @renderFrame(flowName, frame, lastColumn)), 1)
144
144
 
145
145
  # Check the last "fit" column for any special directives (CSS classes).
146
- #
146
+ #
147
147
  # The last "fit" column is the last one that doesn't also contain all the
148
148
  # overflow to be laid out in other columns--typically the second-to-last column.
149
- #
149
+ #
150
150
  # Then, having found a directive, parse the classes and act accordingly.
151
- #
151
+ #
152
152
  # NOTE that this method also takes responsibility for creating the appropriate
153
153
  # next frame for text to flow in. It doesn't need to return it, however,
154
154
  # as the caller will just use `findOrBuildNextFlowFrame` to check for it.
155
- #
155
+ #
156
156
  # @param column - jQuery element to scan for directives
157
157
  # @param layoutComplete - true if this flow has been completely laid out
158
158
  # (and therefore no new flowing regions should be created)
159
- #
159
+ #
160
160
  checkForDirectives: (column, layoutComplete) ->
161
161
  # for each directive
162
162
  (column.find ".alongslide").each (index, directiveElement) =>
@@ -198,7 +198,7 @@ class Alongslide::Layout
198
198
  framesWithPinnedPanels = _.compact [
199
199
  flowFrame if directive.hasClass("now"),
200
200
  nextFlowFrame]
201
-
201
+
202
202
  # set frame classes--pushing columns into subsequent frames if necessary
203
203
  _.each framesWithPinnedPanels, (frame) =>
204
204
  @log "Applying with-pinned-panel styles to flow frame at " +
@@ -225,11 +225,11 @@ class Alongslide::Layout
225
225
 
226
226
  if nextFlowFrame?
227
227
  @setPositionOf nextFlowFrame, to: nextFlowFramePosition + 1
228
-
228
+
229
229
  # unpin pinned panel
230
230
  when directive.hasClass "unpin"
231
231
  panelFrame = @findPanel(id)
232
-
232
+
233
233
  unless panelFrame.length == 0
234
234
  @setPositionOf panelFrame, until:
235
235
  if layoutComplete
@@ -246,14 +246,14 @@ class Alongslide::Layout
246
246
  postPanelFlowFrame.removeClass @withSizedClass(panelFrame)
247
247
 
248
248
  # If column contains nothing other than directives, remove it.
249
- #
249
+ #
250
250
  # Called only when a section has been fully laid out.
251
- #
251
+ #
252
252
  # Do the test on a clone, so we don't strip directives from actual column,
253
253
  # which will still be checked by checkForDirectives.
254
- #
254
+ #
255
255
  # If column's frame is empty, remove that, too.
256
- #
256
+ #
257
257
  checkForEmpties: (column) ->
258
258
  columnClone = column.clone()
259
259
  columnClone.find(".alongslide").detach()
@@ -272,16 +272,16 @@ class Alongslide::Layout
272
272
  # while we're at it, check if any empty frames were created (probably at the end)
273
273
  @frames.children('.flow').find('.frame:empty').each (index, frame) =>
274
274
  @destroyFlowFrame $(frame)
275
-
275
+
276
276
  # Check for orphaned content. This can take many forms, so this method will
277
277
  # grow and evolve as cases emerge.
278
- #
278
+ #
279
279
  checkForOrphans: (column) ->
280
280
  # If column ends with a header, push it to the overflow column.
281
281
  column.find(':last:header').detach().prependTo($('.'+@regionCls+':last'))
282
282
 
283
283
  # Given a flow frame, find the next in line after it--or create one if none exists.
284
- #
284
+ #
285
285
  findOrBuildNextFlowFrame: (lastFrame) ->
286
286
  nextFlowFrame = if lastFrame?.length then lastFrame.next('.frame')
287
287
  unless nextFlowFrame?.length
@@ -289,9 +289,9 @@ class Alongslide::Layout
289
289
  return nextFlowFrame
290
290
 
291
291
  # Build one frame to hold columns of flowing text.
292
- #
292
+ #
293
293
  # Only build new frame if there are none. Otherwise, clone the last one.
294
- #
294
+ #
295
295
  buildFlowFrame: (lastFrame) ->
296
296
  position = if lastFrame?.length
297
297
  @getPositionOf(lastFrame) + 1
@@ -306,7 +306,7 @@ class Alongslide::Layout
306
306
  @setPositionOf frame, to: position
307
307
 
308
308
  # Destroy frame, shifting any subsequent panels up by one.
309
- #
309
+ #
310
310
  destroyFlowFrame: (frame) ->
311
311
  @log "Destroying flow frame at #{@getPositionOf frame}", @FRAME_LEVEL
312
312
  frame.detach()
@@ -329,42 +329,44 @@ class Alongslide::Layout
329
329
 
330
330
  # Pull panel element out of @panels storage, apply its transition, and
331
331
  # append to DOM!
332
- #
332
+ #
333
333
  # @param id - Alongslide panel ID
334
- #
334
+ #
335
335
  buildPanel: (id, position) ->
336
+ @panelNames[position] = id
336
337
  panel = @panels[id].clone().addClass('unstaged').show()
337
338
  alignment = _.filter @ALIGNMENTS, (alignment) -> panel.hasClass(alignment)
338
339
  @log "Building #{alignment} panel frame \"#{id}\" at position #{position}", @FRAME_LEVEL
339
340
  panel.addClass('frame')
341
+ panel.attr('data-panel-index', position);
340
342
  panel.appendTo @frames.children('.panels')
341
343
  @setPositionOf panel, to: position
342
344
  return panel
343
345
 
344
346
  # Destroy all previously laid out content.
345
- #
347
+ #
346
348
  reset: ->
347
349
  @laidOutLength = 0
348
350
 
349
351
  @frames.find('.backgrounds').empty()
350
352
  @frames.find('.flow').empty()
351
353
  @frames.find('.panels').empty()
352
-
354
+
353
355
  # remove regionFlows' internal record of regions we just destroyed
354
356
  _.each document.namedFlows.namedFlows, (flow) -> flow.resetRegions()
355
357
 
356
358
  # Write the given array of backgrounds to the DOM.
357
- #
359
+ #
358
360
  writeBackgrounds: ->
359
361
  for background in @backgrounds
360
362
  @frames.find('.backgrounds').append(background.clone())
361
363
 
362
364
  # Set frame start/end position.
363
- #
365
+ #
364
366
  # @param options
365
367
  # to: in point (= start position)
366
368
  # until: out point (= end position)
367
- #
369
+ #
368
370
  setPositionOf: (frame, options={}) ->
369
371
  frameType = frame.parent().get(0).className
370
372
  if options.to?
@@ -379,18 +381,18 @@ class Alongslide::Layout
379
381
  return frame
380
382
 
381
383
  # Return start position.
382
- #
384
+ #
383
385
  getPositionOf: (frame) ->
384
386
  frame.data(@IN_POINT_KEY)
385
387
 
386
388
  # What position the _next_ (as yet unrendered) frame should be at.
387
- #
389
+ #
388
390
  nextFramePosition: ->
389
391
  framePosition = @lastFramePosition()
390
392
  if framePosition? then framePosition + 1 else 0
391
393
 
392
394
  # Return the largest frame number of all frames.
393
- #
395
+ #
394
396
  lastFramePosition: ->
395
397
  flowsAndPanels = @frames.children('.flow, .panels').find('.frame')
396
398
  allFramePositions = _(flowsAndPanels).map (frame) => @getPositionOf $(frame)
@@ -398,7 +400,7 @@ class Alongslide::Layout
398
400
 
399
401
  # Certain frame CSS classes limit the number of columns allowed
400
402
  # per flow frame.
401
- #
403
+ #
402
404
  numFrameColumns: (frame) ->
403
405
  numColumns = if frame.hasClass('three-columns') then 3 else 2
404
406
  numColumns -= 1 if @isWithHorizontalPanel(frame)
@@ -406,7 +408,7 @@ class Alongslide::Layout
406
408
  return numColumns
407
409
 
408
410
  # Once render is done, build relevant indices for later lookup.
409
- #
411
+ #
410
412
  index: ->
411
413
  @panelIndex = {}
412
414
  @frames.children('.panels').find('.panel.frame').each (index, panel) =>
@@ -417,41 +419,41 @@ class Alongslide::Layout
417
419
  @panelIndex[position].push panel
418
420
 
419
421
  # Re-order elements in DOM if specified.
420
- #
422
+ #
421
423
  # This is a more reliable method of forcing a higher z-index for certain panels.
422
- #
424
+ #
423
425
  reorder: ->
424
426
  frontPanels = @frames.children('.panels').find('.panel.front').detach()
425
427
  @frames.children('.panels').append(frontPanels)
426
428
 
427
429
  # DOM utility.
428
- #
430
+ #
429
431
  # Find background for a given section (flow).
430
- #
432
+ #
431
433
  findBackground: (flowName) ->
432
434
  @frames.children('.backgrounds').find(".background.frame[data-alongslide-id=#{flowName}]")
433
435
 
434
436
  # DOM utility.
435
- #
437
+ #
436
438
  findPanel: (id) ->
437
439
  @frames.children('.panels').find(".panel.frame[data-alongslide-id=#{id}]")
438
440
 
439
441
  # Check panel index for panel at given position, and check if it's horizontal.
440
- #
442
+ #
441
443
  horizontalPanelAt: (position, edge) ->
442
444
  edges = if edge? then [edge] else @HORIZONTAL_EDGES
443
445
  _(@panelIndex[position] || []).any (panel) ->
444
446
  _(edges).any (edge) -> $(panel).hasClass(edge)
445
447
 
446
448
  # Check if flow frame shares space with horizontally-pinned panel.
447
- #
449
+ #
448
450
  isWithHorizontalPanel: (frame) ->
449
451
  for cssClass in _.map(@HORIZONTAL_EDGES, (edge) -> "with-panel-pinned-#{edge}")
450
452
  return true if frame.hasClass(cssClass)
451
453
 
452
454
  # Given a directive for a pinned panel, retun the class to be applied to
453
455
  # flow frames.
454
- #
456
+ #
455
457
  withPinnedClass: (directive) ->
456
458
  edge = _.first _.filter @EDGES, (edge) -> directive.hasClass(edge)
457
459
  "with-panel-pinned-#{edge}"
@@ -466,48 +468,48 @@ class Alongslide::Layout
466
468
 
467
469
  # If panel is partial width (i.e. is with left/right pinned panel),
468
470
  # then return its scrolling scale (0.0-1.0).
469
- #
471
+ #
470
472
  # Called by Scrolling to determine scoll distance.
471
- #
473
+ #
472
474
  # @return partialWidth - a percentage width (0.0-1.0), or undefined.
473
475
  # Note: This number doesn't have to be exact--just has to "feel" right for
474
476
  # pinned panels of different widths.
475
- #
477
+ #
476
478
  framePartialWidth: (frame) ->
477
479
  if @isWithHorizontalPanel(frame)
478
480
  $column = frame.find('.'+@regionCls)
479
481
  return ($column.width() + $column.position().left) * @numFrameColumns(frame) / frame.width()
480
482
 
481
483
  # Return panel alignment.
482
- #
484
+ #
483
485
  panelAlignment: (directive) ->
484
486
  _.first _.filter @ALIGNMENTS, (alignment) -> directive.hasClass(alignment)
485
487
 
486
488
  # Returns true when all flowing text has been laid out (i.e. last column
487
489
  # region no longer contains overflow.)
488
- #
490
+ #
489
491
  flowComplete: (flowName) ->
490
492
  not document.namedFlows.get(flowName).updateOverset()
491
493
 
492
494
  # Utility: Is column empty after we remove directives from it?
493
- #
495
+ #
494
496
  isEmpty: (el) ->
495
497
  $.trim(el.children().html()) == ''
496
498
 
497
499
  # Compute length of total laid out content so far and broadcast it to our
498
500
  # listeners.
499
- #
501
+ #
500
502
  # To listen:
501
- #
503
+ #
502
504
  # $(document).on 'alongslide.progress', (e, progress) ->
503
505
  # #
504
- #
506
+ #
505
507
  updateProgress: (newElement) ->
506
508
  @laidOutLength += newElement.text().length
507
509
  $(document).triggerHandler 'alongslide.progress', (@laidOutLength / @sourceLength)
508
510
 
509
511
  # Write debug log to console if available/desired.
510
- #
512
+ #
511
513
  log: (message, indentLevel = 0) ->
512
514
  indent = (_(indentLevel).times -> ". ").join('')
513
515
  if console? and @debug