scrivito_sdk 0.17.0 → 0.18.0
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/.yardopts +1 -0
- data/app/controllers/scrivito/default_cms_controller.rb +15 -3
- data/app/controllers/scrivito/objs_controller.rb +61 -25
- data/app/controllers/scrivito/users_controller.rb +7 -0
- data/app/controllers/scrivito/webservice_controller.rb +17 -7
- data/app/controllers/scrivito/workspaces_controller.rb +85 -17
- data/app/helpers/scrivito/default_cms_routing_helper.rb +3 -3
- data/config/routes.rb +4 -1
- data/lib/assets/javascripts/scrivito_editing.js +4182 -508
- data/lib/assets/stylesheets/scrivito_editing.css +489 -13
- data/lib/generators/cms/migration/templates/migration.erb +4 -4
- data/lib/scrivito/attribute_collection.rb +1 -6
- data/lib/scrivito/attribute_content.rb +29 -7
- data/lib/scrivito/basic_obj.rb +91 -61
- data/lib/scrivito/basic_widget.rb +0 -11
- data/lib/scrivito/client_config.rb +40 -25
- data/lib/scrivito/cms_backend.rb +54 -0
- data/lib/scrivito/cms_cache_storage.rb +8 -0
- data/lib/scrivito/cms_field_tag.rb +2 -1
- data/lib/scrivito/cms_rest_api.rb +9 -0
- data/lib/scrivito/configuration.rb +4 -2
- data/lib/scrivito/content_state.rb +8 -0
- data/lib/scrivito/content_state_caching.rb +20 -0
- data/lib/scrivito/editing_context.rb +35 -34
- data/lib/scrivito/membership.rb +22 -3
- data/lib/scrivito/memberships_collection.rb +8 -4
- data/lib/scrivito/obj_class.rb +45 -100
- data/lib/scrivito/obj_class_collection.rb +53 -0
- data/lib/scrivito/obj_class_data.rb +33 -0
- data/lib/scrivito/obj_data.rb +26 -48
- data/lib/scrivito/obj_data_from_hash.rb +5 -5
- data/lib/scrivito/obj_data_from_service.rb +9 -3
- data/lib/scrivito/obj_search_builder.rb +0 -5
- data/lib/scrivito/obj_search_enumerator.rb +3 -20
- data/lib/scrivito/objs_collection.rb +7 -0
- data/lib/scrivito/restriction_set.rb +2 -2
- data/lib/scrivito/user.rb +89 -23
- data/lib/scrivito/user_definition.rb +73 -70
- data/lib/scrivito/workspace.rb +52 -8
- data/lib/scrivito/workspace/publish_checker.rb +126 -0
- metadata +6 -2
| @@ -14,16 +14,16 @@ class <%= class_name %> < ::Scrivito::Migration | |
| 14 14 | 
             
                #
         | 
| 15 15 | 
             
                # To get you started, here is a list of the most common SDK methods to alter the CMS content.
         | 
| 16 16 | 
             
                #
         | 
| 17 | 
            -
                # @example Create a new obj class named "Homepage"  | 
| 18 | 
            -
                #   Scrivito::ObjClass.create(name: 'Homepage',  | 
| 17 | 
            +
                # @example Create a new non-binary obj class named "Homepage" that has a "string" attribute named "locale".
         | 
| 18 | 
            +
                #   Scrivito::ObjClass.create(name: 'Homepage', is_binary: false, attributes: [
         | 
| 19 19 | 
             
                #     {name: 'locale', type: :string}
         | 
| 20 20 | 
             
                #   ])
         | 
| 21 21 | 
             
                #
         | 
| 22 22 | 
             
                # @example Find the obj class named "Homepage".
         | 
| 23 23 | 
             
                #   Scrivito::ObjClass.find('Homepage')
         | 
| 24 24 | 
             
                #
         | 
| 25 | 
            -
                # @example Update the " | 
| 26 | 
            -
                #   Scrivito::ObjClass.find('Homepage').update( | 
| 25 | 
            +
                # @example Update the "is_active" attribute of the obj class named "Homepage".
         | 
| 26 | 
            +
                #   Scrivito::ObjClass.find('Homepage').update(is_active: false)
         | 
