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
@@ -8,21 +8,21 @@ Spontaneous.Require = {
8
8
  this.async = asynchronous;
9
9
  var body = document.body;
10
10
  var splash = document.createElement('div');
11
- splash.id = "script-load-splash";
11
+ splash.id = 'script-load-splash';
12
12
  var progress_outer = document.createElement('div');
13
- progress_outer.id = "script-load-progress";
13
+ progress_outer.id = 'script-load-progress';
14
14
  if (this.async) {
15
15
  var progress_inner = document.createElement('div');
16
16
  progress_outer.appendChild(progress_inner);
17
17
  this.bar = progress_inner;
18
18
  this.progress(0);
19
19
  } else {
20
- progress_outer.className = "synchronous";
21
- progress_outer.innerHTML = "Loading...";
20
+ progress_outer.className = 'synchronous';
21
+ progress_outer.innerHTML = 'Loading...';
22
22
  }
23
23
  splash.appendChild(progress_outer);
24
24
  body.appendChild(splash);
25
- this.container = splash
25
+ this.container = splash;
26
26
  },
27
27
  remove: function() {
28
28
  document.body.removeChild(this.container);
@@ -49,19 +49,19 @@ Spontaneous.Require = {
49
49
  if (this.current) {
50
50
  total += this.current[1];
51
51
  }
52
- for (var i = 0, ii = this._completed.length; i < ii; i++) {
52
+ for (i = 0, ii = this._completed.length; i < ii; i++) {
53
53
  total += this._completed[i][1];
54
54
  }
55
55
  return total;
56
56
  },
57
57
  add: function(script) {
58
- this.pending.push(script)
58
+ this.pending.push(script);
59
59
  if (!this.current) { this.next(); }
60
60
  },
61
61
  script_url: function(src) {
62
62
  var url = src;
63
63
  if (Spontaneous.development) {
64
- url += "?"+(new Date()).valueOf();
64
+ url += '?'+(new Date()).valueOf();
65
65
  }
66
66
  return url;
67
67
  },
@@ -76,16 +76,16 @@ Spontaneous.Require = {
76
76
  this.current = s;
77
77
  if (this.async) {
78
78
  var xhr = new XMLHttpRequest();
79
- xhr.open("GET", this.script_url(s[0]), true);
79
+ xhr.open('GET', this.script_url(s[0]), true);
80
80
  var onprogress = (function(req) {
81
81
  return function(event) {
82
82
  req.onprogress(event);
83
- }
83
+ };
84
84
  })(this);
85
85
  var onreadystatechange = (function(req) {
86
86
  return function(event) {
87
87
  req.onreadystatechange(event);
88
- }
88
+ };
89
89
  })(this);
90
90
  xhr.onprogress = onprogress;
91
91
  xhr.onreadystatechange = onreadystatechange;
@@ -117,7 +117,7 @@ Spontaneous.Require = {
117
117
  var script = document.createElement('script');
118
118
  script.type = 'text/javascript';
119
119
  script.text = xhr.responseText;
120
- body.appendChild(script)
120
+ body.appendChild(script);
121
121
  this._completed.push(this.current);
122
122
  this.position = 0;
123
123
  this.next();
@@ -125,5 +125,5 @@ Spontaneous.Require = {
125
125
  }
126
126
  };
127
127
  Spontaneous.require = function(script) {
128
- Spontaneous.Require.add(script)
129
- }
128
+ Spontaneous.Require.add(script);
129
+ };
@@ -8,7 +8,7 @@ Spontaneous.Services = (function($, S) {
8
8
  this.set('services', serviceData);
9
9
  },
10
10
  serviceList: function() {
11
- return this.get("services");
11
+ return this.get('services');
12
12
  },
13
13
  open: function(service) {
14
14
  S.TopBar.showService(service);
@@ -19,14 +19,14 @@ Spontaneous.Services = (function($, S) {
19
19
  S.ContentArea.hideService();
20
20
  },
21
21
  init: function(container) {
22
- this.iframe = dom.iframe("#services_pane", {'src':'about:blank'})
22
+ this.iframe = dom.iframe('#services_pane', {'src':'about:blank'});
23
23
  this.iframe.hide();
24
24
  container.append(this.iframe);
25
25
  return this;
26
26
  },
27
27
  display: function(url) {
28
28
  var iframe = this.iframe;
29
- iframe.fadeIn(200);
29
+ iframe.velocity('fadeIn', 200);
30
30
  // iframe.bind('ready.services', function() {
31
31
  // iframe.fadeIn(200);
32
32
  // });
@@ -27,7 +27,7 @@ Spontaneous.ShardedUpload = (function($, S) {
27
27
  compute_hash: function(array_buffer) {
28
28
  var bytes = new Uint8Array(array_buffer);
29
29
  var sha = Crypto.SHA1(bytes);
30
- this.hash = sha
30
+ this.hash = sha;
31
31
  this.begin_upload();
32
32
  this.failure_count = 0;
33
33
  },
@@ -39,7 +39,7 @@ Spontaneous.ShardedUpload = (function($, S) {
39
39
  S.Ajax.get(['/shard', this.hash].join('/'), this.status_complete.bind(this));
40
40
  },
41
41
  status_complete: function(data, status, xhr) {
42
- if (status === "success") {
42
+ if (status === 'success') {
43
43
  // we're actually done
44
44
  this.complete();
45
45
  } else {
@@ -63,7 +63,7 @@ Spontaneous.ShardedUpload = (function($, S) {
63
63
  var xhr = S.Ajax.authenticatedRequest();
64
64
  var upload = xhr.upload;
65
65
 
66
- xhr.open("POST", path, true);
66
+ xhr.open('POST', path, true);
67
67
  upload.onprogress = this.onprogress.bind(this);
68
68
  upload.onload = this.onload.bind(this);
69
69
  upload.onloadend = this.onloadend.bind(this);
@@ -121,16 +121,17 @@ Spontaneous.ShardedUpload = (function($, S) {
121
121
  this.start_with_index(0);
122
122
  },
123
123
  start_with_index: function(index) {
124
+ var shard;
124
125
  if (index < this.shard_count()) {
125
- var shard = new Shard(this, index, this.slice(index));
126
+ shard = new Shard(this, index, this.slice(index));
126
127
  this.current = shard;
127
128
  shard.start();
128
129
  } else {
129
130
  if (this.failed.length === 0) {
130
131
  this.finalize();
131
132
  } else {
132
- var shard = this.failed.pop();
133
- console.warn('retrying failed shard', shard)
133
+ shard = this.failed.pop();
134
+ console.warn('retrying failed shard', shard);
134
135
  this.current = shard;
135
136
  shard.retry();
136
137
  }
@@ -146,9 +147,9 @@ Spontaneous.ShardedUpload = (function($, S) {
146
147
  this.request(this.method, this.path(), form);
147
148
  },
148
149
  path: function() {
149
- return ["/shard", this.target_id].join('/');
150
+ return ['/shard', this.target_id].join('/');
150
151
  },
151
- method: "PUT",
152
+ method: 'PUT',
152
153
  hashes: function() {
153
154
  var hashes = [];
154
155
  for (var i = 0, ii = this.completed.length; i < ii; i++) {
@@ -6,20 +6,20 @@ Spontaneous.SideBar = (function($, S) {
6
6
  var side_bar = {
7
7
  panel: function() {
8
8
  this.panel = dom.div('#side-bar');
9
- this.logo_panel = dom.div('#logo')
10
- this.page_info_panel = dom.div('.page-info')
11
- this.user_panel = dom.div('#user')
9
+ this.logo_panel = dom.div('#logo');
10
+ this.page_info_panel = dom.div('.page-info');
11
+ this.user_panel = dom.div('#user');
12
12
  this.panel.append(this.logo_panel).append(this.page_info_panel).append(this.user_panel);
13
13
  return this.panel;
14
14
  },
15
15
  location_changed: function(location) {
16
- console.log('page-loaded', location)
16
+ console.log('page-loaded', location);
17
17
  this.page_info_panel.text(location.url);
18
18
  },
19
19
  spinner: function() {
20
20
  if (!this._spinner) {
21
21
  this._spinner = Spontaneous.Progress(this.logo_panel[0], 48, {
22
- spinner_fg_color: "#fff",
22
+ spinner_fg_color: '#fff',
23
23
  period: 850
24
24
  });
25
25
  }
@@ -44,7 +44,7 @@ Spontaneous.State = (function($, S) {
44
44
  },
45
45
  getFieldMetadata: function(field, key) {
46
46
  var s = this.state, f = (s.fields || {})[field.schema_id()] || {};
47
- return f[key]
47
+ return f[key];
48
48
  }
49
49
  });
50
50
  var State = new JS.Singleton({
@@ -60,7 +60,7 @@ Spontaneous.State = (function($, S) {
60
60
  active_box: function(content) {
61
61
  var s = this.get(content);
62
62
  return s.active_box();
63
- },
63
+ }
64
64
  // activate_slot: function(content, slot) {
65
65
  // var s = this.get(content);
66
66
  // s.activate_slot(slot);
@@ -17,20 +17,20 @@ Spontaneous.StatusBar = (function($, S) {
17
17
  this.showing = false;
18
18
  var duration = 200;
19
19
  window.setTimeout(function() {
20
- // S.ContentArea.wrap.animate({'bottom': 0}, duration);
21
- // S.Dialogue.overlay().animate({'bottom': 0}, duration);
22
- this.container.animate({'height': 0}, duration, function() { /* this.container.hide() */ }.bind(this));
20
+ // S.ContentArea.wrap.velocity({'bottom': 0}, duration);
21
+ // S.Dialogue.overlay().velocity({'bottom': 0}, duration);
22
+ this.container.velocity({'height': 0}, duration, function() { /* this.container.hide() */ }.bind(this));
23
23
  }.bind(this), 500);
24
24
  },
25
25
  show: function() {
26
26
  if (this.showing) { return; }
27
27
  this.showing = true;
28
28
  var duration = 200, height = 32;
29
- // S.ContentArea.wrap.animate({'bottom': height}, duration);
30
- // S.Dialogue.overlay().animate({'bottom': height}, duration);
29
+ // S.ContentArea.wrap.velocity({'bottom': height}, duration);
30
+ // S.Dialogue.overlay().velocity({'bottom': height}, duration);
31
31
  this.container.css('height', 0+'px');
32
32
  this.container.show();
33
- this.container.animate({'height': height}, duration);
33
+ this.container.velocity({'height': height}, duration);
34
34
  },
35
35
  progress_container: function() {
36
36
  if (!this._progress_container) {
@@ -5,16 +5,16 @@ Spontaneous.TopBar = (function($, S) {
5
5
 
6
6
  var disableParent = function(el) {
7
7
  el.hover(function() {
8
- $(this).parent().addClass("disabled");
8
+ $(this).parent().addClass('disabled');
9
9
  }, function() {
10
- $(this).parent().removeClass("disabled");
10
+ $(this).parent().removeClass('disabled');
11
11
  });
12
12
  return el;
13
13
  };
14
14
 
15
15
  var slugComparator = function(a, b) {
16
16
  var at = a.slug, bt = b.slug;
17
- if (at > bt) { return 1; }
17
+ if (at > bt) { return 1; }
18
18
  if (at < bt) { return -1; }
19
19
  return 0;
20
20
  };
@@ -24,19 +24,22 @@ Spontaneous.TopBar = (function($, S) {
24
24
  this.roots = roots;
25
25
  },
26
26
  width: function() { return 300; },
27
- title: function() { return "Choose Root"; },
28
- view: function() {
29
- var self = this, w = dom.div('#navigation-page-browser.pop-root-browser'), list = dom.div(".pages"), roots = this.roots.roots;
27
+ title: function() { return 'Choose Root'; },
28
+ view: function() {
29
+ var self = this
30
+ , w = dom.div('#navigation-page-browser.pop-root-browser')
31
+ , list = dom.div('.pages')
32
+ , roots = this.roots.roots;
30
33
  var click = function(page_id) {
31
34
  return function() { self.close(); S.Location.load_id(page_id); };
32
35
  };
33
36
  for (var key in roots) {
34
37
  if (roots.hasOwnProperty(key)) {
35
- var r = dom.div(".page").text(key).click(click(roots[key]));
38
+ var r = dom.div('.page').text(key).click(click(roots[key]));
36
39
  list.append(r);
37
40
  }
38
41
  }
39
- frame.append(list);
42
+ w.append(list);
40
43
  this.wrapper = w;
41
44
  return w;
42
45
  }
@@ -48,26 +51,26 @@ Spontaneous.TopBar = (function($, S) {
48
51
  this.pages = pages;
49
52
  },
50
53
  width: function() { return 300; },
51
- title: function() { return "Go to Page"; },
52
- view: function() {
54
+ title: function() { return 'Go to Page'; },
55
+ view: function() {
53
56
  var self = this, w = dom.div('#navigation-page-browser.pop-root-browser')
54
- , list = dom.div(".pages")
55
- , frame = dom.div(".frame")
56
- , searchArea = dom.div(".search")
57
- , searchInput = dom.input({type: "search", placeholder:"Search"});
57
+ , list = dom.div('.pages')
58
+ , frame = dom.div('.frame')
59
+ , searchArea = dom.div('.search')
60
+ , searchInput = dom.input({type: 'search', placeholder:'Search'});
58
61
  searchArea.append(searchInput);
59
- searchInput.bind("change keyup search", self.updateSearch.bind(self, searchInput));
62
+ searchInput.bind('change keyup search', self.updateSearch.bind(self, searchInput));
60
63
  self.wrapper = w;
61
64
  self.list = list;
62
65
  frame.append(list);
63
- w.append(searchArea, frame)
66
+ w.append(searchArea, frame);
64
67
  this.loadPages();
65
68
  return w;
66
69
  },
67
70
  updateSearch: function(input) {
68
71
  if (!this.pages) { return; }
69
72
 
70
- var self = this, boxes = {}, query = input.val(), search = new RegExp(query, "i");
73
+ var self = this, boxes = {}, query = input.val(), search = new RegExp(query, 'i');
71
74
  // need to bubble up the event if the query is identical as this event
72
75
  // is also triggered on input blur when a page is clicked.
73
76
  if (query === this.query) {
@@ -75,7 +78,7 @@ Spontaneous.TopBar = (function($, S) {
75
78
  }
76
79
 
77
80
  this.query = query;
78
- if (query === "") {
81
+ if (query === '') {
79
82
  self.listPages(this.pages);
80
83
  return;
81
84
  }
@@ -100,7 +103,7 @@ Spontaneous.TopBar = (function($, S) {
100
103
  if (this.pages) {
101
104
  this.listPages(this.pages);
102
105
  } else {
103
- var path = ["/map", this.origin.id].join("/")
106
+ var path = ['/map', this.origin.id].join('/');
104
107
  S.Location.retrieve(path, this.pagesLoaded.bind(this));
105
108
  }
106
109
  },
@@ -113,21 +116,21 @@ Spontaneous.TopBar = (function($, S) {
113
116
  return function() {
114
117
  self.close();
115
118
  S.Location.load_id(p.id);
116
- }
119
+ };
117
120
  };
118
121
  self.clearList();
119
122
  if (Object.keys(generation).length === 0) {
120
- var msg = filter ? "No matches for ‘"+filter+"" : "No pages";
121
- self.list.append(dom.h3().text(msg))
123
+ var msg = filter ? 'No matches for ‘'+filter+'' : 'No pages';
124
+ self.list.append(dom.h3().text(msg));
122
125
  return;
123
126
  }
124
127
  $.each(generation, function(boxname, pages) {
125
128
  pages.sort(slugComparator);
126
- var box = dom.div(".box").append(dom.h4().text(boxname));
129
+ var box = dom.div('.box').append(dom.h4().text(boxname));
127
130
  for (var i = 0, ii = pages.length; i < ii; i++) {
128
- var p = pages[i], page = dom.div(".page").text(p.slug).data('page', p);
131
+ var p = pages[i], page = dom.div('.page').text(p.slug).data('page', p);
129
132
  if (origin && p.id === origin.id) {
130
- page.addClass("current");
133
+ page.addClass('current');
131
134
  }
132
135
  page.click(load_page(p));
133
136
  box.append(page);
@@ -156,21 +159,26 @@ Spontaneous.TopBar = (function($, S) {
156
159
  return S.site_domain;
157
160
  },
158
161
  element: function() {
159
- var self = this, li = dom.li('.root');
162
+ var self = this, li = dom.li('.root-node');
160
163
  var link = dom.a({'href': this.url}).text(this.title).data('page', this.page);
161
164
  if (Object.keys(this.roots.roots).length === 1) {
162
- li.addClass("singluar");
165
+ li.addClass('singluar');
163
166
  } else {
164
167
  li.click(function(event) {
165
168
  var browser = new RootBrowser(self.roots);
166
169
  Spontaneous.Popover.open(event, browser);
167
170
  });
168
171
  }
169
- link.click(function() {
170
- var page = $(this).data('page');
171
- S.Location.load_id(page.id);
172
- return false;
173
- });
172
+ var loaded = S.Location.get('location')
173
+ , active = (loaded.id == this.page.id) // active == true represents the state where the currently shown page is this node
174
+ ;
175
+ if (!active) {
176
+ link.click(function() {
177
+ var page = $(this).data('page');
178
+ S.Location.load_id(page.id);
179
+ return false;
180
+ });
181
+ }
174
182
  disableParent(link);
175
183
  li.append(link);
176
184
  this.link = link;
@@ -189,7 +197,7 @@ Spontaneous.TopBar = (function($, S) {
189
197
  };
190
198
  AncestorNode.prototype = {
191
199
  element: function() {
192
- var page = this.page, li = dom.li(), link = $('<a/>').data('page', page).click(function() {
200
+ var page = this.page, li = dom.li('.ancestor-node'), link = $('<a/>').data('page', page).click(function() {
193
201
  var page = $(this).data('page');
194
202
  S.Location.load_id(page.id);
195
203
  return false;
@@ -198,9 +206,11 @@ Spontaneous.TopBar = (function($, S) {
198
206
  disableParent(link);
199
207
  li.append(link);
200
208
 
201
- li.click(function() {
209
+ li.click(function(e) {
202
210
  var browser = new PageBrowser(page);
203
- Spontaneous.Popover.open(event, browser);
211
+ Spontaneous.Popover.open(e, browser);
212
+ e.preventDefault();
213
+ return false;
204
214
  });
205
215
 
206
216
  return li;
@@ -218,11 +228,12 @@ Spontaneous.TopBar = (function($, S) {
218
228
  CurrentNode.prototype = {
219
229
  element: function() {
220
230
  var self = this
221
- , li = dom.li()
231
+ , li = dom.li('.current-node')
222
232
  , link = dom.a().text(self.title);
223
233
  li.click(function(event) {
224
234
  var browser = new PageBrowser(self.page, self.pages);
225
235
  Spontaneous.Popover.open(event, browser);
236
+ return false;
226
237
  });
227
238
  li.append(link);
228
239
  this.title_element = link;
@@ -246,6 +257,7 @@ Spontaneous.TopBar = (function($, S) {
246
257
  li.click(function(event) {
247
258
  var browser = new PageBrowser(self.origin, self.children());
248
259
  Spontaneous.Popover.open(event, browser);
260
+ return false;
249
261
  });
250
262
  return li;
251
263
  }.cache(),
@@ -255,7 +267,7 @@ Spontaneous.TopBar = (function($, S) {
255
267
  for (var boxname in children) {
256
268
  if (children.hasOwnProperty(boxname)) {
257
269
  for (var i = 0, box = children[boxname], ii = box.length; i < ii; ++i) {
258
- block(box[i])
270
+ block(box[i]);
259
271
  }
260
272
  }
261
273
  }
@@ -282,10 +294,10 @@ Spontaneous.TopBar = (function($, S) {
282
294
  },
283
295
  add_page: function(page, position) {
284
296
  var self = this
285
- , container = page.container
286
- , name = container.name()
297
+ , container = page.container
298
+ , name = container.name()
287
299
  , children = self.origin.children
288
- , box = children[name];
300
+ , box = children[name];
289
301
 
290
302
  if (!box) {
291
303
  box = [];
@@ -305,8 +317,8 @@ Spontaneous.TopBar = (function($, S) {
305
317
 
306
318
  remove_page: function(page) {
307
319
  var self = this
308
- , children = self.origin.children
309
- , container = page.container.name()
320
+ , children = self.origin.children
321
+ , container = page.container.name()
310
322
  , page_id = page.id()
311
323
  , index = (function(children) {
312
324
  for (var boxname in children) {
@@ -338,7 +350,7 @@ Spontaneous.TopBar = (function($, S) {
338
350
  user_loaded: function(user) {
339
351
  if (user.can_publish()) {
340
352
  this.disabled = false;
341
- this.button().removeClass("disabled").fadeIn();
353
+ this.button().removeClass('disabled').velocity('fadeIn');
342
354
  }
343
355
  },
344
356
  update_status: function(status) {
@@ -352,7 +364,7 @@ Spontaneous.TopBar = (function($, S) {
352
364
  this.in_progress = false;
353
365
  this.progress().stop();
354
366
  // this.set_interval(this.normal_check);
355
- this.set_label("Publish");
367
+ this.set_label('Publish');
356
368
  this.button().switchClass('progress', '');
357
369
  this.current_action = this.current_progress = null;
358
370
  // }
@@ -362,11 +374,11 @@ Spontaneous.TopBar = (function($, S) {
362
374
  } else {
363
375
  this.publishing_state();
364
376
  // don't turn off intermediate and replace it with an empty progress dial
365
- // by making sure our progress is > 0 before switching to progress view
366
- if ((progress !== "*")) {
367
- this.progress().update(progress);
368
- } else {
377
+ // by making sure our progress is > 1 before switching to progress view
378
+ if ((progress === '*') || (progress < 1.0)) {
369
379
  this.progress().indeterminate();
380
+ } else {
381
+ this.progress().update(progress);
370
382
  }
371
383
  }
372
384
  },
@@ -376,7 +388,7 @@ Spontaneous.TopBar = (function($, S) {
376
388
  },
377
389
  publishing_state: function() {
378
390
  // this.set_interval(this.rapid_check);
379
- this.set_label("Publishing");
391
+ this.set_label('Publishing');
380
392
  var b = this.button();
381
393
  this.current_action = this.current_progress = null;
382
394
  if (!b.hasClass('progress')) { b.switchClass('', 'progress'); }
@@ -393,7 +405,7 @@ Spontaneous.TopBar = (function($, S) {
393
405
  this._progress_container = dom.span('#publish-progress');
394
406
  this._label = dom.span();
395
407
  this._button = dom.a('#open-publish.disabled').append(this._progress_container).append(this._label).hide();
396
- this.set_label("Publish");
408
+ this.set_label('Publish');
397
409
  this._button.click(function() {
398
410
  if (!this.disabled && !this.in_progress) {
399
411
  S.Publishing.open_dialogue();
@@ -426,25 +438,25 @@ Spontaneous.TopBar = (function($, S) {
426
438
  });
427
439
 
428
440
  var CMSNavigationView = new JS.Class({
429
- initialize: function() {
430
-
441
+ initialize: function(topBar) {
442
+ this.topBar = topBar;
431
443
  },
432
444
  panel: function() {
433
445
  var self = this;
434
446
  if (!self.wrap) {
435
- self.wrap = dom.div("#cms-navigation-view");
447
+ self.wrap = dom.div('#cms-navigation-view');
436
448
  self.location = dom.ul('#navigation');
437
449
  self.mode_switch = dom.a('#switch-mode').
438
450
  text(S.TopBar.opposite_mode(S.ContentArea.mode)).
439
451
  click(function() {
440
- S.TopBar.toggle_modes();
452
+ S.TopBar.toggle_modes(self.previewModeDisabled);
441
453
  });
442
454
 
443
455
  self.publish_button = new PublishButton();
444
456
  self.wrap.append(self.location);
445
457
  self.wrap.append(self.publish_button.button());
446
458
  self.wrap.append(self.mode_switch);
447
- S.User.watch("user", function(user) { self.publish_button.user_loaded(user); });
459
+ S.User.watch('user', function(user) { self.publish_button.user_loaded(user); });
448
460
  }
449
461
  return self.wrap;
450
462
  },
@@ -456,6 +468,22 @@ Spontaneous.TopBar = (function($, S) {
456
468
  var children_node = new ChildrenNode(location);
457
469
  self.location.append(children_node.element());
458
470
  self.children_node = children_node;
471
+ self.updateModeCompatibility(location);
472
+ },
473
+ updateModeCompatibility: function(location) {
474
+ var self = this;
475
+ if (location.private) {
476
+ self.previewModeDisabled = true;
477
+ self.mode_switch.addClass('disabled');
478
+ } else {
479
+ self.previewModeDisabled = false;
480
+ self.mode_switch.removeClass('disabled');
481
+ }
482
+ if (self.previewModeDisabled) {
483
+ this.topBar.set_mode('edit');
484
+ } else {
485
+
486
+ }
459
487
  },
460
488
  page_loaded: function(page) {
461
489
  var self = this, children_node = self.children_node;
@@ -539,9 +567,9 @@ Spontaneous.TopBar = (function($, S) {
539
567
  },
540
568
  panel: function() {
541
569
  var self = this;
542
- this.wrap = dom.div("#service-navigation");
570
+ this.wrap = dom.div('#service-navigation');
543
571
  var title = dom.h2().text(this.service.title);
544
- var close = dom.a(".button").text("Close").click(function() {
572
+ var close = dom.a('.button').text('Close').click(function() {
545
573
  S.Services.close();
546
574
  });
547
575
  this.wrap.append(title, close);
@@ -550,23 +578,23 @@ Spontaneous.TopBar = (function($, S) {
550
578
  });
551
579
  var TopBar = new JS.Singleton({
552
580
  include: Spontaneous.Properties,
553
- location: "/",
581
+ location: '/',
554
582
  panel: function() {
555
583
  this.wrap = dom.div('#top');
556
584
  // this.icon = dom.div('#spontaneous-root');
557
585
  this.icon = this.rootMenu();
558
586
  this.holder = dom.div('#service-outer');
559
- this.navigationView = new CMSNavigationView();
560
- this.serviceStation = dom.div("#service-inner");
587
+ this.navigationView = new CMSNavigationView(this);
588
+ this.serviceStation = dom.div('#service-inner');
561
589
  this.holder.append(this.navigationView.panel(), this.serviceStation);
562
590
  this.wrap.append(this.icon, this.holder);
563
591
  return this.wrap;
564
592
  },
565
593
  rootMenu: function() {
566
594
  var li = dom.div('#spontaneous-root').click(function(event) {
567
- $(this).addClass("active"); // no easy way to remove this
595
+ $(this).addClass('active'); // no easy way to remove this
568
596
  Spontaneous.Popover.open(event, new Spontaneous.RootMenuView(function() {
569
- li.removeClass("active");
597
+ li.removeClass('active');
570
598
  }));
571
599
  });
572
600
  return li.append(dom.span());
@@ -575,7 +603,7 @@ Spontaneous.TopBar = (function($, S) {
575
603
  if (!this.get('mode')) {
576
604
  this.set('mode', S.ContentArea.mode);
577
605
  }
578
- this.navigationView.roots(metadata.roots)
606
+ this.navigationView.roots(metadata.roots);
579
607
  S.Editing.watch('page', this.page_loaded.bind(this));
580
608
  S.Location.watch('location', this.location_loaded.bind(this));
581
609
  },
@@ -601,8 +629,12 @@ Spontaneous.TopBar = (function($, S) {
601
629
  this.page_loaded = function(page) {
602
630
  };
603
631
  },
604
- toggle_modes: function() {
605
- this.set_mode(this.opposite_mode(this.get('mode')));
632
+ toggle_modes: function(previewModeDisabled) {
633
+ var newMode = this.opposite_mode(this.get('mode'));
634
+ if (previewModeDisabled && newMode === 'preview') {
635
+ return;
636
+ }
637
+ this.set_mode(newMode);
606
638
  },
607
639
  opposite_mode: function(to_mode) {
608
640
  if (to_mode === 'preview') {