Forum closed. New forum available at http://community.wymeditor.org/

How to split a bloc

Support forum for WYMeditor.

How to split a bloc

Postby Folken Laëneck on Tue Nov 03, 2009 4:12 pm

Hello,

This post is a "translation" of this one in the french forum. May it help to get a quicker response (if I don't make too many mistakes :) )

I'm trying to improve usability and user-friendliness of the WYMeditor.

In the editor's toolbar, we have a "Paste (from Word)" tool to import text and keep it a minimum formated. But users don't use this tool. Instead they use the OS built-in copy-paste function they are regular with. So I decide to catch all paste command hover the editor and call automatically the paste dialog. For this, I wrote a small plugin based on jquery-hotkeys.js (I know, it's a bit heavy for this purpose but I think I'll use it in other places).

Code: Select all
WYMeditor.editor.prototype.catchPaste = function(options) {
    var wym = this;
    var doc = this._doc;
   
    catchPaste = function(e) {
        e.stopPropagation(); 
        e.preventDefault();
       wym.exec(WYMeditor.PASTE);
    }
   
    $(doc).bind('keydown', 'Ctrl+V', catchPaste );
    $(doc).bind('keydown', 'Meta+V', catchPaste );
    $(doc).bind('keydown', 'Shift+Insert', catchPaste );
   
    $(doc).bind('paste', catchPaste );
};


Note 1 : Meta+V is the keyboard shortcut for paste in Mac OS. WYMeditor offers some shortcut for bold and italic, but only with the Control modifier. It won't be complicated to make them work on Mac OS by switching all the "if(evt.ctrlKey)" tests into "if(evt.ctrlKey || evt.metaKey)".

Note 2 : "Paste" event support depends on the client browser, so it's possible that some users won't see the paste dialog automatically and fallback on the default behaviour.


My problem is that the paste dialog call the WYMeditor.editor.paste() method, which automatically insert content after the current bloc, without considering the position of the cursor in it. So I decide to change the paste() function to make it more "clever". For the moment, it insert content as a classic copy/paste will when it contains no new line character and behave like the normal paste() method when dealing with multiline content.

Code: Select all
// Backup the original paste method
WYMeditor.editor.prototype._paste = WYMeditor.editor.prototype.paste;

WYMeditor.editor.prototype.paste = function(sData) {
   var rExp = new RegExp(this._newLine, "g");
   
   if(sData.search(rExp) != -1) {
      /** @todo: split current bloc at cursor position and select the first part **/
      this._paste(sData);
   } else {
      this.insert(sData);
   }
}


Now I would like to split the current container at the cursor position and paste content after the first part when content is multiline. But as far as I search in API documentation and in WYMeditor source code, I don't find a way to reproduce programmatically what append when the Enter key is pressed.
Is there any function to do this ?

Thanks.
Folken Laëneck
 
Posts: 13
Joined: Wed Jan 07, 2009 12:08 am

Re: How to split a bloc

Postby Folken Laëneck on Wed Nov 04, 2009 12:05 pm

Hello,

I tried to simulate both keyup and keydown events using jquery.simulate.js (Yes, one more plugins but this one was just for test) and it seems that firing a fake event on the current container doesn't have any effect...

this.exec(WYMeditor.FORMAT_BLOCK, this.container().tagName) isn't more efficient.

Did I miss something ?
Folken Laëneck
 
Posts: 13
Joined: Wed Jan 07, 2009 12:08 am

Re: How to split a bloc

Postby mr_lundis on Wed Nov 04, 2009 4:12 pm

Hi!
Try using the insert method instead of paste. The insert method will insert the content you pass at the current caret positions, replacing any current selection (the names are a little bit confusing, I know...) If you're pasting any block elements, they'll split the current paragraph, and the parser will take care of any messy html.

Cheers! ;)
Jonatan Lundin - designer, developer and forum moderator. You should follow me on Twitter!
mr_lundis
 
Posts: 335
Joined: Sun Dec 02, 2007 10:59 am
Location: Sweden

Re: How to split a bloc

Postby Folken Laëneck on Wed Nov 04, 2009 6:35 pm

Why was I persuaded that the insert() method just push text at the carret psition without formatting ? ...

Thanks for the tips, it really helps me. My last problem was that once pasted in the paste dialog's textarea, content doesn't keep any format information, except line breaks. So I just write my own "insert" method, that call the original insert method after applying to content some formating like done in the WYMeditor original paste method.

Plugin code doesn't change, but the second part now looks like this :
Code: Select all
WYMeditor.editor.prototype._insert = function(sData) {
   if(sData.search(new RegExp(this._newLine, "g")) != -1) {
      //split the data, using newlines as the separator
      var aP = sData.split(this._newLine);
      sData = '';
      for(x = aP.length - 1; x >= 0; x--) {
         sData += "<p>" + aP[x] + "</p>";
      }
   }
   this.insert(sData);
}


The _insert method() is called instead paste() when user close the paste dialog (I already rewrote the dialog method to use WYMeditor with jqueryUI dialog, so I can do that without any modification in the original WYMeditor script). It just works :)

Thank you very much Jonatan.
Folken Laëneck
 
Posts: 13
Joined: Wed Jan 07, 2009 12:08 am

Re: How to split a bloc

Postby Folken Laëneck on Fri Nov 27, 2009 5:58 pm

Here is the final code of this plugin, after some IE debug :°

jquery.wymeditor.catchpaste.js
Code: Select all
/**
* The catchpaste plugin call automatically the paste dialog when user
* press Ctrl + V combinaison in editor.

*/
WYMeditor.editor.prototype.sbCatchPaste = function(options) {
    var wym = this;
    var doc = this._doc;
   
    _sbCatchPaste = function(e) {
        e.stopPropagation();
        e.preventDefault();
       wym.exec(WYMeditor.PASTE);
    }
   
    // Unbind des évènements préalablement mis en place (sous IE)
    $(doc.body).unbind('paste').unbind('beforepaste');
    if(jQuery.isFunction(doc.body.onpaste)) {
       doc.body.onpaste = function() {};
    }
    if(jQuery.isFunction(doc.onbeforepaste)) {
       doc.body.onbeforepaste = function() {};
    }
   
    // Capture de tous les évènements devant appeler le dialogue Paste
    $(doc.body).bind('keydown', 'Ctrl+V', _sbCatchPaste );
    $(doc.body).bind('keydown', 'Meta+V', _sbCatchPaste );
    $(doc.body).bind('keydown', 'Shift+Insert', _sbCatchPaste );
   
    $(doc.body).bind('paste', _sbCatchPaste );
    $(doc.body).bind('beforepaste', _sbCatchPaste );
};

/* Overriding native insert method */
WYMeditor.editor.prototype._insert = WYMeditor.editor.insert;

WYMeditor.editor.prototype.insert = function(sData) {
   if(sData.search(new RegExp(this._newLine, "g")) != -1) {
      //split the data, using newlines as the separator
      var aP = sData.split(this._newLine);
      sData = '';
      for(x = aP.length - 1; x >= 0; x--) {
         sData += "<p>" + aP[x] + "</p>";
      }
   }
   this._insert(sData);
};


Du to some IE weirdness you should call this plugin like this :
Code: Select all
postInit:   function(wym) {
   $(wym._doc.body).click( function() {
      wym.sbCatchPaste();
   } );
}


Don't forget to add jquery.jshotkeys.js

This code is a quick snapshot of a more complex codebase, you may encounter some bugs
Folken Laëneck
 
Posts: 13
Joined: Wed Jan 07, 2009 12:08 am


Return to Support

Who is online

Users browsing this forum: No registered users and 2 guests