javascript - CKEditor, custom object with children - Stack Overflow

I am trying to create a plugin for CKEditor that adds a custom object with children.Example:<div>

I am trying to create a plugin for CKEditor that adds a custom object with children.

Example:

<div>
    <img src="someimage.jpg" />
    <p>
        Some text
        <span>Some subtext</span>
    </p>
    <img src="someStaticImage.jpg" />
</div>

In the onOk function i have:

---snip---
this.imgElement.setAttribute('src',path + data.imageSrc);
this.staticImgElement.setAttribute('src',path + 'images/staticimg.jpg');
this.imgElement.appendTo(this.element);
this.imgElement.appendTo(this.element);
this.staticImgElement.appendTo(this.element);
---snip---

I would like for this block to behave as a single element, meaning that pressing backspace deletes the whole block, double clicking on it opens the edit dialog...

Any idea how i could do that?

I came close with setting

this.element.setAttribute('contenteditable','false');

However this doesn't allow content to be inserted before "it", if "it" was the first element in the ckedit window.

EDIT:

More info: I'm using CKEditor 4.0, inline version I wish for my "object" to be like the "image" plugin, where when you double click on the image, a dialog opens, the same one as when you create the object (where you set the src, width...). I managed to make it similar to it, but because it is a div with child elements, CKEditor treats each part as seperate, which makes the deleting of the object (with backspace) behave in a wierd way, only parts of it get deleted, backspace needs to be pressed multiple times to delete the entire object.

I am trying to create a plugin for CKEditor that adds a custom object with children.

Example:

<div>
    <img src="someimage.jpg" />
    <p>
        Some text
        <span>Some subtext</span>
    </p>
    <img src="someStaticImage.jpg" />
</div>

In the onOk function i have:

---snip---
this.imgElement.setAttribute('src',path + data.imageSrc);
this.staticImgElement.setAttribute('src',path + 'images/staticimg.jpg');
this.imgElement.appendTo(this.element);
this.imgElement.appendTo(this.element);
this.staticImgElement.appendTo(this.element);
---snip---

I would like for this block to behave as a single element, meaning that pressing backspace deletes the whole block, double clicking on it opens the edit dialog...

Any idea how i could do that?

I came close with setting

this.element.setAttribute('contenteditable','false');

However this doesn't allow content to be inserted before "it", if "it" was the first element in the ckedit window.

EDIT:

More info: I'm using CKEditor 4.0, inline version I wish for my "object" to be like the "image" plugin, where when you double click on the image, a dialog opens, the same one as when you create the object (where you set the src, width...). I managed to make it similar to it, but because it is a div with child elements, CKEditor treats each part as seperate, which makes the deleting of the object (with backspace) behave in a wierd way, only parts of it get deleted, backspace needs to be pressed multiple times to delete the entire object.

Share Improve this question edited May 11, 2013 at 22:55 Ratzor asked May 11, 2013 at 16:29 RatzorRatzor 3173 silver badges15 bronze badges 7
  • What if you have the plugin insert an empty div before it inserts the block, maybe then you would be able to place the cursor before it to insert content even if it's at the top? – codewaggle Commented May 11, 2013 at 17:08
  • Good idea, but CKEditor automatically inserts a &nbsp; inside an empty element (and i want that functionality for other elements), so a space gets created above the element, which i don't want. And also, i want to be able to click right of the element to make the caret appear, like with images. – Ratzor Commented May 11, 2013 at 17:53
  • Can you provide more details? Which version of CkEditor are you using? If 4, are you using standard or inline method? It would be easier to help if you included more plete code samples: a full <body> with all content specific to the question. Any script that is used in the <head>. The plugin code. It looks like you're adding the object outside of the plugin, so what does the plugin do? I've created a plugin that inserts a block into the editor (CkEditor 3.x), so it's possible to do that as part of the plugin. – codewaggle Commented May 11, 2013 at 19:58
  • You said "double clicking on it opens the edit dialog" while "pressing backspace deletes the whole block". How does double clicking open the edit dialog if you're already in the editor? Are you treating it as an object type that is controlled by your plugin, like an image element is controlled by the CkEditor image plugin? – codewaggle Commented May 11, 2013 at 20:05
  • @codewaggle could you share that plugin, so i can check if the answer to my question is in there? Also, i edited the post, added additional info, hope it better explains my problem. – Ratzor Commented May 11, 2013 at 22:57
 |  Show 2 more ments

2 Answers 2

Reset to default 4

I'm a CKEditor core developer and I think that I've got an interesting news for you :). Coincidentally, right now we're working on Widgets feature which is exactly what you mean.

Making some fragments of the page non-editable by setting contenteditable=false make them unusable. Selecting, copying&pasting, right clicking, using arrow keys - all this is at least partially broken. And it's even worse if you try to add a nested editable element (editable inside non-editable), because e.g. it can be deleted from inside.

That's why we decided to implement a nice API for creating widgets and fix all these bugs under the hood. Maybe not all bugs and in all browsers at the beginning, because there's huge (really... I mean huuuuge :P) amount of them and of course no standard behaviour between browsers at all. But it will be a good start. First version of widgets that will be released in uping CKEditor 4.2 should be usable - this is our goal. Then we'll focus on stabilizing the implementation.

