scrivito_sdk 0.30.0 → 0.40.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scrivito/objs_controller.rb +29 -20
  3. data/app/controllers/scrivito/ui_controller.rb +18 -0
  4. data/app/helpers/scrivito_helper.rb +21 -4
  5. data/app/views/scrivito/objs/obj.json.jbuilder +1 -0
  6. data/app/views/scrivito/objs/update.json.jbuilder +1 -1
  7. data/app/views/scrivito/ui/index.html.erb +13 -0
  8. data/config/ca-bundle.crt +565 -3
  9. data/config/routes.rb +4 -0
  10. data/lib/assets/javascripts/scrivito_sdk.js +28 -19545
  11. data/lib/assets/javascripts/scrivito_ui.js +30398 -0
  12. data/lib/assets/stylesheets/scrivito_sdk.css +228 -232
  13. data/lib/assets/stylesheets/scrivito_ui.css +3148 -0
  14. data/lib/generators/scrivito/install/install_generator.rb +4 -0
  15. data/lib/generators/scrivito/install/templates/app/views/layouts/scrivito_dialog.html.erb +13 -0
  16. data/lib/generators/scrivito/page/templates/details.html.erb +1 -1
  17. data/lib/generators/scrivito/widget/templates/details.html.erb +1 -1
  18. data/lib/generators/scrivito/widget/templates/show.html.erb +1 -1
  19. data/lib/generators/scrivito/widget/templates/thumbnail.html.erb +2 -2
  20. data/lib/generators/scrivito/widget/widget_generator.rb +12 -0
  21. data/lib/scrivito/attribute_content.rb +4 -5
  22. data/lib/scrivito/basic_obj.rb +47 -8
  23. data/lib/scrivito/basic_widget.rb +41 -14
  24. data/lib/scrivito/cache.rb +2 -0
  25. data/lib/scrivito/child_list_tag.rb +1 -1
  26. data/lib/scrivito/client_config.rb +9 -11
  27. data/lib/scrivito/cms_backend.rb +5 -4
  28. data/lib/scrivito/cms_field_tag.rb +6 -2
  29. data/lib/scrivito/cms_rest_api/attribute_serializer.rb +2 -0
  30. data/lib/scrivito/cms_rest_api/widget_extractor.rb +5 -5
  31. data/lib/scrivito/connection_manager.rb +1 -0
  32. data/lib/scrivito/controller_actions.rb +24 -3
  33. data/lib/scrivito/image_tag_helper.rb +0 -12
  34. data/lib/scrivito/layout_tags.rb +1 -8
  35. data/lib/scrivito/link_parser.rb +5 -0
  36. data/lib/scrivito/{memberships_collection.rb → membership_collection.rb} +2 -2
  37. data/lib/scrivito/obj_class.rb +3 -6
  38. data/lib/scrivito/{objs_collection.rb → obj_collection.rb} +1 -1
  39. data/lib/scrivito/obj_create_params_parser.rb +15 -0
  40. data/lib/scrivito/obj_params_parser.rb +37 -45
  41. data/lib/scrivito/obj_update_params_parser.rb +25 -0
  42. data/lib/scrivito/revision.rb +6 -2
  43. data/lib/scrivito/sdk_engine.rb +6 -1
  44. data/lib/scrivito/test_request.rb +4 -0
  45. data/lib/scrivito/uploaded_binary.rb +4 -0
  46. data/lib/scrivito/user.rb +8 -0
  47. data/lib/scrivito/widget_collection.rb +22 -0
  48. data/lib/scrivito/workspace.rb +11 -6
  49. metadata +17 -11
  50. data/app/views/scrivito/objs/copy.json.jbuilder +0 -1
  51. data/app/views/scrivito/objs/create.json.jbuilder +0 -1
  52. data/app/views/scrivito/objs/details.json.jbuilder +0 -1
  53. data/lib/scrivito/widget_field_params.rb +0 -61
@@ -42,15 +42,17 @@ module ControllerActions
42
42
  end
43
43
 
44
44
  def widget_details
45
+ assert_dialog_layout
45
46
  widget = load_widget
