pageflow-sitemap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.jshintrc +18 -0
  4. data/Gemfile +24 -0
  5. data/LICENSE.md +20 -0
  6. data/README.md +47 -0
  7. data/Rakefile +32 -0
  8. data/app/assets/images/pageflow/sitemap/.keep +0 -0
  9. data/app/assets/javascripts/pageflow/sitemap/.keep +0 -0
  10. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/abstract_controller.js +68 -0
  11. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/editor_mode_controller.js +301 -0
  12. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/fragment_parser.js +31 -0
  13. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/selection_mode_controller.js +37 -0
  14. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/selection_navigator.js +43 -0
  15. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/mouse_wheel.js +43 -0
  16. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/multi_drag.js +73 -0
  17. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/scroll_and_zoom.js +286 -0
  18. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/selection_rect.js +104 -0
  19. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/tooltip_target.js +24 -0
  20. data/app/assets/javascripts/pageflow/sitemap/editor/d3/graph_view.js +277 -0
  21. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/chapter_collision.js +33 -0
  22. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/collision.js +116 -0
  23. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/dragging_decorator.js +58 -0
  24. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/grid.js +238 -0
  25. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/link_dragging_decorator.js +42 -0
  26. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout.js +94 -0
  27. data/app/assets/javascripts/pageflow/sitemap/editor/d3/options.js +25 -0
  28. data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/follow_path.js +36 -0
  29. data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/linkpath.js +64 -0
  30. data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/successor_path.js +49 -0
  31. data/app/assets/javascripts/pageflow/sitemap/editor/d3/utils.js +33 -0
  32. data/app/assets/javascripts/pageflow/sitemap/editor/d3/view_model.js +202 -0
  33. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/add_button_view.js +28 -0
  34. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/chapter_placeholders_view.js +22 -0
  35. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/chapters_view.js +89 -0
  36. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/group_view.js +104 -0
  37. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/page_links_view.js +7 -0
  38. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/pages_view.js +112 -0
  39. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/selectable_links_view.js +104 -0
  40. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/storylines_view.js +86 -0
  41. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/successor_links_view.js +7 -0
  42. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/text_label_view.js +45 -0
  43. data/app/assets/javascripts/pageflow/sitemap/editor/d3.js +20 -0
  44. data/app/assets/javascripts/pageflow/sitemap/editor/feature.js +126 -0
  45. data/app/assets/javascripts/pageflow/sitemap/editor/models/selection.js +41 -0
  46. data/app/assets/javascripts/pageflow/sitemap/editor/templates/scroll_bar.jst.ejs +2 -0
  47. data/app/assets/javascripts/pageflow/sitemap/editor/templates/sitemap.jst.ejs +85 -0
  48. data/app/assets/javascripts/pageflow/sitemap/editor/views/scroll_bar_view.js +130 -0
  49. data/app/assets/javascripts/pageflow/sitemap/editor/views/scroll_pane_view.js +73 -0
  50. data/app/assets/javascripts/pageflow/sitemap/editor/views/sitemap_view.js +137 -0
  51. data/app/assets/javascripts/pageflow/sitemap/editor.js +14 -0
  52. data/app/assets/javascripts/pageflow/sitemap/feature.js +3 -0
  53. data/app/assets/javascripts/pageflow/sitemap/scroll_navigator.js +112 -0
  54. data/app/assets/javascripts/pageflow/sitemap.js +5 -0
  55. data/app/assets/stylesheets/pageflow/sitemap/.keep +0 -0
  56. data/app/assets/stylesheets/pageflow/sitemap/editor/add_button.scss +29 -0
  57. data/app/assets/stylesheets/pageflow/sitemap/editor/chapter_placeholders.scss +14 -0
  58. data/app/assets/stylesheets/pageflow/sitemap/editor/chapters.scss +62 -0
  59. data/app/assets/stylesheets/pageflow/sitemap/editor/page_links.scss +19 -0
  60. data/app/assets/stylesheets/pageflow/sitemap/editor/pages.scss +78 -0
  61. data/app/assets/stylesheets/pageflow/sitemap/editor/scroll_bar.css.scss +33 -0
  62. data/app/assets/stylesheets/pageflow/sitemap/editor/scroll_pane.scss +15 -0
  63. data/app/assets/stylesheets/pageflow/sitemap/editor/selectable_links.scss +88 -0
  64. data/app/assets/stylesheets/pageflow/sitemap/editor/selection_rect.scss +12 -0
  65. data/app/assets/stylesheets/pageflow/sitemap/editor/storylines.scss +59 -0
  66. data/app/assets/stylesheets/pageflow/sitemap/editor/successor_links.scss +42 -0
  67. data/app/assets/stylesheets/pageflow/sitemap/editor/text_label.scss +23 -0
  68. data/app/assets/stylesheets/pageflow/sitemap/editor/toolbar.css.scss +45 -0
  69. data/app/assets/stylesheets/pageflow/sitemap/editor.css.scss +96 -0
  70. data/config/locales/de.yml +16 -0
  71. data/config/locales/en.yml +48 -0
  72. data/config/locales/new/help_button.de.yml +7 -0
  73. data/config/locales/new/help_button.en.yml +7 -0
  74. data/config/locales/new/tooltips.de.yml +11 -0
  75. data/config/locales/new/tooltips.en.yml +11 -0
  76. data/config/routes.rb +7 -0
  77. data/config/spring.rb +1 -0
  78. data/exec/rails +12 -0
  79. data/exec/spring +18 -0
  80. data/exec/teaspoon +17 -0
  81. data/lib/pageflow/sitemap/engine.rb +10 -0
  82. data/lib/pageflow/sitemap/plugin.rb +11 -0
  83. data/lib/pageflow/sitemap/version.rb +5 -0
  84. data/lib/pageflow-sitemap.rb +9 -0
  85. data/pageflow-sitemap.gemspec +29 -0
  86. data/spec/d/r/.gitignore +16 -0
  87. data/spec/d/r/README.rdoc +28 -0
  88. data/spec/d/r/Rakefile +6 -0
  89. data/spec/d/r/app/admin/dashboard.rb +33 -0
  90. data/spec/d/r/app/assets/images/.keep +0 -0
  91. data/spec/d/r/app/assets/javascripts/active_admin.js.coffee +2 -0
  92. data/spec/d/r/app/assets/javascripts/application.js +16 -0
  93. data/spec/d/r/app/assets/javascripts/pageflow/application.js +1 -0
  94. data/spec/d/r/app/assets/javascripts/pageflow/editor.js +4 -0
  95. data/spec/d/r/app/assets/stylesheets/active_admin.css.scss +18 -0
  96. data/spec/d/r/app/assets/stylesheets/application.css +13 -0
  97. data/spec/d/r/app/assets/stylesheets/pageflow/application.css.scss +1 -0
  98. data/spec/d/r/app/assets/stylesheets/pageflow/editor.css.scss +1 -0
  99. data/spec/d/r/app/controllers/application_controller.rb +5 -0
  100. data/spec/d/r/app/controllers/concerns/.keep +0 -0
  101. data/spec/d/r/app/helpers/application_helper.rb +2 -0
  102. data/spec/d/r/app/mailers/.keep +0 -0
  103. data/spec/d/r/app/models/.keep +0 -0
  104. data/spec/d/r/app/models/ability.rb +12 -0
  105. data/spec/d/r/app/models/concerns/.keep +0 -0
  106. data/spec/d/r/app/models/user.rb +9 -0
  107. data/spec/d/r/app/views/layouts/application.html.erb +14 -0
  108. data/spec/d/r/bin/bundle +3 -0
  109. data/spec/d/r/bin/rails +4 -0
  110. data/spec/d/r/bin/rake +4 -0
  111. data/spec/d/r/config/application.rb +31 -0
  112. data/spec/d/r/config/boot.rb +4 -0
  113. data/spec/d/r/config/database.yml +39 -0
  114. data/spec/d/r/config/environment.rb +5 -0
  115. data/spec/d/r/config/environments/development.rb +29 -0
  116. data/spec/d/r/config/environments/production.rb +80 -0
  117. data/spec/d/r/config/environments/test.rb +37 -0
  118. data/spec/d/r/config/initializers/active_admin.rb +225 -0
  119. data/spec/d/r/config/initializers/backtrace_silencers.rb +7 -0
  120. data/spec/d/r/config/initializers/devise.rb +252 -0
  121. data/spec/d/r/config/initializers/devise_async.rb +6 -0
  122. data/spec/d/r/config/initializers/filter_parameter_logging.rb +4 -0
  123. data/spec/d/r/config/initializers/friendly_id.rb +88 -0
  124. data/spec/d/r/config/initializers/inflections.rb +16 -0
  125. data/spec/d/r/config/initializers/mime_types.rb +5 -0
  126. data/spec/d/r/config/initializers/pageflow.rb +76 -0
  127. data/spec/d/r/config/initializers/resque.rb +4 -0
  128. data/spec/d/r/config/initializers/resque_enqueue_after_commit_patch.rb +25 -0
  129. data/spec/d/r/config/initializers/resque_logger.rb +16 -0
  130. data/spec/d/r/config/initializers/resque_mailer.rb +4 -0
  131. data/spec/d/r/config/initializers/secret_token.rb +12 -0
  132. data/spec/d/r/config/initializers/session_store.rb +3 -0
  133. data/spec/d/r/config/initializers/wrap_parameters.rb +14 -0
  134. data/spec/d/r/config/locales/devise.en.yml +59 -0
  135. data/spec/d/r/config/locales/en.yml +23 -0
  136. data/spec/d/r/config/routes.rb +59 -0
  137. data/spec/d/r/config.ru +4 -0
  138. data/spec/d/r/db/migrate/00000000000000_create_test_hosted_file.rb +7 -0
  139. data/spec/d/r/db/migrate/00000000000001_create_test_revision_component.rb +10 -0
  140. data/spec/d/r/db/migrate/20150209101518_create_active_admin_comments.rb +19 -0
  141. data/spec/d/r/db/migrate/20150209101524_devise_create_users.rb +46 -0
  142. data/spec/d/r/db/migrate/20150209101530_create_friendly_id_slugs.rb +15 -0
  143. data/spec/d/r/db/migrate/20150209101540_setup_schema.pageflow.rb +208 -0
  144. data/spec/d/r/db/migrate/20150209101541_add_attributes_to_users.pageflow.rb +16 -0
  145. data/spec/d/r/db/migrate/20150209101542_create_themings.pageflow.rb +16 -0
  146. data/spec/d/r/db/migrate/20150209101543_create_themings_for_existing_accounts.pageflow.rb +27 -0
  147. data/spec/d/r/db/migrate/20150209101544_change_theme_references_to_theming_references.pageflow.rb +46 -0
  148. data/spec/d/r/db/migrate/20150209101545_remove_attributes_from_themes.pageflow.rb +11 -0
  149. data/spec/d/r/db/migrate/20150209101546_create_accounts_themes_join_table.pageflow.rb +9 -0
  150. data/spec/d/r/db/migrate/20150209101547_move_cname_from_account_to_theming.pageflow.rb +22 -0
  151. data/spec/d/r/db/migrate/20150209101548_drop_themes.pageflow.rb +15 -0
  152. data/spec/d/r/db/migrate/20150209101549_add_confirmed_by_to_encoded_files.pageflow.rb +7 -0
  153. data/spec/d/r/db/migrate/20150209101550_add_home_url_attributes_to_themings_and_revisions.pageflow.rb +10 -0
  154. data/spec/d/r/db/migrate/20150209101551_create_widgets.pageflow.rb +12 -0
  155. data/spec/d/r/db/migrate/20150209101552_add_emphasize_chapter_beginning_to_revisions.pageflow.rb +6 -0
  156. data/spec/d/r/db/migrate/20150209101553_add_emphasize_new_pages_to_revisions.pageflow.rb +6 -0
  157. data/spec/d/r/db/migrate/20150209101554_add_sharing_image_to_revisions.pageflow.rb +8 -0
  158. data/spec/d/r/db/schema.rb +316 -0
  159. data/spec/d/r/db/seeds.rb +30 -0
  160. data/spec/d/r/lib/assets/.keep +0 -0
  161. data/spec/d/r/lib/tasks/.keep +0 -0
  162. data/spec/d/r/lib/tasks/resque.rake +7 -0
  163. data/spec/d/r/public/404.html +58 -0
  164. data/spec/d/r/public/422.html +58 -0
  165. data/spec/d/r/public/500.html +57 -0
  166. data/spec/d/r/public/favicon.ico +0 -0
  167. data/spec/d/r/public/javascripts/translations.js +2 -0
  168. data/spec/d/r/public/robots.txt +5 -0
  169. data/spec/d/r/vendor/assets/javascripts/.keep +0 -0
  170. data/spec/d/r/vendor/assets/stylesheets/.keep +0 -0
  171. data/spec/javascripts/.jshintrc +26 -0
  172. data/spec/javascripts/pageflow/sitemap/editor/controllers/selection_navigator_spec.js +52 -0
  173. data/spec/javascripts/pageflow/sitemap/editor/d3/layout/collision_spec.js +99 -0
  174. data/spec/javascripts/pageflow/sitemap/editor/d3/layout/dragging_decorator_spec.js +114 -0
  175. data/spec/javascripts/pageflow/sitemap/editor/d3/layout/grid_spec.js +183 -0
  176. data/spec/javascripts/pageflow/sitemap/editor/d3/layout_spec.js +31 -0
  177. data/spec/javascripts/pageflow/sitemap/editor/d3/view_model_spec.js +56 -0
  178. data/spec/javascripts/pageflow/sitemap/editor/models/selection_spec.js +62 -0
  179. data/spec/javascripts/pageflow/sitemap/scroll_navigator_spec.js +5 -0
  180. data/spec/javascripts/spec_helper.js +13 -0
  181. data/spec/javascripts/support/factories.js +81 -0
  182. data/spec/teaspoon_env.rb +182 -0
  183. data/vendor/assets/javascripts/d3.v3.js +9215 -0
  184. metadata +379 -0
