ckeditor5 1.8.0 → 1.9.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/README.md +43 -5
 - data/lib/ckeditor5/rails/assets/webcomponent.mjs +246 -56
 - data/lib/ckeditor5/rails/context/helpers.rb +13 -0
 - data/lib/ckeditor5/rails/context/props.rb +30 -0
 - data/lib/ckeditor5/rails/editor/helpers.rb +7 -14
 - data/lib/ckeditor5/rails/helpers.rb +2 -0
 - data/lib/ckeditor5/rails/version.rb +1 -1
 - metadata +3 -1
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: bb520612d3f2847e8d70c48a8ffb3d1ad4be25800dd5f141a6948caf30b07978
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 5f9850fb6a39774ab796f67b5dc95fa0ec1e6a5fe6f04fb3481f6ff17c76e026
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 7057a3e537f5626b4754b815c1f418ddac64301350aa3b0299d5051dcda474a5f397018389a0e7c773bc1d15687043498a2bcd44518581e4233f8ab4ae85dc52
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 0526b5810f411971ce3adafa1bad252eabaffc566f3d637b6585c2a16a6d6c938078e8b88ed88b34e610477c87c66f5dfc74d092fab2f46f183327f2fca9d287
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -101,6 +101,9 @@ Voilà! You have CKEditor 5 integrated with your Rails application. 🎉 
     | 
|
| 
       101 