46
47
  template_path = "#{widget.obj_class_name.underscore}/details"
47
- render template_path, layout: false, locals: {widget: widget}
48
+ render template_path, layout: 'scrivito_dialog', locals: {widget: widget}
48
49
  end
49
50
 
50
51
  def details_page
52
+ assert_dialog_layout
51
53
  @scrivito_resource = editing_context.selected_workspace.objs
52
54
  .find_including_deleted(params[:resource_id])
53
- render text: '', layout: true
55
+ render text: '', layout: 'scrivito_dialog'
54
56
  end
55
57
 
56
58
  module ClassMethods
@@ -79,6 +81,8 @@ module ControllerActions
79
81
  request.env[EditingContextMiddleware::ENVKEY] || EditingContext.new
80
82
  end
81
83
 
84
+ delegate :comparison, to: :editing_context
85
+
82
86
  def load_object
83
87
  CmsEnv.new(request.env).load
84
88
  loaded_obj = request.env[CmsEnv::OBJ_ENV_KEY]
@@ -87,7 +91,12 @@ module ControllerActions
87
91
  end
88
92
 
89
93
  def load_widget
90
- @obj.widget_from_pool(params[:widget_id])
94
+ if widget = @obj.widget_from_pool(params[:widget_id])
95
+ widget
96
+ elsif comparison.active? # The "diff" mode.
97
+ @obj.in_revision(editing_context.selected_workspace.base_revision)
98
+ .widget_from_pool(params[:widget_id])
99
+ end
91
100
  end
92
101
 
93
102
  #
@@ -103,6 +112,18 @@ module ControllerActions
103
112
  render text: 'Empty Blob', status: 404
104
113
  end
105
114
  end
115
+
116
+ def assert_dialog_layout
117
+ view_context.lookup_context.find('layouts/scrivito_dialog')
118
+ rescue ActionView::MissingTemplate
119
+ raise %{
120
+ Missing the Scrivito dialog layout!
121
+
122
+ Scrivito requires a special view layout in order to render the details dialog.
123
+ Normally the install generator places it in `app/views/layouts/scrivito_dialog.html.erb`.
124
+ If upgrading Scrivito, please re-run the install generator: `rails g scrivito:install`.
125
+ }
126
+ end
106
127
  end
107
128
 
108
129
  end
@@ -13,24 +13,12 @@ class ImageTagHelper < Struct.new(:view_context)
13
13
  end
14
14
 
15
15
  def options(obj, field_name, tag_options, editing_options)
16
- if field_name.nil?
17
- field_name = determine_field_name(obj)
18
- end
19
-
20
16
  tag_options.reverse_merge(src: scrivito_image_tag_src(obj, field_name, editing_options),
21
17
  alt: scrivito_image_tag_alt(obj, field_name))
22
18
  end
23
19
 
24
20
  private
25
21
 
26
- def determine_field_name(obj)
27
- if obj.binary?
28
- :blob
29
- else
30
- raise ScrivitoError, "when omitting `field_name' you have to pass a binary obj"
31
- end
32
- end
33
-
34
22
  def scrivito_image_tag_src(obj, field_name, editing_options)
35
23
  scrivito_image_tag_path(obj, field_name) || editing_options[:placeholder] ||
36
24
  view_context.image_path('scrivito/image_placeholder.png')
@@ -8,7 +8,7 @@ class LayoutTags < Struct.new(:view)
8
8
  resource: resource,
9
9
  return_to: view.params[:return_to]
10
10
  ).to_json
11
- view.content_tag(:div, '', 'data-scrivito-private-config' => config, style: 'display:none')
11
+ view.content_tag(:div, '', 'data-scrivito-private-config' => config)
12
12
  end
13
13
  end
14
14
 
@@ -21,13 +21,6 @@ class LayoutTags < Struct.new(:view)
21
21
  content << "; Version #{GemInfo.version}" if view.scrivito_user
22
22
  view.tag(:meta, name: 'generator', content: content)
23
23
  end
