spontaneous 0.2.0.alpha7 → 0.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -4
- data/Readme.markdown +1 -1
- data/application/css/definitions.css.scss +5 -0
- data/application/css/dialogue.css.scss +62 -0
- data/application/js/content.js +1 -1
- data/application/js/dom.js +1 -1
- data/application/js/event_source.js +3 -0
- data/application/js/{field_types/date_field.js → field/date.js} +2 -2
- data/application/js/{field_types/file_field.js → field/file.js} +2 -2
- data/application/js/{field_types/image_field.js → field/image.js} +54 -20
- data/application/js/{field_types/long_string_field.js → field/long_string.js} +2 -2
- data/application/js/{field_types/markdown_field.js → field/markdown.js} +2 -2
- data/application/js/{field_types/select_field.js → field/select.js} +2 -2
- data/application/js/{field_types/string_field.js → field/string.js} +21 -7
- data/application/js/{field_types/webvideo_field.js → field/webvideo.js} +2 -2
- data/application/js/field.js +2 -2
- data/application/js/publish.js +99 -19
- data/application/js/spontaneous.js +8 -8
- data/application/js/top_bar.js +6 -4
- data/db/migrations/20130109125023_add_page_publish_lock.rb +17 -0
- data/db/migrations/20130111161934_convert_bcrypt_passwords.rb +22 -0
- data/db/migrations/20130114120000_create_revision_tables.rb +106 -0
- data/db/migrations/20130116220423_add_index_to_archive.rb +9 -0
- data/lib/spontaneous/box.rb +53 -18
- data/lib/spontaneous/box_style.rb +2 -3
- data/lib/spontaneous/change.rb +39 -13
- data/lib/spontaneous/cli/fields.rb +29 -0
- data/lib/spontaneous/cli/init.rb +2 -2
- data/lib/spontaneous/cli/migrate.rb +0 -1
- data/lib/spontaneous/cli/server.rb +14 -10
- data/lib/spontaneous/cli/site.rb +20 -9
- data/lib/spontaneous/cli.rb +8 -6
- data/lib/spontaneous/collections/box_set.rb +11 -0
- data/lib/spontaneous/collections/field_set.rb +24 -1
- data/lib/spontaneous/concern.rb +37 -0
- data/lib/spontaneous/config.rb +3 -4
- data/lib/spontaneous/crypt/version.rb +130 -0
- data/lib/spontaneous/crypt.rb +84 -0
- data/lib/spontaneous/data_mapper/content_model/associations.rb +199 -0
- data/lib/spontaneous/data_mapper/content_model/column_accessors.rb +52 -0
- data/lib/spontaneous/data_mapper/content_model/instance_hooks.rb +34 -0
- data/lib/spontaneous/data_mapper/content_model/serialization.rb +54 -0
- data/lib/spontaneous/data_mapper/content_model/timestamps.rb +39 -0
- data/lib/spontaneous/data_mapper/content_model.rb +343 -0
- data/lib/spontaneous/data_mapper/content_table.rb +103 -0
- data/lib/spontaneous/data_mapper/dataset.rb +194 -0
- data/lib/spontaneous/data_mapper/scope.rb +195 -0
- data/lib/spontaneous/data_mapper.rb +161 -0
- data/lib/spontaneous/facet.rb +2 -2
- data/lib/spontaneous/field/base.rb +418 -0
- data/lib/spontaneous/field/date.rb +54 -0
- data/lib/spontaneous/{field_version.rb → field/field_version.rb} +1 -1
- data/lib/spontaneous/field/file.rb +100 -0
- data/lib/spontaneous/{field_types/image_field.rb → field/image.rb} +33 -33
- data/lib/spontaneous/{field_types/location_field.rb → field/location.rb} +2 -2
- data/lib/spontaneous/{field_types/long_string_field.rb → field/long_string.rb} +3 -3
- data/lib/spontaneous/field/markdown.rb +36 -0
- data/lib/spontaneous/{field_types/select_field.rb → field/select.rb} +4 -5
- data/lib/spontaneous/field/string.rb +17 -0
- data/lib/spontaneous/field/update.rb +156 -0
- data/lib/spontaneous/field/webvideo.rb +310 -0
- data/lib/spontaneous/field.rb +80 -0
- data/lib/spontaneous/generators/site/Gemfile.tt +2 -2
- data/lib/spontaneous/generators/site/config/environments/development.rb.tt +1 -1
- data/lib/spontaneous/generators/site/config/environments/production.rb.tt +1 -1
- data/lib/spontaneous/generators/site/lib/content.rb.tt +6 -0
- data/lib/spontaneous/generators/site/schema/box.rb.tt +3 -2
- data/lib/spontaneous/generators/site/schema/page.rb.tt +3 -1
- data/lib/spontaneous/generators/site/schema/piece.rb.tt +3 -1
- data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +3 -1
- data/lib/spontaneous/generators/site.rb +4 -3
- data/lib/spontaneous/image_size.rb +8 -1
- data/lib/spontaneous/layout.rb +5 -1
- data/lib/spontaneous/loader.rb +2 -5
- data/lib/spontaneous/media/file.rb +11 -2
- data/lib/spontaneous/media/temp_file.rb +23 -0
- data/lib/spontaneous/media.rb +20 -39
- data/lib/spontaneous/{plugins → model/box}/allowed_types.rb +38 -17
- data/lib/spontaneous/model/box.rb +18 -0
- data/lib/spontaneous/{plugins → model/core}/aliases.rb +10 -14
- data/lib/spontaneous/{plugins → model/core}/boxes.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/content_groups.rb +2 -2
- data/lib/spontaneous/model/core/editor_class.rb +4 -0
- data/lib/spontaneous/{plugins → model/core}/entries.rb +19 -7
- data/lib/spontaneous/{plugins → model/core}/entry.rb +3 -3
- data/lib/spontaneous/{plugins → model/core}/fields.rb +38 -5
- data/lib/spontaneous/{plugins → model/core}/instance_code.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/media.rb +2 -12
- data/lib/spontaneous/{plugins → model/core}/modifications.rb +7 -6
- data/lib/spontaneous/model/core/page_search.rb +36 -0
- data/lib/spontaneous/{plugins → model/core}/permissions.rb +4 -4
- data/lib/spontaneous/{plugins → model/core}/prototypes.rb +4 -4
- data/lib/spontaneous/{plugins → model/core}/publishing.rb +93 -115
- data/lib/spontaneous/{plugins → model/core}/render.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/schema_hierarchy.rb +7 -11
- data/lib/spontaneous/model/core/schema_id.rb +65 -0
- data/lib/spontaneous/{plugins → model/core}/schema_title.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/serialisation.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/styles.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/supertype.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/visibility.rb +7 -48
- data/lib/spontaneous/model/core.rb +143 -0
- data/lib/spontaneous/{plugins → model/page}/controllers.rb +3 -3
- data/lib/spontaneous/{plugins → model}/page/formats.rb +2 -2
- data/lib/spontaneous/{plugins → model/page}/layouts.rb +2 -2
- data/lib/spontaneous/model/page/locks.rb +14 -0
- data/lib/spontaneous/{plugins → model/page}/page_tree.rb +3 -3
- data/lib/spontaneous/{plugins → model/page}/paths.rb +30 -12
- data/lib/spontaneous/{plugins → model}/page/request.rb +2 -2
- data/lib/spontaneous/{plugins → model/page}/site_map.rb +2 -2
- data/lib/spontaneous/model/page/site_timestamps.rb +44 -0
- data/lib/spontaneous/{page.rb → model/page.rb} +49 -28
- data/lib/spontaneous/{piece.rb → model/piece.rb} +7 -6
- data/lib/spontaneous/model.rb +97 -0
- data/lib/spontaneous/output/context.rb +1 -1
- data/lib/spontaneous/output/format.rb +4 -0
- data/lib/spontaneous/output/template/renderer.rb +2 -2
- data/lib/spontaneous/output.rb +2 -2
- data/lib/spontaneous/page_lock.rb +62 -0
- data/lib/spontaneous/page_piece.rb +1 -1
- data/lib/spontaneous/permissions/access_key.rb +9 -4
- data/lib/spontaneous/permissions/user.rb +19 -9
- data/lib/spontaneous/permissions.rb +2 -5
- data/lib/spontaneous/plugins/application/facets.rb +1 -2
- data/lib/spontaneous/plugins/application/features.rb +1 -1
- data/lib/spontaneous/plugins/application/paths.rb +1 -1
- data/lib/spontaneous/plugins/application/render.rb +1 -1
- data/lib/spontaneous/plugins/application/serialisation.rb +1 -1
- data/lib/spontaneous/plugins/application/state.rb +30 -1
- data/lib/spontaneous/plugins/application/system.rb +12 -12
- data/lib/spontaneous/prototypes/box_prototype.rb +1 -1
- data/lib/spontaneous/prototypes/field_prototype.rb +3 -6
- data/lib/spontaneous/prototypes/style_prototype.rb +1 -1
- data/lib/spontaneous/publishing/immediate.rb +77 -49
- data/lib/spontaneous/publishing/revision.rb +355 -0
- data/lib/spontaneous/publishing/simultaneous.rb +10 -49
- data/lib/spontaneous/publishing.rb +1 -0
- data/lib/spontaneous/rack/around_back.rb +1 -1
- data/lib/spontaneous/rack/around_front.rb +2 -4
- data/lib/spontaneous/rack/around_preview.rb +1 -1
- data/lib/spontaneous/rack/back.rb +80 -63
- data/lib/spontaneous/rack/cacheable_file.rb +2 -2
- data/lib/spontaneous/rack/cookie_authentication.rb +1 -1
- data/lib/spontaneous/rack/front.rb +1 -1
- data/lib/spontaneous/rack/helpers.rb +8 -9
- data/lib/spontaneous/{page_controller.rb → rack/page_controller.rb} +1 -1
- data/lib/spontaneous/rack/public.rb +3 -3
- data/lib/spontaneous/rack.rb +15 -15
- data/lib/spontaneous/schema/uid.rb +4 -1
- data/lib/spontaneous/schema.rb +57 -24
- data/lib/spontaneous/search/database.rb +12 -1
- data/lib/spontaneous/search/index.rb +34 -6
- data/lib/spontaneous/search/results.rb +1 -1
- data/lib/spontaneous/server.rb +3 -3
- data/lib/spontaneous/simultaneous.rb +53 -0
- data/lib/spontaneous/{plugins/site → site}/features.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/helpers.rb +2 -3
- data/lib/spontaneous/{plugins/site → site}/hooks.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/instance.rb +4 -6
- data/lib/spontaneous/{plugins/site → site}/level.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/map.rb +4 -4
- data/lib/spontaneous/{plugins/site → site}/paths.rb +2 -2
- data/lib/spontaneous/site/publishing.rb +89 -0
- data/lib/spontaneous/{plugins/site → site}/schema.rb +4 -4
- data/lib/spontaneous/{plugins/site → site}/search.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/selectors.rb +15 -7
- data/lib/spontaneous/{plugins/site → site}/state.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/storage.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/url.rb +2 -2
- data/lib/spontaneous/site.rb +31 -14
- data/lib/spontaneous/state.rb +5 -6
- data/lib/spontaneous/style.rb +3 -2
- data/lib/spontaneous/utils/database/mysql_dumper.rb +13 -0
- data/lib/spontaneous/utils/database/postgres_dumper.rb +5 -0
- data/lib/spontaneous/version.rb +1 -1
- data/lib/spontaneous.rb +34 -89
- data/spontaneous.gemspec +112 -114
- data/test/experimental/test_crypt.rb +158 -0
- data/test/experimental/test_features.rb +3 -3
- data/test/fixtures/example_application/config/environments/development.rb +1 -1
- data/test/fixtures/example_application/lib/content.rb +5 -0
- data/test/fixtures/example_application/schema/page.rb +2 -1
- data/test/fixtures/example_application/schema/piece.rb +3 -2
- data/test/fixtures/serialisation/class_hash.yaml.erb +5 -5
- data/test/fixtures/serialisation/root_hash.yaml.erb +8 -0
- data/test/functional/test_application.rb +12 -1
- data/test/functional/test_back.rb +80 -48
- data/test/functional/test_front.rb +39 -46
- data/test/functional/test_user_manager.rb +3 -9
- data/test/javascript/test_markdown.rb +2 -2
- data/test/test_helper.rb +78 -23
- data/test/unit/test_alias.rb +21 -15
- data/test/unit/test_asset_bundler.rb +3 -3
- data/test/unit/test_assets.rb +2 -2
- data/test/unit/test_async.rb +7 -6
- data/test/unit/test_authentication.rb +43 -37
- data/test/unit/test_boxes.rb +46 -21
- data/test/unit/test_changesets.rb +65 -20
- data/test/unit/test_config.rb +9 -9
- data/test/unit/test_content.rb +50 -51
- data/test/unit/test_content_inheritance.rb +6 -20
- data/test/unit/test_datamapper.rb +1330 -0
- data/test/unit/test_datamapper_content.rb +214 -0
- data/test/unit/test_fields.rb +543 -54
- data/test/unit/test_formats.rb +2 -3
- data/test/unit/test_generators.rb +6 -6
- data/test/unit/test_helpers.rb +1 -1
- data/test/unit/test_image_size.rb +10 -5
- data/test/unit/test_images.rb +17 -18
- data/test/unit/test_layouts.rb +18 -3
- data/test/unit/test_media.rb +74 -49
- data/test/unit/test_modifications.rb +43 -43
- data/test/unit/test_page.rb +7 -10
- data/test/unit/test_permissions.rb +3 -10
- data/test/unit/test_piece.rb +5 -6
- data/test/unit/test_plugins.rb +7 -14
- data/test/unit/test_prototypes.rb +3 -3
- data/test/unit/test_publishing.rb +49 -27
- data/test/unit/test_render.rb +46 -15
- data/test/unit/test_revisions.rb +124 -127
- data/test/unit/test_schema.rb +53 -58
- data/test/unit/test_search.rb +64 -16
- data/test/unit/test_serialisation.rb +4 -11
- data/test/unit/test_site.rb +11 -12
- data/test/unit/test_structure.rb +2 -5
- data/test/unit/test_styles.rb +22 -24
- data/test/unit/test_type_hierarchy.rb +7 -5
- data/test/unit/test_visibility.rb +79 -55
- metadata +128 -102
- data/lib/sequel/plugins/content_table_inheritance.rb +0 -203
- data/lib/sequel/plugins/scoped_table_name.rb +0 -54
- data/lib/spontaneous/content.rb +0 -129
- data/lib/spontaneous/field_types/date_field.rb +0 -56
- data/lib/spontaneous/field_types/field.rb +0 -302
- data/lib/spontaneous/field_types/file_field.rb +0 -68
- data/lib/spontaneous/field_types/markdown_field.rb +0 -38
- data/lib/spontaneous/field_types/string_field.rb +0 -19
- data/lib/spontaneous/field_types/webvideo_field.rb +0 -313
- data/lib/spontaneous/field_types.rb +0 -38
- data/lib/spontaneous/generators/site/lib/site.rb.tt +0 -4
- data/lib/spontaneous/plugins/field/editor_class.rb +0 -13
- data/lib/spontaneous/plugins/page/site_timestamps.rb +0 -28
- data/lib/spontaneous/plugins/page_search.rb +0 -63
- data/lib/spontaneous/plugins/schema_id.rb +0 -68
- data/lib/spontaneous/plugins/site/publishing.rb +0 -75
- data/lib/spontaneous/rack/fiber_pool.rb +0 -26
- data/test/unit/test_table_scoping.rb +0 -80
data/Gemfile
CHANGED
@@ -2,13 +2,19 @@ source :rubygems
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
# gem "cutaneous", :path => "/Users/garry/Dropbox/Development/spontaneous3/cutaneous"
|
6
|
-
gem 'xapian-full', "~> 1.2.3"
|
7
|
-
gem 'xapian-fu', "~> 1.3"
|
8
|
-
|
9
5
|
group :development do
|
10
6
|
gem 'shoulda', '~> 2.11.3', :git => 'https://github.com/dasch/shoulda.git', :branch => 'minitest'
|
11
7
|
gem 'selenium-client', '~> 1.2.18', :platforms => [:mri_18]
|
12
8
|
# gem 'Selenium', '~> 1.1.14'
|
13
9
|
end
|
14
10
|
|
11
|
+
platforms :jruby do
|
12
|
+
gem 'jruby-openssl'
|
13
|
+
gem 'jdbc-postgres'
|
14
|
+
gem 'jdbc-mysql'
|
15
|
+
end
|
16
|
+
|
17
|
+
platforms :mri do
|
18
|
+
gem 'xapian-ruby', "~> 1.2.12"
|
19
|
+
gem 'xapian-fu', "~> 1.3"
|
20
|
+
end
|
data/Readme.markdown
CHANGED
@@ -8,7 +8,7 @@ This is version 2 of an existing (closed source) CMS that has been in active pro
|
|
8
8
|
|
9
9
|
Spontaneous uses a powerful hierarchical system to organise your information. This breaks out of the bonds of the traditional "title, slug, text" model of CMS content and instead allows content authors to build complex, highly styled pages out of simple, easily editable blocks.
|
10
10
|
|
11
|
-
- Ruby 1.9
|
11
|
+
- Ruby 1.9.3
|
12
12
|
- Using classes instead of db for metadata
|
13
13
|
- Versioning of metadata
|
14
14
|
- Keeps the developer in the text editor
|
@@ -85,6 +85,11 @@ $target-name-size: 14px;
|
|
85
85
|
-moz-border-radius: 0 $radius $radius 0;
|
86
86
|
border-radius: 0 $radius $radius 0; }
|
87
87
|
|
88
|
+
@mixin rounded-left($radius: $corner-radius) {
|
89
|
+
-webkit-border-radius: $radius 0 0 $radius;
|
90
|
+
-moz-border-radius: $radius 0 0 $radius;
|
91
|
+
border-radius: $radius 0 0 $radius; }
|
92
|
+
|
88
93
|
.shadow {
|
89
94
|
-webkit-box-shadow: 0px 3px 30px #cccccc;
|
90
95
|
-moz-box-shadow: 0px 3px 30px #cccccc; }
|
@@ -123,6 +123,7 @@ $dialogue-title-height: 32px;
|
|
123
123
|
border: solid 1px #f2f2f2;
|
124
124
|
margin: $unit;
|
125
125
|
margin-top: 0;
|
126
|
+
color: #333333;
|
126
127
|
&:hover {
|
127
128
|
background-color: #666;
|
128
129
|
color: #fff;
|
@@ -369,6 +370,67 @@ $dialogue-title-height: 32px;
|
|
369
370
|
}
|
370
371
|
.change-set.selected {
|
371
372
|
}
|
373
|
+
.change-set.locked {
|
374
|
+
.pages {
|
375
|
+
position: relative;
|
376
|
+
}
|
377
|
+
.info {
|
378
|
+
@include rounded-left;
|
379
|
+
position: absolute;
|
380
|
+
overflow: hidden;
|
381
|
+
right: 0;
|
382
|
+
top: 0;
|
383
|
+
bottom: 0;
|
384
|
+
width: 0;
|
385
|
+
background-color: rgba(33, 33, 33, 0.9);
|
386
|
+
color: #aaaaaa;
|
387
|
+
font-size: 0.7em;
|
388
|
+
.lock-state {
|
389
|
+
overflow: auto;
|
390
|
+
padding: $unit/2;
|
391
|
+
}
|
392
|
+
.locks {
|
393
|
+
strong {
|
394
|
+
margin-right: $unit/2;
|
395
|
+
&:after {
|
396
|
+
content: ":";
|
397
|
+
}
|
398
|
+
}
|
399
|
+
p {
|
400
|
+
margin: 0 0 $unit/2 0;
|
401
|
+
}
|
402
|
+
}
|
403
|
+
h3 {
|
404
|
+
font-size: 1em;
|
405
|
+
font-weight: normal;
|
406
|
+
margin: 0;
|
407
|
+
color: #fafafa;
|
408
|
+
margin: 0;
|
409
|
+
margin-bottom: $unit/2;
|
410
|
+
}
|
411
|
+
}
|
412
|
+
.page-title {
|
413
|
+
color: #999;
|
414
|
+
}
|
415
|
+
.add {
|
416
|
+
span {
|
417
|
+
&:before {
|
418
|
+
@include awesome-icon("\f023");
|
419
|
+
}
|
420
|
+
}
|
421
|
+
}
|
422
|
+
}
|
423
|
+
&.first-publish {
|
424
|
+
#changes {
|
425
|
+
display: none;
|
426
|
+
}
|
427
|
+
#to-publish {
|
428
|
+
position: absolute;
|
429
|
+
left: 0;
|
430
|
+
right: 0;
|
431
|
+
width: auto;
|
432
|
+
}
|
433
|
+
}
|
372
434
|
}
|
373
435
|
|
374
436
|
#root-menu {
|
data/application/js/content.js
CHANGED
@@ -101,7 +101,7 @@ Spontaneous.Content = (function($, S) {
|
|
101
101
|
"type:", "'"+type.title+"'",
|
102
102
|
"field_name:", f.name
|
103
103
|
);
|
104
|
-
type_class = Spontaneous.
|
104
|
+
type_class = Spontaneous.Field.String;
|
105
105
|
}
|
106
106
|
var field = new type_class(this, f);
|
107
107
|
// field.watch('value', this.field_updated.bind(this, field));
|
data/application/js/dom.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading DOM...');
|
2
2
|
|
3
3
|
Spontaneous.Dom = (function($, S) {
|
4
|
-
var tags = 'div p iframe a span img select option label ul li dl dt dd table tr td h1 h2 h3 h4 header input button form textarea optgroup'.split(' ');
|
4
|
+
var tags = 'div p iframe a span strong img select option label ul li dl dt dd table tr td h1 h2 h3 h4 header input button form textarea optgroup'.split(' ');
|
5
5
|
var Dom = {
|
6
6
|
body: function() {
|
7
7
|
return $(document.body);
|
@@ -11,6 +11,9 @@ Spontaneous.EventSource = (function($, S) {
|
|
11
11
|
|
12
12
|
addEventListener: function(event, callback) {
|
13
13
|
this.eventSource().addEventListener(event, callback);
|
14
|
+
},
|
15
|
+
removeEventListener: function(event, callback) {
|
16
|
+
this.eventSource().removeEventListener(event, callback);
|
14
17
|
}
|
15
18
|
});
|
16
19
|
return EventSource;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading DateField...')
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.Date = (function($, S) {
|
3
3
|
var dom = S.Dom;
|
4
|
-
var DateField = new JS.Class(Spontaneous.
|
4
|
+
var DateField = new JS.Class(Spontaneous.Field.String, {
|
5
5
|
input: function() {
|
6
6
|
var input = this.callSuper();
|
7
7
|
input.datepicker({ "dateFormat": "DD, d MM yy" });
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading FileField...')
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.File = (function($, S) {
|
3
3
|
var dom = S.Dom;
|
4
|
-
var FileField = new JS.Class(Spontaneous.
|
4
|
+
var FileField = new JS.Class(Spontaneous.Field.String, {
|
5
5
|
selected_files: false,
|
6
6
|
|
7
7
|
preview: function() {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading ImageField...')
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.Image = (function($, S) {
|
3
3
|
var dom = S.Dom;
|
4
|
-
var ImageFieldConflictView = new JS.Class(S.
|
4
|
+
var ImageFieldConflictView = new JS.Class(S.Field.String.ConflictView, {
|
5
5
|
|
6
6
|
panel: function() {
|
7
7
|
var labels = dom.div('.image-field-conflict.labels.differences'),
|
@@ -29,7 +29,7 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
29
29
|
}
|
30
30
|
});
|
31
31
|
|
32
|
-
var ImageField = new JS.Class(Spontaneous.
|
32
|
+
var ImageField = new JS.Class(Spontaneous.Field.File, {
|
33
33
|
is_image: function() {
|
34
34
|
return true;
|
35
35
|
},
|
@@ -57,10 +57,40 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
57
57
|
this.callSuper();
|
58
58
|
},
|
59
59
|
|
60
|
+
currentValue: function() {
|
61
|
+
var v = this.get('value');
|
62
|
+
if ((pending = v['__pending__'])) {
|
63
|
+
return pending['value'];
|
64
|
+
}
|
65
|
+
return v['__ui__'] || v['original'];
|
66
|
+
},
|
67
|
+
|
68
|
+
/*
|
69
|
+
* HACK: The async nature of image updates means that the version setting
|
70
|
+
* may be out of date not because of the actions of another, but because
|
71
|
+
* the field version has been updated in the background.
|
72
|
+
* The right way to do this would be to use an event to update the field
|
73
|
+
* values at the point where the update is complete, but that's a big change.
|
74
|
+
*
|
75
|
+
* If I do that then I could use it to update all field values across all sessions
|
76
|
+
* and avoid most conflicts by keeping the field values up-to-date automatically
|
77
|
+
* but I'm not ready for that just yet...
|
78
|
+
*
|
79
|
+
* Instead hackily use the pending version and hope it's not going to cause
|
80
|
+
* weird problems with simultaneous updates.
|
81
|
+
*/
|
82
|
+
version: function() {
|
83
|
+
var value = this.get("value");
|
84
|
+
if ((pending = value["__pending__"])) {
|
85
|
+
return pending["version"];
|
86
|
+
}
|
87
|
+
return this.data.version;
|
88
|
+
},
|
89
|
+
|
60
90
|
preview: function(container) {
|
61
91
|
Spontaneous.UploadManager.register(this);
|
62
92
|
var self = this
|
63
|
-
, value = this.
|
93
|
+
, value = this.currentValue()
|
64
94
|
, src = value.src
|
65
95
|
, img = null
|
66
96
|
, dim = 45
|
@@ -109,7 +139,7 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
109
139
|
this.spinner().indeterminate();
|
110
140
|
|
111
141
|
if (files.length > 0) {
|
112
|
-
this.
|
142
|
+
this.select_files(files);
|
113
143
|
var file = files[0],
|
114
144
|
url = window.URL.createObjectURL(file)
|
115
145
|
, image = this.image;
|
@@ -162,7 +192,7 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
162
192
|
return outer;
|
163
193
|
},
|
164
194
|
conflicts_resolved: function(resolution_list) {
|
165
|
-
console.log('conflicts_resolved', resolution_list)
|
195
|
+
// console.log('conflicts_resolved', resolution_list)
|
166
196
|
var resolution = resolution_list[0];
|
167
197
|
this.set_edited_value(resolution.value);
|
168
198
|
this.set_version(resolution.version);
|
@@ -187,10 +217,10 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
187
217
|
return this._spinner;
|
188
218
|
},
|
189
219
|
upload_complete: function(values) {
|
190
|
-
|
220
|
+
this.mark_unmodified();
|
191
221
|
this.callSuper(values)
|
192
222
|
if (values) {
|
193
|
-
var value = this.
|
223
|
+
var value = this.currentValue();
|
194
224
|
if (this.image) {
|
195
225
|
var img = new Image()
|
196
226
|
img.onload = function() {
|
@@ -202,20 +232,20 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
202
232
|
},
|
203
233
|
|
204
234
|
width: function() {
|
205
|
-
if (this.data.values && this.
|
206
|
-
return this.
|
235
|
+
if (this.data.values && this.currentValue()) {
|
236
|
+
return this.currentValue().width;
|
207
237
|
}
|
208
238
|
return 0;
|
209
239
|
},
|
210
240
|
height: function() {
|
211
|
-
if (this.data.values && this.
|
212
|
-
return this.
|
241
|
+
if (this.data.values && this.currentValue()) {
|
242
|
+
return this.currentValue().height;
|
213
243
|
}
|
214
244
|
return 0;
|
215
245
|
},
|
216
246
|
edit: function() {
|
217
247
|
var wrap = dom.div({'style':'position:relative;'}),
|
218
|
-
value = this.
|
248
|
+
value = this.currentValue(),
|
219
249
|
src = value.src,
|
220
250
|
img = dom.img({'src':src}),
|
221
251
|
info, sizes, filename_info, filesize_info, dimensions_info;
|
@@ -255,12 +285,11 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
255
285
|
if (files.length > 0) {
|
256
286
|
var file = files[0], url = window.URL.createObjectURL(file);
|
257
287
|
img.attr('src', url).removeClass('empty');
|
258
|
-
this.
|
288
|
+
this.select_files(files);
|
259
289
|
img.attr('src', url)
|
260
290
|
this._edited_value = url;
|
261
291
|
this.image.attr('src', url)
|
262
292
|
window.URL.revokeObjectURL(url);
|
263
|
-
console.log(file)
|
264
293
|
set_info(File.filename(file), file.fileSize, null, null)
|
265
294
|
}
|
266
295
|
}.bind(this);
|
@@ -328,8 +357,16 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
328
357
|
return wrap;
|
329
358
|
},
|
330
359
|
|
360
|
+
select_files: function(files) {
|
361
|
+
this.selected_files = files;
|
362
|
+
this.mark_modified();
|
363
|
+
},
|
364
|
+
|
365
|
+
is_modified: function() {
|
366
|
+
return this.get_modified_state();
|
367
|
+
},
|
368
|
+
|
331
369
|
get_input: function() {
|
332
|
-
console.log("FileField", "#get_input")
|
333
370
|
this.input = this.generate_input();
|
334
371
|
return this.input;
|
335
372
|
},
|
@@ -338,14 +375,11 @@ Spontaneous.FieldTypes.ImageField = (function($, S) {
|
|
338
375
|
return this.input.val();
|
339
376
|
},
|
340
377
|
cancel_edit: function() {
|
341
|
-
this.image.attr('src', this.
|
378
|
+
this.image.attr('src', this.currentValue().src);
|
342
379
|
},
|
343
380
|
conflict_view: function(dialogue, conflict) {
|
344
381
|
return new ImageFieldConflictView(dialogue, conflict);
|
345
382
|
},
|
346
|
-
original_value: function() {
|
347
|
-
return this.value().original;
|
348
|
-
},
|
349
383
|
edited_value: function() {
|
350
384
|
return this._edited_value;
|
351
385
|
},
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading LongStringField...')
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.LongString = (function($, S) {
|
3
3
|
var dom = S.Dom;
|
4
|
-
var LongStringField = new JS.Class(Spontaneous.
|
4
|
+
var LongStringField = new JS.Class(Spontaneous.Field.String, {
|
5
5
|
generate_input: function() {
|
6
6
|
return dom.textarea(dom.id(this.css_id()), {'name':this.form_name(), 'rows':10, 'cols':30}).text(this.unprocessed_value());
|
7
7
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// console.log('Loading DiscountField...')
|
2
2
|
|
3
|
-
Spontaneous.
|
3
|
+
Spontaneous.Field.Markdown = (function($, S) {
|
4
4
|
var dom = S.Dom;
|
5
5
|
var TextCommand = new JS.Class({
|
6
6
|
name: '',
|
@@ -594,7 +594,7 @@ Spontaneous.FieldTypes.MarkdownField = (function($, S) {
|
|
594
594
|
});
|
595
595
|
|
596
596
|
|
597
|
-
var MarkdownField = new JS.Class(Spontaneous.
|
597
|
+
var MarkdownField = new JS.Class(Spontaneous.Field.String, {
|
598
598
|
actions: [Bold, Italic, H1, H2, UL, OL, Link],
|
599
599
|
generate_input: function() {
|
600
600
|
var input = dom.textarea(dom.id(this.css_id()), {'name':this.form_name(), 'rows':10, 'cols':90}).val(this.unprocessed_value()), height = this.content.getFieldMetadata(this, 'height');
|
@@ -1,11 +1,11 @@
|
|
1
1
|
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.Select = (function($, S) {
|
3
3
|
"use strict";
|
4
4
|
|
5
5
|
var dom = S.Dom
|
6
6
|
, ajax = S.Ajax;
|
7
7
|
|
8
|
-
var SelectField = new JS.Class(Spontaneous.
|
8
|
+
var SelectField = new JS.Class(Spontaneous.Field.String, {
|
9
9
|
edit: function() {
|
10
10
|
var self = this
|
11
11
|
, type = this.type
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// console.log('Loading StringField...')
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.String = (function($, S) {
|
3
3
|
var dom = S.Dom;
|
4
4
|
var StringFieldConflictView = new JS.Class({
|
5
5
|
initialize: function(dialogue, conflict) {
|
@@ -106,13 +106,15 @@ Spontaneous.FieldTypes.StringField = (function($, S) {
|
|
106
106
|
return 'field-'+this.name+'-'+this.id();
|
107
107
|
},
|
108
108
|
form_name: function() {
|
109
|
-
return this.input_name(
|
109
|
+
return this.input_name();
|
110
110
|
},
|
111
|
-
version_name: function() {
|
112
|
-
|
113
|
-
},
|
114
|
-
input_name: function(
|
115
|
-
|
111
|
+
// version_name: function() {
|
112
|
+
// return this.input_name('version');
|
113
|
+
// },
|
114
|
+
input_name: function(param) {
|
115
|
+
var name = 'field['+this.schema_id()+']';
|
116
|
+
if (param) { n += '['+param+']'; }
|
117
|
+
return name;
|
116
118
|
},
|
117
119
|
schema_id: function() {
|
118
120
|
return this.type.schema_id;
|
@@ -145,6 +147,18 @@ Spontaneous.FieldTypes.StringField = (function($, S) {
|
|
145
147
|
// version in the case of a conflict
|
146
148
|
return true;
|
147
149
|
},
|
150
|
+
mark_modified: function() {
|
151
|
+
this.set_modified_state(true);
|
152
|
+
},
|
153
|
+
mark_unmodified: function() {
|
154
|
+
this.set_modified_state(false);
|
155
|
+
},
|
156
|
+
set_modified_state: function(state) {
|
157
|
+
this._is_modified = state;
|
158
|
+
},
|
159
|
+
get_modified_state: function() {
|
160
|
+
return this._is_modified;
|
161
|
+
},
|
148
162
|
original_value: function() {
|
149
163
|
return this.unprocessed_value();
|
150
164
|
},
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading DateField...')
|
2
|
-
Spontaneous.
|
2
|
+
Spontaneous.Field.WebVideo = (function($, S) {
|
3
3
|
var dom = S.Dom;
|
4
|
-
var WebVideoField = new JS.Class(Spontaneous.
|
4
|
+
var WebVideoField = new JS.Class(Spontaneous.Field.String, {
|
5
5
|
// get_input: function() {
|
6
6
|
// this.input = $(dom.textarea, {'id':this.css_id(), 'name':this.form_name(), 'rows':10, 'cols':30}).text(this.unprocessed_value());
|
7
7
|
// return this.input;
|
data/application/js/field.js
CHANGED
data/application/js/publish.js
CHANGED
@@ -6,6 +6,25 @@ Spontaneous.Publishing = (function($, S) {
|
|
6
6
|
var PublishingDialogue = new JS.Class(Dialogue, {
|
7
7
|
initialize: function(content) {
|
8
8
|
this.change_sets = [];
|
9
|
+
var callback = this.page_lock_removed.bind(this);
|
10
|
+
var page_lock_removed = function(event) {
|
11
|
+
callback($.parseJSON(event.data))
|
12
|
+
};
|
13
|
+
S.EventSource.addEventListener('page_lock_status', page_lock_removed);
|
14
|
+
this.page_lock_removed_listener = page_lock_removed;
|
15
|
+
},
|
16
|
+
page_lock_removed: function(page_ids) {
|
17
|
+
var changes = this.change_sets, toUnlock = [];
|
18
|
+
page_ids.forEach(function(id) {
|
19
|
+
toUnlock = toUnlock.concat(changes.filter(function(c) { return c.change.id == id }))
|
20
|
+
});
|
21
|
+
|
22
|
+
toUnlock.forEach(function(cs) {
|
23
|
+
cs.unlock();
|
24
|
+
});
|
25
|
+
},
|
26
|
+
cleanup: function() {
|
27
|
+
S.EventSource.removeEventListener('page_lock_status', this.page_lock_removed_listener);
|
9
28
|
},
|
10
29
|
width: function() {
|
11
30
|
return '90%';
|
@@ -44,35 +63,54 @@ Spontaneous.Publishing = (function($, S) {
|
|
44
63
|
this.close();
|
45
64
|
},
|
46
65
|
|
47
|
-
change_list_loaded: function(
|
48
|
-
var
|
66
|
+
change_list_loaded: function(outstanding) {
|
67
|
+
var change_list = outstanding.changes
|
68
|
+
, w = this.wrapper
|
69
|
+
, self = this
|
70
|
+
, changed_wrap = dom.div("#changes.change-list")
|
71
|
+
, publish_wrap = dom.div("#to-publish.change-list")
|
72
|
+
, first_publish = outstanding.first_publish
|
73
|
+
, append_to;
|
74
|
+
if (first_publish) {
|
75
|
+
w.addClass("first-publish");
|
76
|
+
}
|
49
77
|
w.empty();
|
50
|
-
var changed_wrap = dom.div("#changes.change-list"), publish_wrap = dom.div("#to-publish.change-list")
|
51
78
|
w.append(changed_wrap, publish_wrap)
|
52
79
|
if (change_list.length === 0) {
|
53
80
|
var summary = dom.p('.publish-up-to-date').text("The site is up to date");
|
54
81
|
w.append(summary);
|
55
|
-
|
82
|
+
self.disable_button('Publish');
|
56
83
|
} else {
|
57
84
|
var publish_all = dom.a('.button').text('Publish All').click(function() {
|
58
|
-
|
59
|
-
}.bind(
|
85
|
+
self.set_publish_all(true);
|
86
|
+
}.bind(self));
|
60
87
|
var clear_all = dom.a('.button').text('Clear All').click(function() {
|
61
|
-
|
62
|
-
}.bind(
|
88
|
+
self.set_publish_all(false);
|
89
|
+
}.bind(self));
|
90
|
+
|
63
91
|
var changed_toolbar = dom.div('.actions').append(dom.div().text("Modified pages")).append(publish_all);
|
64
|
-
var publish_toolbar = dom.div('.actions').append(dom.div().text("Publish pages"))
|
92
|
+
var publish_toolbar = dom.div('.actions').append(dom.div().text("Publish pages"));
|
93
|
+
if (!first_publish) {
|
94
|
+
publish_toolbar.append(clear_all);
|
95
|
+
}
|
65
96
|
var changed_entries = dom.div('.change-sets'), publish_entries = dom.div('.change-sets')
|
66
97
|
changed_wrap.append(changed_toolbar, changed_entries);
|
67
98
|
publish_wrap.append(publish_toolbar, publish_entries);
|
99
|
+
append_to = changed_entries;
|
100
|
+
if (first_publish) {
|
101
|
+
append_to = publish_entries;
|
102
|
+
}
|
68
103
|
for (var i = 0, ii = change_list.length; i < ii; i++) {
|
69
|
-
var cs = new ChangeSet(i,
|
70
|
-
|
71
|
-
|
104
|
+
var cs = new ChangeSet(i, self, change_list[i], first_publish);
|
105
|
+
self.change_sets.push(cs);
|
106
|
+
append_to.append(cs.panel())
|
72
107
|
}
|
73
|
-
|
74
|
-
|
75
|
-
|
108
|
+
if (!first_publish) {
|
109
|
+
publish_entries.append(dom.div('.instructions').text('Add pages to publish from the list on the left'));
|
110
|
+
}
|
111
|
+
|
112
|
+
self.changed_entries = changed_entries;
|
113
|
+
self.publish_entries = publish_entries;
|
76
114
|
}
|
77
115
|
},
|
78
116
|
set_publish_all: function(state) {
|
@@ -183,11 +221,23 @@ Spontaneous.Publishing = (function($, S) {
|
|
183
221
|
}
|
184
222
|
});
|
185
223
|
var ChangeSet = new JS.Class({
|
186
|
-
initialize: function(id, dialogue, change) {
|
224
|
+
initialize: function(id, dialogue, change, selected) {
|
187
225
|
this.id = id;
|
188
226
|
this.dialogue = dialogue;
|
189
227
|
this.change = change;
|
190
|
-
this.selected
|
228
|
+
this.selected = selected || false;
|
229
|
+
this.mustPublish = selected || false;
|
230
|
+
},
|
231
|
+
locks: function(){
|
232
|
+
return this.change.update_locks;
|
233
|
+
},
|
234
|
+
isLocked: function() {
|
235
|
+
return this.locks().length > 0;
|
236
|
+
},
|
237
|
+
unlock: function() {
|
238
|
+
var w = this.wrapper;
|
239
|
+
w.removeClass("locked").find(".lock-state").remove();
|
240
|
+
this.locks().length = 0;
|
191
241
|
},
|
192
242
|
page_ids: function() {
|
193
243
|
var ids = [this.change.id];
|
@@ -206,19 +256,48 @@ Spontaneous.Publishing = (function($, S) {
|
|
206
256
|
, page_list = dom.div('.pages')
|
207
257
|
, add = dom.div('.add').append(dom.span().text(''))
|
208
258
|
, page = this.page()
|
209
|
-
, pages = this.dependent_pages()
|
259
|
+
, pages = this.dependent_pages()
|
260
|
+
, locked = this.isLocked()
|
261
|
+
, info = dom.div(".info").hide();
|
210
262
|
|
211
263
|
if (page.isUnpublished()) {
|
212
264
|
w.addClass('unpublished');
|
213
265
|
}
|
266
|
+
if (locked) {
|
267
|
+
w.addClass('locked');
|
268
|
+
var lockState = dom.div(".lock-state")
|
269
|
+
, title = dom.h3().html("<strong>Cannot publish page</strong> until the following actions have completed:")
|
270
|
+
, details = dom.div(".locks")
|
271
|
+
, locks = this.locks();
|
272
|
+
locks.forEach(function(lock) {
|
273
|
+
var line = dom.p();
|
274
|
+
line.text(lock.description);
|
275
|
+
line.prepend(dom.strong().text(lock.location));
|
276
|
+
details.append(line);
|
277
|
+
});
|
278
|
+
lockState.append(title, details)
|
279
|
+
info.append(lockState);
|
280
|
+
page_list.append(info);
|
281
|
+
add.hover(function() {
|
282
|
+
info.show().animate({"width": "100%"}, 150);
|
283
|
+
}, function() {
|
284
|
+
info.hide().css("width", 0);
|
285
|
+
});
|
286
|
+
}
|
214
287
|
page_list.append(page.panel());
|
215
288
|
for (var i = 0, ii = pages.length; i < ii; i++) {
|
216
289
|
page_list.append(pages[i].panel());
|
217
290
|
}
|
291
|
+
|
218
292
|
add.click(function() {
|
219
293
|
this.select_toggle();
|
220
294
|
}.bind(this));
|
221
|
-
|
295
|
+
|
296
|
+
inner.append(page_list);
|
297
|
+
|
298
|
+
if (!this.mustPublish) {
|
299
|
+
inner.append(add);
|
300
|
+
}
|
222
301
|
w.append(inner);
|
223
302
|
return w;
|
224
303
|
},
|
@@ -229,6 +308,7 @@ Spontaneous.Publishing = (function($, S) {
|
|
229
308
|
},
|
230
309
|
select: function(state) {
|
231
310
|
var self = this;
|
311
|
+
if (this.isLocked()) { return ; }
|
232
312
|
if (state === self.selected) { return; }
|
233
313
|
if (!state && self.dependency_forces_publish()) {
|
234
314
|
return;
|
@@ -30,14 +30,14 @@
|
|
30
30
|
//= require box
|
31
31
|
//= require page
|
32
32
|
//= require field
|
33
|
-
//= require
|
34
|
-
//= require
|
35
|
-
//= require
|
36
|
-
//= require
|
37
|
-
//= require
|
38
|
-
//= require
|
39
|
-
//= require
|
40
|
-
//= require
|
33
|
+
//= require field/string
|
34
|
+
//= require field/long_string
|
35
|
+
//= require field/file
|
36
|
+
//= require field/image
|
37
|
+
//= require field/markdown
|
38
|
+
//= require field/date
|
39
|
+
//= require field/webvideo
|
40
|
+
//= require field/select
|
41
41
|
//= require content_area
|
42
42
|
//= require preview
|
43
43
|
//= require editing
|
data/application/js/top_bar.js
CHANGED
@@ -144,7 +144,7 @@ Spontaneous.TopBar = (function($, S) {
|
|
144
144
|
} else {
|
145
145
|
this.select.show();
|
146
146
|
}
|
147
|
-
return '('+(count)+'
|
147
|
+
return '('+(count)+' page'+(count === 1 ? '' : 's')+')';
|
148
148
|
},
|
149
149
|
optgroup: function(boxname) {
|
150
150
|
return dom.optgroup().attr('label', boxname);
|
@@ -378,9 +378,11 @@ Spontaneous.TopBar = (function($, S) {
|
|
378
378
|
}
|
379
379
|
});
|
380
380
|
|
381
|
-
page.
|
382
|
-
|
383
|
-
|
381
|
+
if (!page.is_root()) {
|
382
|
+
page.watch('slug', function(title) {
|
383
|
+
self.navigation_current.set_title(title);
|
384
|
+
});
|
385
|
+
}
|
384
386
|
|
385
387
|
page.title_field().watch('value', function(title) {
|
386
388
|
Spontaneous.set_browser_title(title);
|