| 27 27 | 
             
                #
         | 
| 28 28 | 
             
                # @example Add an "enum" attribute named "category" to the obj class named "Homepage".
         | 
| 29 29 | 
             
                #   Scrivito::ObjClass.find('Homepage').attributes.add(name: 'category', type: :enum, values: %w(tech, social))
         | 
| @@ -54,14 +54,9 @@ module Scrivito | |
| 54 54 | 
             
                #   instance or an attribute property hash.
         | 
| 55 55 | 
             
                # @return [Scrivito::AttributeCollection]
         | 
| 56 56 | 
             
                def add(attribute)
         | 
| 57 | 
            -
                  unless attribute.respond_to?(:to_cms_rest_api)
         | 
| 58 | 
            -
                    attribute = Attribute.new(attribute)
         | 
| 59 | 
            -
                  end
         | 
| 60 | 
            -
             | 
| 57 | 
            +
                  attribute = Attribute.new(attribute) unless attribute.respond_to?(:to_cms_rest_api)
         | 
| 61 58 | 
             
                  @attributes << attribute
         | 
| 62 | 
            -
             | 
| 63 59 | 
             
                  @obj_class.update(attributes: @attributes)
         | 
| 64 | 
            -
             | 
| 65 60 | 
             
                  self
         | 
| 66 61 | 
             
                end
         | 
| 67 62 | 
             
                alias_method :<<, :add
         | 
| @@ -40,7 +40,8 @@ module AttributeContent | |
| 40 40 | 
             
              end
         | 
| 41 41 |  | 
| 42 42 | 
             
              def has_custom_attribute?(name)
         | 
| 43 | 
            -
                 | 
| 43 | 
            +
                name = name.to_s
         | 
| 44 | 
            +
                name != 'blob' && data_from_cms.has_custom_attribute?(name)
         | 
| 44 45 | 
             
              end
         | 
| 45 46 | 
             
              alias_method :has_attribute?, :has_custom_attribute?
         | 
| 46 47 |  | 
| @@ -54,7 +55,12 @@ module AttributeContent | |
| 54 55 | 
             
              # @api public
         | 
| 55 56 | 
             
              def [](key)
         | 
| 56 57 | 
             
                key = key.to_s
         | 
| 57 | 
            -
             | 
| 58 | 
            +
             | 
| 59 | 
            +
                if key == '_obj_class'
         | 
| 60 | 
            +
                  obj_class
         | 
| 61 | 
            +
                else
         | 
| 62 | 
            +
                  has_attribute?(key) ? read_attribute(key) : nil
         | 
| 63 | 
            +
                end
         | 
| 58 64 | 
             
              end
         | 
| 59 65 |  | 
| 60 66 | 
             
              # Hook method to control which widget classes should be available for this page.
         | 
| @@ -85,8 +91,8 @@ module AttributeContent | |
| 85 91 | 
             
                  cms_data_in_revision = cms_data_for_revision(revision)
         | 
| 86 92 |  | 
| 87 93 | 
             
                  if cms_data_in_revision
         | 
| 88 | 
            -
                    other_value = cms_data_in_revision. | 
| 89 | 
            -
                    if data_from_cms. | 
| 94 | 
            +
                    other_value = cms_data_in_revision.value_without_default_of(attribute_name.to_s)
         | 
| 95 | 
            +
                    if data_from_cms.value_without_default_of(attribute_name.to_s) == other_value
         | 
| 90 96 | 
             
                      Modification::UNMODIFIED
         | 
| 91 97 | 
             
                    else
         | 
| 92 98 | 
             
                      Modification::EDITED
         | 
| @@ -102,6 +108,22 @@ module AttributeContent | |
| 102 108 | 
             
                @attribute_cache = {}
         | 
| 103 109 | 
             
              end
         | 
| 104 110 |  | 
| 111 | 
            +
              # Returns the obj class name of this object.
         | 
| 112 | 
            +
              # @api public
         | 
| 113 | 
            +
              # @return [String]
         | 
| 114 | 
            +
              def obj_class_name
         | 
| 115 | 
            +
                data_from_cms.value_of('_obj_class')
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              # Returns the obj class of this object.
         | 
| 119 | 
            +
              # @api public
         | 