@@ -0,0 +1,238 @@
1
+ pageflow.sitemap.layout.Grid = function(chaptersGroupedByStorylines, pagesGroupedByChapters, options) {
2
+ var positions = {};
3
+ var chapterSizes = {};
4
+ var heights = {};
5
+ var size = {x: 0, y: 0};
6
+
7
+ var laneWidth = this.laneWidth = options.pageWidth + 2 * options.pageMarginWidth;
8
+ var rowHeight = this.rowHeight = options.pageHeight + 2 * options.pageMarginHeight;
9
+
10
+ this.chaptersGroupedByStorylines = chaptersGroupedByStorylines;
11
+ this.pagesGroupedByChapters = pagesGroupedByChapters;
12
+ this.size = size;
13
+
14
+ this.position = function(target) {
15
+ return positions[target.cid];
16
+ };
17
+
18
+ this.linkSource = function(page) {
19
+ return {
20
+ x: this.position(page).x,
21
+ y: this.position(page).y,
22
+ width: options.pageWidth,
23
+ height: heights[page.cid] || options.pageHeight
24
+ };
25
+ };
26
+
27
+ this.linkTarget = function(page, link) {
28
+ return this.linkSource(page);
29
+ };
30
+
31
+ this.chapterHeight = function(chapter) {
32
+ return heights[chapter.cid];
33
+ };
34
+
35
+ this.height = function(target) {
36
+ if (!heights[target.cid]) {
37
+ debugger;
38
+ }
39
+
40
+ return heights[target.cid];
41
+ };
42
+
43
+ this.isAbovePage = function(page, position) {
44
+ var pagePosition = this.position(page);
45
+
46
+ return (Math.abs(position.x - pagePosition.x) < laneWidth / 2 &&
47
+ Math.abs(position.y - pagePosition.y) <= rowHeight / 2 &&
48
+ position.y < pagePosition.y + rowHeight / 2);
49
+ };
50
+
51
+ this.isAboveChapter = function(chapter, position) {
52
+ var chapterPosition = this.position(chapter);
53
+
54
+ return (Math.abs(position.x - chapterPosition.x) < laneWidth / 2 &&
55
+ Math.abs(position.y - chapterPosition.y) <= rowHeight / 2 &&
56
+ position.y < chapterPosition.y + rowHeight / 2);
57
+ };
58
+
59
+ this.pointInsidePage = function(page, position) {
60
+ var pagePosition = this.position(page);
61
+
62
+ return (Math.abs(position.x - pagePosition.x) <= (options.pageWidth + options.pageMarginWidth) / 2 &&
63
+ Math.abs(position.y - pagePosition.y) <= (options.pageHeight + options.pageMarginHeight) / 2);
64
+ };
65
+
66
+ this.pointInsideChapter = function(chapter, position) {
67
+ var chapterPosition = this.position(chapter);
68
+ var chapterHeight = this.chapterHeight(chapter);
69
+
70
+ return (Math.abs(position.x - chapterPosition.x) < laneWidth / 2 &&
71
+ position.y >= chapterPosition.y - rowHeight / 2 &&
72
+ position.y < chapterPosition.y + chapterHeight);
73
+ };
74
+
75
+ this.pointInsideStoryline = function(storyline, position) {
76
+ var storylinePosition = this.position(storyline);
77
+ var height = this.height(storyline);
78
+
79
+ return (Math.abs(position.x - storylinePosition.x) < laneWidth / 2 &&
80
+ position.y >= storylinePosition.y - rowHeight * 1.5 &&
81
+ position.y < storylinePosition.y + height);
82
+ };
83
+
84
+ this.isBelowChapter = function(chapter, position) {
85
+ var chapterPosition = this.position(chapter);
86
+ var chapterBottom =
87
+ this.position(chapter).y +
88
+ this.chapterHeight(chapter) +
89
+ 2 * options.pageMarginHeight;
90
+
91
+ return (Math.abs(position.x - chapterPosition.x) < laneWidth / 2 &&
92
+ Math.abs(position.y - chapterBottom) <= rowHeight / 2 &&
93
+ position.y < chapterBottom + rowHeight / 2);
94
+ };
95
+
96
+ this.isBelowStoryline = function(storyline, position) {
97
+ var storylinePosition = this.position(storyline);
98
+ var storylineBottom =
99
+ this.position(storyline).y +
100
+ this.height(storyline) +
101
+ 2 * options.pageMarginHeight;
102
+
103
+ return (Math.abs(position.x - storylinePosition.x) < laneWidth / 2 &&
104
+ Math.abs(position.y - storylineBottom) <= rowHeight / 2 &&
105
+ position.y < storylineBottom + rowHeight / 2);
106
+ };
107
+
108
+ this.laneAndRowFromPoint = function(position) {
109
+ return {
110
+ lane: Math.round(position.x / laneWidth),
111
+ row: Math.round(position.y / rowHeight)
112
+ };
113
+ };
114
+
115
+ this.freeGridCellFromPoint = function(position) {
116
+ if (!this.storylineFromPoint(position) &&
117
+ !this.chapterFromPoint(position) &&
118
+ !this.pageFromPoint(position)) {
119
+
120
+ return this.gridCellFromPoint(position);
121
+ }
122
+ };
123
+
124
+ this.gridCellFromPoint = function(position) {
125
+ var laneAndRow = this.laneAndRowFromPoint(position);
126
+
127
+ if (laneAndRow.lane >= 0 && laneAndRow.row >= 0) {
128
+ return {
129
+ laneAndRow: laneAndRow,
130
+ x: laneAndRow.lane * laneWidth,
131
+ y: laneAndRow.row * rowHeight,
132
+ width: options.pageWidth,
133
+ height: options.pageHeight
134
+ };
135
+ }
136
+ };
137
+
138
+ this.storylineFromPoint = function(position) {
139
+ var that = this;
140
+
141
+ return _(chaptersGroupedByStorylines).reduce(function(result, group) {
142
+ return result || (group.storyline &&
143
+ that.pointInsideStoryline(group.storyline, position));
144
+ }, null);
145
+ };
146
+
147
+ this.chapterFromPoint = function(position) {
148
+ var that = this;
149
+
150
+ return _(pagesGroupedByChapters).reduce(function(result, group) {
151
+ return result || (group.chapter &&
152
+ that.pointInsideChapter(group.chapter, position));
153
+ }, null);
154
+ };
155
+
156
+ this.pageFromPoint = function(position) {
157
+ var that = this;
158
+
159
+ return _(pagesGroupedByChapters).reduce(function(result, group) {
160
+ return result || _(group.pages).find(function(page) {
161
+ return that.pointInsidePage(page, position);
162
+ });
163
+ }, null);
164
+ };
165
+
166
+ this.isLegal = function() {
167
+ };
168
+
169
+ _.each(pagesGroupedByChapters, function(group) {
170
+ var chapter = group.chapter;
171
+
172
+ if (chapter) {
173
+ var chapterSize = Math.max(1, group.pages.length);
174
+ chapterSizes[chapter.cid] = chapterSize + 0.5;
175
+ heights[chapter.cid] = chapterSize * rowHeight - 2 * options.pageMarginHeight;
176
+ }
177
+ });
178
+
179
+ _.each(chaptersGroupedByStorylines, function(group) {
180
+ var storyline = group.storyline;
181
+
182
+ if (storyline) {
183
+ positions[storyline.cid] = {
184
+ x: lane(storyline) * laneWidth,
185
+ y: row(storyline) * rowHeight
186
+ };
187
+
188
+ var storylineSize = _.reduce(group.chapters, function(offset, chapter) {
189
+ var chapterSize = chapterSizes[chapter.cid];
190
+
191
+ var storylineLane = lane(storyline);
192
+ var storylineRow = row(storyline) + offset;
193
+
194
+ positions[chapter.cid] = {
195
+ _lane: storylineLane,
196
+ _row: storylineRow,
197
+ x: storylineLane * laneWidth,
198
+ y: storylineRow * rowHeight
199
+ };
200
+
201
+ return offset + chapterSize;
202
+ }, 0);
203
+
204
+ heights[storyline.cid] = Math.max(1, storylineSize) * rowHeight;
205
+
206
+ if (!heights[storyline.cid]) {
207
+ debugger;
208
+ }
209
+ }
210
+ });
211
+
212
+ _.each(pagesGroupedByChapters, function(group) {
213
+ var chapter = group.chapter;
214
+
215
+ if (chapter && positions[chapter.cid]) {
216
+ var chapterLane = positions[chapter.cid]._lane;
217
+ var chapterRow = positions[chapter.cid]._row;
218
+
219
+ _.each(group.pages, function(page, index) {
220
+ positions[page.cid] = {
221
+ x: chapterLane * laneWidth,
222
+ y: (chapterRow + index) * rowHeight
223
+ };
224
+
225
+ size.x = Math.max(size.x, positions[page.cid].x + laneWidth);
226
+ size.y = Math.max(size.y, positions[page.cid].y + rowHeight);
227
+ });
228
+ }
229
+ });
230
+
231
+ function lane(storyline) {
232
+ return storyline.configuration.get('lane') || 0;
233
+ }
234
+
235
+ function row(storyline) {
236
+ return storyline.configuration.get('row') || 0;
237
+ }
238
+ };
@@ -0,0 +1,42 @@
1
+ pageflow.sitemap.layout.LinkDraggingDecorator = function(selection, layout, options) {
2
+ var decorator = function() {
3
+ var targetPage, targetChapter;
4
+
5
+ if (options.dragPosition) {
6
+ targetPage = layout.pageFromPoint(options.dragPosition);
7
+
8
+ this.chapterPlaceholder = layout.freeGridCellFromPoint(options.dragPosition);
9
+ }
10
+
11
+ this.linkTarget = function(page, link) {
12
+ if (selection.contains(link) && options.dragPosition) {
13
+ if (targetPage) {
14
+ return layout.linkTarget(targetPage, link);
15
+ }
16
+
17
+ if (this.chapterPlaceholder) {
18
+ return this.chapterPlaceholder;
19
+ }
20
+
21
+ return {
22
+ x: options.dragPosition.x,
23
+ y: options.dragPosition.y,
24
+ width: 0,
25
+ height: 0
26
+ };
27
+ }
28
+ else {
29
+ return layout.linkTarget(page, link);
30
+ }
31
+ };
32
+
33
+ this.isDragging = function(target) {
34
+ return (options.dragPosition && selection.contains(target)) ||
35
+ layout.isDragging(target);
36
+ };
37
+
38
+ };
39
+
40
+ decorator.prototype = layout;
41
+ return new decorator();
42
+ };
@@ -0,0 +1,94 @@
1
+ //= require_self
2
+ //= require ./layout/grid
3
+ //= require ./layout/dragging_decorator
4
+ //= require ./layout/link_dragging_decorator
5
+ //= require ./layout/collision
6
+
7
+ (function() {
8
+ var s = pageflow.sitemap;
9
+
10
+ s.layout = {
11
+ defaultGrid: {
12
+ pageWidth: 125,
13
+ pageHeight: 70,
14
+ pageMarginWidth: 30,
15
+ pageMarginHeight: 12
16
+ },
17
+
18
+ create: function(entry, selection, options) {
19
+ options = _.extend({
20
+ grid: this.defaultGrid
21
+ }, options || {});
22
+
23
+ // We begin by layouting chapters and pages in a grid.
24
+
25
+ var originalLayout =
26
+ new s.layout.Grid(chaptersGroupedByStorylines(entry),
27
+ pagesGroupedByChapters(entry),
28
+ options.grid);
29
+
30
+ // Then we create a layout in which the selected pages are
31
+ // translated by the dragDelta.
32
+
33
+ var draggingLayout =
34
+ new s.layout.DraggingDecorator(selection,
35
+ originalLayout,
36
+ originalLayout,
37
+ {delta: options.dragDelta});
38
+ // When dragging pages, the reset of the layout collapses as if
39
+ // the dragged pages were removed. This is the layout we want to
40
+ // consider when we check collision with dragged pages.
41
+
42
+ var collapsedLayout =
43
+ new s.layout.Grid(draggingLayout.nonDraggedChaptersGroupedByStorylines,
44
+ draggingLayout.nonDraggedPagesGroupedByChapters,
45
+ options.grid);
46
+
47
+ // Group pages as if they already had been dropped into a target
48
+ // new chapters. This allows us to calculate a grid layout with
49
+ // free spaces where pages would be dropped.
50
+
51
+ var collision =
52
+ new s.layout.Collision(draggingLayout, collapsedLayout);
53
+
54
+ var spacingLayout =
55
+ new s.layout.Grid(collision.chaptersGroupedByDragTargetStorylines(),
56
+ collision.pagesGroupedByDragTargetChapters(),
57
+ options.grid);
58
+
59
+ // The final layout that we want to draw is split into two
60
+ // parts: For the selected pages, we want to use the position
61
+ // from the original layout translated by the dragDelta. For all
62
+ // other pages we want to use the positions from the spacing
63
+ // layout which already contains placeholder positions for the
64
+ // dragged pages.
65
+
66
+ var layout = new s.layout.DraggingDecorator(selection,
67
+ spacingLayout,
68
+ originalLayout,
69
+ {delta: options.dragDelta});
70
+
71
+ return new s.layout.LinkDraggingDecorator(selection,
72
+ layout,
73
+ {dragPosition: options.dragPosition});
74
+ }
75
+ };
76
+
77
+ function chaptersGroupedByStorylines(entry) {
78
+ return entry.storylines.map(function(storyline) {
79
+ return {
80
+ storyline: storyline,
81
+ chapters: storyline.chapters.toArray()
82
+ };
83
+ });
84
+ }
85
+
86
+ function pagesGroupedByChapters(entry) {
87
+ return entry.chapters.map(function(chapter) {
88
+ return {
89
+ chapter: chapter,
90
+ pages: chapter.pages.toArray()
91
+ };
92
+ });
93
+ }
94
+ }());
@@ -0,0 +1,25 @@
1
+ /*global options*/
2
+ window.options = sitemap.settings = {
3
+ margin: {
4
+ top: 60,
5
+ right: 60,
6
+ bottom: 60,
7
+ left: 60
8
+ },
9
+ page: {
10
+ height: 70,
11
+ width: 125,
12
+ verticalMargin: 30,
13
+ horizontalMargin: 30
14
+ },
15
+
16
+ arrowSize: 8,
17
+
18
+ radius: 20,
19
+ duration: 400,
20
+
21
+ panSpeed: 200,
22
+ panBoundary: 20 // Within 20px from edges will pan when dragging.
23
+ };
24
+
25
+ options.boxHeight = options.page.width + options.page.verticalMargin;
@@ -0,0 +1,36 @@
1
+ pageflow.sitemap.followPath = function(d) {
2
+ var points = sitemap.followPath.points(d);
3
+
4
+ var p = [points.start, points.p1, points.p2, points.end].map(function(d) {
5
+ return [d.x, d.y];
6
+ });
7
+
8
+ return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
9
+ };
10
+
11
+ pageflow.sitemap.followPath.points = function(d) {
12
+ var start, p1, p2, end;
13
+ var options = pageflow.sitemap.settings;
14
+
15
+ start = {
16
+ x: d.source.x,
17
+ y: d.source.y + options.page.width / 2
18
+ };
19
+ p1 = start;
20
+
21
+ p2 = {
22
+ x: d.target.x,
23
+ y: d.target.y - options.page.width / 2 - options.arrowSize - 20
24
+ };
25
+ end = {
26
+ x: d.target.x,
27
+ y: d.target.y - options.page.width / 2 - options.arrowSize
28
+ };
29
+
30
+ return {
31
+ start: start,
32
+ p1: p1,
33
+ p2: p2,
34
+ end: end
35
+ };
36
+ };
@@ -0,0 +1,64 @@
1
+ /*global options, sitemap*/
2
+
3
+ // path generator to be used in d3 attrib function for path element
4
+ // path.attr('d', sitemap.linkpath);
5
+ sitemap.linkpath = function(d) {
6
+ var points = sitemap.linkpath.points(d);
7
+
8
+ var p = [points.start, points.p1, points.p2, points.end].map(function(d) {
9
+ return [d.x, d.y];
10
+ });
11
+
12
+ return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
13
+ };
14
+
15
+ sitemap.linkpath.points = function(d) {
16
+ var deltaX = d.source.x - d.target.x;
17
+ var deltaY = d.source.y - d.target.y;
18
+
19
+ var start = { x: d.source.x, y: d.source.y + 5},
20
+ p1 = { x: d.source.x, y: d.source.y + 5},
21
+ p2 = { x: d.target.x, y: d.target.y - 5},
22
+ end = { x: d.target.x, y: d.target.y - 5};
23
+
24
+ var horizontalMargin = options.page.horizontalMargin * 2;
25
+
26
+ var offsetStart = d.source.width / 2,
27
+ offsetEnd = d.target.width / 2 + options.arrowSize;
28
+
29
+ // start of path
30
+ if (deltaX > options.page.width) {
31
+ // path from left to right
32
+ start.x -= offsetStart;
33
+ p1.x -= offsetStart + horizontalMargin;
34
+
35
+ }
36
+ else {
37
+ // path from right to left
38
+ start.x += offsetStart;
39
+ p1.x += offsetStart + horizontalMargin;
40
+ }
41
+
42
+ if (deltaX === 0 && deltaY === 0) {
43
+ p1 = p2 = end = start;
44
+ }
45
+ else {
46
+ if (deltaX < -options.page.width) {
47
+ // path from right to left
48
+ end.x -= offsetEnd;
49
+ p2.x -= offsetEnd + horizontalMargin;
50
+ }
51
+ else {
52
+ // path from left to right
53
+ p2.x += offsetEnd + horizontalMargin;
54
+ end.x += offsetEnd;
55
+ }
56
+ }
57
+
58
+ return {
59
+ start: start,
60
+ p1: p1,
61
+ p2: p2,
62
+ end: end
63
+ };
64
+ };
@@ -0,0 +1,49 @@
1
+ pageflow.sitemap.successorPath = function(d) {
2
+ var points = sitemap.successorPath.points(d);
3
+
4
+ var p = [points.start, points.p1, points.p2, points.end].map(function(d) {
5
+ return [d.x, d.y];
6
+ });
7
+
8
+ return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
9
+ };
10
+
11
+ pageflow.sitemap.successorPath.points = function(d) {
12
+ var deltaX = d.source.x - d.target.x;
13
+ var deltaY = d.source.y - d.target.y;
14
+
15
+ var start = { x: d.source.x, y: d.source.y},
16
+ p1 = { x: d.source.x, y: d.source.y + 40},
17
+ p2 = { x: d.target.x, y: d.target.y - 40},
18
+ end = { x: d.target.x, y: d.target.y};
19
+
20
+ var offsetStart = d.source.height - pageflow.sitemap.settings.page.height / 2 - 25,
21
+ offsetEnd = d.target.height / 2 + pageflow.sitemap.settings.arrowSize;
22
+
23
+ start.y += offsetStart;
24
+ p1.y += offsetStart;
25
+
26
+ if (deltaX === 0 && deltaY === 0) {
27
+ p1 = p2 = end = start;
28
+ }
29
+ else {
30
+ end.y -= offsetEnd;
31
+ p2.y -= offsetEnd;
32
+
33
+ if (deltaX > 0) {
34
+ end.x += 15;
35
+ p2.x += 15;
36
+ }
37
+ else {
38
+ end.x -= 15;
39
+ p2.x -= 15;
40
+ }
41
+ }
42
+
43
+ return {
44
+ start: start,
45
+ p1: p1,
46
+ p2: p2,
47
+ end: end
48
+ };
49
+ };
@@ -0,0 +1,33 @@
1
+ pageflow.sitemap.utils = {
2
+ size: function(selection, w, h) {
3
+ selection
4
+ .attr('width', w)
5
+ .attr('height', h);
6
+ },
7
+
8
+ translate: function(x, y) {
9
+ return 'translate(' + x + ',' + y + ')';
10
+ },
11
+
12
+ fn: {
13
+ d: function(property) {
14
+ return function(d) {
15
+ return d[property];
16
+ };
17
+ },
18
+
19
+ translate: function(x, y) {
20
+ return function(d) {
21
+ return 'translate(' + d[x] + ',' + d[y] + ')';
22
+ };
23
+ },
24
+
25
+ trigger: function(fn) {
26
+ return function(d) {
27
+ if (typeof fn === 'function') {
28
+ fn.apply(this, arguments);
29
+ }
30
+ };
31
+ }
32
+ }
33
+ };