PS. CKEditor Roadmap says that CKE 4.2 will be ready in 11 days and this is not true, unfortunately. We're delayed, but I don't want to estimate now how much.

You indicated that you've created the plugin that handles the object, but that the problem you want to solve is the inability to insert content before the object when it's the first item.

It looks like this bug report is about this issue:
Can't move cursor behind non-editable element (or placeholder) in CKEditor

I used my plugin to insert this block of code into the editor:

  <div contenteditable="false">
      <img src="someimage.jpg" />
      <p>
          Some text
          <span>Some subtext</span>
      </p>
      <img src="someStaticImage.jpg" />
  </div>

You can also add the display: inline-block; style if you want (see discussion below):

From my tests, it seems like you can't put content before the object using the back arrow, but if you back arrow to that row of content and press the home key, you can type before the object. It also seems that if you click with your mouse in the upper left corner, you can add content before the object.

Both approaches push the object onto the next line because it's a <div>, you can change the style of the div to display: inline-block; if you want the object to stay on the first row. I tried just making the object <div> a <span> instead, but then it bees possible to edit parts of the object.

You can't use backspace to delete the object, but you can click the object to select it and then delete it.

I checked the info discussed above with Firefox 20 and IE 9 on Win 7. Google Chrome has a bunch of problems:
When the block of HTML is inserted with the plugin, the contenteditable="false" attribute is stripped out.

So I tried to see how it worked if I just pasted that block of code into CkEditor while in source mode. The contenteditable="false" attribute wasn't stripped out, but the whole content area became uneditable.

My tests were using CkEditor 3.6.1, so this may not be a problem in CkEditor 4.X.

This bug report seems to be about the problem I encountered with being unable to do anything in the content area using Chrome, the report indicates version 3.X:
ContentEditable, Image and Chrome

Additional Info
Here's a plugin from CKSource that might be helpful:
Magic Line

The description:
With this plugin you can create new paragraphs into spaces where normally would be impossible to reach. For example, above a table at the beginning of the document.


Here's my plugin that inserts content into the editor, it doesn't solve the problem you have, but you might use it to add functionality to your plugin. I'll write the full instructions in case someone who hasn't created a plugin finds this and wants to give it a try.

Here's the code that goes in the ckeditor/plugins/cwmarinsertsnippet/plugin.js file:

/**
 * Plugin to insert the contents of an element into the editor content area.
 */

// Register the plugin with the editor. cwmarinsertsnippet
// http://docs.cksource./ckeditor_api/symbols/CKEDITOR.plugins.html
CKEDITOR.plugins.add( 'cwmarinsertsnippet',
{
    // The plugin initialization logic goes inside this method.
    // http://docs.cksource./ckeditor_api/symbols/CKEDITOR.pluginDefinition.html#init
    init: function( editor )
    {
        // Define an editor mand that grabs the content of an element and inserts it into the content area.
        // http://docs.cksource./ckeditor_api/symbols/CKEDITOR.editor.html#addCommand
        editor.addCommand( 'cwMarInsertSnippet',
    {
      // Define a function that will be fired when the mand is executed.
      // http://docs.cksource./ckeditor_api/symbols/CKEDITOR.mandDefinition.html#exec
      exec : function( editor )
      {
        // Create an element based on a native DOM element.
        var codesnippet = new CKEDITOR.dom.element( document.getElementById( 'resmar' ) );
        //alert( codesnippet.getHtml() );

        // Insert the element content into the document.
        // http://docs.cksource./ckeditor_api/symbols/CKEDITOR.editor.html#insertHtml
        editor.insertHtml( codesnippet.getHtml() );
      }
    });

        // Create a toolbar button that executes the plugin mand.
        // http://docs.cksource./ckeditor_api/symbols/CKEDITOR.ui.html#addButton
        editor.ui.addButton( 'CwMarInsertSnippet',
        {
            // Toolbar button tooltip.
            label: 'Insert Search Box',
            // Reference to the plugin mand name.
            mand: 'cwMarInsertSnippet',
            // Button's icon file path.
            icon: this.path + 'images/buttonicon.gif'
        });
    }
});

It needs to be added to the config file with:

config.extraPlugins = 'cwmarinsertsnippet';

and to make the button visible, the button name "CwMarInsertSnippet" needs to be added to the config toolbar entry:

CKEDITOR.config.toolbar_XXXX
  [
Snip...
    { name: 'tools',        items : [ 'About','CwMarInsertSnippet' ] },
... End Snip
  ];

The button for the plugin should be 13px X 13px (for CkEditor 3.X, not sure about version 4.X). It gets placed here:
ckeditor/plugins/cwmarinsertsnippet/images

The name should match the one used in the editor.ui.addButton function at the end of the plugin code (this path can really be anywhere you want).


Here's an example of the code to be added to the page where CkEditor is being used:

<div id ="resmar">
  <div contenteditable="false">
      <img src="someimage.jpg" />
      <p>
          Some text
          <span>Some subtext</span>
      </p>
      <img src="someStaticImage.jpg" />
  </div>
</div>

You can also add the display: inline-block; style if you want:

  <div style="display:inline-block" contenteditable="false">

The container element can be hidden with styling if it shouldn't appear on the page.

Basically, just put the content you want to insert inside the element with the target ID

<div id ="resmar">
  Content to be inserted.
</div>

Of course the plugin name and the element ID can be anything you like.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745394015a4625795.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信