| 120 | 
            +
              # @return [ObjClass]
         | 
| 121 | 
            +
              def obj_class
         | 
| 122 | 
            +
                if obj_class_data = CmsBackend.instance.find_obj_class_data_by_name(revision, obj_class_name)
         | 
| 123 | 
            +
                  ObjClass.new(obj_class_data, revision.workspace)
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
              end
         | 
| 126 | 
            +
             | 
| 105 127 | 
             
              private
         | 
| 106 128 |  | 
| 107 129 | 
             
              attr_writer :data_from_cms
         | 
| @@ -140,7 +162,7 @@ module AttributeContent | |
| 140 162 | 
             
                  link_definitions = link_definitions.map(&:with_indifferent_access)
         | 
| 141 163 |  | 
| 142 164 | 
             
                  object_ids = link_definitions.map { |link_data| link_data[:destination] }.compact.uniq
         | 
| 143 | 
            -
                  objects = object_ids.empty? ? [] :  | 
| 165 | 
            +
                  objects = object_ids.empty? ? [] : BasicObj.find(object_ids)
         | 
| 144 166 | 
             
                  link_definitions.each_with_object([]) do |link_data, links|
         | 
| 145 167 | 
             
                    obj = objects.detect { |o| o && o.id == link_data[:destination] }
         | 
| 146 168 | 
             
                    link = Link.new(link_data.merge(obj: obj))
         | 
| @@ -153,7 +175,7 @@ module AttributeContent | |
| 153 175 |  | 
| 154 176 | 
             
              def build_link(attribute_value)
         | 
| 155 177 | 
             
                return unless attribute_value
         | 
| 156 | 
            -
             | 
| 178 | 
            +
             | 
| 157 179 | 
             
                if attribute_value['destination']
         | 
| 158 180 | 
             
                  build_internal_link(attribute_value)
         | 
| 159 181 | 
             
                else
         | 
| @@ -163,7 +185,7 @@ module AttributeContent | |
| 163 185 |  | 
| 164 186 | 
             
              def build_internal_link(attribute_value)
         | 
