spontaneous 0.2.0.beta5 → 0.2.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +39 -0
  4. data/Gemfile +2 -0
  5. data/Readme.markdown +4 -4
  6. data/application/css/core.css.scss +144 -43
  7. data/application/css/definitions.css.scss +50 -16
  8. data/application/css/dialogue.css.scss +5 -2
  9. data/application/css/editing.css.scss +7 -7
  10. data/application/css/font.css.scss +1 -1
  11. data/application/css/meta.css.scss +6 -6
  12. data/application/css/popover.css.scss +6 -6
  13. data/application/css/top.css.scss +8 -1
  14. data/application/js/add_alias_dialogue.js +137 -36
  15. data/application/js/add_home_dialogue.js +10 -10
  16. data/application/js/ajax.js +26 -26
  17. data/application/js/authentication.js +2 -2
  18. data/application/js/box.js +21 -10
  19. data/application/js/box_container.js +13 -7
  20. data/application/js/compatibility.js +19 -17
  21. data/application/js/conflicted_field_dialogue.js +5 -5
  22. data/application/js/content.js +22 -16
  23. data/application/js/content_area.js +62 -33
  24. data/application/js/dialogue.js +16 -16
  25. data/application/js/dom.js +9 -10
  26. data/application/js/edit_panel.js +25 -20
  27. data/application/js/editing.js +21 -8
  28. data/application/js/entry.js +1 -1
  29. data/application/js/extensions.js +11 -11
  30. data/application/js/field/boolean.js +6 -6
  31. data/application/js/field/date.js +1 -1
  32. data/application/js/field/file.js +17 -17
  33. data/application/js/field/image.js +27 -27
  34. data/application/js/field/markdown.js +72 -71
  35. data/application/js/field/select.js +9 -9
  36. data/application/js/field/string.js +3 -3
  37. data/application/js/field/webvideo.js +2 -2
  38. data/application/js/field_preview.js +3 -0
  39. data/application/js/init.js +3 -2
  40. data/application/js/jquery-selection-position.js +13 -13
  41. data/application/js/location.js +17 -12
  42. data/application/js/login.js +2 -2
  43. data/application/js/meta_view/user_admin.js +101 -101
  44. data/application/js/metadata.js +1 -1
  45. data/application/js/page.js +2 -2
  46. data/application/js/page_browser.js +13 -13
  47. data/application/js/page_entry.js +1 -1
  48. data/application/js/panel/root_menu.js +10 -10
  49. data/application/js/popover.js +6 -5
  50. data/application/js/popover_view.js +5 -5
  51. data/application/js/preview.js +10 -4
  52. data/application/js/progress.js +6 -6
  53. data/application/js/properties.js +35 -6
  54. data/application/js/publish.js +43 -43
  55. data/application/js/require.js +14 -14
  56. data/application/js/services.js +3 -3
  57. data/application/js/sharded_upload.js +9 -8
  58. data/application/js/side_bar.js +5 -5
  59. data/application/js/state.js +2 -2
  60. data/application/js/status_bar.js +6 -6
  61. data/application/js/top_bar.js +97 -65
  62. data/application/js/types.js +9 -6
  63. data/application/js/upload.js +4 -4
  64. data/application/js/upload_manager.js +21 -21
  65. data/application/js/user.js +1 -1
  66. data/application/js/vendor/jquery.velocity.min.js +7 -0
  67. data/application/js/views.js +32 -8
  68. data/application/js/views/box_view.js +51 -31
  69. data/application/js/views/page_piece_view.js +17 -15
  70. data/application/js/views/page_view.js +54 -43
  71. data/application/js/views/piece_view.js +44 -37
  72. data/application/static/font/fontawesome-webfont-4f0022f25672c7f501c339cbf98d9117.ttf +0 -0
  73. data/application/views/index.erb +1 -0
  74. data/db/migrations/20130114120000_create_revision_tables.rb +2 -1
  75. data/db/migrations/20130813111009_increase_path_length.rb +11 -2
  76. data/db/migrations/20140506171823_add_index_to_target_id.rb +11 -0
  77. data/db/migrations/20140514090204_add_content_hash.rb +59 -0
  78. data/db/migrations/20140519150253_add_content_hash_timestamp.rb +20 -0
  79. data/lib/spontaneous.rb +0 -1
  80. data/lib/spontaneous/asset/environment.rb +77 -15
  81. data/lib/spontaneous/box.rb +21 -0
  82. data/lib/spontaneous/capistrano/deploy.rb +1 -1
  83. data/lib/spontaneous/capistrano/sync.rb +8 -7
  84. data/lib/spontaneous/change.rb +4 -2
  85. data/lib/spontaneous/cli/fields.rb +7 -3
  86. data/lib/spontaneous/cli/generate.rb +2 -0
  87. data/lib/spontaneous/cli/init.rb +24 -93
  88. data/lib/spontaneous/cli/init/db.rb +94 -0
  89. data/lib/spontaneous/cli/init/mysql.rb +17 -0
  90. data/lib/spontaneous/cli/init/postgresql.rb +33 -0
  91. data/lib/spontaneous/cli/init/sqlite.rb +14 -0
  92. data/lib/spontaneous/cli/site.rb +45 -20
  93. data/lib/spontaneous/collections/box_set.rb +3 -0
  94. data/lib/spontaneous/collections/entry_set.rb +43 -4
  95. data/lib/spontaneous/collections/field_set.rb +14 -2
  96. data/lib/spontaneous/data_mapper.rb +40 -7
  97. data/lib/spontaneous/data_mapper/content_model.rb +1 -1
  98. data/lib/spontaneous/data_mapper/content_model/associations.rb +63 -12
  99. data/lib/spontaneous/data_mapper/content_model/timestamps.rb +9 -14
  100. data/lib/spontaneous/data_mapper/content_table.rb +4 -2
  101. data/lib/spontaneous/data_mapper/dataset.rb +31 -2
  102. data/lib/spontaneous/data_mapper/scope.rb +37 -20
  103. data/lib/spontaneous/errors.rb +6 -0
  104. data/lib/spontaneous/facet.rb +20 -10
  105. data/lib/spontaneous/field/base.rb +8 -1
  106. data/lib/spontaneous/field/file.rb +28 -3
  107. data/lib/spontaneous/field/image.rb +2 -0
  108. data/lib/spontaneous/field/update.rb +6 -0
  109. data/lib/spontaneous/field/webvideo/vimeo.rb +6 -1
  110. data/lib/spontaneous/field/webvideo/vine.rb +1 -1
  111. data/lib/spontaneous/field/webvideo/youtube.rb +1 -1
  112. data/lib/spontaneous/generators/site.rb +6 -4
  113. data/lib/spontaneous/generators/site/.gitignore +1 -0
  114. data/lib/spontaneous/generators/site/Gemfile.tt +3 -3
  115. data/lib/spontaneous/generators/site/config/{indexes.rb.tt → initializers/indexes.rb.tt} +0 -0
  116. data/lib/spontaneous/generators/site/config/initializers/publishing.rb.tt +78 -0
  117. data/lib/spontaneous/generators/site/{config/database.yml.tt → db/mysql2.yml.tt} +7 -6
  118. data/lib/spontaneous/generators/site/db/postgres.yml.tt +25 -0
  119. data/lib/spontaneous/generators/site/db/sqlite3.yml.tt +18 -0
  120. data/lib/spontaneous/generators/site/public/humans.txt.tt +14 -0
  121. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +51 -0
  122. data/lib/spontaneous/loader.rb +1 -1
  123. data/lib/spontaneous/logger.rb +1 -1
  124. data/lib/spontaneous/media/image/optimizer.rb +1 -1
  125. data/lib/spontaneous/media/image/processor.rb +11 -2
  126. data/lib/spontaneous/media/image/renderable.rb +2 -0
  127. data/lib/spontaneous/model.rb +3 -0
  128. data/lib/spontaneous/model/box/allowed_types.rb +17 -4
  129. data/lib/spontaneous/model/core.rb +36 -3
  130. data/lib/spontaneous/model/core/aliases.rb +5 -2
  131. data/lib/spontaneous/model/core/boxes.rb +6 -0
  132. data/lib/spontaneous/model/core/cascading_change.rb +38 -0
  133. data/lib/spontaneous/model/core/content_hash.rb +171 -0
  134. data/lib/spontaneous/model/core/entries.rb +0 -19
  135. data/lib/spontaneous/model/core/fields.rb +11 -0
  136. data/lib/spontaneous/model/core/modifications.rb +22 -21
  137. data/lib/spontaneous/model/core/render.rb +3 -0
  138. data/lib/spontaneous/model/core/serialisation.rb +18 -17
  139. data/lib/spontaneous/model/page.rb +35 -8
  140. data/lib/spontaneous/model/page/page_tree.rb +20 -8
  141. data/lib/spontaneous/model/page/paths.rb +79 -50
  142. data/lib/spontaneous/model/page/singleton.rb +71 -0
  143. data/lib/spontaneous/model/page/site_map.rb +2 -1
  144. data/lib/spontaneous/model/page/site_timestamps.rb +2 -2
  145. data/lib/spontaneous/model/piece.rb +10 -0
  146. data/lib/spontaneous/output/context.rb +13 -6
  147. data/lib/spontaneous/output/format.rb +30 -5
  148. data/lib/spontaneous/output/helpers/script_helper.rb +8 -0
  149. data/lib/spontaneous/output/helpers/stylesheet_helper.rb +7 -0
  150. data/lib/spontaneous/output/renderable.rb +16 -0
  151. data/lib/spontaneous/output/store.rb +1 -1
  152. data/lib/spontaneous/output/template/renderer.rb +2 -2
  153. data/lib/spontaneous/page_piece.rb +25 -1
  154. data/lib/spontaneous/prototypes/box_prototype.rb +13 -0
  155. data/lib/spontaneous/prototypes/field_prototype.rb +7 -4
  156. data/lib/spontaneous/publishing.rb +10 -5
  157. data/lib/spontaneous/publishing/immediate.rb +32 -349
  158. data/lib/spontaneous/publishing/pipeline.rb +43 -0
  159. data/lib/spontaneous/publishing/progress.rb +186 -0
  160. data/lib/spontaneous/publishing/publish.rb +107 -0
  161. data/lib/spontaneous/publishing/rerender.rb +17 -0
  162. data/lib/spontaneous/publishing/revision.rb +53 -18
  163. data/lib/spontaneous/publishing/simultaneous.rb +1 -1
  164. data/lib/spontaneous/publishing/steps.rb +154 -0
  165. data/lib/spontaneous/publishing/steps/activate_revision.rb +45 -0
  166. data/lib/spontaneous/publishing/steps/archive_old_revisions.rb +22 -0
  167. data/lib/spontaneous/publishing/steps/base_step.rb +49 -0
  168. data/lib/spontaneous/publishing/steps/copy_static_files.rb +74 -0
  169. data/lib/spontaneous/publishing/steps/create_revision_directory.rb +24 -0
  170. data/lib/spontaneous/publishing/steps/generate_rackup_file.rb +51 -0
  171. data/lib/spontaneous/publishing/steps/generate_search_indexes.rb +24 -0
  172. data/lib/spontaneous/publishing/steps/render_revision.rb +69 -0
  173. data/lib/spontaneous/publishing/steps/write_revision_file.rb +43 -0
  174. data/lib/spontaneous/rack/back.rb +3 -1
  175. data/lib/spontaneous/rack/back/alias.rb +9 -8
  176. data/lib/spontaneous/rack/front.rb +1 -1
  177. data/lib/spontaneous/rack/middleware.rb +7 -4
  178. data/lib/spontaneous/rack/middleware/transaction.rb +14 -0
  179. data/lib/spontaneous/rack/page_controller.rb +23 -8
  180. data/lib/spontaneous/revision.rb +5 -10
  181. data/lib/spontaneous/schema.rb +5 -0
  182. data/lib/spontaneous/server.rb +3 -1
  183. data/lib/spontaneous/site.rb +17 -10
  184. data/lib/spontaneous/site/publishing.rb +25 -3
  185. data/lib/spontaneous/site/state.rb +7 -3
  186. data/lib/spontaneous/tasks/database.rake +5 -10
  187. data/lib/spontaneous/utils/database/mysql_dumper.rb +5 -1
  188. data/lib/spontaneous/version.rb +1 -1
  189. data/spontaneous.gemspec +4 -3
  190. data/test/fixtures/example_application/config/initializers/initializer1.rb +1 -0
  191. data/test/fixtures/example_application/config/initializers/initializer2.rb +1 -0
  192. data/test/fixtures/example_application/config/initializers/publishing.rb +13 -0
  193. data/test/fixtures/search/config/{indexes.rb → initializers/indexes.rb} +0 -0
  194. data/test/fixtures/serialisation/root_hash.yaml.erb +10 -4
  195. data/test/functional/test_application.rb +10 -0
  196. data/test/functional/test_back.rb +23 -5
  197. data/test/functional/test_cli.rb +98 -34
  198. data/test/functional/test_front.rb +7 -3
  199. data/test/test_helper.rb +35 -28
  200. data/test/unit/test_alias.rb +20 -3
  201. data/test/unit/test_assets.rb +58 -30
  202. data/test/unit/test_changesets.rb +20 -12
  203. data/test/unit/test_content_hash.rb +496 -0
  204. data/test/unit/test_context.rb +28 -1
  205. data/test/unit/test_controllers.rb +96 -61
  206. data/test/unit/test_crypt.rb +1 -8
  207. data/test/unit/test_datamapper.rb +95 -19
  208. data/test/unit/test_features.rb +1 -4
  209. data/test/unit/test_fields.rb +61 -12
  210. data/test/unit/test_generators.rb +39 -2
  211. data/test/unit/test_images.rb +3 -1
  212. data/test/unit/test_modifications.rb +224 -219
  213. data/test/unit/test_output_store.rb +10 -0
  214. data/test/unit/{test_formats.rb → test_outputs.rb} +75 -6
  215. data/test/unit/test_page.rb +61 -15
  216. data/test/unit/test_plugins.rb +2 -42
  217. data/test/unit/test_publishing_pipeline.rb +1050 -0
  218. data/test/unit/test_render.rb +30 -0
  219. data/test/unit/test_revisions.rb +110 -2
  220. data/test/unit/test_schema.rb +4 -0
  221. data/test/unit/test_search.rb +1 -1
  222. data/test/unit/test_serialisation.rb +6 -1
  223. data/test/unit/test_singletons.rb +159 -0
  224. data/test/unit/test_site.rb +71 -44
  225. metadata +140 -86
  226. data/application/static/font/fontawesome-webfont-1c66a4738b40ef0f6b1abca0ba9a796d.ttf +0 -0
  227. data/test/unit/test_publishing.rb +0 -330
