pageflow-sitemap 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +25 -0
- data/.jshintrc +18 -0
- data/Gemfile +24 -0
- data/LICENSE.md +20 -0
- data/README.md +47 -0
- data/Rakefile +32 -0
- data/app/assets/images/pageflow/sitemap/.keep +0 -0
- data/app/assets/javascripts/pageflow/sitemap/.keep +0 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/controllers/abstract_controller.js +68 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/controllers/editor_mode_controller.js +301 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/controllers/fragment_parser.js +31 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/controllers/selection_mode_controller.js +37 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/controllers/selection_navigator.js +43 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/mouse_wheel.js +43 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/multi_drag.js +73 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/scroll_and_zoom.js +286 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/selection_rect.js +104 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/tooltip_target.js +24 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/graph_view.js +277 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/chapter_collision.js +33 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/collision.js +116 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/dragging_decorator.js +58 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/grid.js +238 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/link_dragging_decorator.js +42 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout.js +94 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/options.js +25 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/follow_path.js +36 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/linkpath.js +64 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/successor_path.js +49 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/utils.js +33 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/view_model.js +202 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/add_button_view.js +28 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/chapter_placeholders_view.js +22 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/chapters_view.js +89 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/group_view.js +104 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/page_links_view.js +7 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/pages_view.js +112 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/selectable_links_view.js +104 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/storylines_view.js +86 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/successor_links_view.js +7 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/text_label_view.js +45 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/d3.js +20 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/feature.js +126 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/models/selection.js +41 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/templates/scroll_bar.jst.ejs +2 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/templates/sitemap.jst.ejs +85 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/views/scroll_bar_view.js +130 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/views/scroll_pane_view.js +73 -0
- data/app/assets/javascripts/pageflow/sitemap/editor/views/sitemap_view.js +137 -0
- data/app/assets/javascripts/pageflow/sitemap/editor.js +14 -0
- data/app/assets/javascripts/pageflow/sitemap/feature.js +3 -0
- data/app/assets/javascripts/pageflow/sitemap/scroll_navigator.js +112 -0
- data/app/assets/javascripts/pageflow/sitemap.js +5 -0
- data/app/assets/stylesheets/pageflow/sitemap/.keep +0 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/add_button.scss +29 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/chapter_placeholders.scss +14 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/chapters.scss +62 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/page_links.scss +19 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/pages.scss +78 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/scroll_bar.css.scss +33 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/scroll_pane.scss +15 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/selectable_links.scss +88 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/selection_rect.scss +12 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/storylines.scss +59 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/successor_links.scss +42 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/text_label.scss +23 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor/toolbar.css.scss +45 -0
- data/app/assets/stylesheets/pageflow/sitemap/editor.css.scss +96 -0
- data/config/locales/de.yml +16 -0
- data/config/locales/en.yml +48 -0
- data/config/locales/new/help_button.de.yml +7 -0
- data/config/locales/new/help_button.en.yml +7 -0
- data/config/locales/new/tooltips.de.yml +11 -0
- data/config/locales/new/tooltips.en.yml +11 -0
- data/config/routes.rb +7 -0
- data/config/spring.rb +1 -0
- data/exec/rails +12 -0
- data/exec/spring +18 -0
- data/exec/teaspoon +17 -0
- data/lib/pageflow/sitemap/engine.rb +10 -0
- data/lib/pageflow/sitemap/plugin.rb +11 -0
- data/lib/pageflow/sitemap/version.rb +5 -0
- data/lib/pageflow-sitemap.rb +9 -0
- data/pageflow-sitemap.gemspec +29 -0
- data/spec/d/r/.gitignore +16 -0
- data/spec/d/r/README.rdoc +28 -0
- data/spec/d/r/Rakefile +6 -0
- data/spec/d/r/app/admin/dashboard.rb +33 -0
- data/spec/d/r/app/assets/images/.keep +0 -0
- data/spec/d/r/app/assets/javascripts/active_admin.js.coffee +2 -0
- data/spec/d/r/app/assets/javascripts/application.js +16 -0
- data/spec/d/r/app/assets/javascripts/pageflow/application.js +1 -0
- data/spec/d/r/app/assets/javascripts/pageflow/editor.js +4 -0
- data/spec/d/r/app/assets/stylesheets/active_admin.css.scss +18 -0
- data/spec/d/r/app/assets/stylesheets/application.css +13 -0
- data/spec/d/r/app/assets/stylesheets/pageflow/application.css.scss +1 -0
- data/spec/d/r/app/assets/stylesheets/pageflow/editor.css.scss +1 -0
- data/spec/d/r/app/controllers/application_controller.rb +5 -0
- data/spec/d/r/app/controllers/concerns/.keep +0 -0
- data/spec/d/r/app/helpers/application_helper.rb +2 -0
- data/spec/d/r/app/mailers/.keep +0 -0
- data/spec/d/r/app/models/.keep +0 -0
- data/spec/d/r/app/models/ability.rb +12 -0
- data/spec/d/r/app/models/concerns/.keep +0 -0
- data/spec/d/r/app/models/user.rb +9 -0
- data/spec/d/r/app/views/layouts/application.html.erb +14 -0
- data/spec/d/r/bin/bundle +3 -0
- data/spec/d/r/bin/rails +4 -0
- data/spec/d/r/bin/rake +4 -0
- data/spec/d/r/config/application.rb +31 -0
- data/spec/d/r/config/boot.rb +4 -0
- data/spec/d/r/config/database.yml +39 -0
- data/spec/d/r/config/environment.rb +5 -0
- data/spec/d/r/config/environments/development.rb +29 -0
- data/spec/d/r/config/environments/production.rb +80 -0
- data/spec/d/r/config/environments/test.rb +37 -0
- data/spec/d/r/config/initializers/active_admin.rb +225 -0
- data/spec/d/r/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/d/r/config/initializers/devise.rb +252 -0
- data/spec/d/r/config/initializers/devise_async.rb +6 -0
- data/spec/d/r/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/d/r/config/initializers/friendly_id.rb +88 -0
- data/spec/d/r/config/initializers/inflections.rb +16 -0
- data/spec/d/r/config/initializers/mime_types.rb +5 -0
- data/spec/d/r/config/initializers/pageflow.rb +76 -0
- data/spec/d/r/config/initializers/resque.rb +4 -0
- data/spec/d/r/config/initializers/resque_enqueue_after_commit_patch.rb +25 -0
- data/spec/d/r/config/initializers/resque_logger.rb +16 -0
- data/spec/d/r/config/initializers/resque_mailer.rb +4 -0
- data/spec/d/r/config/initializers/secret_token.rb +12 -0
- data/spec/d/r/config/initializers/session_store.rb +3 -0
- data/spec/d/r/config/initializers/wrap_parameters.rb +14 -0
- data/spec/d/r/config/locales/devise.en.yml +59 -0
- data/spec/d/r/config/locales/en.yml +23 -0
- data/spec/d/r/config/routes.rb +59 -0
- data/spec/d/r/config.ru +4 -0
- data/spec/d/r/db/migrate/00000000000000_create_test_hosted_file.rb +7 -0
- data/spec/d/r/db/migrate/00000000000001_create_test_revision_component.rb +10 -0
- data/spec/d/r/db/migrate/20150209101518_create_active_admin_comments.rb +19 -0
- data/spec/d/r/db/migrate/20150209101524_devise_create_users.rb +46 -0
- data/spec/d/r/db/migrate/20150209101530_create_friendly_id_slugs.rb +15 -0
- data/spec/d/r/db/migrate/20150209101540_setup_schema.pageflow.rb +208 -0
- data/spec/d/r/db/migrate/20150209101541_add_attributes_to_users.pageflow.rb +16 -0
- data/spec/d/r/db/migrate/20150209101542_create_themings.pageflow.rb +16 -0
- data/spec/d/r/db/migrate/20150209101543_create_themings_for_existing_accounts.pageflow.rb +27 -0
- data/spec/d/r/db/migrate/20150209101544_change_theme_references_to_theming_references.pageflow.rb +46 -0
- data/spec/d/r/db/migrate/20150209101545_remove_attributes_from_themes.pageflow.rb +11 -0
- data/spec/d/r/db/migrate/20150209101546_create_accounts_themes_join_table.pageflow.rb +9 -0
- data/spec/d/r/db/migrate/20150209101547_move_cname_from_account_to_theming.pageflow.rb +22 -0
- data/spec/d/r/db/migrate/20150209101548_drop_themes.pageflow.rb +15 -0
- data/spec/d/r/db/migrate/20150209101549_add_confirmed_by_to_encoded_files.pageflow.rb +7 -0
- data/spec/d/r/db/migrate/20150209101550_add_home_url_attributes_to_themings_and_revisions.pageflow.rb +10 -0
- data/spec/d/r/db/migrate/20150209101551_create_widgets.pageflow.rb +12 -0
- data/spec/d/r/db/migrate/20150209101552_add_emphasize_chapter_beginning_to_revisions.pageflow.rb +6 -0
- data/spec/d/r/db/migrate/20150209101553_add_emphasize_new_pages_to_revisions.pageflow.rb +6 -0
- data/spec/d/r/db/migrate/20150209101554_add_sharing_image_to_revisions.pageflow.rb +8 -0
- data/spec/d/r/db/schema.rb +316 -0
- data/spec/d/r/db/seeds.rb +30 -0
- data/spec/d/r/lib/assets/.keep +0 -0
- data/spec/d/r/lib/tasks/.keep +0 -0
- data/spec/d/r/lib/tasks/resque.rake +7 -0
- data/spec/d/r/public/404.html +58 -0
- data/spec/d/r/public/422.html +58 -0
- data/spec/d/r/public/500.html +57 -0
- data/spec/d/r/public/favicon.ico +0 -0
- data/spec/d/r/public/javascripts/translations.js +2 -0
- data/spec/d/r/public/robots.txt +5 -0
- data/spec/d/r/vendor/assets/javascripts/.keep +0 -0
- data/spec/d/r/vendor/assets/stylesheets/.keep +0 -0
- data/spec/javascripts/.jshintrc +26 -0
- data/spec/javascripts/pageflow/sitemap/editor/controllers/selection_navigator_spec.js +52 -0
- data/spec/javascripts/pageflow/sitemap/editor/d3/layout/collision_spec.js +99 -0
- data/spec/javascripts/pageflow/sitemap/editor/d3/layout/dragging_decorator_spec.js +114 -0
- data/spec/javascripts/pageflow/sitemap/editor/d3/layout/grid_spec.js +183 -0
- data/spec/javascripts/pageflow/sitemap/editor/d3/layout_spec.js +31 -0
- data/spec/javascripts/pageflow/sitemap/editor/d3/view_model_spec.js +56 -0
- data/spec/javascripts/pageflow/sitemap/editor/models/selection_spec.js +62 -0
- data/spec/javascripts/pageflow/sitemap/scroll_navigator_spec.js +5 -0
- data/spec/javascripts/spec_helper.js +13 -0
- data/spec/javascripts/support/factories.js +81 -0
- data/spec/teaspoon_env.rb +182 -0
- data/vendor/assets/javascripts/d3.v3.js +9215 -0
- metadata +379 -0
@@ -0,0 +1,202 @@
|
|
1
|
+
pageflow.sitemap.ViewModel = function(session, layout) {
|
2
|
+
var entry = session.entry;
|
3
|
+
var selection = session.selection;
|
4
|
+
var highlightedStoryline = session.highlightedStoryline;
|
5
|
+
var highlightedPage = session.highlightedPage;
|
6
|
+
var isPageDisabled = session.isPageDisabled || function() { return false; };
|
7
|
+
|
8
|
+
var storylines = this.storylines = [];
|
9
|
+
var chapters = this.chapters = [];
|
10
|
+
var nodes = this.nodes = this.pages = [];
|
11
|
+
var successorLinks = this.successorLinks = [];
|
12
|
+
var pageLinks = this.links = [];
|
13
|
+
var chapterPlaceholders = this.chapterPlaceholders = [];
|
14
|
+
var size = this.size = {x: 0, y: 0};
|
15
|
+
|
16
|
+
var nodesByName = {};
|
17
|
+
|
18
|
+
buildStorylines();
|
19
|
+
buildSuccessorLinks();
|
20
|
+
buildPageLinks();
|
21
|
+
buildChapterPlaceholders();
|
22
|
+
|
23
|
+
function buildStorylines() {
|
24
|
+
entry.storylines.each(function(storyline) {
|
25
|
+
storylines.push({
|
26
|
+
id: 'storyline:' + storyline.cid,
|
27
|
+
storyline: storyline,
|
28
|
+
|
29
|
+
title: storyline.title(),
|
30
|
+
|
31
|
+
main: storyline.isMain(),
|
32
|
+
selected: selection.contains(storyline),
|
33
|
+
dragged: layout.isDragging(storyline),
|
34
|
+
droppable: layout.isLegal(),
|
35
|
+
highlighted: highlightedStoryline === storyline,
|
36
|
+
|
37
|
+
x: layout.position(storyline).x,
|
38
|
+
y: layout.position(storyline).y,
|
39
|
+
height: layout.height(storyline)
|
40
|
+
});
|
41
|
+
|
42
|
+
buildChapters(storyline.chapters);
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
function buildChapters(chaptersCollection) {
|
47
|
+
chaptersCollection.each(function(chapter) {
|
48
|
+
var chapterNodes = [];
|
49
|
+
|
50
|
+
chapter.pages.each(function(page) {
|
51
|
+
var id = "page:" + page.cid;
|
52
|
+
|
53
|
+
var thumbnailFile = page.thumbnailFile();
|
54
|
+
|
55
|
+
var node = {
|
56
|
+
id: id,
|
57
|
+
|
58
|
+
page: page,
|
59
|
+
chapter: chapter,
|
60
|
+
|
61
|
+
pageCid: page.cid,
|
62
|
+
title: page.title() || I18n.t('pageflow.sitemap.editor.unnamed_page'),
|
63
|
+
thumbnailUrl: thumbnailFile ? thumbnailFile.get('link_thumbnail_url') : '',
|
64
|
+
|
65
|
+
selected: selection.contains(page),
|
66
|
+
dragged: layout.isDragging(page),
|
67
|
+
highlighted: highlightedPage === page,
|
68
|
+
destroying: page.isDestroying() || chapter.isDestroying(),
|
69
|
+
disabled: isPageDisabled(page),
|
70
|
+
|
71
|
+
x0: layout.position(page).x,
|
72
|
+
y0: layout.position(page).y,
|
73
|
+
x: layout.position(page).x,
|
74
|
+
y: layout.position(page).y,
|
75
|
+
};
|
76
|
+
|
77
|
+
chapterNodes.push(node);
|
78
|
+
nodes.push(node);
|
79
|
+
|
80
|
+
nodesByName[page.cid] = node;
|
81
|
+
});
|
82
|
+
|
83
|
+
chapters.push({
|
84
|
+
id: 'group:' + chapter.cid,
|
85
|
+
chapter: chapter,
|
86
|
+
|
87
|
+
title: chapter.get('title') || I18n.t('pageflow.sitemap.editor.unnamed_chapter'),
|
88
|
+
|
89
|
+
selected: selection.contains(chapter),
|
90
|
+
dragged: layout.isDragging(chapter),
|
91
|
+
droppable: layout.isLegal(),
|
92
|
+
empty: chapterNodes.length === 0,
|
93
|
+
destroying: chapter.isDestroying(),
|
94
|
+
|
95
|
+
x: layout.position(chapter).x,
|
96
|
+
y: layout.position(chapter).y,
|
97
|
+
height: layout.chapterHeight(chapter)
|
98
|
+
});
|
99
|
+
});
|
100
|
+
}
|
101
|
+
|
102
|
+
function buildPageLinks() {
|
103
|
+
entry.pages.each(function(page) {
|
104
|
+
if (page.pageLinks()) {
|
105
|
+
page.pageLinks().each(function(link) {
|
106
|
+
var targetPage = link.targetPage();
|
107
|
+
|
108
|
+
if (targetPage) {
|
109
|
+
pageLinks.push({
|
110
|
+
id: 'link' + ':' + page.cid + '-' + targetPage.cid,
|
111
|
+
link: link,
|
112
|
+
links: page.pageLinks(),
|
113
|
+
sourcePage: page,
|
114
|
+
|
115
|
+
source: layout.linkSource(page),
|
116
|
+
target: layout.linkTarget(targetPage, link),
|
117
|
+
|
118
|
+
label: link.label(),
|
119
|
+
|
120
|
+
selected: selection.contains(link),
|
121
|
+
dragged: layout.isDragging(link),
|
122
|
+
placeholder: false
|
123
|
+
});
|
124
|
+
}
|
125
|
+
});
|
126
|
+
|
127
|
+
if (!page.isDestroying() && !page.chapter.isDestroying()) {
|
128
|
+
var link = {placeholder: page};
|
129
|
+
|
130
|
+
pageLinks.push({
|
131
|
+
id: 'dangling-link' + ':' + page.cid,
|
132
|
+
link: link,
|
133
|
+
links: page.pageLinks(),
|
134
|
+
sourcePage: page,
|
135
|
+
|
136
|
+
source: layout.linkSource(page),
|
137
|
+
target: layout.linkTarget(page, link),
|
138
|
+
|
139
|
+
selected: selection.contains(link),
|
140
|
+
dragged: layout.isDragging(link),
|
141
|
+
placeholder: true
|
142
|
+
});
|
143
|
+
}
|
144
|
+
}
|
145
|
+
});
|
146
|
+
}
|
147
|
+
|
148
|
+
function buildSuccessorLinks() {
|
149
|
+
entry.storylines.each(function(storyline) {
|
150
|
+
var successorPage = entry.pages.getByPermaId(storyline.configuration.get('scroll_successor_id'));
|
151
|
+
var link = {successor: storyline};
|
152
|
+
|
153
|
+
if (successorPage) {
|
154
|
+
successorLinks.push({
|
155
|
+
id: 'successor:' + storyline.cid + '-' + successorPage.cid,
|
156
|
+
storyline: storyline,
|
157
|
+
link: link,
|
158
|
+
|
159
|
+
source: layout.linkSource(storyline),
|
160
|
+
target: layout.linkTarget(successorPage, link),
|
161
|
+
|
162
|
+
selected: selection.contains(link),
|
163
|
+
dragged: layout.isDragging(link),
|
164
|
+
placeholder: false
|
165
|
+
});
|
166
|
+
}
|
167
|
+
else if (!storyline.isDestroying()) {
|
168
|
+
successorLinks.push({
|
169
|
+
id: 'dangling-successor:' + storyline.cid,
|
170
|
+
storyline: storyline,
|
171
|
+
link: link,
|
172
|
+
|
173
|
+
source: layout.linkSource(storyline),
|
174
|
+
target: layout.linkTarget(storyline, link),
|
175
|
+
|
176
|
+
selected: selection.contains(link),
|
177
|
+
dragged: layout.isDragging(link),
|
178
|
+
placeholder: true
|
179
|
+
});
|
180
|
+
}
|
181
|
+
});
|
182
|
+
}
|
183
|
+
|
184
|
+
function buildChapterPlaceholders() {
|
185
|
+
if (layout.chapterPlaceholder) {
|
186
|
+
chapterPlaceholders.push(_.extend({
|
187
|
+
id: 'chapter-placeholder'
|
188
|
+
}, layout.chapterPlaceholder));
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
function eachPair(collection, fn) {
|
193
|
+
if (collection.length < 2) {
|
194
|
+
return;
|
195
|
+
}
|
196
|
+
|
197
|
+
_.reduce(collection, function(last, item) {
|
198
|
+
fn(last, item);
|
199
|
+
return item;
|
200
|
+
});
|
201
|
+
}
|
202
|
+
};
|
@@ -0,0 +1,28 @@
|
|
1
|
+
pageflow.sitemap.addButtonView = pageflow.sitemap.groupView.define('add_button', function(s) {
|
2
|
+
this.update()
|
3
|
+
.attr('transform', s.utils.fn.translate('left', 'top'))
|
4
|
+
;
|
5
|
+
|
6
|
+
this.child('rect', function() {
|
7
|
+
this.enter()
|
8
|
+
.attr('width', s.utils.fn.d('width'))
|
9
|
+
.attr('height', s.utils.fn.d('height'))
|
10
|
+
.call(s.behavior.tooltipTarget(this.options.tooltipTranslationKey))
|
11
|
+
.on('mouseover', function() {
|
12
|
+
d3.select(this.parentNode).classed('hover', true);
|
13
|
+
})
|
14
|
+
.on('mouseout', function() {
|
15
|
+
d3.select(this.parentNode).classed('hover', false);
|
16
|
+
})
|
17
|
+
.on('click', s.utils.fn.trigger(this.options.click))
|
18
|
+
;
|
19
|
+
});
|
20
|
+
|
21
|
+
this.child('text', function() {
|
22
|
+
this.enter()
|
23
|
+
.attr('transform', function(d) {
|
24
|
+
return s.utils.translate(d.width / 2, d.height / 2);
|
25
|
+
})
|
26
|
+
.text("\u2795");
|
27
|
+
});
|
28
|
+
});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
sitemap.chapterPlaceholdersView = sitemap.groupView.define('chapter_placeholder', function(s) {
|
2
|
+
this.update()
|
3
|
+
.attr('transform', function(d) {
|
4
|
+
return s.utils.translate(d.x - d.width / 2, d.y - d.height / 2);
|
5
|
+
})
|
6
|
+
;
|
7
|
+
|
8
|
+
this.child('rect', function() {
|
9
|
+
this.update()
|
10
|
+
.attr('width', s.utils.fn.d('width'))
|
11
|
+
.attr('height', s.utils.fn.d('height'))
|
12
|
+
;
|
13
|
+
});
|
14
|
+
|
15
|
+
this.child('text', function() {
|
16
|
+
this.enter()
|
17
|
+
.attr('transform', function(d) {
|
18
|
+
return s.utils.translate(d.width / 2, d.height / 2);
|
19
|
+
})
|
20
|
+
.text('+');
|
21
|
+
});
|
22
|
+
});
|
@@ -0,0 +1,89 @@
|
|
1
|
+
/*global options*/
|
2
|
+
|
3
|
+
sitemap.chaptersView = sitemap.groupView.define('chapter', function(s) {
|
4
|
+
var opts = this.options;
|
5
|
+
|
6
|
+
var w = options.page.width + 20,
|
7
|
+
barHeight = 20;
|
8
|
+
|
9
|
+
this.update()
|
10
|
+
.classed('selected', s.utils.fn.d('selected'))
|
11
|
+
.classed('dragged', s.utils.fn.d('dragged'))
|
12
|
+
.classed('empty', s.utils.fn.d('empty'))
|
13
|
+
.classed('destroying', s.utils.fn.d('destroying'))
|
14
|
+
.attr('transform', function(d) {
|
15
|
+
return 'translate(' +
|
16
|
+
(d.x - options.page.width / 2 - 10) + ',' +
|
17
|
+
(d.y - options.page.height / 2 - 25) +
|
18
|
+
')';
|
19
|
+
})
|
20
|
+
;
|
21
|
+
|
22
|
+
this.child('rect.border', function() {
|
23
|
+
this.enter()
|
24
|
+
.attr('width', w)
|
25
|
+
;
|
26
|
+
|
27
|
+
this.update()
|
28
|
+
.attr('height', function (d) { var h = d.height + 35 + 13; return h > 0 ? h : 0; })
|
29
|
+
;
|
30
|
+
});
|
31
|
+
|
32
|
+
this.child('rect.handle', function() {
|
33
|
+
this.enter()
|
34
|
+
.attr('width', w)
|
35
|
+
.attr('height', barHeight)
|
36
|
+
.on('mouseover', function() {
|
37
|
+
d3.select(this.parentNode).classed('hover', true);
|
38
|
+
})
|
39
|
+
.on('mouseout', function() {
|
40
|
+
d3.select(this.parentNode).classed('hover', false);
|
41
|
+
})
|
42
|
+
.on('click', function() {
|
43
|
+
if (opts.clicked) {
|
44
|
+
opts.clicked.apply(this, arguments);
|
45
|
+
}
|
46
|
+
})
|
47
|
+
.on('mousedown', function() {
|
48
|
+
if (opts.mousedown) {
|
49
|
+
opts.mousedown.apply(this, arguments);
|
50
|
+
}
|
51
|
+
})
|
52
|
+
;
|
53
|
+
});
|
54
|
+
|
55
|
+
this.enter().call(sitemap.behavior.multiDrag({
|
56
|
+
drag: opts.drag,
|
57
|
+
dragend: opts.dragend
|
58
|
+
}));
|
59
|
+
|
60
|
+
this.enter()
|
61
|
+
.append('foreignObject')
|
62
|
+
.style('pointer-events', 'none')
|
63
|
+
.attr('width', w)
|
64
|
+
.attr('height', barHeight)
|
65
|
+
.append('xhtml:body')
|
66
|
+
.html('<div class="title_text"></div>')
|
67
|
+
;
|
68
|
+
|
69
|
+
this.update().each(function(d) {
|
70
|
+
d3.selectAll(this.getElementsByTagName('div'))
|
71
|
+
.text(d.title);
|
72
|
+
});
|
73
|
+
|
74
|
+
this.call(s.addButtonView(addChapterButtonData, {
|
75
|
+
tooltipTranslationKey: 'pageflow.sitemap.editor.tooltips.insert_chapter',
|
76
|
+
click: s.utils.fn.trigger(this.options.addChapterButtonClick)
|
77
|
+
}));
|
78
|
+
|
79
|
+
function addChapterButtonData(d) {
|
80
|
+
return [{
|
81
|
+
id: d.id + ':add_chapter',
|
82
|
+
chapter: d.chapter,
|
83
|
+
left: 0,
|
84
|
+
top: d.height + 38 + 11,
|
85
|
+
width: w,
|
86
|
+
height: 21
|
87
|
+
}];
|
88
|
+
}
|
89
|
+
});
|
@@ -0,0 +1,104 @@
|
|
1
|
+
pageflow.sitemap.groupView = {
|
2
|
+
define: function(className, fn) {
|
3
|
+
var s = pageflow.sitemap;
|
4
|
+
|
5
|
+
return function(data, options) {
|
6
|
+
options = options || {};
|
7
|
+
|
8
|
+
return function(container) {
|
9
|
+
var previousNodes = container
|
10
|
+
.selectAll('.' + className);
|
11
|
+
|
12
|
+
var previousData = {};
|
13
|
+
|
14
|
+
if (previousNodes.length) {
|
15
|
+
previousData = _(previousNodes.data()).reduce(function(result, data) {
|
16
|
+
result[data.id] = withoutModels(data);
|
17
|
+
return result;
|
18
|
+
}, {});
|
19
|
+
}
|
20
|
+
|
21
|
+
var nodes = previousNodes
|
22
|
+
.data(data, s.utils.fn.d('id'))
|
23
|
+
.order();
|
24
|
+
|
25
|
+
var nodesEnter = nodes
|
26
|
+
.enter()
|
27
|
+
.append('g');
|
28
|
+
|
29
|
+
var nodesUpdate = nodes
|
30
|
+
.filter(function(d) {
|
31
|
+
var prev = previousData[d.id];
|
32
|
+
|
33
|
+
return !prev || !_.isEqual(prev, withoutModels(d));
|
34
|
+
});
|
35
|
+
|
36
|
+
nodesEnter
|
37
|
+
.attr('id', s.utils.fn.d('id'))
|
38
|
+
.classed(className, true);
|
39
|
+
|
40
|
+
fn.call({
|
41
|
+
options: options || {},
|
42
|
+
|
43
|
+
enter: function() {
|
44
|
+
return nodesEnter;
|
45
|
+
},
|
46
|
+
|
47
|
+
update: function() {
|
48
|
+
return nodesUpdate;
|
49
|
+
},
|
50
|
+
|
51
|
+
call: function(fn) {
|
52
|
+
nodesUpdate.call(fn);
|
53
|
+
},
|
54
|
+
|
55
|
+
child: childFactory(nodesEnter, nodesUpdate, options)
|
56
|
+
}, pageflow.sitemap);
|
57
|
+
|
58
|
+
if (!window.dontRemove) {
|
59
|
+
nodes.exit()
|
60
|
+
.remove();
|
61
|
+
}
|
62
|
+
};
|
63
|
+
};
|
64
|
+
|
65
|
+
function childFactory(nodesEnter, nodesUpdate, options) {
|
66
|
+
return function(selector, fn) {
|
67
|
+
var components = selector.split('.');
|
68
|
+
var tagName = components[0];
|
69
|
+
var className = components[1];
|
70
|
+
|
71
|
+
var enteredChild = nodesEnter
|
72
|
+
.append(tagName)
|
73
|
+
.attr('class', className);
|
74
|
+
|
75
|
+
var child = nodesUpdate.select(selector);
|
76
|
+
|
77
|
+
if (fn) {
|
78
|
+
fn.call({
|
79
|
+
options: options,
|
80
|
+
|
81
|
+
enter: function() {
|
82
|
+
return enteredChild;
|
83
|
+
},
|
84
|
+
|
85
|
+
update: function() {
|
86
|
+
return child;
|
87
|
+
},
|
88
|
+
});
|
89
|
+
}
|
90
|
+
|
91
|
+
return child;
|
92
|
+
};
|
93
|
+
}
|
94
|
+
|
95
|
+
function withoutModels(item) {
|
96
|
+
return _(item).reduce(function(result, value, key) {
|
97
|
+
if (!value || !value.cid) {
|
98
|
+
result[key] = value;
|
99
|
+
}
|
100
|
+
return result;
|
101
|
+
}, {});
|
102
|
+
}
|
103
|
+
}
|
104
|
+
};
|
@@ -0,0 +1,112 @@
|
|
1
|
+
/*global options*/
|
2
|
+
|
3
|
+
pageflow.sitemap.pagesView = pageflow.sitemap.groupView.define('page', function(s) {
|
4
|
+
this.update()
|
5
|
+
.classed('selected', function(d) { return d.selected; })
|
6
|
+
.classed('highlighted', function(d) { return d.highlighted; })
|
7
|
+
.classed('destroying', s.utils.fn.d('destroying'))
|
8
|
+
.classed('disabled', s.utils.fn.d('disabled'))
|
9
|
+
.attr('transform', transformStart)
|
10
|
+
.transition().duration(options.duration)
|
11
|
+
.attr('transform', transformFinal)
|
12
|
+
;
|
13
|
+
|
14
|
+
this.enter()
|
15
|
+
.call(sitemap.behavior.multiDrag({
|
16
|
+
drag: this.options.drag,
|
17
|
+
dragend: this.options.dragend
|
18
|
+
}))
|
19
|
+
;
|
20
|
+
|
21
|
+
var trX = -options.page.width / 2,
|
22
|
+
trY = options.page.height / 2,
|
23
|
+
opts = this.options;
|
24
|
+
|
25
|
+
this.child('rect.bg', function() {
|
26
|
+
this.enter()
|
27
|
+
.attr('width', options.page.width)
|
28
|
+
.attr('height', options.page.height)
|
29
|
+
.attr('transform', 'translate(' + trX + ',' + (-trY) + ')')
|
30
|
+
.on('mouseover', function(d) {
|
31
|
+
d3.select(this.parentNode).classed('hover', true);
|
32
|
+
d3.selectAll('[id^="link:' + d.pageCid +'"]').classed('highlight', true);
|
33
|
+
})
|
34
|
+
.on('mouseout', function(d) {
|
35
|
+
d3.select(this.parentNode).classed('hover', false);
|
36
|
+
d3.selectAll('.highlight').classed('highlight', false);
|
37
|
+
})
|
38
|
+
.on('click', s.utils.fn.trigger(this.options.click))
|
39
|
+
.on('dblclick', s.utils.fn.trigger(this.options.dblclick))
|
40
|
+
.on('mousedown', s.utils.fn.trigger(this.options.mousedown))
|
41
|
+
;
|
42
|
+
});
|
43
|
+
|
44
|
+
this.child('image', function() {
|
45
|
+
this.enter()
|
46
|
+
.attr('x', 0)
|
47
|
+
.attr('y', 0)
|
48
|
+
.attr('width', options.page.width)
|
49
|
+
.attr('height', options.page.height)
|
50
|
+
.attr('transform', 'translate(' + trX + ',' + (-trY) + ')')
|
51
|
+
;
|
52
|
+
|
53
|
+
this.update()
|
54
|
+
.each(function(d) {
|
55
|
+
d3.select(this)
|
56
|
+
.attr('xlink:href', d.thumbnailUrl)
|
57
|
+
;
|
58
|
+
})
|
59
|
+
;
|
60
|
+
});
|
61
|
+
|
62
|
+
this.child('rect.title', function() {
|
63
|
+
this.enter()
|
64
|
+
.attr('width', options.page.width)
|
65
|
+
.attr('height', options.page.height)
|
66
|
+
.attr('transform', 'translate(' + (trX) + ',' + (-trY) + ')')
|
67
|
+
;
|
68
|
+
});
|
69
|
+
|
70
|
+
this.child('rect.border', function() {
|
71
|
+
this.enter()
|
72
|
+
.attr('width', options.page.width + 8)
|
73
|
+
.attr('height', options.page.height +8 )
|
74
|
+
.attr('transform', 'translate(' + (trX -4) + ',' + (-trY -4) + ')')
|
75
|
+
;
|
76
|
+
});
|
77
|
+
|
78
|
+
this.enter()
|
79
|
+
.append('foreignObject')
|
80
|
+
.style('pointer-events', 'none')
|
81
|
+
.attr('width', options.page.width-2)
|
82
|
+
.attr('height', options.page.height)
|
83
|
+
.attr('transform', 'translate(' + (trX+1) + ',' + (-trY) + ')')
|
84
|
+
.append('xhtml:body')
|
85
|
+
.html('<div class="title_text"></div>')
|
86
|
+
;
|
87
|
+
|
88
|
+
this.update()
|
89
|
+
.each(function(d) {
|
90
|
+
d3.selectAll(this.getElementsByTagName('div')).text(d.title || '');
|
91
|
+
})
|
92
|
+
;
|
93
|
+
|
94
|
+
this.call(s.addButtonView(addPageButtonData, {
|
95
|
+
tooltipTranslationKey: 'pageflow.sitemap.editor.tooltips.insert_page',
|
96
|
+
click: s.utils.fn.trigger(this.options.addPageButtonClick)
|
97
|
+
}));
|
98
|
+
|
99
|
+
function addPageButtonData(d) {
|
100
|
+
return [{
|
101
|
+
id: d.id + ':add_page',
|
102
|
+
page: d.page,
|
103
|
+
left: trX - 1,
|
104
|
+
top: 37,
|
105
|
+
width: options.page.width + 2,
|
106
|
+
height: 20
|
107
|
+
}];
|
108
|
+
}
|
109
|
+
|
110
|
+
function transformStart(d) { return 'translate(' + d.x0 + ',' + d.y0 + ')'; }
|
111
|
+
function transformFinal(d) { return 'translate(' + d.x + ',' + d.y + ')'; }
|
112
|
+
});
|
@@ -0,0 +1,104 @@
|
|
1
|
+
pageflow.sitemap.selectableLinksView = function(options, fn) {
|
2
|
+
var className = options.className;
|
3
|
+
var path = options.path;
|
4
|
+
var direction = options.direction;
|
5
|
+
|
6
|
+
return pageflow.sitemap.groupView.define(className, function(s) {
|
7
|
+
this.enter()
|
8
|
+
.classed('selectable_link', true)
|
9
|
+
;
|
10
|
+
|
11
|
+
this.update()
|
12
|
+
.sort(function(d1, d2) {
|
13
|
+
return d1.placeholder || d1.selected ? 1 : -1;
|
14
|
+
})
|
15
|
+
.classed('selected', s.utils.fn.d('selected'))
|
16
|
+
.classed('dragged', s.utils.fn.d('dragged'))
|
17
|
+
.classed('placeholder', s.utils.fn.d('placeholder'))
|
18
|
+
;
|
19
|
+
|
20
|
+
this.child('path.selection_highlight', function() {
|
21
|
+
this.update()
|
22
|
+
.attr('d', path)
|
23
|
+
;
|
24
|
+
});
|
25
|
+
|
26
|
+
this.child('path.arrow', function() {
|
27
|
+
this.update()
|
28
|
+
.attr('d', path)
|
29
|
+
.attr('marker-end', function(d) {
|
30
|
+
return 'url(#' + className + (d.dragged ? '_triangle_highlight)' : '_triangle)');
|
31
|
+
})
|
32
|
+
;
|
33
|
+
});
|
34
|
+
|
35
|
+
this.child('path.selection_target', function() {
|
36
|
+
this.enter()
|
37
|
+
.on('mousedown', this.options.click)
|
38
|
+
.on('mouseover', function() {
|
39
|
+
d3.select(this.parentNode)
|
40
|
+
.classed('highlight', true)
|
41
|
+
.select('.arrow').attr('marker-end', 'url(#' + className + '_triangle_highlight)')
|
42
|
+
;
|
43
|
+
})
|
44
|
+
.on('mouseout', function() {
|
45
|
+
d3.select(this.parentNode)
|
46
|
+
.classed('highlight', false)
|
47
|
+
.select('.arrow').attr('marker-end', 'url(#' + className + '_triangle)')
|
48
|
+
;
|
49
|
+
})
|
50
|
+
.call(sitemap.behavior.multiDrag({
|
51
|
+
drag: this.options.drag,
|
52
|
+
dragend: this.options.dragend,
|
53
|
+
enabled: function(d) {
|
54
|
+
return d.selected;
|
55
|
+
}
|
56
|
+
}))
|
57
|
+
;
|
58
|
+
|
59
|
+
this.update()
|
60
|
+
.attr('d', path);
|
61
|
+
});
|
62
|
+
|
63
|
+
this.update().call(s.textLabelView(function(d) {
|
64
|
+
var p = path.points(d);
|
65
|
+
|
66
|
+
return [{
|
67
|
+
id: d.id + ':label',
|
68
|
+
label: d.label,
|
69
|
+
x: p.end.x,
|
70
|
+
y: p.end.y,
|
71
|
+
anchor: p.end.x - p.start.x < 10 ? 'left' : 'right'
|
72
|
+
}];
|
73
|
+
}));
|
74
|
+
|
75
|
+
this.child('path.drag_target', function() {
|
76
|
+
this.enter()
|
77
|
+
.call(s.behavior.tooltipTarget(options.placeholderTooltipTranslationKey))
|
78
|
+
.on('mousedown', this.options.click)
|
79
|
+
.call(sitemap.behavior.multiDrag({
|
80
|
+
drag: this.options.drag,
|
81
|
+
dragend: this.options.dragend,
|
82
|
+
}));
|
83
|
+
|
84
|
+
this.update()
|
85
|
+
.attr('d', function(d) {
|
86
|
+
var point = path.points(d).end;
|
87
|
+
return direction === 'down' ? halfCircleBottom(point) : halfCircleRight(point);
|
88
|
+
})
|
89
|
+
;
|
90
|
+
|
91
|
+
function halfCircleBottom(point) {
|
92
|
+
return 'M' + point.x + ',' + (point.y + 5) + ' h20 a20,20 0 0 1 -20,20 a20,20 0 0 1 -20,-20 z';
|
93
|
+
}
|
94
|
+
|
95
|
+
function halfCircleRight(point) {
|
96
|
+
return 'M' + point.x + ',' + point.y + ' v-20 a20,20 0 0 1 20,20 a20,20 0 0 1 -20,20 z';
|
97
|
+
}
|
98
|
+
});
|
99
|
+
|
100
|
+
if (fn) {
|
101
|
+
fn.call(this, s);
|
102
|
+
}
|
103
|
+
});
|
104
|
+
};
|