| 165 187 | 
             
                properties = {
         | 
| 166 | 
            -
                  obj:  | 
| 188 | 
            +
                  obj: BasicObj.find(attribute_value['destination']),
         | 
| 167 189 | 
             
                  title: attribute_value['title'],
         | 
| 168 190 | 
             
                  query: attribute_value['query'],
         | 
| 169 191 | 
             
                  fragment: attribute_value['fragment'],
         | 
    
        data/lib/scrivito/basic_obj.rb
    CHANGED
    
    | @@ -6,6 +6,20 @@ module Scrivito | |
| 6 6 | 
             
              # The CMS file class
         | 
| 7 7 | 
             
              # @api public
         | 
| 8 8 | 
             
              class BasicObj
         | 
| 9 | 
            +
                UNIQ_ATTRIBUTES = %w[
         | 
| 10 | 
            +
                  _id
         | 
| 11 | 
            +
                  _path
         | 
| 12 | 
            +
                  _permalink
         | 
| 13 | 
            +
                ].freeze
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                GENERATED_ATTRIBUTES = %w[
         | 
| 16 | 
            +
                  _conflicts
         | 
| 17 | 
            +
                  _last_changed
         | 
| 18 | 
            +
                  _modification
         | 
| 19 | 
            +
                  _obj_type
         | 
| 20 | 
            +
                  _text_links
         | 
| 21 | 
            +
                ].freeze
         | 
| 22 | 
            +
             | 
| 9 23 | 
             
                extend ActiveModel::Naming
         | 
| 10 24 |  | 
| 11 25 | 
             
                include AttributeContent
         | 
| @@ -77,10 +91,9 @@ module Scrivito | |
| 77 91 | 
             
                def self.create(attributes)
         | 
| 78 92 | 
             
                  attributes = with_default_obj_class(attributes)
         | 
| 79 93 | 
             
                  api_attributes, widget_properties = prepare_attributes_for_rest_api(attributes, nil)
         | 
| 80 | 
            -
                  json =  | 
| 81 | 
            -
                  obj = find(json[' | 
| 94 | 
            +
                  json = Workspace.current.api_request(:post, '/objs', obj: api_attributes)
         | 
| 95 | 
            +
                  obj = find(json['_id'])
         | 
| 82 96 | 
             
                  CmsRestApi::WidgetExtractor.notify_persisted_widgets(obj, widget_properties)
         | 
| 83 | 
            -
                  Workspace.current.reload
         | 
| 84 97 | 
             
                  obj
         | 
| 85 98 | 
             
                end
         | 
| 86 99 |  | 
| @@ -263,23 +276,36 @@ module Scrivito | |
| 263 276 | 
             
                #   )
         | 
| 264 277 | 
             
                def update(attributes)
         | 
| 265 278 | 
             
                  api_attributes, widget_properties = prepare_attributes_for_rest_api(attributes)
         | 
| 266 | 
            -
                   | 
| 267 | 
            -
                   | 
| 268 | 
            -
                  reload
         | 
| 279 | 
            +
                  workspace.api_request(:put, "/objs/#{id}", obj: api_attributes)
         | 
| 280 | 
            +
                  reload_data
         | 
| 269 281 | 
             
                  CmsRestApi::WidgetExtractor.notify_persisted_widgets(self, widget_properties)
         | 
| 270 282 | 
             
                  self
         | 
| 271 283 | 
             
                end
         | 
| 272 284 |  | 
| 285 | 
            +
                # Copies itself to a given path.
         | 
| 286 | 
            +
                # @api public
         | 
| 287 | 
            +
                # @param [Hash] options
         | 
| 288 | 
            +
                # @option options [String,Symbol] :_path (nil) the path of the copy.
         | 
| 289 | 
            +
                # @option options [String,Symbol] :_id (nil) the id of the copy.
         | 
| 290 | 
            +
                # @option options [String,Symbol] :_permalink (nil) the permalink of the copy.
         | 
| 291 | 
            +
                # @raise [ArgumentError] if +options+ includes invalid keys.
         | 
| 292 | 
            +
                # @return [Obj] the created copy
         | 
| 293 | 
            +
                # @example Copy a blog post.
         | 
| 294 | 
            +
                #   blog_post = Obj.find_by_path('/blog/first_post')
         | 
| 295 | 
            +
                #   blog_post.copy(_path: '/blog/second_post')
         | 
| 296 | 
            +
                def copy(options)
         | 
| 297 | 
            +
                  options = options.stringify_keys.assert_valid_keys('_path', '_id', '_permalink')
         | 
| 298 | 
            +
                  json = workspace.api_request(:post, '/objs', obj: copyable_attributes.merge(options))
         | 
| 299 | 
            +
                  self.class.find(json['_id'])
         | 
| 300 | 
            +
                end
         | 
| 301 | 
            +
             | 
| 273 302 | 
             
                # Destroys the {BasicObj Obj} in the current {Workspace}
         | 
| 274 303 | 
             
                # @api public
         | 
| 275 304 | 
             
                def destroy
         | 
| 276 305 | 
             
                  if children.any?
         | 
| 277 306 | 
             
                    raise ClientError.new(I18n.t('scrivito.errors.models.basic_obj.has_children'), 412)
         | 
| 278 307 | 
             
                  end
         | 
| 279 | 
            -
             | 
| 280 | 
            -
                  CmsRestApi.delete(cms_rest_api_path)
         | 
| 281 | 
            -
             | 
| 282 | 
            -
                  workspace.reload
         | 
| 308 | 
            +
                  workspace.api_request(:delete, "/objs/#{id}")
         | 
| 283 309 | 
             
                end
         | 
| 284 310 |  | 
| 285 311 | 
             
                def to_param
         | 
| @@ -486,26 +512,15 @@ module Scrivito | |
| 486 512 | 
             
                # even if the obj_class in the database has changed.
         | 
| 487 513 | 
             
                # @api public
         | 
| 488 514 | 
             
                def reload
         | 
| 489 | 
            -
                   | 
| 490 | 
            -
             | 
| 491 | 
            -
                  reload_data = Proc.new do
         | 
| 492 | 
            -
                    CmsBackend.instance.find_obj_data_by(workspace.revision, :id, [id]).first.first
         | 
| 493 | 
            -
                  end
         | 
| 494 | 
            -
             | 
| 495 | 
            -
                  update_data(reload_data)
         | 
| 496 | 
            -
                end
         | 
| 497 | 
            -
             | 
| 498 | 
            -
                # @return [String]
         | 
| 499 | 
            -
                # @api public
         | 
| 500 | 
            -
                def obj_class_name
         | 
| 501 | 
            -
                  read_attribute('_obj_class')
         | 
| 515 | 
            +
                  workspace.reload
         | 
| 516 | 
            +
                  reload_data
         | 
| 502 517 | 
             
                end
         | 
| 503 518 |  | 
| 504 | 
            -
                 | 
| 505 | 
            -
             | 
| 506 | 
            -
             | 
| 507 | 
            -
             | 
| 508 | 
            -
                   | 
| 519 | 
            +
                def reload_data
         | 
| 520 | 
            +
                  id = self.id.to_s
         | 
| 521 | 
            +
                  update_data -> {
         | 
| 522 | 
            +
                    CmsBackend.instance.find_obj_data_by(workspace.revision, :id, [id]).first.first
         | 
| 523 | 
            +
                  }
         | 
| 509 524 | 
             
                end
         | 
| 510 525 |  | 
| 511 526 | 
             
                # @api public
         | 
| @@ -665,35 +680,23 @@ module Scrivito | |
| 665 680 | 
             
                # This method does not work with +new+ or +deleted+ objects.
         | 
| 666 681 | 
             
                # This method also does also not work for the +published+ workspace or the +rtc+ working copy.
         | 
| 667 682 | 
             
                def revert
         | 
| 668 | 
            -
                   | 
| 683 | 
            +
                  assert_revertable
         | 
| 669 684 |  | 
| 670 | 
            -
                  if  | 
| 671 | 
            -
                     | 
| 672 | 
            -
             | 
| 673 | 
            -
                     | 
| 674 | 
            -
                    when Modification::UNMODIFIED
         | 
| 675 | 
            -
                      # don't do anything
         | 
| 676 | 
            -
                    when Modification::EDITED
         | 
| 677 | 
            -
                      previous_content = CmsRestApi.get(
         | 
| 678 | 
            -
                          "revisions/#{workspace.base_revision_id}/objs/#{id}")
         | 
| 679 | 
            -
                      updated_content = previous_content.except('id', '_id')
         | 
| 680 | 
            -
             | 
| 681 | 
            -
                      added_widget_ids = read_widget_pool.keys - previous_content['_widget_pool'].keys
         | 
| 682 | 
            -
                      added_widget_ids.each do |added_widget_id|
         | 
| 683 | 
            -
                        updated_content['_widget_pool'][added_widget_id] = nil
         | 
| 684 | 
            -
                      end
         | 
| 685 | 
            +
                  if modification == Modification::EDITED
         | 
| 686 | 
            +
                    base_revision_path = "revisions/#{workspace.base_revision_id}/objs/#{id}"
         | 
| 687 | 
            +
                    previous_attributes = CmsRestApi.get(base_revision_path).except('_id')
         | 
| 688 | 
            +
                    previous_widget_pool = previous_attributes['_widget_pool']
         | 
| 685 689 |  | 
| 686 | 
            -
             | 
| 690 | 
            +
                    ids_of_new_widgets = read_widget_pool.keys - previous_widget_pool.keys
         | 
| 691 | 
            +
                    ids_of_new_widgets.each { |widget_id| previous_widget_pool[widget_id] = nil }
         | 
| 687 692 |  | 
| 688 | 
            -
             | 
| 689 | 
            -
                     | 
| 690 | 
            -
                      raise ScrivitoError, "cannot revert changes, since obj is #{modification}."
         | 
| 691 | 
            -
                    end
         | 
| 693 | 
            +
                    workspace.api_request(:put, "/objs/#{id}", obj: previous_attributes)
         | 
| 694 | 
            +
                    reload
         | 
| 692 695 | 
             
                  end
         | 
| 693 696 | 
             
                end
         | 
| 694 697 |  | 
| 695 698 | 
             
                def mark_resolved
         | 
| 696 | 
            -
                   | 
| 699 | 
            +
                  workspace.api_request(:put, "/objs/#{id}", obj: {_conflicts: nil})
         | 
| 697 700 | 
             
                  reload
         | 
| 698 701 | 
             
                end
         | 
| 699 702 |  | 
| @@ -718,6 +721,10 @@ module Scrivito | |
| 718 721 | 
             
                  read_attribute('_conflicts') != nil
         | 
| 719 722 | 
             
                end
         | 
| 720 723 |  | 
| 724 | 
            +
                def publishable?
         | 
| 725 | 
            +
                  !has_conflict?
         | 
| 726 | 
            +
                end
         | 
| 727 | 
            +
             | 
| 721 728 | 
             
                def all_widgets_from_pool
         | 
| 722 729 | 
             
                  read_widget_pool.keys.map do |widget_id|
         | 
| 723 730 | 
             
                    widget_from_pool(widget_id)
         | 
| @@ -734,6 +741,24 @@ module Scrivito | |
| 734 741 | 
             
                  raise ScrivitoError.new('Could not generate a new unused widget id')
         | 
| 735 742 | 
             
                end
         | 
| 736 743 |  | 
| 744 | 
            +
                # Generates a +Hash+ containing all public attributes. The hash will _not_ include attributes,
         | 
| 745 | 
            +
                # which are read-only or used for internal purpose.
         | 
| 746 | 
            +
                # @api public
         | 
| 747 | 
            +
                # @return [Hash] a hash containing all public attributes.
         | 
| 748 | 
            +
                # @example
         | 
| 749 | 
            +
                #   old_obj = Obj.homepage
         | 
| 750 | 
            +
                #   attrs = old_obj.to_h
         | 
| 751 | 
            +
                #   puts attrs
         | 
| 752 | 
            +
                #   #=> {"_obj_class"=>"Publication", "_path"=>"/", "_id"=>"f64a68258ca15faf", "_widget_pool"=>{}}
         | 
| 753 | 
            +
                #   old_obj.destroy
         | 
| 754 | 
            +
                #
         | 
| 755 | 
            +
                #   new_obj = Obj.create(attrs)
         | 
| 756 | 
            +
                #   puts new_obj == old_obj
         | 
| 757 | 
            +
                #   #=> true
         | 
| 758 | 
            +
                def to_h
         | 
| 759 | 
            +
                  data_from_cms.to_h.except(*GENERATED_ATTRIBUTES)
         | 
| 760 | 
            +
                end
         | 
| 761 | 
            +
             | 
| 737 762 | 
             
                private
         | 
| 738 763 |  | 
| 739 764 | 
             
                def cms_data_for_revision(revision)
         | 
| @@ -774,10 +799,6 @@ module Scrivito | |
| 774 799 | 
             
                  Blob.find(blob_spec["id"]) if blob_spec
         | 
| 775 800 | 
             
                end
         | 
| 776 801 |  | 
| 777 | 
            -
                def cms_rest_api_path(obj_id = id)
         | 
| 778 | 
            -
                  "#{self.class.cms_rest_api_path(workspace)}/#{obj_id}"
         | 
| 779 | 
            -
                end
         | 
| 780 | 
            -
             | 
| 781 802 | 
             
                def workspace
         | 
| 782 803 | 
             
                  if revision.workspace
         | 
| 783 804 | 
             
                    revision.workspace
         | 
| @@ -794,17 +815,26 @@ module Scrivito | |
| 794 815 | 
             
                  self.class.prepare_attributes_for_rest_api(attributes, self)
         | 
| 795 816 | 
             
                end
         | 
| 796 817 |  | 
| 818 | 
            +
                def copyable_attributes
         | 
| 819 | 
            +
                  workspace.api_request(:get, "/objs/#{id}")
         | 
| 820 | 
            +
                      .except(*GENERATED_ATTRIBUTES)
         | 
| 821 | 
            +
                      .except(*UNIQ_ATTRIBUTES)
         | 
| 822 | 
            +
                end
         | 
| 823 | 
            +
             | 
| 824 | 
            +
                def assert_revertable
         | 
| 825 | 
            +
                  workspace.assert_revertable
         | 
| 826 | 
            +
                  raise "revert not supported for binary objs" if binary?
         | 
| 827 | 
            +
                  if modification == Modification::NEW || modification == Modification::DELETED
         | 
| 828 | 
            +
                    raise ScrivitoError, "cannot revert changes, since obj is #{modification}."
         | 
| 829 | 
            +
                  end
         | 
| 830 | 
            +
                end
         | 
| 831 | 
            +
             | 
| 797 832 | 
             
                class << self
         | 
| 798 833 | 
             
                  def restore(obj_id)
         | 
| 799 834 | 
             
                    Workspace.current.assert_revertable
         | 
| 800 | 
            -
             | 
| 801 835 | 
             
                    base_revision_path = "revisions/#{Workspace.current.base_revision_id}/objs/#{obj_id}"
         | 
| 802 | 
            -
                    obj_attributes = CmsRestApi.get(base_revision_path). | 
| 803 | 
            -
                     | 
| 804 | 
            -
                  end
         | 
| 805 | 
            -
             | 
| 806 | 
            -
                  def cms_rest_api_path(workspace = Workspace.current)
         | 
| 807 | 
            -
                    "workspaces/#{workspace.id}/objs"
         | 
| 836 | 
            +
                    obj_attributes = CmsRestApi.get(base_revision_path).merge('_id' => obj_id)
         | 
| 837 | 
            +
                    Workspace.current.api_request(:post, '/objs', obj: obj_attributes)
         | 
| 808 838 | 
             
                  end
         | 
| 809 839 |  | 
| 810 840 | 
             
                  def prepare_attributes_for_rest_api(attributes, obj)
         | 
| @@ -99,17 +99,6 @@ class BasicWidget | |
| 99 99 | 
             
                @attributes_to_be_saved.nil?
         | 
| 100 100 | 
             
              end
         | 
| 101 101 |  | 
| 102 | 
            -
              def obj_class_name
         | 
| 103 | 
            -
                data_from_cms.value_of('_obj_class')
         | 
| 104 | 
            -
              end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
              # Returns the {Scrivito::ObjClass} of this widget.
         | 
| 107 | 
            -
              # @return [Scrivito::ObjClass]
         | 
| 108 | 
            -
              # @api public
         | 
| 109 | 
            -
              def obj_class
         | 
| 110 | 
            -
                ObjClass.find(obj_class_name)
         | 
| 111 | 
            -
              end
         | 
| 112 | 
            -
             | 
| 113 102 | 
             
              def ==(other)
         | 
| 114 103 | 
             
                other.respond_to?(:obj) && obj == other.obj && other.respond_to?(:id) && id == other.id
         | 
| 115 104 | 
             
              end
         | 
| @@ -7,46 +7,33 @@ class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context, :resour | |
| 7 7 |  | 
| 8 8 | 
             
              def to_json
         | 
| 9 9 | 
             
                config = {}
         | 
| 10 | 
            -
                config[:editing_context] | 
| 10 | 
            +
                config[:editing_context]  = editing_context_config
         | 
| 11 | 
            +
                config[:i18n]             = i18n_config
         | 
| 12 | 
            +
                config[:obj]              = obj_config
         | 
| 13 | 
            +
                config[:resource_dialog]  = resource_dialog_config
         | 
| 14 | 
            +
                config[:user]             = user_config
         | 
| 11 15 | 
             
                config[:user_permissions] = user_permissions_config
         | 
| 12 | 
            -
                config[:i18n] = i18n_config
         | 
| 13 | 
            -
                config[:obj] = obj_config
         | 
| 14 | 
            -
                config[:resource_dialog] = resource_dialog_config
         | 
| 15 16 | 
             
                config.to_json
         | 
| 16 17 | 
             
              end
         | 
| 17 18 |  | 
| 18 19 | 
             
              private
         | 
| 19 20 |  | 
| 20 | 
            -
              def user_permissions_config
         | 
| 21 | 
            -
                {
         | 
| 22 | 
            -
                  publish_workspace: can_publish_workspace
         | 
| 23 | 
            -
                }
         | 
| 24 | 
            -
              end
         | 
| 25 | 
            -
             | 
| 26 21 | 
             
              def editing_context_config
         | 
| 27 22 | 
             
                {
         | 
| 28 23 | 
             
                  display_mode: editing_context.display_mode,
         | 
| 29 24 |  | 
| 30 25 | 
             
                  selected_workspace: {
         | 
| 31 | 
            -
                    id:  | 
| 32 | 
            -
                    title:  | 
| 26 | 
            +
                    id: selected_workspace.id,
         | 
| 27 | 
            +
                    title: selected_workspace.title
         | 
| 33 28 | 
             
                  },
         | 
| 34 29 |  | 
| 35 30 | 
             
                  visible_workspace: {
         | 
| 36 | 
            -
                    id:  | 
| 37 | 
            -
                    title:  | 
| 31 | 
            +
                    id: visible_workspace.id,
         | 
| 32 | 
            +
                    title: visible_workspace.title
         | 
| 38 33 | 
             
                  }
         | 
| 39 34 | 
             
                }
         | 
| 40 35 | 
             
              end
         | 
| 41 36 |  | 
| 42 | 
            -
              def can_publish_workspace
         | 
| 43 | 
            -
                if editing_context.editor
         | 
| 44 | 
            -
                  editing_context.editor.able_to?(:publish_workspace)
         | 
| 45 | 
            -
                else
         | 
| 46 | 
            -
                  false
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
              end
         | 
| 49 | 
            -
             | 
| 50 37 | 
             
              def i18n_config
         | 
| 51 38 | 
             
                {locale: I18n.locale}
         | 
| 52 39 | 
             
              end
         | 
| @@ -61,6 +48,7 @@ class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context, :resour | |
| 61 48 | 
             
                      has_conflict: obj.has_conflict?,
         | 
| 62 49 | 
             
                      has_details_view: obj_has_details_view?,
         | 
| 63 50 | 
             
                      modification: modification(obj),
         | 
| 51 | 
            +
                      restriction_messages: editor.restriction_messages_for(obj),
         | 
| 64 52 | 
             
                    }
         | 
| 65 53 | 
             
                  }
         | 
| 66 54 | 
             
                else
         | 
| @@ -77,7 +65,7 @@ class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context, :resour | |
| 77 65 | 
             
              def resource_dialog_config
         | 
| 78 66 | 
             
                if resource
         | 
| 79 67 | 
             
                  {
         | 
| 80 | 
            -
                    obj: Configuration.obj_formats.fetch('_default').call(resource),
         | 
| 68 | 
            +
                    obj: Configuration.obj_formats.fetch('_default').call(resource, editor),
         | 
| 81 69 | 
             
                    return_to: return_to,
         | 
| 82 70 | 
             
                  }
         | 
| 83 71 | 
             
                else
         | 
| @@ -85,13 +73,40 @@ class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context, :resour | |
| 85 73 | 
             
                end
         | 
| 86 74 | 
             
              end
         | 
| 87 75 |  | 
| 76 | 
            +
              def user_permissions_config
         | 
| 77 | 
            +
                {
         | 
| 78 | 
            +
                  publish_workspace: editor.can?(:publish, selected_workspace)
         | 
| 79 | 
            +
                }
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              def user_config
         | 
| 83 | 
            +
                {
         | 
| 84 | 
            +
                  current: {
         | 
| 85 | 
            +
                    id: editor.id
         | 
| 86 | 
            +
                  }
         | 
| 87 | 
            +
                }
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 88 90 | 
             
              def modification(obj_or_resource)
         | 
| 89 | 
            -
                 | 
| 90 | 
            -
             | 
| 91 | 
            +
                comparison = editing_context.comparison
         | 
| 92 | 
            +
                if comparison.active?
         | 
| 93 | 
            +
                  comparison.modification(obj_or_resource)
         | 
| 91 94 | 
             
                else
         | 
| 92 95 | 
             
                  obj_or_resource.modification
         | 
| 93 96 | 
             
                end
         | 
| 94 97 | 
             
              end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              def editor
         | 
| 100 | 
            +
                editing_context.editor
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              def selected_workspace
         | 
| 104 | 
            +
                editing_context.selected_workspace
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
              def visible_workspace
         | 
| 108 | 
            +
                editing_context.visible_workspace
         | 
| 109 | 
            +
              end
         | 
| 95 110 | 
             
            end
         | 
| 96 111 |  | 
| 97 112 | 
             
            end
         |