101 
     | 
    
         
             
                - [Inline editor 📝](#inline-editor-)
         
     | 
| 
       102 
102 
     | 
    
         
             
                - [Balloon editor 🎈](#balloon-editor-)
         
     | 
| 
       103 
103 
     | 
    
         
             
                - [Decoupled editor 🌐](#decoupled-editor-)
         
     | 
| 
      
 104 
     | 
    
         
            +
              - [Using Context 📦](#using-context-)
         
     | 
| 
      
 105 
     | 
    
         
            +
                - [Benefits of Using Context in Collaboration 🤝](#benefits-of-using-context-in-collaboration-)
         
     | 
| 
      
 106 
     | 
    
         
            +
                - [Using Context in CKEditor 5 🔄](#using-context-in-ckeditor-5-)
         
     | 
| 
       104 
107 
     | 
    
         
             
              - [How to access editor instance? 🤔](#how-to-access-editor-instance-)
         
     | 
| 
       105 
108 
     | 
    
         
             
              - [Common Tasks and Solutions 💡](#common-tasks-and-solutions-)
         
     | 
| 
       106 
109 
     | 
    
         
             
                - [Setting Editor Language 🌐](#setting-editor-language-)
         
     | 
| 
         @@ -184,9 +187,6 @@ Configuration of the editor can be complex, and it's recommended to use the [CKE 
     | 
|
| 
       184 
187 
     | 
    
         | 
| 
       185 
188 
     | 
    
         
             
            ### Available Configuration Methods ⚙️
         
     | 
| 
       186 
189 
     | 
    
         | 
| 
       187 
     | 
    
         
            -
            <details>
         
     | 
| 
       188 
     | 
    
         
            -
              <summary>Expand to show available methods 📖</summary>
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
190 
     | 
    
         
             
            #### `cdn(cdn = nil, &block)` method
         
     | 
| 
       191 
191 
     | 
    
         | 
| 
       192 
192 
     | 
    
         
             
            Defines the CDN to be used for CKEditor 5 assets. The example below shows how to set the CDN to `:jsdelivr`:
         
     | 
| 
         @@ -569,8 +569,6 @@ CKEditor5::Rails.configure do 
     | 
|
| 
       569 
569 
     | 
    
         
             
            end
         
     | 
| 
       570 
570 
     | 
    
         
             
            ```
         
     | 
| 
       571 
571 
     | 
    
         | 
| 
       572 
     | 
    
         
            -
            </details>
         
     | 
| 
       573 
     | 
    
         
            -
             
     | 
| 
       574 
572 
     | 
    
         
             
            ## Including CKEditor 5 assets 📦
         
     | 
| 
       575 
573 
     | 
    
         | 
| 
       576 
574 
     | 
    
         
             
            To include CKEditor 5 assets in your application, you can use the `ckeditor5_assets` helper method. This method takes the version of CKEditor 5 as an argument and includes the necessary resources of the editor. Depending on the specified configuration, it includes the JS and CSS assets from the official CKEditor 5 CDN or one of the popular CDNs.
         
     | 
| 
         @@ -965,6 +963,46 @@ If you want to use a decoupled editor, you can pass the `type` keyword argument 
     | 
|
| 
       965 
963 
     | 
    
         
             
            <% end %>
         
     | 
| 
       966 
964 
     | 
    
         
             
            ```
         
     | 
| 
       967 
965 
     | 
    
         | 
| 
      
 966 
     | 
    
         
            +
            ## Using Context 📦
         
     | 
| 
      
 967 
     | 
    
         
            +
             
     | 
| 
      
 968 
     | 
    
         
            +
            Context CKEditor 5 is a feature that allows multiple editor instances to share a common configuration and state. This is particularly useful in collaborative environments where multiple users are editing different parts of the same document simultaneously. By using a shared context, all editor instances can synchronize their configurations, plugins, and other settings, ensuring a consistent editing experience across all users.
         
     | 
| 
      
 969 
     | 
    
         
            +
             
     | 
| 
      
 970 
     | 
    
         
            +
            ### Benefits of Using Context in Collaboration 🤝
         
     | 
| 
      
 971 
     | 
    
         
            +
             
     | 
| 
      
 972 
     | 
    
         
            +
            1. **Consistency**: Ensures that all editor instances have the same configuration, plugins, and settings, providing a uniform editing experience.
         
     | 
| 
      
 973 
     | 
    
         
            +
            2. **Synchronization**: Allows real-time synchronization of content and changes across multiple editor instances, making collaborative editing seamless.
         
     | 
| 
      
 974 
     | 
    
         
            +
            3. **Resource Sharing**: Reduces the overhead of loading and initializing multiple editor instances by sharing common resources and configurations.
         
     | 
| 
      
 975 
     | 
    
         
            +
            4. **Simplified Management**: Makes it easier to manage and update the configuration and state of multiple editor instances from a single point.
         
     | 
| 
      
 976 
     | 
    
         
            +
             
     | 
| 
      
 977 
     | 
    
         
            +
            ### Using Context in CKEditor 5 🔄
         
     | 
| 
      
 978 
     | 
    
         
            +
             
     | 
| 
      
 979 
     | 
    
         
            +
            Format of the `ckeditor5_context` helper:
         
     | 
| 
      
 980 
     | 
    
         
            +
             
     | 
| 
      
 981 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 982 
     | 
    
         
            +
            <%= ckeditor5_context config: { ...you context config... }, plugins: [ ...your context plugins... ] do %>
         
     | 
| 
      
 983 
     | 
    
         
            +
              <%= ckeditor5_editor %>
         
     | 
| 
      
 984 
     | 
    
         
            +
              <%= ckeditor5_editor %>
         
     | 
| 
      
 985 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 986 
     | 
    
         
            +
            ```
         
     | 
| 
      
 987 
     | 
    
         
            +
             
     | 
| 
      
 988 
     | 
    
         
            +
            Example usage:
         
     | 
| 
      
 989 
     | 
    
         
            +
             
     | 
| 
      
 990 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 991 
     | 
    
         
            +
            <!-- app/views/demos/index.html.erb -->
         
     | 
| 
      
 992 
     | 
    
         
            +
             
     | 
| 
      
 993 
     | 
    
         
            +
            <% content_for :head do %>
         
     | 
| 
      
 994 
     | 
    
         
            +
              <%= ckeditor5_assets preset: :ultrabasic %>
         
     | 
| 
      
 995 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 996 
     | 
    
         
            +
             
     | 
| 
      
 997 
     | 
    
         
            +
            <%= ckeditor5_context do %>
         
     | 
| 
      
 998 
     | 
    
         
            +
              <%= ckeditor5_editor initial_data: 'Hello World' %>
         
     | 
| 
      
 999 
     | 
    
         
            +
             
     | 
| 
      
 1000 
     | 
    
         
            +
              <br>
         
     | 
| 
      
 1001 
     | 
    
         
            +
             
     | 
| 
      
 1002 
     | 
    
         
            +
              <%= ckeditor5_editor initial_data: 'Hello World 2' %>
         
     | 
| 
      
 1003 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 1004 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1005 
     | 
    
         
            +
             
     | 
| 
       968 
1006 
     | 
    
         
             
            ## How to access editor instance? 🤔
         
     | 
| 
       969 
1007 
     | 
    
         | 
| 
       970 
1008 
     | 
    
         
             
            You can access the editor instance using plain HTML and JavaScript, as CKEditor 5 is a web component with defined `instance`, `instancePromise` and `editables` properties.
         
     | 
| 
         @@ -57,16 +57,30 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       57 
57 
     | 
    
         
             
              /** @type {String} Initial HTML passed to component */
         
     | 
| 
       58 
58 
     | 
    
         
             
              #initialHTML = '';
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
              /** @type {CKEditorContextComponent|null} */
         
     | 
| 
      
 61 
     | 
    
         
            +
              #context = null;
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              /** @type {String} ID of editor within context */
         
     | 
| 
      
 64 
     | 
    
         
            +
              #contextEditorId = null;
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       60 
66 
     | 
    
         
             
              /**
         
     | 
| 
       61 
67 
     | 
    
         
             
               * Lifecycle callback when element is connected to DOM
         
     | 
| 
       62 
68 
     | 
    
         
             
               * Initializes the editor when DOM is ready
         
     | 
| 
       63 
69 
     | 
    
         
             
               * @protected
         
     | 
| 
       64 
70 
     | 
    
         
             
               */
         
     | 
| 
       65 
71 
     | 
    
         
             
              connectedCallback() {
         
     | 
| 
      
 72 
     | 
    
         
            +
                this.#context = this.closest('ckeditor-context-component');
         
     | 
| 
       66 
73 
     | 
    
         
             
                this.#initialHTML = this.innerHTML;
         
     | 
| 
       67 
74 
     | 
    
         | 
| 
       68 
75 
     | 
    
         
             
                try {
         
     | 
| 
       69 
     | 
    
         
            -
                  execIfDOMReady(() =>  
     | 
| 
      
 76 
     | 
    
         
            +
                  execIfDOMReady(async () => {
         
     | 
| 
      
 77 
     | 
    
         
            +
                    if (this.#context) {
         
     | 
| 
      
 78 
     | 
    
         
            +
                      await this.#context.instancePromise.promise;
         
     | 
| 
      
 79 
     | 
    
         
            +
                      this.#context.registerEditor(this);
         
     | 
| 
      
 80 
     | 
    
         
            +
                    }
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    await this.reinitializeEditor();
         
     | 
| 
      
 83 
     | 
    
         
            +
                  });
         
     | 
| 
       70 
84 
     | 
    
         
             
                } catch (error) {
         
     | 
| 
       71 
85 
     | 
    
         
             
                  console.error('Failed to initialize editor:', error);
         
     | 
| 
       72 
86 
     | 
    
         
             
                  this.dispatchEvent(new CustomEvent('editor-error', { detail: error }));
         
     | 
| 
         @@ -84,7 +98,7 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       84 
98 
     | 
    
         
             
                if (oldValue !== null &&
         
     | 
| 
       85 
99 
     | 
    
         
             
                    oldValue !== newValue &&
         
     | 
| 
       86 
100 
     | 
    
         
             
                    CKEditorComponent.observedAttributes.includes(name) && this.isConnected) {
         
     | 
| 
       87 
     | 
    
         
            -
                  await this 
     | 
| 
      
 101 
     | 
    
         
            +
                  await this.reinitializeEditor();
         
     | 
| 
       88 
102 
     | 
    
         
             
                }
         
     | 
| 
       89 
103 
     | 
    
         
             
              }
         
     | 
| 
       90 
104 
     | 
    
         | 
| 
         @@ -94,9 +108,12 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       94 
108 
     | 
    
         
             
               * @protected
         
     | 
| 
       95 
109 
     | 
    
         
             
               */
         
     | 
| 
       96 
110 
     | 
    
         
             
              async disconnectedCallback() {
         
     | 
| 
      
 111 
     | 
    
         
            +
                if (this.#context) {
         
     | 
| 
      
 112 
     | 
    
         
            +
                  this.#context.unregisterEditor(this);
         
     | 
| 
      
 113 
     | 
    
         
            +
                }
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
       97 
115 
     | 
    
         
             
                try {
         
     | 
| 
       98 
     | 
    
         
            -
                  await this 
     | 
| 
       99 
     | 
    
         
            -
                  await this.watchdog?.destroy();
         
     | 
| 
      
 116 
     | 
    
         
            +
                  await this.#destroy();
         
     | 
| 
       100 
117 
     | 
    
         
             
                } catch (error) {
         
     | 
| 
       101 
118 
     | 
    
         
             
                  console.error('Failed to destroy editor:', error);
         
     | 
| 
       102 
119 
     | 
    
         
             
                }
         
     | 
| 
         @@ -119,6 +136,7 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       119 
136 
     | 
    
         | 
| 
       120 
137 
     | 
    
         
             
              /**
         
     | 
| 
       121 
138 
     | 
    
         
             
               * Determines appropriate editor element tag based on editor type
         
     | 
| 
      
 139 
     | 
    
         
            +
               *
         
     | 
| 
       122 
140 
     | 
    
         
             
               * @private
         
     | 
| 
       123 
141 
     | 
    
         
             
               * @returns {string} HTML tag name to use
         
     | 
| 
       124 
142 
     | 
    
         
             
               */
         
     | 
| 
         @@ -133,57 +151,25 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       133 
151 
     | 
    
         
             
              }
         
     | 
| 
       134 
152 
     | 
    
         | 
| 
       135 
153 
     | 
    
         
             
              /**
         
     | 
| 
       136 
     | 
    
         
            -
               *  
     | 
| 
       137 
     | 
    
         
            -
               * Looks for objects with { $element: "selector" } format and replaces them with actual elements.
         
     | 
| 
      
 154 
     | 
    
         
            +
               * Gets the CKEditor context instance if available.
         
     | 
| 
       138 
155 
     | 
    
         
             
               *
         
     | 
| 
       139 
156 
     | 
    
         
             
               * @private
         
     | 
| 
       140 
     | 
    
         
            -
               * @ 
     | 
| 
       141 
     | 
    
         
            -
               * @returns {Object} Processed configuration object with resolved element references
         
     | 
| 
      
 157 
     | 
    
         
            +
               * @returns {import('ckeditor5').ContextWatchdog|null}
         
     | 
| 
       142 
158 
     | 
    
         
             
               */
         
     | 
| 
       143 
     | 
    
         
            -
              # 
     | 
| 
       144 
     | 
    
         
            -
                 
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                }
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
                if (Array.isArray(obj)) {
         
     | 
| 
       149 
     | 
    
         
            -
                  return obj.map(item => this.#resolveElementReferences(item));
         
     | 
| 
       150 
     | 
    
         
            -
                }
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
                const result = Object.create(null);
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
                for (const key of Object.getOwnPropertyNames(obj)) {
         
     | 
| 
       155 
     | 
    
         
            -
                  if (!isSafeKey(key)) {
         
     | 
| 
       156 
     | 
    
         
            -
                    console.warn(`Suspicious key "${key}" detected in config, skipping`);
         
     | 
| 
       157 
     | 
    
         
            -
                    continue;
         
     | 
| 
       158 
     | 
    
         
            -
                  }
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
                  const value = obj[key];
         
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
                  if (value && typeof value === 'object') {
         
     | 
| 
       163 
     | 
    
         
            -
                    if (value.$element) {
         
     | 
| 
       164 
     | 
    
         
            -
                      const selector = value.$element;
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
                      if (typeof selector !== 'string') {
         
     | 
| 
       167 
     | 
    
         
            -
                        console.warn(`Invalid selector type for "${key}", expected string`);
         
     | 
| 
       168 
     | 
    
         
            -
                        continue;
         
     | 
| 
       169 
     | 
    
         
            -
                      }
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
                      const element = document.querySelector(selector);
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
                      if (!element) {
         
     | 
| 
       174 
     | 
    
         
            -
                        console.warn(`Element not found for selector: ${selector}`);
         
     | 
| 
       175 
     | 
    
         
            -
                      }
         
     | 
| 
      
 159 
     | 
    
         
            +
              get #contextWatchdog() {
         
     | 
| 
      
 160 
     | 
    
         
            +
                return this.#context?.instance;
         
     | 
| 
      
 161 
     | 
    
         
            +
              }
         
     | 
| 
       176 
162 
     | 
    
         | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
                  }
         
     | 
| 
      
 163 
     | 
    
         
            +
              /**
         
     | 
| 
      
 164 
     | 
    
         
            +
               * Destroys the editor instance and watchdog if available
         
     | 
| 
      
 165 
     | 
    
         
            +
               */
         
     | 
| 
      
 166 
     | 
    
         
            +
              async #destroy() {
         
     | 
| 
      
 167 
     | 
    
         
            +
                if (this.#contextEditorId) {
         
     | 
| 
      
 168 
     | 
    
         
            +
                  await this.#contextWatchdog.remove(this.#contextEditorId);
         
     | 
| 
       184 
169 
     | 
    
         
             
                }
         
     | 
| 
       185 
170 
     | 
    
         | 
| 
       186 
     | 
    
         
            -
                 
     | 
| 
      
 171 
     | 
    
         
            +
                await this.instance?.destroy();
         
     | 
| 
      
 172 
     | 
    
         
            +
                await this.watchdog?.destroy();
         
     | 
| 
       187 
173 
     | 
    
         
             
              }
         
     | 
| 
       188 
174 
     | 
    
         | 
| 
       189 
175 
     | 
    
         
             
              /**
         
     | 
| 
         @@ -195,7 +181,7 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       195 
181 
     | 
    
         
             
              #getConfig() {
         
     | 
| 
       196 
182 
     | 
    
         
             
                const config = JSON.parse(this.getAttribute('config') || '{}');
         
     | 
| 
       197 
183 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
                return  
     | 
| 
      
 184 
     | 
    
         
            +
                return resolveElementReferences(config);
         
     | 
| 
       199 
185 
     | 
    
         
             
              }
         
     | 
| 
       200 
186 
     | 
    
         | 
| 
       201 
187 
     | 
    
         
             
              /**
         
     | 
| 
         @@ -232,13 +218,27 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       232 
218 
     | 
    
         
             
                  plugins,
         
     | 
| 
       233 
219 
     | 
    
         
             
                };
         
     | 
| 
       234 
220 
     | 
    
         | 
| 
       235 
     | 
    
         
            -
                console.warn('Initializing CKEditor with:', { config, watchdog: this.hasWatchdog() });
         
     | 
| 
      
 221 
     | 
    
         
            +
                console.warn('Initializing CKEditor with:', { config, watchdog: this.hasWatchdog(), context: this.#context });
         
     | 
| 
       236 
222 
     | 
    
         | 
| 
       237 
223 
     | 
    
         
             
                // Initialize watchdog if needed
         
     | 
| 
       238 
224 
     | 
    
         
             
                let watchdog = null;
         
     | 
| 
       239 
225 
     | 
    
         
             
                let instance = null;
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
      
 226 
     | 
    
         
            +
                let contextId = null;
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                if (this.#context) {
         
     | 
| 
      
 229 
     | 
    
         
            +
                  contextId = uid();
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                  await this.#contextWatchdog.add( {
         
     | 
| 
      
 232 
     | 
    
         
            +
                    creator: (_element, _config) => Editor.create(_element, _config),
         
     | 
| 
      
 233 
     | 
    
         
            +
                    id: contextId,
         
     | 
| 
      
 234 
     | 
    
         
            +
                    sourceElementOrData: content,
         
     | 
| 
      
 235 
     | 
    
         
            +
                    type: 'editor',
         
     | 
| 
      
 236 
     | 
    
         
            +
                    config,
         
     | 
| 
      
 237 
     | 
    
         
            +
                  } );
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
                  instance = this.#contextWatchdog.getItem(contextId);
         
     | 
| 
      
 240 
     | 
    
         
            +
                } else if (this.hasWatchdog()) {
         
     | 
| 
      
 241 
     | 
    
         
            +
                  // Let's create use with plain watchdog.
         
     | 
| 
       242 
242 
     | 
    
         
             
                  const { EditorWatchdog } = await import('ckeditor5');
         
     | 
| 
       243 
243 
     | 
    
         
             
                  const watchdog = new EditorWatchdog(Editor);
         
     | 
| 
       244 
244 
     | 
    
         | 
| 
         @@ -246,12 +246,14 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       246 
246 
     | 
    
         | 
| 
       247 
247 
     | 
    
         
             
                  instance = watchdog.editor;
         
     | 
| 
       248 
248 
     | 
    
         
             
                } else {
         
     | 
| 
      
 249 
     | 
    
         
            +
                  // Let's create the editor without watchdog.
         
     | 
| 
       249 
250 
     | 
    
         
             
                  instance = await Editor.create(content, config);
         
     | 
| 
       250 
251 
     | 
    
         
             
                }
         
     | 
| 
       251 
252 
     | 
    
         | 
| 
       252 
253 
     | 
    
         
             
                this.dispatchEvent(new CustomEvent('editor-ready', { detail: instance }));
         
     | 
| 
       253 
254 
     | 
    
         | 
| 
       254 
255 
     | 
    
         
             
                return {
         
     | 
| 
      
 256 
     | 
    
         
            +
                  contextId,
         
     | 
| 
       255 
257 
     | 
    
         
             
                  instance,
         
     | 
| 
       256 
258 
     | 
    
         
             
                  watchdog,
         
     | 
| 
       257 
259 
     | 
    
         
             
                };
         
     | 
| 
         @@ -263,11 +265,12 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       263 
265 
     | 
    
         
             
               * @private
         
     | 
| 
       264 
266 
     | 
    
         
             
               * @returns {Promise<void>}
         
     | 
| 
       265 
267 
     | 
    
         
             
               */
         
     | 
| 
       266 
     | 
    
         
            -
              async  
     | 
| 
      
 268 
     | 
    
         
            +
              async reinitializeEditor() {
         
     | 
| 
       267 
269 
     | 
    
         
             
                if (this.instance) {
         
     | 
| 
       268 
270 
     | 
    
         
             
                  this.instancePromise = Promise.withResolvers();
         
     | 
| 
       269 
271 
     | 
    
         | 
| 
       270 
     | 
    
         
            -
                  await this 
     | 
| 
      
 272 
     | 
    
         
            +
                  await this.#destroy();
         
     | 
| 
      
 273 
     | 
    
         
            +
             
     | 
| 
       271 
274 
     | 
    
         
             
                  this.instance = null;
         
     | 
| 
       272 
275 
     | 
    
         
             
                }
         
     | 
| 
       273 
276 
     | 
    
         | 
| 
         @@ -288,10 +291,11 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       288 
291 
     | 
    
         
             
                }
         
     | 
| 
       289 
292 
     | 
    
         | 
| 
       290 
293 
     | 
    
         
             
                try {
         
     | 
| 
       291 
     | 
    
         
            -
                  const { watchdog, instance } = await this.#initializeEditor(this.editables || this.#getConfig().initialData || '');
         
     | 
| 
      
 294 
     | 
    
         
            +
                  const { watchdog, instance, contextId } = await this.#initializeEditor(this.editables || this.#getConfig().initialData || '');
         
     | 
| 
       292 
295 
     | 
    
         | 
| 
       293 
296 
     | 
    
         
             
                  this.watchdog = watchdog;
         
     | 
| 
       294 
297 
     | 
    
         
             
                  this.instance = instance;
         
     | 
| 
      
 298 
     | 
    
         
            +
                  this.#contextEditorId = contextId;
         
     | 
| 
       295 
299 
     | 
    
         | 
| 
       296 
300 
     | 
    
         
             
                  this.#setupContentSync();
         
     | 
| 
       297 
301 
     | 
    
         
             
                  this.#setupEditableHeight();
         
     | 
| 
         @@ -511,6 +515,129 @@ class CKEditorComponent extends HTMLElement { 
     | 
|
| 
       511 
515 
     | 
    
         
             
              }
         
     | 
| 
       512 
516 
     | 
    
         
             
            }
         
     | 
| 
       513 
517 
     | 
    
         | 
| 
      
 518 
     | 
    
         
            +
            /**
         
     | 
| 
      
 519 
     | 
    
         
            +
             * Custom element that provides shared CKEditor context for multiple editors.
         
     | 
| 
      
 520 
     | 
    
         
            +
             *
         
     | 
| 
      
 521 
     | 
    
         
            +
             * @extends HTMLElement
         
     | 
| 
      
 522 
     | 
    
         
            +
             * @example
         
     | 
| 
      
 523 
     | 
    
         
            +
             *
         
     | 
| 
      
 524 
     | 
    
         
            +
             * <ckeditor-context-component plugins='[ ... ]'>
         
     | 
| 
      
 525 
     | 
    
         
            +
             *  <ckeditor-component type="ClassicEditor" config='{"toolbar": ["bold", "italic"]}'>
         
     | 
| 
      
 526 
     | 
    
         
            +
             *  <ckeditor-component type="ClassicEditor" config='{"toolbar": ["bold", "italic"]}'>
         
     | 
| 
      
 527 
     | 
    
         
            +
             * </ckeditor-component>
         
     | 
| 
      
 528 
     | 
    
         
            +
             */
         
     | 
| 
      
 529 
     | 
    
         
            +
            class CKEditorContextComponent extends HTMLElement {
         
     | 
| 
      
 530 
     | 
    
         
            +
              static get observedAttributes() {
         
     | 
| 
      
 531 
     | 
    
         
            +
                return ['plugins', 'config'];
         
     | 
| 
      
 532 
     | 
    
         
            +
              }
         
     | 
| 
      
 533 
     | 
    
         
            +
             
     | 
| 
      
 534 
     | 
    
         
            +
              /** @type {import('ckeditor5').Context|null} */
         
     | 
| 
      
 535 
     | 
    
         
            +
              instance = null;
         
     | 
| 
      
 536 
     | 
    
         
            +
             
     | 
| 
      
 537 
     | 
    
         
            +
              /** @type {Promise<import('ckeditor5').Context>} */
         
     | 
| 
      
 538 
     | 
    
         
            +
              instancePromise = Promise.withResolvers();
         
     | 
| 
      
 539 
     | 
    
         
            +
             
     | 
| 
      
 540 
     | 
    
         
            +
              /** @type {Set<CKEditorComponent>} */
         
     | 
| 
      
 541 
     | 
    
         
            +
              #connectedEditors = new Set();
         
     | 
| 
      
 542 
     | 
    
         
            +
             
     | 
| 
      
 543 
     | 
    
         
            +
              async connectedCallback() {
         
     | 
| 
      
 544 
     | 
    
         
            +
                try {
         
     | 
| 
      
 545 
     | 
    
         
            +
                  execIfDOMReady(() => this.#initializeContext());
         
     | 
| 
      
 546 
     | 
    
         
            +
                } catch (error) {
         
     | 
| 
      
 547 
     | 
    
         
            +
                  console.error('Failed to initialize context:', error);
         
     | 
| 
      
 548 
     | 
    
         
            +
                  this.dispatchEvent(new CustomEvent('context-error', { detail: error }));
         
     | 
| 
      
 549 
     | 
    
         
            +
                }
         
     | 
| 
      
 550 
     | 
    
         
            +
              }
         
     | 
| 
      
 551 
     | 
    
         
            +
             
     | 
| 
      
 552 
     | 
    
         
            +
              async attributeChangedCallback(name, oldValue, newValue) {
         
     | 
| 
      
 553 
     | 
    
         
            +
                if (oldValue !== null && oldValue !== newValue) {
         
     | 
| 
      
 554 
     | 
    
         
            +
                  await this.#initializeContext();
         
     | 
| 
      
 555 
     | 
    
         
            +
                }
         
     | 
| 
      
 556 
     | 
    
         
            +
              }
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
              async disconnectedCallback() {
         
     | 
| 
      
 559 
     | 
    
         
            +
                if (this.instance) {
         
     | 
| 
      
 560 
     | 
    
         
            +
                  await this.instance.destroy();
         
     | 
| 
      
 561 
     | 
    
         
            +
                  this.instance = null;
         
     | 
| 
      
 562 
     | 
    
         
            +
                }
         
     | 
| 
      
 563 
     | 
    
         
            +
              }
         
     | 
| 
      
 564 
     | 
    
         
            +
             
     | 
| 
      
 565 
     | 
    
         
            +
              /**
         
     | 
| 
      
 566 
     | 
    
         
            +
               * Register editor component with this context
         
     | 
| 
      
 567 
     | 
    
         
            +
               *
         
     | 
| 
      
 568 
     | 
    
         
            +
               * @param {CKEditorComponent} editor
         
     | 
| 
      
 569 
     | 
    
         
            +
               */
         
     | 
| 
      
 570 
     | 
    
         
            +
              registerEditor(editor) {
         
     | 
| 
      
 571 
     | 
    
         
            +
                this.#connectedEditors.add(editor);
         
     | 
| 
      
 572 
     | 
    
         
            +
              }
         
     | 
| 
      
 573 
     | 
    
         
            +
             
     | 
| 
      
 574 
     | 
    
         
            +
              /**
         
     | 
| 
      
 575 
     | 
    
         
            +
               * Unregister editor component from this context
         
     | 
| 
      
 576 
     | 
    
         
            +
               *
         
     | 
| 
      
 577 
     | 
    
         
            +
               * @param {CKEditorComponent} editor
         
     | 
| 
      
 578 
     | 
    
         
            +
               */
         
     | 
| 
      
 579 
     | 
    
         
            +
              unregisterEditor(editor) {
         
     | 
| 
      
 580 
     | 
    
         
            +
                this.#connectedEditors.delete(editor);
         
     | 
| 
      
 581 
     | 
    
         
            +
              }
         
     | 
| 
      
 582 
     | 
    
         
            +
             
     | 
| 
      
 583 
     | 
    
         
            +
              /**
         
     | 
| 
      
 584 
     | 
    
         
            +
               * Initialize CKEditor context with shared configuration
         
     | 
| 
      
 585 
     | 
    
         
            +
               *
         
     | 
| 
      
 586 
     | 
    
         
            +
               * @private
         
     | 
| 
      
 587 
     | 
    
         
            +
               */
         
     | 
| 
      
 588 
     | 
    
         
            +
              async #initializeContext() {
         
     | 
| 
      
 589 
     | 
    
         
            +
                if (this.instance) {
         
     | 
| 
      
 590 
     | 
    
         
            +
                  this.instancePromise = Promise.withResolvers();
         
     | 
| 
      
 591 
     | 
    
         
            +
             
     | 
| 
      
 592 
     | 
    
         
            +
                  await this.instance.destroy();
         
     | 
| 
      
 593 
     | 
    
         
            +
             
     | 
| 
      
 594 
     | 
    
         
            +
                  this.instance = null;
         
     | 
| 
      
 595 
     | 
    
         
            +
                }
         
     | 
| 
      
 596 
     | 
    
         
            +
             
     | 
| 
      
 597 
     | 
    
         
            +
                const { Context, ContextWatchdog } = await import('ckeditor5');
         
     | 
| 
      
 598 
     | 
    
         
            +
                const plugins = await this.#getPlugins();
         
     | 
| 
      
 599 
     | 
    
         
            +
                const config = this.#getConfig();
         
     | 
| 
      
 600 
     | 
    
         
            +
             
     | 
| 
      
 601 
     | 
    
         
            +
                this.instance = new ContextWatchdog(Context, {
         
     | 
| 
      
 602 
     | 
    
         
            +
                  crashNumberLimit: 10
         
     | 
| 
      
 603 
     | 
    
         
            +
                });
         
     | 
| 
      
 604 
     | 
    
         
            +
             
     | 
| 
      
 605 
     | 
    
         
            +
                await this.instance.create({
         
     | 
| 
      
 606 
     | 
    
         
            +
                  ...config,
         
     | 
| 
      
 607 
     | 
    
         
            +
                  plugins
         
     | 
| 
      
 608 
     | 
    
         
            +
                });
         
     | 
| 
      
 609 
     | 
    
         
            +
             
     | 
| 
      
 610 
     | 
    
         
            +
                this.instance.on('itemError', (...args) => {
         
     | 
| 
      
 611 
     | 
    
         
            +
                  console.error('Context item error:', ...args);
         
     | 
| 
      
 612 
     | 
    
         
            +
                });
         
     | 
| 
      
 613 
     | 
    
         
            +
             
     | 
| 
      
 614 
     | 
    
         
            +
                this.instancePromise.resolve(this.instance);
         
     | 
| 
      
 615 
     | 
    
         
            +
                this.dispatchEvent(new CustomEvent('context-ready', { detail: this.instance }));
         
     | 
| 
      
 616 
     | 
    
         
            +
             
     | 
| 
      
 617 
     | 
    
         
            +
                // Reinitialize connected editors.
         
     | 
| 
      
 618 
     | 
    
         
            +
                await Promise.all(
         
     | 
| 
      
 619 
     | 
    
         
            +
                  [...this.#connectedEditors].map(editor => editor.reinitializeEditor())
         
     | 
| 
      
 620 
     | 
    
         
            +
                );
         
     | 
| 
      
 621 
     | 
    
         
            +
              }
         
     | 
| 
      
 622 
     | 
    
         
            +
             
     | 
| 
      
 623 
     | 
    
         
            +
              async #getPlugins() {
         
     | 
| 
      
 624 
     | 
    
         
            +
                const raw = this.getAttribute('plugins');
         
     | 
| 
      
 625 
     | 
    
         
            +
             
     | 
| 
      
 626 
     | 
    
         
            +
                return loadAsyncImports(raw ? JSON.parse(raw) : []);
         
     | 
| 
      
 627 
     | 
    
         
            +
              }
         
     | 
| 
      
 628 
     | 
    
         
            +
             
     | 
| 
      
 629 
     | 
    
         
            +
              /**
         
     | 
| 
      
 630 
     | 
    
         
            +
               * Gets context configuration with resolved element references.
         
     | 
| 
      
 631 
     | 
    
         
            +
               *
         
     | 
| 
      
 632 
     | 
    
         
            +
               * @private
         
     | 
| 
      
 633 
     | 
    
         
            +
               */
         
     | 
| 
      
 634 
     | 
    
         
            +
              #getConfig() {
         
     | 
| 
      
 635 
     | 
    
         
            +
                const config = JSON.parse(this.getAttribute('config') || '{}');
         
     | 
| 
      
 636 
     | 
    
         
            +
             
     | 
| 
      
 637 
     | 
    
         
            +
                return resolveElementReferences(config);
         
     | 
| 
      
 638 
     | 
    
         
            +
              }
         
     | 
| 
      
 639 
     | 
    
         
            +
            }
         
     | 
| 
      
 640 
     | 
    
         
            +
             
     | 
| 
       514 
641 
     | 
    
         
             
            /**
         
     | 
| 
       515 
642 
     | 
    
         
             
             * Tracks and manages editable roots for CKEditor MultiRoot editor.
         
     | 
| 
       516 
643 
     | 
    
         
             
             * Provides a proxy-based API for dynamically managing editable elements with automatic
         
     | 
| 
         @@ -894,6 +1021,69 @@ function isSafeKey(key) { 
     | 
|
| 
       894 
1021 
     | 
    
         
             
                      key !== 'prototype';
         
     | 
| 
       895 
1022 
     | 
    
         
             
            }
         
     | 
| 
       896 
1023 
     | 
    
         | 
| 
      
 1024 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1025 
     | 
    
         
            +
             * Resolves element references in configuration object.
         
     | 
| 
      
 1026 
     | 
    
         
            +
             * Looks for objects with { $element: "selector" } format and replaces them with actual elements.
         
     | 
| 
      
 1027 
     | 
    
         
            +
             *
         
     | 
| 
      
 1028 
     | 
    
         
            +
             * @param {Object} obj - Configuration object to process
         
     | 
| 
      
 1029 
     | 
    
         
            +
             * @returns {Object} Processed configuration object with resolved element references
         
     | 
| 
      
 1030 
     | 
    
         
            +
             */
         
     | 
| 
      
 1031 
     | 
    
         
            +
            function resolveElementReferences(obj) {
         
     | 
| 
      
 1032 
     | 
    
         
            +
              if (!obj || typeof obj !== 'object') {
         
     | 
| 
      
 1033 
     | 
    
         
            +
                return obj;
         
     | 
| 
      
 1034 
     | 
    
         
            +
              }
         
     | 
| 
      
 1035 
     | 
    
         
            +
             
     | 
| 
      
 1036 
     | 
    
         
            +
              if (Array.isArray(obj)) {
         
     | 
| 
      
 1037 
     | 
    
         
            +
                return obj.map(item => resolveElementReferences(item));
         
     | 
| 
      
 1038 
     | 
    
         
            +
              }
         
     | 
| 
      
 1039 
     | 
    
         
            +
             
     | 
| 
      
 1040 
     | 
    
         
            +
              const result = Object.create(null);
         
     | 
| 
      
 1041 
     | 
    
         
            +
             
     | 
| 
      
 1042 
     | 
    
         
            +
              for (const key of Object.getOwnPropertyNames(obj)) {
         
     | 
| 
      
 1043 
     | 
    
         
            +
                if (!isSafeKey(key)) {
         
     | 
| 
      
 1044 
     | 
    
         
            +
                  console.warn(`Suspicious key "${key}" detected in config, skipping`);
         
     | 
| 
      
 1045 
     | 
    
         
            +
                  continue;
         
     | 
| 
      
 1046 
     | 
    
         
            +
                }
         
     | 
| 
      
 1047 
     | 
    
         
            +
             
     | 
| 
      
 1048 
     | 
    
         
            +
                const value = obj[key];
         
     | 
| 
      
 1049 
     | 
    
         
            +
             
     | 
| 
      
 1050 
     | 
    
         
            +
                if (value && typeof value === 'object') {
         
     | 
| 
      
 1051 
     | 
    
         
            +
                  if (value.$element) {
         
     | 
| 
      
 1052 
     | 
    
         
            +
                    const selector = value.$element;
         
     | 
| 
      
 1053 
     | 
    
         
            +
             
     | 
| 
      
 1054 
     | 
    
         
            +
                    if (typeof selector !== 'string') {
         
     | 
| 
      
 1055 
     | 
    
         
            +
                      console.warn(`Invalid selector type for "${key}", expected string`);
         
     | 
| 
      
 1056 
     | 
    
         
            +
                      continue;
         
     | 
| 
      
 1057 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1058 
     | 
    
         
            +
             
     | 
| 
      
 1059 
     | 
    
         
            +
                    const element = document.querySelector(selector);
         
     | 
| 
      
 1060 
     | 
    
         
            +
             
     | 
| 
      
 1061 
     | 
    
         
            +
                    if (!element) {
         
     | 
| 
      
 1062 
     | 
    
         
            +
                      console.warn(`Element not found for selector: ${selector}`);
         
     | 
| 
      
 1063 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1064 
     | 
    
         
            +
             
     | 
| 
      
 1065 
     | 
    
         
            +
                    result[key] = element || null;
         
     | 
| 
      
 1066 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 1067 
     | 
    
         
            +
                    result[key] = resolveElementReferences(value);
         
     | 
| 
      
 1068 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1069 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1070 
     | 
    
         
            +
                  result[key] = value;
         
     | 
| 
      
 1071 
     | 
    
         
            +
                }
         
     | 
| 
      
 1072 
     | 
    
         
            +
              }
         
     | 
| 
      
 1073 
     | 
    
         
            +
             
     | 
| 
      
 1074 
     | 
    
         
            +
              return result;
         
     | 
| 
      
 1075 
     | 
    
         
            +
            }
         
     | 
| 
      
 1076 
     | 
    
         
            +
             
     | 
| 
      
 1077 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1078 
     | 
    
         
            +
             * Custom element that provides shared CKEditor context for multiple editors.
         
     | 
| 
      
 1079 
     | 
    
         
            +
             *
         
     | 
| 
      
 1080 
     | 
    
         
            +
             * @returns {String} unique id
         
     | 
| 
      
 1081 
     | 
    
         
            +
             */
         
     | 
| 
      
 1082 
     | 
    
         
            +
            function uid() {
         
     | 
| 
      
 1083 
     | 
    
         
            +
              return Math.random().toString(36).substring(2);
         
     | 
| 
      
 1084 
     | 
    
         
            +
            }
         
     | 
| 
      
 1085 
     | 
    
         
            +
             
     | 
| 
       897 
1086 
     | 
    
         
             
            customElements.define('ckeditor-component', CKEditorComponent);
         
     | 
| 
       898 
1087 
     | 
    
         
             
            customElements.define('ckeditor-editable-component', CKEditorEditableComponent);
         
     | 
| 
       899 
1088 
     | 
    
         
             
            customElements.define('ckeditor-ui-part-component', CKEditorUIPartComponent);
         
     | 
| 
      
 1089 
     | 
    
         
            +
            customElements.define('ckeditor-context-component', CKEditorContextComponent);
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'props'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module CKEditor5::Rails::Context
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Helpers
         
     | 
| 
      
 7 
     | 
    
         
            +
                def ckeditor5_context(**config, &block)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  context_props = Props.new(config)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  tag.send(:'ckeditor-context-component', **context_props.to_attributes, &block)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module CKEditor5::Rails
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Context
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Props
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(config)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @config = config
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def to_attributes
         
     | 
| 
      
 11 
     | 
    
         
            +
                    {
         
     | 
| 
      
 12 
     | 
    
         
            +
                      plugins: serialize_plugins,
         
     | 
| 
      
 13 
     | 
    
         
            +
                      config: serialize_config
         
     | 
| 
      
 14 
     | 
    
         
            +
                    }
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  private
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  attr_reader :config
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def serialize_plugins
         
     | 
| 
      
 22 
     | 
    
         
            +
                    (config[:plugins] || []).map { |plugin| Editor::PropsPlugin.normalize(plugin).to_h }.to_json
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def serialize_config
         
     | 
| 
      
 26 
     | 
    
         
            +
                    config.except(:plugins).to_json
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -29,16 +29,13 @@ module CKEditor5::Rails 
     | 
|
| 
       29 
29 
     | 
    
         
             
                  type ||= preset.type
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
                  validated_height = validate_editable_height(type, editable_height) || preset.editable_height
         
     | 
| 
       32 
     | 
    
         
            -
                  editor_props = Editor::Props.new(
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                    html_attributes.merge(validated_height ? { 'editable-height' => validated_height } : {}),
         
     | 
| 
       40 
     | 
    
         
            -
                    &block
         
     | 
| 
       41 
     | 
    
         
            -
                  )
         
     | 
| 
      
 32 
     | 
    
         
            +
                  editor_props = Editor::Props.new(controller_context, type, config, watchdog: watchdog)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  tag_attributes = html_attributes
         
     | 
| 
      
 35 
     | 
    
         
            +
                                   .merge(editor_props.to_attributes)
         
     | 
| 
      
 36 
     | 
    
         
            +
                                   .merge(validated_height ? { 'editable-height' => validated_height } : {})
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  tag.send(:'ckeditor-component', **tag_attributes, &block)
         
     | 
| 
       42 
39 
     | 
    
         
             
                end
         
     | 
| 
       43 
40 
     | 
    
         | 
| 
       44 
41 
     | 
    
         
             
                def ckeditor5_editable(name = nil, **kwargs, &block)
         
     | 
| 
         @@ -91,10 +88,6 @@ module CKEditor5::Rails 
     | 
|
| 
       91 
88 
     | 
    
         
             
                    raise PresetNotFoundError, "Preset #{preset} is not defined."
         
     | 
| 
       92 
89 
     | 
    
         
             
                end
         
     | 
| 
       93 
90 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
                def render_editor_component(props, html_attributes, &block)
         
     | 
| 
       95 
     | 
    
         
            -
                  tag.send(:'ckeditor-component', **props.to_attributes, **html_attributes, &block)
         
     | 
| 
       96 
     | 
    
         
            -
                end
         
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
91 
     | 
    
         
             
                def validate_editable_height(type, height)
         
     | 
| 
       99 
92 
     | 
    
         
             
                  return nil if height.nil?
         
     | 
| 
       100 
93 
     | 
    
         | 
| 
         @@ -3,11 +3,13 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require_relative 'cdn/helpers'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require_relative 'cloud/helpers'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require_relative 'editor/helpers'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative 'context/helpers'
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
8 
     | 
    
         
             
            module CKEditor5::Rails
         
     | 
| 
       8 
9 
     | 
    
         
             
              module Helpers
         
     | 
| 
       9 
10 
     | 
    
         
             
                include Cdn::Helpers
         
     | 
| 
       10 
11 
     | 
    
         
             
                include Cloud::Helpers
         
     | 
| 
       11 
12 
     | 
    
         
             
                include Editor::Helpers
         
     | 
| 
      
 13 
     | 
    
         
            +
                include Context::Helpers
         
     | 
| 
       12 
14 
     | 
    
         
             
              end
         
     | 
| 
       13 
15 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: ckeditor5
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.9.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Mateusz Bagiński
         
     | 
| 
         @@ -51,6 +51,8 @@ files: 
     | 
|
| 
       51 
51 
     | 
    
         
             
            - lib/ckeditor5/rails/cdn/helpers.rb
         
     | 
| 
       52 
52 
     | 
    
         
             
            - lib/ckeditor5/rails/cdn/url_generator.rb
         
     | 
| 
       53 
53 
     | 
    
         
             
            - lib/ckeditor5/rails/cloud/helpers.rb
         
     | 
| 
      
 54 
     | 
    
         
            +
            - lib/ckeditor5/rails/context/helpers.rb
         
     | 
| 
      
 55 
     | 
    
         
            +
            - lib/ckeditor5/rails/context/props.rb
         
     | 
| 
       54 
56 
     | 
    
         
             
            - lib/ckeditor5/rails/editor/config_helpers.rb
         
     | 
| 
       55 
57 
     | 
    
         
             
            - lib/ckeditor5/rails/editor/helpers.rb
         
     | 
| 
       56 
58 
     | 
    
         
             
            - lib/ckeditor5/rails/editor/props.rb
         
     |