scrivito_sdk 1.16.0.rc1 → 1.17.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/cms/scrivito/attribute_serializer.rb +2 -0
- data/app/cms/scrivito/basic_obj.rb +73 -24
- data/app/cms/scrivito/basic_widget.rb +36 -14
- data/app/cms/scrivito/cms_backend.rb +1 -1
- data/app/cms/scrivito/cms_field_tag.rb +2 -2
- data/app/cms/scrivito/cms_rest_api.rb +7 -4
- data/app/cms/scrivito/cms_rest_api/widget_extractor.rb +42 -27
- data/app/cms/scrivito/controller_actions.rb +1 -1
- data/app/cms/scrivito/editing_context_middleware.rb +2 -4
- data/app/cms/scrivito/layout_tags.rb +3 -3
- data/app/cms/scrivito/migrations/migration_store.rb +2 -2
- data/app/cms/scrivito/obj_collection.rb +5 -5
- data/app/cms/scrivito/obj_search_enumerator.rb +47 -0
- data/app/cms/scrivito/page_config.rb +2 -2
- data/app/cms/scrivito/sdk_engine.rb +1 -1
- data/app/cms/scrivito/ui_config.rb +3 -2
- data/app/controllers/scrivito/objs_controller.rb +2 -2
- data/app/controllers/scrivito/ui_controller.rb +2 -2
- data/config/ca-bundle.crt +143 -78
- data/lib/assets/javascripts/scrivito.js +1 -1
- data/lib/assets/javascripts/scrivito_ui_redirect.js +1 -1
- data/lib/assets/javascripts/scrivito_with_js_sdk.js +58 -107
- data/lib/assets/stylesheets/scrivito_editing.css +1 -1
- metadata +8 -37
- data/app/views/google_maps_widget/show.html.erb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24bd5086592408534913facabf378aca4cee04e9d749b33bc9b22e2fd253849f
|
4
|
+
data.tar.gz: c840807dab6c5ec6c0f9f4cfa97b900a27ef739f415c06a18fb91c70609f2833
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae653310b1e55e892d45e37c1a1748a01231b5d34b8e1180cae0000ef6e2dddde3694415cdc609e065cf530f929587c5cb1e1d431d20f296a201b8a6f4286da9
|
7
|
+
data.tar.gz: 7ad67012b3de012bada117385977b1438d6791bb2a5750da7e27dbadff818af5d0e84da79921929277b6e5f228f57b50f4c499af86a3a4ed40616252c6363533
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ of concepts and APIs, tutorials, and release notes.
|
|
12
12
|
|
13
13
|
## License
|
14
14
|
|
15
|
-
Copyright (c) 2009 -
|
15
|
+
Copyright (c) 2009 - 2020 Infopark Group GmbH (http://www.infopark.com)
|
16
16
|
|
17
17
|
This software can be used and modified under the LGPL-3.0. Please refer to
|
18
18
|
http://www.gnu.org/licenses/lgpl-3.0.html for the license text.
|
@@ -29,6 +29,8 @@ class AttributeSerializer < Struct.new(:obj_class, :obj_id)
|
|
29
29
|
_permalink
|
30
30
|
].include?(attribute_name)
|
31
31
|
[attribute_name, attribute_value.to_s]
|
32
|
+
elsif attribute_name == '_restriction'
|
33
|
+
[attribute_name, attribute_value]
|
32
34
|
else
|
33
35
|
raise_unknown_attribute(attribute_name)
|
34
36
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'json'
|
2
1
|
require 'ostruct'
|
3
2
|
require 'active_model/naming'
|
4
3
|
|
@@ -25,15 +24,18 @@ module Scrivito
|
|
25
24
|
PublicSystemAttributeDefinition = Class.new(AttributeDefinition)
|
26
25
|
|
27
26
|
SYSTEM_ATTRIBUTES = AttributeDefinitionCollection.new(
|
28
|
-
'_id'
|
29
|
-
'
|
30
|
-
'
|
31
|
-
'
|
32
|
-
'
|
33
|
-
|
34
|
-
'
|
35
|
-
'
|
36
|
-
|
27
|
+
'_id' => PublicSystemAttributeDefinition.new(:_id, :string),
|
28
|
+
'_created_at' => PublicSystemAttributeDefinition.new(:_created_at, :date),
|
29
|
+
'_last_changed' => PublicSystemAttributeDefinition.new(:_last_changed, :date),
|
30
|
+
'_first_published_at' => PublicSystemAttributeDefinition.new(:_first_published_at, :date),
|
31
|
+
'_published_at' => PublicSystemAttributeDefinition.new(:_published_at, :date),
|
32
|
+
'_obj_class' => PublicSystemAttributeDefinition.new(:_obj_class, :string),
|
33
|
+
'_path' => PublicSystemAttributeDefinition.new(:_path, :string),
|
34
|
+
'_permalink' => PublicSystemAttributeDefinition.new(:_permalink, :string),
|
35
|
+
|
36
|
+
'_conflicts' => AttributeDefinition.new(:_conflicts, nil),
|
37
|
+
'_modification' => AttributeDefinition.new(:_modification, nil),
|
38
|
+
'_widget_pool' => AttributeDefinition.new(:_widget_pool, nil),
|
37
39
|
)
|
38
40
|
|
39
41
|
UNIQ_ATTRIBUTES = %w[
|
@@ -44,7 +46,10 @@ module Scrivito
|
|
44
46
|
|
45
47
|
GENERATED_ATTRIBUTES = %w[
|
46
48
|
_conflicts
|
49
|
+
_created_at
|
47
50
|
_last_changed
|
51
|
+
_first_published_at
|
52
|
+
_published_at
|
48
53
|
_modification
|
49
54
|
_obj_type
|
50
55
|
_text_links
|
@@ -138,14 +143,14 @@ module Scrivito
|
|
138
143
|
else
|
139
144
|
attributes = build_attributes_with_defaults(attributes, context)
|
140
145
|
attributes = prepare_attributes_for_instantiation(attributes)
|
141
|
-
|
146
|
+
extraction, api_attributes = prepare_attributes_for_rest_api(attributes)
|
142
147
|
|
143
148
|
workspace = Workspace.current
|
144
149
|
obj_data = workspace.create_obj(obj: api_attributes)
|
145
150
|
obj = BasicObj.instantiate(obj_data)
|
146
151
|
obj.revision = workspace.revision
|
147
152
|
|
148
|
-
|
153
|
+
extraction.notify_persisted(obj)
|
149
154
|
obj
|
150
155
|
end
|
151
156
|
end
|
@@ -301,7 +306,7 @@ module Scrivito
|
|
301
306
|
# @api public
|
302
307
|
def self.find_by_path(path)
|
303
308
|
Workspace.current.objs.find_one_by(:path, path,
|
304
|
-
|
309
|
+
type_computer.obj_class_name_for_type(self))
|
305
310
|
end
|
306
311
|
|
307
312
|
# Find an {Scrivito::BasicObj Obj} with the given name.
|
@@ -329,7 +334,7 @@ module Scrivito
|
|
329
334
|
# @api public
|
330
335
|
def self.find_by_permalink(permalink)
|
331
336
|
Workspace.current.objs.find_one_by(:permalink, permalink,
|
332
|
-
|
337
|
+
type_computer.obj_class_name_for_type(self))
|
333
338
|
end
|
334
339
|
|
335
340
|
# Returns the {Scrivito::BasicObj Obj} with the given permalink, or raises
|
@@ -414,9 +419,9 @@ module Scrivito
|
|
414
419
|
# }
|
415
420
|
# )
|
416
421
|
def update(attributes)
|
417
|
-
|
422
|
+
extraction, api_attributes = prepare_attributes_for_rest_api(attributes)
|
418
423
|
update_data(workspace.update_obj(id, obj: api_attributes))
|
419
|
-
|
424
|
+
extraction.notify_persisted(self)
|
420
425
|
self
|
421
426
|
end
|
422
427
|
|
@@ -633,7 +638,7 @@ module Scrivito
|
|
633
638
|
return [] if binary?
|
634
639
|
toclist = children
|
635
640
|
toclist = toclist.reject { |toc| toc.binary? } unless args.include?(:all)
|
636
|
-
toclist
|
641
|
+
toclist.sort_by(&:id)
|
637
642
|
end
|
638
643
|
|
639
644
|
# @api public
|
@@ -659,13 +664,23 @@ module Scrivito
|
|
659
664
|
SYSTEM_KEYS = Set.new(%w[
|
660
665
|
body
|
661
666
|
_id
|
667
|
+
_created_at
|
662
668
|
_last_changed
|
669
|
+
_first_published_at
|
670
|
+
_published_at
|
663
671
|
_path
|
664
672
|
_permalink
|
665
673
|
_obj_class
|
666
674
|
title
|
667
675
|
])
|
668
676
|
|
677
|
+
DATE_KEYS = Set.new(%w[
|
678
|
+
_created_at
|
679
|
+
_last_changed
|
680
|
+
_first_published_at
|
681
|
+
_published_at
|
682
|
+
])
|
683
|
+
|
669
684
|
# Returns the value of a system or custom attribute specified by its name.
|
670
685
|
# Passing an invalid key will not raise an error but return +nil+.
|
671
686
|
# @api public
|
@@ -704,11 +719,39 @@ module Scrivito
|
|
704
719
|
}
|
705
720
|
end
|
706
721
|
|
722
|
+
# @note If the custom attribute +created_at+ is defined, this value will be returned
|
723
|
+
# instead of the system attribute +_created_at+. To access the system attribute
|
724
|
+
# regardless of a custom attribute, call {#[] <code>obj[:_created_at]</code>}.
|
725
|
+
# @return [nil, ActiveSupport::TimeWithZone]
|
726
|
+
# @api public
|
727
|
+
def created_at
|
728
|
+
read_custom_or_system_attribute('created_at')
|
729
|
+
end
|
730
|
+
|
731
|
+
# @return [ActiveSupport::TimeWithZone]
|
707
732
|
# @api public
|
708
733
|
def last_changed
|
709
734
|
read_attribute('_last_changed')
|
710
735
|
end
|
711
736
|
|
737
|
+
# @note If the custom attribute +first_published_at+ is defined, this value will be returned
|
738
|
+
# instead of the system attribute +_first_published_at+. To access the system attribute
|
739
|
+
# regardless of a custom attribute, call {#[] <code>obj[:_first_published_at]</code>}.
|
740
|
+
# @return [nil, ActiveSupport::TimeWithZone]
|
741
|
+
# @api public
|
742
|
+
def first_published_at
|
743
|
+
read_custom_or_system_attribute('first_published_at')
|
744
|
+
end
|
745
|
+
|
746
|
+
# @note If the custom attribute +published_at+ is defined, this value will be returned
|
747
|
+
# instead of the system attribute +_published_at+. To access the system attribute
|
748
|
+
# regardless of a custom attribute, call {#[] <code>obj[:_published_at]</code>}.
|
749
|
+
# @return [nil, ActiveSupport::TimeWithZone]
|
750
|
+
# @api public
|
751
|
+
def published_at
|
752
|
+
read_custom_or_system_attribute('published_at')
|
753
|
+
end
|
754
|
+
|
712
755
|
def new?(revision=workspace.base_revision)
|
713
756
|
quick_modification(revision) == "new"
|
714
757
|
end
|
@@ -991,15 +1034,16 @@ module Scrivito
|
|
991
1034
|
end
|
992
1035
|
|
993
1036
|
def self.prepare_attributes_for_rest_api(attributes, obj = nil)
|
994
|
-
|
1037
|
+
extraction = CmsRestApi::WidgetExtractor.call(attributes, obj)
|
1038
|
+
obj_attributes = extraction.attributes
|
995
1039
|
obj_id = obj ? obj.id : obj_attributes.fetch(:_id)
|
996
1040
|
workspace = obj ? obj.revision.workspace : Workspace.current
|
997
1041
|
|
998
1042
|
api_attributes = serialize_attributes(
|
999
|
-
obj_attributes, widget_pool_attributes, workspace, obj_id
|
1043
|
+
obj_attributes, extraction.widget_pool_attributes, workspace, obj_id
|
1000
1044
|
)
|
1001
1045
|
|
1002
|
-
[
|
1046
|
+
[extraction, api_attributes]
|
1003
1047
|
end
|
1004
1048
|
|
1005
1049
|
def self.find_attribute_definitions(obj_class, basic_class = self)
|
@@ -1025,7 +1069,7 @@ module Scrivito
|
|
1025
1069
|
|
1026
1070
|
private_class_method def self.serialize_widget_pool_attributes(serializer, widget_pool_attributes)
|
1027
1071
|
{}.tap do |serialized_attributes|
|
1028
|
-
widget_pool_attributes.
|
1072
|
+
widget_pool_attributes.each_value do |(widget, widget_attributes)|
|
1029
1073
|
obj_class = widget_attributes['_obj_class']
|
1030
1074
|
widget_serializer = AttributeSerializer.new(obj_class, serializer.obj_id)
|
1031
1075
|
|
@@ -1037,6 +1081,12 @@ module Scrivito
|
|
1037
1081
|
|
1038
1082
|
private
|
1039
1083
|
|
1084
|
+
def read_custom_or_system_attribute(attribute_name)
|
1085
|
+
return read_attribute(attribute_name) if has_custom_attribute?(attribute_name)
|
1086
|
+
|
1087
|
+
read_attribute("_#{attribute_name}")
|
1088
|
+
end
|
1089
|
+
|
1040
1090
|
def children_including_deleted
|
1041
1091
|
workspace.objs.find_by_parent_path_including_deleted(path)
|
1042
1092
|
end
|
@@ -1066,8 +1116,7 @@ module Scrivito
|
|
1066
1116
|
|
1067
1117
|
def instantiate_widget(widget_id, widget_data)
|
1068
1118
|
BasicWidget.instantiate(widget_data).tap do |widget|
|
1069
|
-
widget.
|
1070
|
-
widget.obj = self
|
1119
|
+
widget.attach_to_obj(self, widget_id)
|
1071
1120
|
end
|
1072
1121
|
end
|
1073
1122
|
|
@@ -1151,7 +1200,7 @@ module Scrivito
|
|
1151
1200
|
|
1152
1201
|
def value_of_system_attribute(attribute_name)
|
1153
1202
|
attribute_value = data_from_cms.value_of(attribute_name)
|
1154
|
-
if attribute_name
|
1203
|
+
if DATE_KEYS.include?(attribute_name)
|
1155
1204
|
DateConversion.deserialize_from_backend(attribute_value)
|
1156
1205
|
else
|
1157
1206
|
attribute_value
|
@@ -95,8 +95,6 @@ class BasicWidget
|
|
95
95
|
|
96
96
|
attr_accessor :container, :container_attribute_name
|
97
97
|
|
98
|
-
attr_writer :obj, :id
|
99
|
-
|
100
98
|
attr_reader :attributes_to_be_saved
|
101
99
|
|
102
100
|
delegate :widget_from_pool, to: :obj
|
@@ -221,12 +219,29 @@ class BasicWidget
|
|
221
219
|
@attributes_to_be_saved.nil?
|
222
220
|
end
|
223
221
|
|
222
|
+
def attach_to_obj(an_obj, widget_id = compute_widget_id(an_obj))
|
223
|
+
@obj = an_obj
|
224
|
+
@id = widget_id
|
225
|
+
|
226
|
+
attributes_to_be_saved
|
227
|
+
end
|
228
|
+
|
224
229
|
def ==(other)
|
225
|
-
|
230
|
+
eql?(other)
|
226
231
|
end
|
227
232
|
|
228
233
|
def eql?(other)
|
229
|
-
|
234
|
+
other.respond_to?(:equality_identifier, true) &&
|
235
|
+
equality_identifier.eql?(other.equality_identifier)
|
236
|
+
end
|
237
|
+
|
238
|
+
def hash
|
239
|
+
unless persisted?
|
240
|
+
# An unbound widget will likely be attached soon, which mutates its #hash value. Evil.
|
241
|
+
raise ScrivitoError, 'a new widget is not allowed to be used as a hash key'
|
242
|
+
end
|
243
|
+
|
244
|
+
equality_identifier.hash
|
230
245
|
end
|
231
246
|
|
232
247
|
#
|
@@ -262,7 +277,7 @@ class BasicWidget
|
|
262
277
|
{ obj: {_widget_pool: {id => previous_widget_content}} })
|
263
278
|
reload
|
264
279
|
else
|
265
|
-
raise ScrivitoError, "cannot revert changes, since widget is #{modification}
|
280
|
+
raise ScrivitoError, "cannot revert changes, since widget is #{modification}"
|
266
281
|
end
|
267
282
|
end
|
268
283
|
|
@@ -297,14 +312,6 @@ class BasicWidget
|
|
297
312
|
end
|
298
313
|
end
|
299
314
|
|
300
|
-
def hash
|
301
|
-
if @obj && @id
|
302
|
-
(id + obj.id).hash
|
303
|
-
else
|
304
|
-
super
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
315
|
# Returns the entity ({Scrivito::BasicObj} or {Scrivito::BasicWidget})
|
309
316
|
# that references this widget.
|
310
317
|
# @api public
|
@@ -360,7 +367,8 @@ class BasicWidget
|
|
360
367
|
end
|
361
368
|
end
|
362
369
|
|
363
|
-
def
|
370
|
+
def notify_persisted(obj)
|
371
|
+
@obj = obj
|
364
372
|
@attributes_to_be_saved = nil
|
365
373
|
reload_data
|
366
374
|
end
|
@@ -398,6 +406,12 @@ class BasicWidget
|
|
398
406
|
referenced + referenced.map { |widget| widget.contained_widgets }.flatten
|
399
407
|
end
|
400
408
|
|
409
|
+
protected
|
410
|
+
|
411
|
+
def equality_identifier
|
412
|
+
[id, obj.id]
|
413
|
+
end
|
414
|
+
|
401
415
|
private
|
402
416
|
|
403
417
|
def workspace
|
@@ -433,6 +447,14 @@ class BasicWidget
|
|
433
447
|
def value_of_system_attribute(attribute_name)
|
434
448
|
data_from_cms.value_of(attribute_name)
|
435
449
|
end
|
450
|
+
|
451
|
+
def compute_widget_id(obj)
|
452
|
+
@attributes_to_be_saved.delete('_id') || generate_widget_id(obj)
|
453
|
+
end
|
454
|
+
|
455
|
+
def generate_widget_id(obj)
|
456
|
+
obj.present? ? obj.generate_widget_pool_id : BasicObj.generate_widget_pool_id
|
457
|
+
end
|
436
458
|
end
|
437
459
|
|
438
460
|
end
|
@@ -206,7 +206,7 @@ module Scrivito
|
|
206
206
|
private_class_method :blob_data_cache_key
|
207
207
|
|
208
208
|
def self.search_params_cache_key(params)
|
209
|
-
|
209
|
+
JSON.generate(normalize_search_param(params))
|
210
210
|
end
|
211
211
|
private_class_method :search_params_cache_key
|
212
212
|
|
@@ -67,7 +67,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_option
|
|
67
67
|
if FIELD_TYPES_WITH_ORIGINAL_CONTENT.include?(field_type)
|
68
68
|
original_value = view.scrivito_value(current_value)
|
69
69
|
original_content = original_content(field_type, original_value, current_value)
|
70
|
-
encoded_content = Base64.strict_encode64(
|
70
|
+
encoded_content = Base64.strict_encode64(JSON.generate(original_content))
|
71
71
|
options['private-field-original-content'] = encoded_content
|
72
72
|
end
|
73
73
|
|
@@ -161,7 +161,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_option
|
|
161
161
|
end
|
162
162
|
|
163
163
|
def valid_values
|
164
|
-
|
164
|
+
JSON.generate(obj_or_widget.attribute_definitions[field_name].try(:values) || [])
|
165
165
|
end
|
166
166
|
|
167
167
|
def assert_valid_attribute
|
@@ -123,7 +123,7 @@ module Scrivito
|
|
123
123
|
timer)
|
124
124
|
request = method_to_net_http_class(method).new(path(resource_path))
|
125
125
|
set_headers(request)
|
126
|
-
request.body =
|
126
|
+
request.body = JSON.generate(payload) if payload.present?
|
127
127
|
|
128
128
|
response = retry_once_on_network_error(method, timer) do
|
129
129
|
CmsRestApi::RateLimit.retry_on_rate_limit(timer) do
|
@@ -138,12 +138,12 @@ module Scrivito
|
|
138
138
|
private_class_method def self.handle_response(resource_path, response)
|
139
139
|
http_code = response.code.to_i
|
140
140
|
if response.code.start_with?('2')
|
141
|
-
|
141
|
+
JSON.parse(response.body)
|
142
142
|
elsif response.code == '403'
|
143
143
|
raise AccessDenied.new(response.body)
|
144
144
|
else
|
145
145
|
begin
|
146
|
-
error_body =
|
146
|
+
error_body = JSON.parse(response.body)
|
147
147
|
specific_output = error_body['error']
|
148
148
|
|
149
149
|
if response.code.start_with?('4')
|
@@ -155,7 +155,7 @@ module Scrivito
|
|
155
155
|
else # 3xx and >500 are treated as NetworkErrors
|
156
156
|
raise NetworkError.new(response.body, http_code)
|
157
157
|
end
|
158
|
-
rescue
|
158
|
+
rescue JSON::ParserError, TypeError
|
159
159
|
raise NetworkError.new(response.body, http_code)
|
160
160
|
end
|
161
161
|
end
|
@@ -170,6 +170,9 @@ module Scrivito
|
|
170
170
|
message = task_data["message"] ||
|
171
171
|
"Missing error message in task response #{task_data}"
|
172
172
|
|
173
|
+
if task_data['status'] == 'exception'
|
174
|
+
raise BackendError.new(message, 500)
|
175
|
+
end
|
173
176
|
backend_code = task_data['code']
|
174
177
|
raise ClientError.new(message, backend_code: backend_code)
|
175
178
|
end
|
@@ -1,53 +1,68 @@
|
|
1
1
|
module Scrivito
|
2
2
|
class CmsRestApi
|
3
3
|
class WidgetExtractor
|
4
|
-
|
5
4
|
# Extract widgets from a given attribute tree
|
6
5
|
# first return param: a flat hash of widget_like => updated widget attributes
|
7
6
|
# second return param: the updated attributes
|
8
7
|
def self.call(attributes, obj=nil)
|
8
|
+
new(obj).extract_widgets(attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(obj)
|
12
|
+
@obj = obj
|
13
|
+
end
|
14
|
+
|
15
|
+
def extract_widgets(attributes)
|
16
|
+
@extracted_widgets = {}
|
9
17
|
updated_attributes = attributes.dup
|
10
|
-
|
18
|
+
widget_pool = updated_attributes.delete(:_widget_pool)
|
19
|
+
extract_widgets_from_pool(widget_pool) if widget_pool
|
20
|
+
extract_widgets_from_attributes(updated_attributes)
|
11
21
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
Extraction.new(extracted_widgets, updated_attributes)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :obj
|
28
|
+
attr_reader :extracted_widgets
|
29
|
+
|
30
|
+
def extract_widgets_from_pool(widget_pool)
|
31
|
+
widget_pool.each do |widget, widget_properties|
|
32
|
+
extracted_widgets[widget.id] = [widget, widget_properties]
|
33
|
+
extract_widgets_from_attributes(widget_properties)
|
18
34
|
end
|
35
|
+
end
|
19
36
|
|
20
|
-
|
37
|
+
def extract_widgets_from_attributes(attributes)
|
38
|
+
attributes.each do |attribute_name, value|
|
21
39
|
if value.is_a?(Array) && value.all? { |w| w.is_a?(BasicWidget) }
|
22
40
|
value.each do |widget|
|
23
41
|
unless widget.persisted?
|
24
|
-
|
25
|
-
extracted_widgets[widget] = widget
|
26
|
-
|
42
|
+
widget_attributes = widget.attach_to_obj(obj)
|
43
|
+
extracted_widgets[widget.id] = [widget, widget_attributes]
|
44
|
+
extract_widgets_from_attributes(widget_attributes)
|
27
45
|
end
|
28
46
|
end
|
29
47
|
end
|
30
48
|
end
|
31
|
-
|
32
|
-
return extracted_widgets, updated_attributes
|
33
49
|
end
|
34
50
|
|
35
|
-
|
36
|
-
|
37
|
-
widget.obj = obj
|
38
|
-
end
|
51
|
+
class Extraction
|
52
|
+
attr_reader :widget_pool_attributes, :attributes
|
39
53
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
widget.obj = obj
|
44
|
-
widget.forget_unsaved_attributes
|
45
|
-
end
|
54
|
+
def initialize(widget_pool_attributes, attributes)
|
55
|
+
@widget_pool_attributes = widget_pool_attributes
|
56
|
+
@attributes = attributes
|
46
57
|
end
|
47
|
-
end
|
48
58
|
|
49
|
-
|
50
|
-
|
59
|
+
def notify_persisted(obj)
|
60
|
+
widget_pool_attributes.each_value do |(widget, attributes)|
|
61
|
+
if attributes.present?
|
62
|
+
widget.notify_persisted(obj)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
51
66
|
end
|
52
67
|
end
|
53
68
|
end
|