24
-
25
- def reset_stylesheet_tag
26
- view.content_tag(:style, %{
27
- *[data-scrivito-field-type="widget"],
28
- *[data-scrivito-private-widget-id] { position: relative; }
29
- }.squish, {type: 'text/css'}, false)
30
- end
31
24
  end
32
25
 
33
26
  end
@@ -9,6 +9,11 @@ module Scrivito
9
9
 
10
10
  def parse(url)
11
11
  uri = Addressable::URI.parse(url)
12
+
13
+ if (params = route(uri.to_s)) && params[:controller] == 'scrivito/ui'
14
+ uri.path = params[:application_path]
15
+ end
16
+
12
17
  link_params = {}
13
18
 
14
19
  if obj = find_obj(uri)
@@ -1,8 +1,8 @@
1
1
  module Scrivito
2
2
  # @api public
3
- # The MembershipsCollection includes all members of a given {Workspace}.
3
+ # The MembershipCollection includes all members of a given {Workspace}.
4
4
  # You can access it using {Workspace#memberships} method.
5
- class MembershipsCollection
5
+ class MembershipCollection
6
6
  extend Forwardable
7
7
  include Enumerable
8
8
 
@@ -8,16 +8,13 @@ module Scrivito
8
8
  include ModelIdentity
9
9
 
10
10
  class << self
11
- # Returns all the obj classes.
12
11
  #
12
+ # Returns all obj classes.
13
13
  # @api public
14
+ # @return Scrivito::ObjClassCollection
14
15
  #
15
- # @example Find all obj classes in the current {Scrivito::Workspace}.
16
- # ObjClass.all
17
- #
18
- # @return [Array<Scrivito::ObjClass>]
19
16
  def all
20
- Workspace.current.obj_classes.to_a
17
+ Workspace.current.obj_classes
21
18
  end
22
19
 
23
20
  # Finds an obj class by its name.
@@ -2,7 +2,7 @@ module Scrivito
2
2
  # This class allows you to retrieve Objects from a specific working copy.
3
3
  # You can get an instance by accessing {Workspace#objs}.
4
4
  # @api public
5
- class ObjsCollection
5
+ class ObjCollection
6
6
  attr_reader :workspace
7
7
 
8
8
  def initialize(workspace)
@@ -0,0 +1,15 @@
1
+ module Scrivito
2
+ class ObjCreateParamsParser < Struct.new(:host, :port)
3
+ include ObjParamsParser
4
+
5
+ private
6
+
7
+ def convert_params(params)
8
+ if obj_class_name = params['_obj_class']
9
+ convert_field_params(ObjClass.find(obj_class_name), params)
10
+ else
11
+ raise ArgumentError, 'Missing "_obj_class" param'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,63 +1,55 @@
1
1
  module Scrivito
2
- class ObjParamsParser
3
- def initialize(host, port)
4
- @host = host
5
- @port = port
2
+ module ObjParamsParser
3
+ class UnknownWidgetAction < ScrivitoError
6
4
  end
7
5
 
8
- def parse(obj, orig_params)
9
- raise "Required parameter 'obj' is missing." unless orig_params.present?
10
- raise "Parameter 'obj' is not a hash." unless orig_params.is_a?(Hash)
11
-
12
- params = orig_params.dup
13
-
14
- if obj
15
- widget_field_params = WidgetFieldParams.new
16
-
17
- convert_params(params, obj, widget_field_params)
18
-
19
- if widget_pool_params = params['_widget_pool']
20
- convert_widget_pool_params(widget_pool_params, obj, widget_field_params)
21
- end
22
-
23
- additional_widget_pool_params = widget_field_params.pool_params
24
- if additional_widget_pool_params.any?
25
- params['_widget_pool'] ||= {}
26
- params['_widget_pool'].merge!(additional_widget_pool_params)
27
- end
28
- end
29
-
6
+ def parse(params)
7
+ params = params.deep_dup
8
+ convert_params(params)
30
9
  params
31
10
  end
32
11
 
33
12
  private
34
13
 
