alongslide 0.9.9 → 0.9.10

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.
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