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,52 @@
1
+ describe('pageflow.sitemap.SelectioNavigator', function() {
2
+ var s = pageflow.sitemap;
3
+
4
+ describe('on select:chapters', function() {
5
+ it('navigates to chapter if only one is selected', function() {
6
+ var api = {navigate: sinon.spy()};
7
+ var selection = new s.Selection();
8
+ var selectionNavigator = new s.SelectionNavigator({
9
+ api: api,
10
+ selection: selection
11
+ });
12
+ var chapter = new Backbone.Model({id: 6});
13
+
14
+ selectionNavigator.attach();
15
+ selection.select('chapters', [chapter]);
16
+
17
+ expect(api.navigate).to.have.been.calledWith('/chapters/6', {trigger: true});
18
+ });
19
+
20
+ it('navigates to multiSelectionPath if more than one is selected', function() {
21
+ var api = {navigate: sinon.spy()};
22
+ var selection = new s.Selection();
23
+ var selectionNavigator = new s.SelectionNavigator({
24
+ api: api,
25
+ selection: selection,
26
+ multiSelectionPath: '/multi'
27
+ });
28
+ var chapter0 = new Backbone.Model({id: 6});
29
+ var chapter1 = new Backbone.Model({id: 7});
30
+
31
+ selectionNavigator.attach();
32
+ selection.select('chapters', [chapter0, chapter1]);
33
+
34
+ expect(api.navigate).to.have.been.calledWith('/multi', {trigger: true});
35
+ });
36
+
37
+ it('navigates to emptySelectionPath if more than one is selected', function() {
38
+ var api = {navigate: sinon.spy()};
39
+ var selection = new s.Selection();
40
+ var selectionNavigator = new s.SelectionNavigator({
41
+ api: api,
42
+ selection: selection,
43
+ emptySelectionPath: '/none'
44
+ });
45
+
46
+ selectionNavigator.attach();
47
+ selection.select('chapters', []);
48
+
49
+ expect(api.navigate).to.have.been.calledWith('/none', {trigger: true});
50
+ });
51
+ });
52
+ });
@@ -0,0 +1,99 @@
1
+ describe('pageflow.sitemap.layout.Collision', function() {
2
+ var s = pageflow.sitemap;
3
+ var l = pageflow.sitemap.layout;
4
+ var f = support.factories;
5
+
6
+ describe('#pagesGroupedByDragTargetChapters', function() {
7
+ it('moves selected pages above drag target page', function() {
8
+ var sourceChapter = f.chapter();
9
+ var targetChapter = f.chapter();
10
+ var draggedPage = f.page(sourceChapter);
11
+ var otherSourcePage = f.page(sourceChapter);
12
+ var targetPage = f.page(targetPage);
13
+ var selection = new s.Selection({pages: [draggedPage]});
14
+
15
+ var draggedLayout = {
16
+ draggedPages: [draggedPage],
17
+ position: sinon.stub().returns({x: 110, y: 200}),
18
+ };
19
+
20
+ var targetLayout = {
21
+ isAbovePage: sinon.stub().returns(false),
22
+
23
+ isBelowChapter: sinon.stub().returns(false),
24
+
25
+ pagesGroupedByChapters: [
26
+ {
27
+ chapter: sourceChapter,
28
+ pages: [otherSourcePage]
29
+ },
30
+ {
31
+ chapter: targetChapter,
32
+ pages: [targetPage]
33
+ }
34
+ ]
35
+ };
36
+ targetLayout.isAbovePage.withArgs(targetPage, {x: 110, y: 200}).returns(true);
37
+
38
+ var collision = new l.Collision(draggedLayout, targetLayout);
39
+ var result = collision.pagesGroupedByDragTargetChapters();
40
+
41
+ expect(result).to.deep.eq([
42
+ {
43
+ chapter: sourceChapter,
44
+ pages: [otherSourcePage]
45
+ },
46
+ {
47
+ chapter: targetChapter,
48
+ pages: [draggedPage, targetPage]
49
+ },
50
+ ]);
51
+ });
52
+
53
+ it('moves selected pages to end of drag target chapter', function() {
54
+ var sourceChapter = f.chapter();
55
+ var targetChapter = f.chapter();
56
+ var draggedPage = f.page(sourceChapter);
57
+ var otherSourcePage = f.page(sourceChapter);
58
+ var targetPage = f.page(targetPage);
59
+ var selection = new s.Selection({pages: [draggedPage]});
60
+
61
+ var draggedLayout = {
62
+ draggedPages: [draggedPage],
63
+ position: sinon.stub().returns({x: 110, y: 200}),
64
+ };
65
+
66
+ var targetLayout = {
67
+ isAbovePage: sinon.stub().returns(false),
68
+
69
+ isBelowChapter: sinon.stub().returns(false),
70
+
71
+ pagesGroupedByChapters: [
72
+ {
73
+ chapter: sourceChapter,
74
+ pages: [otherSourcePage]
75
+ },
76
+ {
77
+ chapter: targetChapter,
78
+ pages: [targetPage]
79
+ }
80
+ ]
81
+ };
82
+ targetLayout.isBelowChapter.withArgs(targetChapter, {x: 110, y: 200}).returns(true);
83
+
84
+ var collision = new l.Collision(draggedLayout, targetLayout);
85
+ var result = collision.pagesGroupedByDragTargetChapters();
86
+
87
+ expect(result).to.deep.eq([
88
+ {
89
+ chapter: sourceChapter,
90
+ pages: [otherSourcePage]
91
+ },
92
+ {
93
+ chapter: targetChapter,
94
+ pages: [targetPage, draggedPage]
95
+ },
96
+ ]);
97
+ });
98
+ });
99
+ });
@@ -0,0 +1,114 @@
1
+ describe('pageflow.sitemap.layout.DraggingDecorator', function() {
2
+ var s = pageflow.sitemap;
3
+ var l = pageflow.sitemap.layout;
4
+ var f = support.factories;
5
+
6
+ var options = {rowHeight: 100, laneWidth: 100};
7
+
8
+ describe('#position', function() {
9
+ it('returns translated position if dragged', function() {
10
+ var chapter = f.chapter();
11
+ var selection = new s.Selection();
12
+ var layout = {
13
+ position: sinon.stub().returns({x: 100, y: 200})
14
+ };
15
+ var draggingLayout = new l.DraggingDecorator(selection,
16
+ layout,
17
+ layout,
18
+ {delta: {x: 10, y: 15}});
19
+
20
+ selection.select('chapters', [chapter]);
21
+ var pos = draggingLayout.position(chapter);
22
+
23
+ expect(pos).to.deep.eq({x: 110, y: 215});
24
+ });
25
+
26
+ it('returns untranslated position if not dragged', function() {
27
+ var chapter = f.chapter();
28
+ var selection = new s.Selection();
29
+ var layout = {
30
+ position: sinon.stub().returns({x: 100, y: 200})
31
+ };
32
+ var draggingLayout = new l.DraggingDecorator(selection,
33
+ layout,
34
+ layout,
35
+ {delta: {x: 10, y: 15}});
36
+
37
+ var pos = draggingLayout.position(chapter);
38
+
39
+ expect(pos).to.deep.eq({x: 100, y: 200});
40
+ });
41
+ });
42
+
43
+ describe('#draggedPages', function() {
44
+ it('contains selected pages if dragging', function() {
45
+ var page = f.page();
46
+ var selection = new s.Selection({pages: [page]});
47
+ var layout = {};
48
+
49
+ var draggingLayout = new l.DraggingDecorator(selection,
50
+ layout,
51
+ layout,
52
+ {delta: {x: 10, y: 15}});
53
+
54
+ expect(draggingLayout.draggedPages).to.deep.eq([page]);
55
+ });
56
+
57
+ it('is empty if not dragging', function() {
58
+ var page = f.page();
59
+ var selection = new s.Selection({pages: [page]});
60
+ var layout = {};
61
+
62
+ var draggingLayout = new l.DraggingDecorator(selection,
63
+ layout,
64
+ layout,
65
+ {});
66
+
67
+ expect(draggingLayout.draggedPages).to.deep.eq([]);
68
+ });
69
+ });
70
+
71
+ describe('#pagesGroupedByChapters', function() {
72
+ it('delegates to wrapped layout', function() {
73
+ var page = f.page();
74
+ var selection = new s.Selection({pages: [page]});
75
+ var groups = [];
76
+ var layout = {
77
+ pagesGroupedByChapters: groups
78
+ };
79
+
80
+ var draggingLayout = new l.DraggingDecorator(selection,
81
+ layout,
82
+ layout,
83
+ {delta: {x: 10, y: 15}});
84
+
85
+ expect(draggingLayout.pagesGroupedByChapters).to.eq(groups);
86
+ });
87
+ });
88
+
89
+ describe('#nonDraggedPagesGroupedByChapters', function() {
90
+ it('filters out dragged pages', function() {
91
+ var chapter = f.chapter();
92
+ var page0 = f.page(chapter);
93
+ var page1 = f.page(chapter);
94
+ var selection = new s.Selection({pages: [page1]});
95
+ var groups = [{
96
+ chapter: chapter,
97
+ pages: [page0, page1]
98
+ }];
99
+ var layout = {
100
+ pagesGroupedByChapters: groups
101
+ };
102
+
103
+ var draggingLayout = new l.DraggingDecorator(selection,
104
+ layout,
105
+ layout,
106
+ {delta: {x: 10, y: 15}});
107
+
108
+ expect(draggingLayout.nonDraggedPagesGroupedByChapters).to.deep.eq([{
109
+ chapter: chapter,
110
+ pages: [page0]
111
+ }]);
112
+ });
113
+ });
114
+ });
@@ -0,0 +1,183 @@
1
+ describe('pageflow.sitemap.layout.Grid', function() {
2
+ var l = pageflow.sitemap.layout;
3
+ var f = support.factories;
4
+
5
+ var options = {
6
+ pageHeight: 60,
7
+ pageWidth: 60,
8
+ pageMarginWidth: 20,
9
+ pageMarginHeight: 20
10
+ };
11
+
12
+ describe('#position', function() {
13
+ it('returns storyline position accoring to coordinates', function() {
14
+ var storyline = f.storyline(f.entry(), {configuration: {row: 2, lane: 1}});
15
+ var chaptersGroupedByStorylines = [{
16
+ storyline: storyline,
17
+ chapters: []
18
+ }];
19
+ var pagesGroupedByChapters = [];
20
+ var gridLayout = new l.Grid(chaptersGroupedByStorylines, pagesGroupedByChapters, options);
21
+
22
+ var pos = gridLayout.position(storyline);
23
+
24
+ expect(pos).to.deep.eq({x: 100, y: 200});
25
+ });
26
+
27
+ it('returns chapter position accoring to storyline position', function() {
28
+ var storyline = f.storyline(f.entry(), {configuration: {row: 2, lane: 1}});
29
+ var chapter1 = f.chapter(storyline);
30
+ var chapter2 = f.chapter(storyline);
31
+ var chaptersGroupedByStorylines = [{
32
+ storyline: storyline,
33
+ chapters: [chapter1, chapter2]
34
+ }];
35
+ var pagesGroupedByChapters = [
36
+ {chapter: chapter1, pages: []},
37
+ {chapter: chapter2, pages: []}
38
+ ];
39
+ var gridLayout = new l.Grid(chaptersGroupedByStorylines, pagesGroupedByChapters, options);
40
+
41
+ var pos1 = gridLayout.position(chapter1);
42
+ var pos2 = gridLayout.position(chapter2);
43
+
44
+ expect(pos1).to.deep.eq({x: 100, y: 200});
45
+ expect(pos2).to.deep.eq({x: 100, y: 300});
46
+ });
47
+
48
+ xit('returns page position according to chapter coordinates', function() {
49
+ var chapter = f.chapter(f.entry(), {configuration: {row: 2, lane: 1}});
50
+ var page1 = f.page(chapter);
51
+ var page2 = f.page(chapter);
52
+ var gridLayout = new l.Grid([
53
+ {
54
+ chapter: chapter,
55
+ pages: [page1, page2]
56
+ }
57
+ ], options);
58
+
59
+ var pos1 = gridLayout.position(page1);
60
+ var pos2 = gridLayout.position(page2);
61
+
62
+ expect(pos1).to.deep.eq({x: 100, y: 200});
63
+ expect(pos2).to.deep.eq({x: 100, y: 300});
64
+ });
65
+ });
66
+
67
+ xdescribe('#chapterHeight', function() {
68
+ it('returns height of chapter', function() {
69
+ var chapter = f.chapter(f.entry(), {configuration: {row: 2, lane: 1}});
70
+ var page1 = f.page(chapter);
71
+ var page2 = f.page(chapter);
72
+ var gridLayout = new l.Grid([
73
+ {
74
+ chapter: chapter,
75
+ pages: [page1, page2]
76
+ }
77
+ ], options);
78
+
79
+ var height = gridLayout.chapterHeight(chapter);
80
+
81
+ expect(height).to.eq(60 + 20 + 20 + 60);
82
+ });
83
+ });
84
+
85
+ xdescribe('#isAbovePage', function() {
86
+ it('returns true if position is centered above page', function() {
87
+ var chapter = f.chapter(f.entry(), {configuration: {row: 2, lane: 1}});
88
+ var page = f.page(chapter);
89
+ var gridLayout = new l.Grid([
90
+ {
91
+ chapter: chapter,
92
+ pages: [page]
93
+ }
94
+ ], options);
95
+
96
+ var result = gridLayout.isAbovePage(page, {x: 100, y: 190});
97
+
98
+ expect(result).to.eq(true);
99
+ });
100
+
101
+ it('returns false if position is in lower half of page', function() {
102
+ var chapter = f.chapter(f.entry(), {configuration: {row: 2, lane: 1}});
103
+ var page = f.page(chapter);
104
+ var gridLayout = new l.Grid([
105
+ {
106
+ chapter: chapter,
107
+ pages: [page]
108
+ }
109
+ ], options);
110
+
111
+ var result = gridLayout.isAbovePage(page, {x: 100, y: 260});
112
+
113
+ expect(result).to.eq(false);
114
+ });
115
+ });
116
+
117
+ xdescribe('#isBelowChapter', function() {
118
+ it('returns true if position is centered below chapter', function() {
119
+ var chapter = f.chapter(f.entry(), {configuration: {row: 2, lane: 1}});
120
+ var page = f.page(chapter);
121
+ var gridLayout = new l.Grid([
122
+ {
123
+ chapter: chapter,
124
+ pages: [page]
125
+ }
126
+ ], options);
127
+
128
+ var result = gridLayout.isBelowChapter(chapter, {x: 100, y: 200 + 60 + 20});
129
+
130
+ expect(result).to.eq(true);
131
+ });
132
+
133
+ it('returns false if position is too far up inside the chapter', function() {
134
+ var chapter = f.chapter(f.entry(), {configuration: {row: 2, lane: 1}});
135
+ var page = f.page(chapter);
136
+ var gridLayout = new l.Grid([
137
+ {
138
+ chapter: chapter,
139
+ pages: [page]
140
+ }
141
+ ], options);
142
+
143
+ var result = gridLayout.isBelowChapter(chapter, {x: 100, y: 200 + 20});
144
+
145
+ expect(result).to.eq(false);
146
+ });
147
+ });
148
+
149
+ xdescribe('#laneAndRowFromPoint', function() {
150
+ it('maps point to row and lane', function() {
151
+ var gridLayout = new l.Grid([], options);
152
+
153
+ var result = gridLayout.laneAndRowFromPoint({x: 0, y: 100});
154
+
155
+ expect(result).to.deep.eql({lane: 0, row: 1});
156
+ });
157
+ });
158
+
159
+ xdescribe('#size', function() {
160
+ it('returns width and height of all pages', function() {
161
+ var chapter1 = f.chapter(f.entry(), {configuration: {row: 1, lane: 0}});
162
+ var page11 = f.page(chapter1);
163
+ var page12 = f.page(chapter1);
164
+ var page13 = f.page(chapter1);
165
+ var chapter2 = f.chapter(f.entry(), {configuration: {row: 0, lane: 2}});
166
+ var page21 = f.page(chapter2);
167
+ var gridLayout = new l.Grid([
168
+ {
169
+ chapter: chapter1,
170
+ pages: [page11, page12, page13]
171
+ },
172
+ {
173
+ chapter: chapter2,
174
+ pages: [page11]
175
+ }
176
+ ], options);
177
+
178
+ var result = gridLayout.size;
179
+
180
+ expect(result).to.deep.eq({x: 300, y: 400});
181
+ });
182
+ });
183
+ });
@@ -0,0 +1,31 @@
1
+ describe('pageflow.sitemap.layout', function() {
2
+ var s = pageflow.sitemap;
3
+ var f = support.factories;
4
+
5
+ describe('.create', function() {
6
+ it('creates a layout', function() {
7
+ var entry = f.entry();
8
+ var chapter = f.chapter(entry, {configuration: {lane: 0, row: 0}});
9
+ var otherChapter = f.chapter(entry, {configuration: {lane: 1, row: 0}});
10
+ var page = f.page(chapter);
11
+ var draggedPage = f.page(otherChapter);
12
+ var selection = new s.Selection({pages: [draggedPage]});
13
+
14
+ var layout = s.layout.create(entry, selection, {
15
+ dragDelta: {
16
+ x: 10,
17
+ y: 20
18
+ },
19
+ grid: {
20
+ pageHeight: 60,
21
+ pageWidth: 60,
22
+ pageMarginWidth: 20,
23
+ pageMarginHeight: 20,
24
+ }
25
+ });
26
+
27
+ expect(layout.position(page)).to.deep.eq({x: 0, y: 0});
28
+ expect(layout.position(draggedPage)).to.deep.eq({x: 110, y: 20});
29
+ });
30
+ });
31
+ });
@@ -0,0 +1,56 @@
1
+ //describe('pageflow.sitemap.ViewModel', function() {
2
+ // var f = support.factories;
3
+ // var p = pageflow;
4
+ // var s = window.sitemap;
5
+ //
6
+ // it('sets selected property on pages from selection', function() {
7
+ // var entry = f.entry();
8
+ // var chapter = f.chapter(entry);
9
+ // var page = f.page(chapter);
10
+ // var selection = new s.Selection();
11
+ //
12
+ // selection.select('pages', [page]);
13
+ // var viewModel = new s.ViewModel(entry, selection);
14
+ //
15
+ // expect(viewModel.pages[0].selected).to.eq(true);
16
+ // });
17
+ //
18
+ // it('applies dragDx and dragDy to selected page', function() {
19
+ // var entry = f.entry();
20
+ // var chapter = f.chapter(entry);
21
+ // var page = f.page(chapter);
22
+ // var selection = new s.Selection();
23
+ //
24
+ // selection.select('pages', [page]);
25
+ // var viewModel = new s.ViewModel(entry, selection, {dragDx: 10, dragDy: 10});
26
+ //
27
+ // expect(viewModel.pages[0].x).to.eq(10);
28
+ // expect(viewModel.pages[0].y).to.eq(10);
29
+ // });
30
+ //
31
+ // it('does not apply dragDx and dragDy to unselected page', function() {
32
+ // var entry = f.entry();
33
+ // var chapter = f.chapter(entry);
34
+ // var page = f.page(chapter);
35
+ // var selection = new s.Selection();
36
+ //
37
+ // var viewModel = new s.ViewModel(entry, selection, {dragDx: 10, dragDy: 10});
38
+ //
39
+ // expect(viewModel.pages[0].x).to.eq(0);
40
+ // expect(viewModel.pages[0].y).to.eq(0);
41
+ // });
42
+ //
43
+ // describe('chapters[].virtualPages', function() {
44
+ // it('contains non selected pages of chapter', function() {
45
+ // var entry = f.entry();
46
+ // var chapter = f.chapter(entry, {configuration: {lane: 1, row: 1}});
47
+ // var otherChapter = f.chapter(entry, {configuration: {lane: 2, row: 1}});
48
+ // var page = f.page(chapter);
49
+ // var selection = new s.Selection();
50
+ //
51
+ // var viewModel = new s.ViewModel(entry, selection);
52
+ //
53
+ // expect(viewModel.chapters[0].virtualPages).to.deep.eq([page]);
54
+ // });
55
+ // });
56
+ //});
@@ -0,0 +1,62 @@
1
+ describe('pageflow.sitemap.Selection', function() {
2
+ var s = pageflow.sitemap;
3
+
4
+ describe('#contains', function() {
5
+ it('returns true if page is selected', function() {
6
+ var selection = new s.Selection();
7
+ var page = {};
8
+
9
+ selection.select('pages', [page]);
10
+
11
+ expect(selection.contains(page)).to.eq(true);
12
+ });
13
+ });
14
+
15
+ describe('#select', function() {
16
+ it('resets previous selection', function() {
17
+ var selection = new s.Selection();
18
+ var page = {};
19
+ var chapter = {};
20
+
21
+ selection.select('pages', [page]);
22
+ selection.select('chapters', [chapter]);
23
+
24
+ expect(selection.get('pages')).to.deep.eq([]);
25
+ });
26
+
27
+ it('triggers select:<name> event', function() {
28
+ var selection = new s.Selection();
29
+ var page = {};
30
+ var handler = sinon.spy();
31
+
32
+ selection.on('select:pages', handler);
33
+ selection.select('pages', [page]);
34
+
35
+ expect(handler).to.have.been.calledWith([page]);
36
+ });
37
+
38
+ describe('with additive option', function() {
39
+ it('adds model of same type', function() {
40
+ var selection = new s.Selection();
41
+ var page0 = {};
42
+ var page1 = {};
43
+
44
+ selection.select('pages', [page0]);
45
+ selection.select('pages', [page1], {additive: true});
46
+
47
+ expect(selection.get('pages')).to.deep.eq([page0, page1]);
48
+ });
49
+
50
+ it('resets previous selection of other type', function() {
51
+ var selection = new s.Selection();
52
+ var page = {};
53
+ var chapter = {};
54
+
55
+ selection.select('chapters', [chapter]);
56
+ selection.select('pages', [page], {additive: true});
57
+
58
+ expect(selection.get('chapters')).to.deep.eq([]);
59
+ });
60
+ });
61
+ });
62
+ });
@@ -0,0 +1,5 @@
1
+ describe('pageflow.sitemap.ScrollNavigator', function() {
2
+ describe('#back', function() {
3
+
4
+ });
5
+ });
@@ -0,0 +1,13 @@
1
+ //= require support/sinon
2
+ //= require support/chai
3
+ //= require support/sinon-chai
4
+
5
+ //= require pageflow/base
6
+ //= require pageflow/editor/base
7
+ //= require pageflow/sitemap/editor
8
+
9
+ //= require_self
10
+ //= require support/factories
11
+
12
+ window.support = {};
13
+ window.expect = chai.expect;
@@ -0,0 +1,81 @@
1
+ support.factories = {
2
+ entry: function(attributes) {
3
+ var entry = new Backbone.Model(attributes);
4
+
5
+ entry.storylines = new pageflow.StorylinesCollection();
6
+ entry.chapters = new pageflow.ChaptersCollection();
7
+ entry.pages = new pageflow.PagesCollection();
8
+
9
+ return entry;
10
+ },
11
+
12
+ storyline: function(entry, attributes) {
13
+ entry = entry || this.entry();
14
+
15
+ attributes = attributes || {};
16
+ attributes.id = _.uniqueId();
17
+
18
+ var storyline = new Backbone.Model(_(attributes).omit('configuration'));
19
+
20
+ storyline.configuration = new Backbone.Model(attributes.configuration);
21
+ storyline.chapter = new pageflow.StorylineChaptersCollection({
22
+ chapters: entry.chapters,
23
+ storyline: storyline
24
+ });
25
+
26
+ entry.storylines.add(storyline);
27
+
28
+ return storyline;
29
+ },
30
+
31
+ chapter: function(entry, storyline, attributes) {
32
+ storyline = storyline || this.storyline();
33
+
34
+ attributes = attributes || {};
35
+ attributes.id = _.uniqueId();
36
+
37
+ var chapter = new Backbone.Model(_(attributes).omit('configuration'));
38
+
39
+ chapter.configuration = new Backbone.Model(attributes.configuration);
40
+ chapter.pages = new pageflow.ChapterPagesCollection({
41
+ pages: entry.pages,
42
+ chapter: chapter
43
+ });
44
+
45
+ entry.chapters.add(chapter);
46
+
47
+ return chapter;
48
+ },
49
+
50
+ page: function(chapter, attributes) {
51
+ chapter = chapter || this.chapter();
52
+
53
+ attributes = attributes || {};
54
+ attributes.id = _.uniqueId();
55
+ attributes.chapter_id = chapter.id;
56
+
57
+ var page = new Backbone.Model(_(attributes).omit('configuration'));
58
+
59
+ page.configuration = new Backbone.Model(attributes.configuration);
60
+ page.pageLinks = function() {
61
+ return support.factories.pageLinks();
62
+ };
63
+ page.chapterPosition = function() {
64
+ return chapter.get('position');
65
+ };
66
+
67
+ chapter.pages.add(page);
68
+
69
+ return page;
70
+ },
71
+
72
+ pageLinks: function() {
73
+ var pageLinks = new Backbone.Collection();
74
+
75
+ pageLinks.canAddLink = function() {
76
+ return false;
77
+ };
78
+
79
+ return pageLinks;
80
+ }
81
+ };