35
- def convert_widget_pool_params(widget_pool_params, obj, widget_field_params_parser)
36
- widget_pool_params.each_pair do |widget_id, widget_params|
37
- widget = obj.widget_from_pool(widget_id)
38
- if widget_params.present?
39
- convert_params(widget_params, widget, widget_field_params_parser)
14
+ def convert_field_params(obj_class, params)
15
+ params.each_pair do |key, value|
16
+ if key.to_s == 'blob' && obj_class.legacy_type?
17
+ params[key] = parse_binary_field_params(value)
18
+ next
40
19
  end
20
+
21
+ params[key] = case type = obj_class.attributes[key].try(:type)
22
+ when 'html' then ContentConversion.convert_html_links(value, host, port)
23
+ when 'linklist' then ContentConversion.convert_linklist_urls(value, host, port)
24
+ when 'link' then ContentConversion.convert_link(value, host, port)
25
+ when 'widget' then parse_widget_field_params(value)
26
+ when 'binary' then parse_binary_field_params(value)
27
+ else value
28
+ end
41
29
  end
42
30
  end
43
31
 
44
- def convert_params(params, obj, widget_field_params)
45
- params.each do |key, value|
46
- type = obj.type_of_attribute(key.to_s)
47
-
48
- params[key] = case type
49
- when 'html'
50
- ContentConversion.convert_html_links(value, @host, @port)
51
- when 'linklist'
52
- ContentConversion.convert_linklist_urls(value, @host, @port)
53
- when 'link'
54
- ContentConversion.convert_link(value, @host, @port)
55
- when 'widget'
56
- widget_field_params.convert(value)
32
+ def parse_widget_field_params(params)
33
+ params.map do |widget_id_or_params|
34
+ if widget_id_or_params.is_a?(Hash)
35
+ action, widget_params = widget_id_or_params.flatten
36
+ case action
37
+ when 'create' then Widget.new(widget_params)
38
+ when 'copy'
39
+ widget_id = widget_params['src_widget_id']
40
+ widget = Obj.find(widget_params['src_obj_id']).widgets[widget_id]
41
+ raise ResourceNotFound, "Could not find Widget with id #{widget_id}" unless widget
42
+ widget.copy
43
+ else raise UnknownWidgetAction
44
+ end
57
45
  else
58
- value
46
+ obj.widgets[widget_id_or_params]
59
47
  end
60
48
  end
61
49
  end
50
+
51
+ def parse_binary_field_params(params)
52
+ UploadedBinary.new(params) if params
53
+ end
62
54
  end
63
55
  end
@@ -0,0 +1,25 @@
1
+ module Scrivito
2
+ class ObjUpdateParamsParser < Struct.new(:obj, :host, :port)
3
+ include ObjParamsParser
4
+
5
+ private
6
+
7
+ def convert_params(params)
8
+ convert_field_params(obj.obj_class, params)
9
+ convert_widget_pool_params(params)
10
+ end
11
+
12
+ def convert_widget_pool_params(params)
13
+ return unless params['_widget_pool']
14
+
15
+ widget_pool = {}
16
+ params['_widget_pool'].each_pair do |widget_id, widget_params|
17
+ if widget_params.present?
18
+ widget = obj.widgets[widget_id]
19
+ widget_pool[widget] = convert_field_params(widget.obj_class, widget_params)
20
+ end
21
+ end
22
+ params['_widget_pool'] = widget_pool
23
+ end
24
+ end
25
+ end
@@ -1,8 +1,12 @@
1
1
  module Scrivito
2
2
 
3
- class Revision < Struct.new(:id, :content_state, :workspace)
3
+ class Revision < Struct.new(:id, :content_state, :workspace, :base)
4
4
  def initialize(options)
5
- super(*options.values_at(:id, :content_state, :workspace))
5
+ super(*options.values_at(:id, :content_state, :workspace, :base))
6
+ end
7
+
8
+ def base?
9
+ !!base
6
10
  end
7
11
  end
8
12
 
@@ -36,7 +36,12 @@ module ::Scrivito
36
36
 
37
37
  initializer 'scrivito.add_sdk_assets' do |app|
38
38
  # Specify which file should be precompiled for packaging
