scrivito_sdk 1.16.0.rc1 → 1.17.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|