@@ -7,7 +7,7 @@ Spontaneous.Metadata = (function($, S) {
7
7
  S.Types.loaded(metadata.types);
8
8
  S.User.loaded(metadata.user);
9
9
  S.Services.loaded(metadata.services);
10
- if (callback) { callback(metadata); };
10
+ if (callback) { callback(metadata); }
11
11
  };
12
12
  };
13
13
  return {
@@ -10,13 +10,13 @@ Spontaneous.Page = (function($, S) {
10
10
  },
11
11
 
12
12
  save_complete: function(values) {
13
- this.callSuper(values)
13
+ this.callSuper(values);
14
14
  this.set('slug', values.slug);
15
15
  this.set('path', values.path);
16
16
  },
17
17
 
18
18
  is_root: function() {
19
- return (this.get('path') === "/");
19
+ return (this.get('path') === '/');
20
20
  },
21
21
  depth: function() {
22
22
  // depth in this case refers to content depth which is always 0 for pages
@@ -3,7 +3,7 @@
3
3
 
4
4
  Spontaneous.PageBrowser = (function($, S) {
5
5
  var dom = S.Dom
6
- , flattenPageList = function(pageList) {
6
+ , flattenPageList = function(pageList) {
7
7
  var pages = []
8
8
  , comparator = function(a, b) {
9
9
  var at = a.title, bt = b.title;
@@ -17,7 +17,7 @@ Spontaneous.PageBrowser = (function($, S) {
17
17
  };
18
18
  var PageBrowser = new JS.Class(Spontaneous.PopoverView, {
19
19
  initialize: function(origin) {
20
- origin = String(origin || "");
20
+ origin = String(origin || '');
21
21
  if (/^\//.test(origin)) {
22
22
  this.origin = origin || '/';
23
23
  this.selected = this.origin;
@@ -32,22 +32,22 @@ Spontaneous.PageBrowser = (function($, S) {
32
32
  origin_list: function() {
33
33
  return function(location) {
34
34
  return flattenPageList(location.generation);
35
- }
35
+ };
36
36
  },
37
37
  children_list: function() {
38
38
  return function(location) {
39
39
  return flattenPageList(location.children);
40
- }
40
+ };
41
41
  },
42
42
  origin_ancestors: function() {
43
43
  return function(location) {
44
44
  return location.ancestors;
45
- }
45
+ };
46
46
  },
47
47
  children_ancestors: function() {
48
48
  return function(location) {
49
49
  return location.ancestors.concat(location);
50
- }
50
+ };
51
51
  },
52
52
  get_page_list: function() {
53
53
  var path;
@@ -89,12 +89,12 @@ Spontaneous.PageBrowser = (function($, S) {
89
89
  };
90
90
  };
91
91
 
92
- for (var i = 0, ii = ancestors.length; i < ii; i++) {
93
- var a = ancestors[i], li = dom.li().append(dom.a().text(a.title)).append(dom.span().text("/")).click(click(a));
92
+ for (i = 0, ii = ancestors.length; i < ii; i++) {
93
+ var a = ancestors[i], li = dom.li().append(dom.a().text(a.title)).append(dom.span().text('/')).click(click(a));
94
94
  list.append(li);
95
95
  }
96
96
  if (ancestors.length === 0) {
97
- list.append(dom.li().append(dom.a().text('Choose a page...')))
97
+ list.append(dom.li().append(dom.a().text('Choose a page...')));
98
98
  }
99
99
  this.ancestors.append(list);
100
100
  },
@@ -108,11 +108,11 @@ Spontaneous.PageBrowser = (function($, S) {
108
108
  var next_click = function() {
109
109
  _browser.next_level(page);
110
110
  return false;
111
- }
111
+ };
112
112
 
113
113
  var row = dom.div('.page').click(selected(page)), title = dom.a().text(page.title);
114
114
  if (page.children > 0) {
115
- var next = dom.span()
115
+ var next = dom.span();
116
116
  next.click(next_click);
117
117
  row.append(next);
118
118
  }
@@ -142,11 +142,11 @@ Spontaneous.PageBrowser = (function($, S) {
142
142
  this.manager.page_selected(page);
143
143
  },
144
144
  title: function() {
145
- return "Choose Page";
145
+ return 'Choose Page';
146
146
  },
147
147
  width: function() {
148
148
  return 400;
149
- },
149
+ }
150
150
  // position_from_event: function(event) {
151
151
  // return {top: event.clientX, left: event.clientY};
152
152
  // },
@@ -8,7 +8,7 @@ Spontaneous.PageEntry = (function($, S) {
8
8
  },
9
9
  save_complete: function(values) {
10
10
  var _this = this;
11
- _this.callSuper(values)
11
+ _this.callSuper(values);
12
12
  _this.set('slug', values.slug);
13
13
  _this.set('path', values.path);
14
14
  }
@@ -10,51 +10,51 @@
10
10
  return 250;
11
11
  },
12
12
  title: function() {
13
- return "Main Menu";
13
+ return 'Main Menu';
14
14
  },
15
15
  position_from_event: function(event) {
16
16
  var pos = this.callSuper();
17
17
  return {left: pos.left - 12, top: pos.top + 1};
18
18
  },
19
19
  view: function() {
20
- var outer = dom.div("#root-menu")
20
+ var outer = dom.div('#root-menu');
21
21
  outer.append(this.serviceMenu(), this.userActionMenu());
22
22
  return outer;
23
23
  },
24
24
  after_close: function() {
25
- if (this.afterCloseCallback && (typeof this.afterCloseCallback === "function")) {
25
+ if (this.afterCloseCallback && (typeof this.afterCloseCallback === 'function')) {
26
26
  this.afterCloseCallback();
27
27
  }
28
28
  },
29
29
  userActionMenu: function() {
30
- var menu = dom.ul(".user-actions");
30
+ var menu = dom.ul('.user-actions');
31
31
  menu.append(dom.li('.user.title').text(S.User.name()));
32
32
  if (S.User.is_admin()) {
33
- var manage = dom.a().text("User Administration").click(function() {
33
+ var manage = dom.a().text('User Administration').click(function() {
34
34
  Spontaneous.ContentArea.enterMeta(sharedUserAdmin);
35
35
  Spontaneous.Popover.close();
36
36
  });
37
37
  menu.append(dom.li('.user-administration').append(manage));
38
38
  }
39
- var logout = dom.a().text("Logout").click(function() {
40
- console.log("Logout");
39
+ var logout = dom.a().text('Logout').click(function() {
40
+ console.log('Logout');
41
41
  S.User.logout();
42
42
  });
43
43
  menu.append(dom.li('.logout').append(logout));
44
44
  return menu;
45
45
  },
46
46
  serviceMenu: function() {
47
- var menu = dom.ul(".external-services");
47
+ var menu = dom.ul('.external-services');
48
48
  var self = this;
49
49
  var services = S.Services.serviceList();
50
50
  if (services.length > 0) {
51
- menu.append(dom.li(".title").text("Services"));
51
+ menu.append(dom.li('.title').text('Services'));
52
52
  services.forEach(function(service) {
53
53
  var link = dom.a().text(service.title).click(function() {
54
54
  self.close();
55
55
  S.Services.open(service);
56
56
  });
57
- menu.append(dom.li().append(link))
57
+ menu.append(dom.li().append(link));
58
58
  });
59
59
  }
60
60
  return menu;
@@ -12,6 +12,7 @@ Spontaneous.Popover = (function($, S) {
12
12
  this.depth = 0;
13
13
  },
14
14
  open: function(event) {
15
+ event.preventDefault();
15
16
  var view = this.view;
16
17
  var location = view.attach_to();
17
18
  var wrapper = dom.div('.pop-over');
@@ -23,7 +24,7 @@ Spontaneous.Popover = (function($, S) {
23
24
  view_wrapper.append(view.view());
24
25
 
25
26
  if (view.has_navigation) {
26
- var back_btn = dom.a('.button.back').append(dom.span('.pointer')).append(dom.span('.label').text("Back")).css('visibility', 'hidden');
27
+ var back_btn = dom.a('.button.back').append(dom.span('.pointer')).append(dom.span('.label').text('Back')).css('visibility', 'hidden');
27
28
  header.append(back_btn);
28
29
  }
29
30
  var target = event.currentTarget;
@@ -44,7 +45,7 @@ Spontaneous.Popover = (function($, S) {
44
45
  }.bind(this);
45
46
 
46
47
  if (view.scroll) {
47
- view.scroll_element().bind("scroll.popover", update_position);
48
+ view.scroll_element().bind('scroll.popover', update_position);
48
49
  }
49
50
  this.wrapper = wrapper;
50
51
  this.is_open = true;
@@ -55,7 +56,7 @@ Spontaneous.Popover = (function($, S) {
55
56
  var view = this.view, o = view.position_from_event(target), handle_width = 30, offset = 10, left = -30, top = 18;
56
57
 
57
58
  if (view.align === 'right') {
58
- handle.css('left', (view.width() - (offset + handle_width)) + 'px')
59
+ handle.css('left', (view.width() - (offset + handle_width)) + 'px');
59
60
  left = -(view.width() - (offset + handle_width/2) + 8);
60
61
  }
61
62
  wrapper.css({top:(o.top), left:(o.left + left)});
@@ -67,7 +68,7 @@ Spontaneous.Popover = (function($, S) {
67
68
  close: function() {
68
69
  var view = this.view;
69
70
  if (view.scroll) {
70
- view.scroll_element().unbind("scroll.popover");
71
+ view.scroll_element().unbind('scroll.popover');
71
72
  }
72
73
  Popover.close();
73
74
  return false;
@@ -107,7 +108,7 @@ Spontaneous.Popover = (function($, S) {
107
108
  if (event.keyCode === 27) {
108
109
  Popover.close();
109
110
  }
110
- })
111
+ });
111
112
  return Popover;
112
113
  })(jQuery, Spontaneous);
113
114
 
@@ -17,7 +17,7 @@ Spontaneous.PopoverView = (function($, S) {
17
17
  align: 'left',
18
18
  has_navigation: true,
19
19
  title: function() {
20
- return "Popover";
20
+ return 'Popover';
21
21
  },
22
22
  width: function() {
23
23
  return 400;
@@ -31,10 +31,10 @@ Spontaneous.PopoverView = (function($, S) {
31
31
  return p;
32
32
  },
33
33
  position_from_element: function(t) {
34
- var t = $(t), o = this.element_position(t);
35
- o.top += t.outerHeight();
36
- o.left += t.outerWidth() / 2;
37
- return o
34
+ var $t = $(t), o = this.element_position($t);
35
+ o.top += $t.outerHeight();
36
+ o.left += $t.outerWidth() / 2;
37
+ return o;
38
38
  },
39
39
  element_position: function(el) {
40
40
  return $(el).offset();
@@ -3,7 +3,7 @@
3
3
  Spontaneous.Preview = (function($, S, $window) {
4
4
  var dom = S.Dom, goto_id = 0;
5
5
  var click_param = function() {
6
- return "?__click="+(++goto_id);
6
+ return '?__click='+(++goto_id);
7
7
  };
8
8
  var Preview = new JS.Singleton({
9
9
  include: Spontaneous.Properties,
@@ -13,10 +13,10 @@ Spontaneous.Preview = (function($, S, $window) {
13
13
  },
14
14
 
15
15
  title: function() {
16
- return this.get('title') || "";
16
+ return this.get('title') || '';
17
17
  },
18
18
  init: function(container) {
19
- this.iframe = dom.iframe("#preview_pane", {'src':'about:blank'})
19
+ this.iframe = dom.iframe('#preview_pane', {'src':'about:blank'});
20
20
  this.iframe.hide();
21
21
  container.append(this.iframe);
22
22
  return this;
@@ -42,7 +42,7 @@ Spontaneous.Preview = (function($, S, $window) {
42
42
  };
43
43
 
44
44
  $iframe.hide();
45
- $iframe.one("load", function() {
45
+ $iframe.one('load', function() {
46
46
  $iframe.show();
47
47
  if (!preview.previewPathMonitor) {
48
48
  preview.previewPathMonitor = $window.setInterval(monitor, monitorInterval);
@@ -72,6 +72,12 @@ Spontaneous.Preview = (function($, S, $window) {
72
72
  },
73
73
  show: function() {
74
74
  this.iframe.show();
75
+ },
76
+ showLoading: function() {
77
+ // best to just ignore this message
78
+ },
79
+ hideLoading: function() {
80
+ // best to just ignore this message
75
81
  }
76
82
  });
77
83
  return Preview;
@@ -3,9 +3,9 @@
3
3
  Spontaneous.Progress = (function($, S) {
4
4
  var Progress = function(parent, size, options) {
5
5
  var defaults = {
6
- spinner_fg_color: "#000000", // colour
6
+ spinner_fg_color: '#000000', // colour
7
7
  spinner_bg_color: null, // null or false for transparent
8
- progress_fg_color: "#000000", // colour
8
+ progress_fg_color: '#000000', // colour
9
9
  progress_bg_color: false, // null or false for transparent
10
10
  spinner_alpha: 1,
11
11
  progress_alpha: 1,
@@ -23,7 +23,7 @@ Spontaneous.Progress = (function($, S) {
23
23
  settings[k] = defaults[k];
24
24
  }
25
25
 
26
- for (var k in options) {
26
+ for (k in options) {
27
27
  settings[k] = options[k];
28
28
  }
29
29
  return {
@@ -51,7 +51,7 @@ Spontaneous.Progress = (function($, S) {
51
51
  if (!this._color[c]) {
52
52
  this._color[c] = this._parse_color(this.options[c]);
53
53
  }
54
- return "rgba("+this._color[c][0]+", "+this._color[c][1]+", "+this._color[c][2]+", " +alpha+ ")";
54
+ return 'rgba('+this._color[c][0]+', '+this._color[c][1]+', '+this._color[c][2]+', ' +alpha+ ')';
55
55
  },
56
56
 
57
57
  canvas: function() {
@@ -171,7 +171,7 @@ Spontaneous.Progress = (function($, S) {
171
171
  ctx.clearRect(0,0,this.size,this.size);
172
172
  var r1 = radius - (radius * this.options.segment_length);
173
173
 
174
- var p = ((2.0 * Math.PI * r1) / this.options.segments) * this.options.segment_width ;
174
+ var p = ((2.0 * Math.PI * r1) / this.options.segments) * this.options.segment_width;
175
175
  var r2 = radius;
176
176
 
177
177
  if (this.options.rounded) r2 -= p/2;
@@ -356,4 +356,4 @@ Spontaneous.Progress = (function($, S) {
356
356
  };
357
357
  };
358
358
  return Progress;
359
- })(jQuery, Spontaneous);
359
+ })(jQuery, Spontaneous);
@@ -23,14 +23,14 @@ Spontaneous.Properties = (function($, S) {
23
23
  },
24
24
  _props_set_individual: function(property_name, value) {
25
25
  if (this._props_set_individual_wo_callbacks(property_name, value)) {
26
- this._props_notify_changed([ property_name ]);
26
+ this._props_notify_changed([property_name]);
27
27
  }
28
28
  },
29
29
  _props_set_individual_wo_callbacks: function(property_name, value) {
30
- if (this._props_debug) { console.log("setting ", property_name, value) }
30
+ if (this._props_debug) { console.log('setting ', property_name, value); }
31
31
  orig_value = this._props_properties()[property_name];
32
32
  this._props_properties()[property_name] = value;
33
- var changed = (value !== orig_value)
33
+ var changed = (value !== orig_value);
34
34
  return changed;
35
35
  },
36
36
  _props_set_multiple: function(values) {
@@ -49,9 +49,20 @@ Spontaneous.Properties = (function($, S) {
49
49
  },
50
50
  _props_add_listener: function(name, callback) {
51
51
  var current_listeners = this._props_listeners()[name] || [];
52
+ // console.log('current_listeners', name, current_listeners.length)
52
53
  current_listeners.push({'callback': callback});
53
54
  this._props_listeners()[name] = current_listeners;
54
55
  },
56
+ _props_remove_listener: function(name, callback) {
57
+ var current_listeners = this._props_listeners()[name] || [], listeners = [];
58
+ for (var i = 0, ii = current_listeners.length; i < ii; i++) {
59
+ var l = current_listeners[i];
60
+ if (l.callback !== callback) {
61
+ listeners.push(l);
62
+ }
63
+ }
64
+ this._props_listeners()[name] = listeners;
65
+ },
55
66
  // get the value of a property
56
67
  get: function(property_name) {
57
68
  return this._props_properties()[property_name];
@@ -63,7 +74,7 @@ Spontaneous.Properties = (function($, S) {
63
74
  // all watchers of this property will be notified of the change
64
75
  // (only if the value acutally changes)
65
76
  set: function() {
66
- if (arguments.length === 1 && typeof arguments[0] === "object") {
77
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
67
78
  this._props_set_multiple(arguments[0]);
68
79
  } else if (arguments.length ===2) {
69
80
  this._props_set_individual(arguments[0], arguments[1]);
@@ -71,11 +82,14 @@ Spontaneous.Properties = (function($, S) {
71
82
  },
72
83
  // assign a callback function to a property to be called when that property changes
73
84
  watch: function(property_name, callback) {
74
- return this._props_add_listener(property_name, callback)
85
+ return this._props_add_listener(property_name, callback);
86
+ },
87
+ unwatch: function(property_name, callback) {
88
+ return this._props_remove_listener(property_name, callback);
75
89
  },
76
90
  // assign a callback to an event to be called when that event is triggered
77
91
  bind: function(event_name, callback) {
78
- return this._props_add_listener(event_name, callback)
92
+ return this._props_add_listener(event_name, callback);
79
93
  },
80
94
  // trigger a particular event
81
95
  trigger: function() {
@@ -84,6 +98,21 @@ Spontaneous.Properties = (function($, S) {
84
98
  for (var i = 0, ii = listeners.length; i < ii; i++) {
85
99
  listeners[i].callback.apply(null, args);
86
100
  }
101
+ },
102
+ // set a listener on the 'property_name' property of the object `target`
103
+ // and remember it so we can remove it later (using 'unwatchOthers')
104
+ watchOther: function(target, property_name, callback) {
105
+ var others = this._props_watching || [];
106
+ others.push({target: target, property_name: property_name, callback: callback});
107
+ this._props_watching = others;
108
+ return target.watch(property_name, callback);
109
+ },
110
+ unwatchOthers: function() {
111
+ var others = this._props_watching || [];
112
+ for (var i = 0, ii = others.length; i < ii; i++) {
113
+ var watcher = others[i];
114
+ watcher.target.unwatch(watcher.property_name, watcher.callback);
115
+ }
87
116
  }
88
117
  });
89
118
  return Properties;
@@ -8,7 +8,7 @@ Spontaneous.Publishing = (function($, S) {
8
8
  this.change_sets = [];
9
9
  var callback = this.page_lock_removed.bind(this);
10
10
  var page_lock_removed = function(event) {
11
- callback($.parseJSON(event.data))
11
+ callback($.parseJSON(event.data));
12
12
  };
13
13
  S.EventSource.addEventListener('page_lock_status', page_lock_removed);
14
14
  this.page_lock_removed_listener = page_lock_removed;
@@ -16,7 +16,7 @@ Spontaneous.Publishing = (function($, S) {
16
16
  page_lock_removed: function(page_ids) {
17
17
  var changes = this.change_sets, toUnlock = [];
18
18
  page_ids.forEach(function(id) {
19
- toUnlock = toUnlock.concat(changes.filter(function(c) { return c.change.id == id }))
19
+ toUnlock = toUnlock.concat(changes.filter(function(c) { return c.change.id == id; }));
20
20
  });
21
21
 
22
22
  toUnlock.forEach(function(cs) {
@@ -30,21 +30,21 @@ Spontaneous.Publishing = (function($, S) {
30
30
  return '90%';
31
31
  },
32
32
  title: function() {
33
- return "Publish Changes";
33
+ return 'Publish Changes';
34
34
  },
35
35
  class_name: function() {
36
- return "publishing";
36
+ return 'publishing';
37
37
  },
38
38
  body: function() {
39
39
  var wrapper = dom.div('#publishing-dialogue');
40
- var spinner = dom.div(".spinner");
40
+ var spinner = dom.div('.spinner');
41
41
  wrapper.append(spinner);
42
42
 
43
43
  this.spinnerWrap = spinner;
44
44
  this.wrapper = wrapper;
45
45
  this.spinner = S.Progress(spinner[0], 48, {period: 800, segment_length: 0.30});
46
- this.spinner.start()
47
- spinner.append(dom.div().append(dom.p().text("Loading changes...")))
46
+ this.spinner.start();
47
+ spinner.append(dom.div().append(dom.p().text('Loading changes...')));
48
48
  Spontaneous.Ajax.get('/changes', this.change_list_loaded.bind(this));
49
49
  return wrapper;
50
50
  },
@@ -74,16 +74,16 @@ Spontaneous.Publishing = (function($, S) {
74
74
  var change_list = outstanding.changes
75
75
  , w = this.wrapper
76
76
  , self = this
77
- , changed_wrap = dom.div("#changes.change-list").css("opacity", 0)
78
- , publish_wrap = dom.div("#to-publish.change-list").css("opacity", 0)
77
+ , changed_wrap = dom.div('#changes.change-list').css('opacity', 0)
78
+ , publish_wrap = dom.div('#to-publish.change-list').css('opacity', 0)
79
79
  , must_publish_all = outstanding.first_publish || outstanding.must_publish_all
80
80
  , spinner = this.spinner
81
81
  , append_to;
82
82
  if (must_publish_all) {
83
- w.addClass("first-publish");
83
+ w.addClass('first-publish');
84
84
  }
85
85
  if (change_list.length === 0) {
86
- var summary = dom.p('.publish-up-to-date').text("The site is up to date");
86
+ var summary = dom.p('.publish-up-to-date').text('The site is up to date');
87
87
  w.append(summary);
88
88
  self.disable_button('Publish');
89
89
  } else {
@@ -94,12 +94,12 @@ Spontaneous.Publishing = (function($, S) {
94
94
  self.set_publish_all(false);
95
95
  }.bind(self));
96
96
 
97
- var changed_toolbar = dom.div('.actions').append(dom.div().text("Modified pages")).append(publish_all);
98
- var publish_toolbar = dom.div('.actions').append(dom.div().text("Publish pages"));
97
+ var changed_toolbar = dom.div('.actions').append(dom.div().text('Modified pages')).append(publish_all);
98
+ var publish_toolbar = dom.div('.actions').append(dom.div().text('Publish pages'));
99
99
  if (!must_publish_all) {
100
100
  publish_toolbar.append(clear_all);
101
101
  }
102
- var changed_entries = dom.div('.change-sets'), publish_entries = dom.div('.change-sets')
102
+ var changed_entries = dom.div('.change-sets'), publish_entries = dom.div('.change-sets');
103
103
  changed_wrap.append(changed_toolbar, changed_entries);
104
104
  publish_wrap.append(publish_toolbar, publish_entries);
105
105
  append_to = changed_entries;
@@ -109,7 +109,7 @@ Spontaneous.Publishing = (function($, S) {
109
109
  for (var i = 0, ii = change_list.length; i < ii; i++) {
110
110
  var cs = new ChangeSet(i, self, change_list[i], must_publish_all);
111
111
  self.change_sets.push(cs);
112
- append_to.append(cs.panel())
112
+ append_to.append(cs.panel());
113
113
  }
114
114
  if (!must_publish_all) {
115
115
  publish_entries.append(dom.div('.instructions').text('Add pages to publish from the list on the left'));
@@ -117,8 +117,8 @@ Spontaneous.Publishing = (function($, S) {
117
117
  spinner.stop();
118
118
  this.spinnerWrap.remove();
119
119
  w.empty();
120
- w.append(changed_wrap, publish_wrap)
121
- changed_wrap.add(publish_wrap).animate({opacity: 1});
120
+ w.append(changed_wrap, publish_wrap);
121
+ changed_wrap.add(publish_wrap).velocity({opacity: 1});
122
122
  self.changed_entries = changed_entries;
123
123
  self.publish_entries = publish_entries;
124
124
  this.spinner = this.spinnerWrap = null;
@@ -139,11 +139,11 @@ Spontaneous.Publishing = (function($, S) {
139
139
  change_set.panel().disappear();
140
140
  panel.appear();
141
141
  } else {
142
- panel = this.publish_entries.find('#'+id)
142
+ panel = this.publish_entries.find('#'+id);
143
143
  panel.disappear(function() {
144
144
  panel.remove();
145
145
  var entries = __this.publish_entries;
146
- if (entries.find('.change-set').length == 0) {
146
+ if (entries.find('.change-set').length === 0) {
147
147
  entries.find('.instructions').fadeIn();
148
148
  }
149
149
  });
@@ -158,7 +158,7 @@ Spontaneous.Publishing = (function($, S) {
158
158
  var dependentGraph = this.change_sets.filter(function(set) {
159
159
  return set.has_dependency(dependentPage);
160
160
  });
161
- var group = dependentSet.concat(dependentGraph)
161
+ var group = dependentSet.concat(dependentGraph);
162
162
  group.forEach(function(set) {
163
163
  set.select(true);
164
164
  });
@@ -194,18 +194,18 @@ Spontaneous.Publishing = (function($, S) {
194
194
  return !this.published_at;
195
195
  },
196
196
  isDependent: function() {
197
- return !this.hasOwnProperty("dependent");
197
+ return !this.hasOwnProperty('dependent');
198
198
  },
199
199
 
200
200
  panel: function() {
201
201
  var self = this
202
- , pageTitle = dom.span(".page-title").html(this.title)
203
- , classes = ".title" + (this.isDependent() ? ".dependent" : "")
202
+ , pageTitle = dom.span('.page-title').html(this.title)
203
+ , classes = '.title' + (this.isDependent() ? '.dependent' : '')
204
204
  , modificationDate = dom.div('.modification-date').html(this.modifiedAt())
205
205
  , publicationDate = dom.div('.publication-date').html(this.publishedAt())
206
- , metadata = dom.div(".dates").append(modificationDate, publicationDate)
206
+ , metadata = dom.div('.dates').append(modificationDate, publicationDate);
207
207
  if (this.isUnpublished()) {
208
- pageTitle.attr("title", "This page is new and has never been published");
208
+ pageTitle.attr('title', 'This page is new and has never been published');
209
209
  }
210
210
  return dom.div(classes).append(pageTitle, dom.div('.url').text(this.url)).append(metadata).click(function() {
211
211
  S.Dialogue.close();
@@ -213,7 +213,7 @@ Spontaneous.Publishing = (function($, S) {
213
213
  });
214
214
  },
215
215
  modifiedAt: function() {
216
- return "Modified: " + this.formatDate(this.modified_at);
216
+ return 'Modified: ' + this.formatDate(this.modified_at);
217
217
  },
218
218
  publishedAt: function() {
219
219
  var date;
@@ -222,13 +222,13 @@ Spontaneous.Publishing = (function($, S) {
222
222
  } else {
223
223
  date = this.formatDate(this.published_at);
224
224
  }
225
- return "Published: " + date;
225
+ return 'Published: ' + date;
226
226
  },
227
227
  formatDate: function(dateString) {
228
- if (!dateString) { return ""; }
228
+ if (!dateString) { return ''; }
229
229
  var d = new Date(dateString);
230
230
  // use date.js formatting
231
- return d.toString("d MMM yyyy, HH:mm");
231
+ return d.toString('d MMM yyyy, HH:mm');
232
232
  }
233
233
  });
234
234
  var ChangeSet = new JS.Class({
@@ -236,7 +236,7 @@ Spontaneous.Publishing = (function($, S) {
236
236
  this.id = id;
237
237
  this.dialogue = dialogue;
238
238
  this.change = change;
239
- this.selected = selected || false;
239
+ this.selected = selected || false;
240
240
  this.mustPublish = selected || false;
241
241
  },
242
242
  locks: function(){
@@ -247,7 +247,7 @@ Spontaneous.Publishing = (function($, S) {
247
247
  },
248
248
  unlock: function() {
249
249
  var w = this.wrapper;
250
- w.removeClass("locked").find(".lock-state").remove();
250
+ w.removeClass('locked').find('.lock-state').remove();
251
251
  this.locks().length = 0;
252
252
  },
253
253
  page_ids: function() {
@@ -269,16 +269,16 @@ Spontaneous.Publishing = (function($, S) {
269
269
  , page = this.page()
270
270
  , pages = this.dependent_pages()
271
271
  , locked = this.isLocked()
272
- , info = dom.div(".info").hide();
272
+ , info = dom.div('.info').hide();
273
273
 
274
274
  if (page.isUnpublished()) {
275
275
  w.addClass('unpublished');
276
276
  }
277
277
  if (locked) {
278
278
  w.addClass('locked');
279
- var lockState = dom.div(".lock-state")
280
- , title = dom.h3().html("<strong>Cannot publish page</strong> until the following actions have completed:")
281
- , details = dom.div(".locks")
279
+ var lockState = dom.div('.lock-state')
280
+ , title = dom.h3().html('<strong>Cannot publish page</strong> until the following actions have completed:')
281
+ , details = dom.div('.locks')
282
282
  , locks = this.locks();
283
283
  locks.forEach(function(lock) {
284
284
  var line = dom.p();
@@ -286,13 +286,13 @@ Spontaneous.Publishing = (function($, S) {
286
286
  line.prepend(dom.strong().text(lock.location));
287
287
  details.append(line);
288
288
  });
289
- lockState.append(title, details)
289
+ lockState.append(title, details);
290
290
  info.append(lockState);
291
291
  page_list.append(info);
292
292
  add.hover(function() {
293
- info.show().animate({"width": "100%"}, 150);
293
+ info.show().velocity({'width': '100%'}, 150);
294
294
  }, function() {
295
- info.hide().css("width", 0);
295
+ info.hide().css('width', 0);
296
296
  });
297
297
  }
298
298
  page_list.append(page.panel());
@@ -319,7 +319,7 @@ Spontaneous.Publishing = (function($, S) {
319
319
  },
320
320
  select: function(state) {
321
321
  var self = this;
322
- if (this.isLocked()) { return ; }
322
+ if (this.isLocked()) { return; }
323
323
  if (state === self.selected) { return; }
324
324
  if (!state && self.dependency_forces_publish()) {
325
325
  return;
@@ -337,18 +337,18 @@ Spontaneous.Publishing = (function($, S) {
337
337
  }
338
338
  },
339
339
  select_toggle: function() {
340
- this.select(!this.selected)
340
+ this.select(!this.selected);
341
341
  },
342
342
  update_view: function() {
343
343
  if (this.selected) {
344
- this.wrapper.addClass('selected')
344
+ this.wrapper.addClass('selected');
345
345
  } else {
346
- this.wrapper.removeClass('selected')
346
+ this.wrapper.removeClass('selected');
347
347
  }
348
348
  },
349
349
  page: function() {
350
350
  return new Page(this.change);
351
- }.cache("_page_"),
351
+ }.cache('_page_'),
352
352
 
353
353
  dependency_forces_publish: function() {
354
354
  return this.dialogue.dependency_forces_publish(this);