39
- app.config.assets.precompile += %w(scrivito_sdk.js scrivito_sdk.css)
39
+ app.config.assets.precompile += %w[
40
+ scrivito_sdk.css
41
+ scrivito_sdk.js
42
+ scrivito_ui.css
43
+ scrivito_ui.js
44
+ ]
40
45
  app.config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
41
46
  end
42
47
 
@@ -36,5 +36,9 @@ module Scrivito
36
36
  end
37
37
  end
38
38
  end
39
+
40
+ def for_cms_object(*args)
41
+ raise "The method `for_cms_object' was removed. Please use `for_scrivito_obj' instead"
42
+ end
39
43
  end
40
44
  end
@@ -0,0 +1,4 @@
1
+ module Scrivito
2
+ class UploadedBinary < Struct.new(:params)
3
+ end
4
+ end
data/lib/scrivito/user.rb CHANGED
@@ -144,6 +144,8 @@ module Scrivito
144
144
  # @param [BasicObj] obj the obj that should be published
145
145
  # @return [Array<String>] Hints why the user can't publish
146
146
  def restriction_messages_for(obj)
147
+ assert_restrictions_applicable(obj)
148
+
147
149
  return [] if can_always?(:publish, :workspace)
148
150
 
149
151
  if obj.modification == Modification::EDITED
@@ -185,6 +187,12 @@ module Scrivito
185
187
  raise ScrivitoError.new("Invalid verb '#{verb}'") unless VERBS.include?(verb)
186
188
  end
187
189
 
190
+ def assert_restrictions_applicable(obj)
191
+ if obj.revision.base?
192
+ raise ScrivitoError.new("The revision of #{obj.inspect} may not be a base revision")
193
+ end
194
+ end
195
+
188
196
  def sandbox_suggest_user_proc(input)
189
197
  suggest_users_proc.call(input)
190
198
  rescue Exception => e
@@ -0,0 +1,22 @@
1
+ module Scrivito
2
+ # @api public
3
+ # The +WidgetCollection+ represents all {Scrivito::BasicWidget Widgets} referenced by an
4
+ # {Scrivito::BasicObj Obj} or its subwidgets.
5
+ class WidgetCollection
6
+ def initialize(obj)
7
+ @obj = obj
8
+ end
9
+
10
+ # @api public
11
+ # Access a {Scrivito::BasicWidget Widget} by its +id+
12
+ # @param [String] widget_id the id of the widget
13
+ # @return [Scrivito::BasicWidget, nil] the Widget with the given +widget_id+ or nil
14
+ def [](widget_id)
15
+ obj.widget_from_pool(widget_id)
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :obj
21
+ end
22
+ end
@@ -181,9 +181,9 @@ class Workspace
181
181
  # @api public
182
182
  # Returns the members of this workspace and their roles
183
183
  #
184
- # @return [MembershipsCollection]
184
+ # @return [MembershipCollection]
185
185
  def memberships
186
- @memberships ||= MembershipsCollection.new(self)
186
+ @memberships ||= MembershipCollection.new(self)
187
187
  end
188
188
 
189
189
  def data
@@ -208,7 +208,12 @@ class Workspace
208
208
 
209
209
  def base_revision
210
210
  if base_revision_id
211
- @base_revision ||= Revision.new(id: base_revision_id, content_state: base_content_state)
211
+ @base_revision ||= Revision.new(
212
+ id: base_revision_id,
213
+ content_state: base_content_state,
214
+ workspace: self,
215
+ base: true
216
+ )
212
217
  end
213
218
  end
214
219
 
@@ -229,11 +234,11 @@ class Workspace
229
234
  raise ScrivitoError, 'rtc workspace may contain attribute and class changes' if rtc?
230
235
  end
231
236
 
232
- # {ObjsCollection} for this working copy
237
+ # {ObjCollection} for this working copy
233
238
  # @api public
234
- # @return {ObjsCollection}
239
+ # @return {ObjCollection}
235
240
  def objs
236
- @objs ||= ObjsCollection.new(self)
241
+ @objs ||= ObjCollection.new(self)
237
242
  end
238
243
 
239
244
  # Returns all obj classes of this working copy.