[silva.core.editor][Sylvain Viollon] Various fixes on the silvai...

[email protected]
Newsgroups gmane.comp.web.zope.silva.cvs
Message-ID <[email protected]>
author:    Sylvain Viollon
date:      Fri Aug 02 13:29:48 2013 +0200
revision:  251:dcaecb1a2e77 in silva.core.editor
branch:    
details:   https://hg.infrae.com/silva.core.editor?cmd=changeset;node=dcaecb1a2e77
modified:  src/silva/core/editor/static/plugins/silvaimage/dialogs/image.js src/silva/core/editor/static/plugins/silvaimage/plugin.js src/silva/core/editor/static/plugins/silvautils/plugin.js
added:     
removed:   
log:       Various fixes on the silvaimage plugin and silvautils.


diffstat:

 src/silva/core/editor/static/plugins/silvaimage/dialogs/image.js |    4 +-
 src/silva/core/editor/static/plugins/silvaimage/plugin.js        |  130 ++++++---
 src/silva/core/editor/static/plugins/silvautils/plugin.js        |   97 +++++-
 3 files changed, 163 insertions(+), 68 deletions(-)

diffs (388 lines):

diff -r 949c825e54ad -r dcaecb1a2e77 src/silva/core/editor/static/plugins/silvaimage/dialogs/image.js
--- a/src/silva/core/editor/static/plugins/silvaimage/dialogs/image.js	Thu Aug 01 16:03:12 2013 +0200
+++ b/src/silva/core/editor/static/plugins/silvaimage/dialogs/image.js	Fri Aug 02 13:29:48 2013 +0200
@@ -304,7 +304,7 @@
         onShow: function() {
             var data = {};
             var editor = this.getParentEditor();
-            var div = CKEDITOR.plugins.silvaimage.getSelectedImage(editor);
+            var div = CKEDITOR.plugins.silvaimage.getCurrentImage(editor);
 
             var defaultSettings = function() {
                 data.link = {};
@@ -418,7 +418,7 @@
             data.image = {};
             this.commitContent(data);
 
-            var div = CKEDITOR.plugins.silvaimage.getSelectedImage(editor),
+            var div = CKEDITOR.plugins.silvaimage.getCurrentImage(editor),
                 div_attributes = {};
 
             var a = null;
diff -r 949c825e54ad -r dcaecb1a2e77 src/silva/core/editor/static/plugins/silvaimage/plugin.js
--- a/src/silva/core/editor/static/plugins/silvaimage/plugin.js	Thu Aug 01 16:03:12 2013 +0200
+++ b/src/silva/core/editor/static/plugins/silvaimage/plugin.js	Fri Aug 02 13:29:48 2013 +0200
@@ -1,8 +1,10 @@
+
 
 (function(CKEDITOR, $){
 
     CKEDITOR.plugins.silvaimage = {
         isImage: function(element) {
+            // Given an element return true if it is an image.
             if (element != null &&
                 element.is('div') &&
                 element.hasClass('image')) {
@@ -10,30 +12,48 @@
             };
             return false;
         },
-        getSelectedImage: function(editor, select_element) {
-            try {
-                var selection = editor.getSelection();
-                var base = null;
+        findImage: function(element) {
+            // Given an element find the nearest image.
+            var image;
 
-                if (selection.getType() == CKEDITOR.SELECTION_ELEMENT) {
-                    base = selection.getSelectedElement();
-                } else {
-                    base = selection.getStartElement();
+            if (element !== null) {
+                image = element.getAscendant('div', true);
+
+                if (API.isImage(image)) {
+                    return image;
                 };
+            };
+            return null;
 
-                var element = base.getAscendant('div', true);
+        },
+        setCurrentImage: function(editor, image) {
+            // Save the currently edited image in the editor. This is
+            // used to pass the image to the command.
+            editor._.silvaWorkingImage = image;
+        },
+        getCurrentImage: function(editor) {
+            // Return the image that is currently being modified. This
+            // is used instead of getSelectedImage because the editor
+            // selection can change during the modification, and the
+            // reference to the image lost.
+            if (editor._.silvaWorkingImage  !== undefined) {
+                return editor._.silvaWorkingImage;
+            };
+            return null;
+        },
+        getSelectedImage: function(editor, no_selection) {
+            // Find the currently selected image. Correct the selection if needed.
+            var selected = CKEDITOR.plugins.silvautils.getSelectedElement(editor),
+                image = API.findImage(selected);
 
-                if (CKEDITOR.plugins.silvaimage.isImage(element)) {
-                    if (select_element !== false && element.$ !== base.$) {
-                        // Be sure the source is selected
-                        selection.selectElement(element);
-                    };
-                    return element;
+            console.log(selected && selected.$);
+            if (image !== null) {
+                if (!no_selection && selected.$ !== image.$) {
+                    CKEDITOR.plugins.silvautils.selectBlock(editor, image);
                 };
-                return null;
-            } catch(e) {
-                return null;
-            }
+                return image;
+            };
+            return null;
         }
     };
 
@@ -41,26 +61,9 @@
     var API = CKEDITOR.plugins.silvaimage;
 
     CKEDITOR.plugins.add('silvaimage', {
-        requires: ['dialog', 'silvautils', 'silvalink', 'selection'],
+        requires: ['dialog', 'silvautils', 'silvalink'],
         init: function(editor) {
-            // Patch selection to select the whole contenteditable
-            // instead of only a element in it (this prevent to select an image in FF)
-            (function () {
-                if (CKEDITOR.dom.selection.prototype.origSelectElement === undefined) {
-                    CKEDITOR.dom.selection.prototype.origSelectElement = CKEDITOR.dom.selection.prototype.selectElement;
-                    CKEDITOR.dom.selection.prototype.selectElement = function(element) {
-                        var div = element.getAscendant('div', true);
-
-                        while (div !== null && div.getAttribute('contenteditable') !== 'false') {
-                            div = div.getAscendant('div', false);
-                        };
-                        if (div !== null) {
-                            element = div;
-                        };
-                        return this.origSelectElement(element);
-                    };
-                };
-            })();
+            var UTILS = CKEDITOR.plugins.silvautils;
 
             editor.addCommand(
                 'silvaimage',
@@ -111,22 +114,59 @@
                     '}');
             // Events
             editor.on('selectionChange', function(event) {
-                var element = API.getSelectedImage(editor);
-                var imageCommand = editor.getCommand('silvaimage');
+                var image = API.getSelectedImage(editor),
+                    command = editor.getCommand('silvaimage');
 
-                if (element != null) {
-                    imageCommand.setState(CKEDITOR.TRISTATE_ON);
+                API.setCurrentImage(editor, image);
+                if (image != null) {
+                    command.setState(CKEDITOR.TRISTATE_ON);
                 } else {
-                    imageCommand.setState(CKEDITOR.TRISTATE_OFF);
+                    command.setState(CKEDITOR.TRISTATE_OFF);
                 };
             });
             editor.on('doubleclick', function(event) {
-                var element = API.getSelectedImage(editor);
+                var image = API.getSelectedImage(editor);
 
-                if (element != null) {
+                API.setCurrentImage(editor, image);
+                if (image != null) {
                     event.data.dialog = 'silvaimage';
                 };
             });
+            if (!CKEDITOR.env.gecko) {
+                editor.on('contentDom', function() {
+                    editor.document.on('mousedown', function(event) {
+                        var selected,
+                            image = API.findImage(event.data.getTarget());
+
+                        if (image !== null) {
+                            selected = UTILS.getSelectedElement(editor);
+                            if (selected === null || selected.$ !== image.$) {
+                                UTILS.selectBlock(editor, image);
+                            };
+                            // Prevent broken drag'n drop.
+                            event.data.preventDefault();
+                        };
+                    });
+                });
+                };
+            editor.on('key', function(event) {
+                if (editor.mode != 'wysiwyg')
+                    return;
+
+                var code = event.data.keyCode;
+                // Improve the navigation before and after the code source with the arrows.
+                if (code in {9:1, 37:1, 38:1, 39:1, 40:1}) {
+                    setTimeout(function() {
+                        var image = API.getSelectedImage(editor, true),
+                            on_top = code in {37:1, 38:1};
+
+                        if (image !== null) {
+                            UTILS.selectText(editor, UTILS.getParagraph(editor, image, on_top), on_top);
+                        };
+                    }, 25);
+                };
+            });
+
             // Dialog
             CKEDITOR.dialog.add('silvaimage', this.path + 'dialogs/image.js');
             // Menu
diff -r 949c825e54ad -r dcaecb1a2e77 src/silva/core/editor/static/plugins/silvautils/plugin.js
--- a/src/silva/core/editor/static/plugins/silvautils/plugin.js	Thu Aug 01 16:03:12 2013 +0200
+++ b/src/silva/core/editor/static/plugins/silvautils/plugin.js	Fri Aug 02 13:29:48 2013 +0200
@@ -1,38 +1,47 @@
 (function($, jsontemplate, CKEDITOR) {
     if (CKEDITOR.env.ie) {
         CKEDITOR.plugins.silvautils = {
+            /**
+             * Return a element where the current selection points to
+             * (IE implementation).
+             */
             getSelectedElement: function(editor) {
                 var selection = selection = editor.document.$.selection,
-                    range;
+                    range,
+                    element = null;
 
                 if (selection.type != "None") {
                     range = editor.document.$.selection.createRange();
                     if (selection.type == "Text") {
-                        return new CKEDITOR.dom.element(range.parentElement);
+                        element = range.parentElement();
+                    } else if (range.length > 0) {
+                        element = range.item(0);
                     };
-                    if (range.length > 0) {
-                        return new CKEDITOR.dom.element(range.item(0));
-                    };
+                };
+                if (element !== null) {
+                    return new CKEDITOR.dom.element(element);
                 };
                 return null;
             },
             /**
              * Given a block element with contenteditable set to false,
-             * select it in the editor.
+             * select it in the editor (IE implementation).
              */
             selectBlock: function(editor, block) {
                 var selection = editor.getSelection(),
                     range;
 
-                if (selection === null)  {
-                    return;
+                if (selection !== null)  {
+                    selection.unlock();
                 };
-                selection.unlock();
                 range = editor.document.$.body.createControlRange();
                 range.add(block.$);
                 range.select();
                 // Force CKEditor to refresh it caches. We need to 'lock'
                 // our changes to prevent them to be reverted by CKEditor.
+                if (selection === null) {
+                    selection = editor.getSelection();
+                };
                 selection.lock();
                 editor.forceNextSelectionCheck();
                 editor.selectionChange(true);
@@ -44,16 +53,15 @@
             },
             /**
              * Given a text node, move the caret at the begining or the
-             * end of it.
+             * end of it (IE implementation).
              */
             selectText: function(editor, text, at_the_end) {
                 var selection = editor.getSelection(),
                     range;
 
-                if (selection === null)  {
-                    return;
+                if (selection !== null)  {
+                    selection.unlock();
                 };
-                selection.unlock();
                 // CKEditor utilities doesn't seems to work on IE. Do
                 // it manually.
                 range = editor.document.$.body.createTextRange();
@@ -63,6 +71,9 @@
                 range.select();
                 // Force CKEditor to refresh it caches. We need to 'lock'
                 // our changes to prevent them to be reverted by CKEditor.
+                if (selection === null) {
+                    selection = editor.getSelection();
+                };
                 selection.lock();
                 editor.forceNextSelectionCheck();
                 editor.selectionChange(true);
@@ -75,6 +86,10 @@
         };
     } else {
         CKEDITOR.plugins.silvautils = {
+            /**
+             * Return a element where the current selection points to
+             * (non-IE implementation).
+             */
             getSelectedElement: function(editor) {
                 var selection = editor.document.$.getSelection(),
                     range;
@@ -89,14 +104,11 @@
             },
             /**
              * Given a block element with contenteditable set to false,
-             * select it in the editor.
+             * select it in the editor (non-IE implementation).
              */
             selectBlock: function(editor, block) {
                 var selection, range;
 
-                if (editor.getSelection() === null)  {
-                    return;
-                };
                 range = editor.document.$.createRange();
                 if (CKEDITOR.env.webkit) {
                     range.selectNodeContents(block.$);
@@ -110,14 +122,11 @@
             },
             /**
              * Given a text node, move the caret at the begining or the
-             * end of it.
+             * end of it (non-IE implementation).
              */
             selectText: function(editor, text, at_the_end) {
                 var selection, range;
 
-                if (editor.getSelection() === null)  {
-                    return;
-                };
                 range = editor.document.$.createRange();
                 range.selectNodeContents(text.$);
                 range.collapse(!at_the_end);
@@ -129,9 +138,55 @@
             }
         };
     };
+    CKEDITOR.plugins.silvautils = CKEDITOR.tools.extend(CKEDITOR.plugins.silvautils, {
+        /**
+         * Get (or add) a paragraph before (or after) the targeted
+         * element.
+         */
+        getParagraph: function(editor, target, before_target) {
+            var result;
+
+            if (before_target) {
+                result = target.getPrevious();
+                if (result === null || result.getName() != 'p') {
+                    result = editor.document.createElement('p');
+                    CKEDITOR.env.webkit && result.appendBogus();
+                    result.insertBefore(target);
+                };
+            } else {
+                result = target.getNext();
+                if (result === null || result.getName() != 'p') {
+                    result = editor.document.createElement('p');
+                    CKEDITOR.env.webkit && result.appendBogus();
+                    result.insertAfter(target);
+                };
+            };
+            return result;
+        }
+    });
 
     CKEDITOR.plugins.add('silvautils', {
+        requires: ['selection'],
         init: function(editor) {
+            // Patch selection to select the whole contenteditable
+            // instead of only a element in it (this prevent to select an image in FF)
+            (function () {
+                if (CKEDITOR.dom.selection.prototype.origSelectElement === undefined) {
+                    CKEDITOR.dom.selection.prototype.origSelectElement = CKEDITOR.dom.selection.prototype.selectElement;
+                    CKEDITOR.dom.selection.prototype.selectElement = function(element) {
+                        var div = element.getAscendant('div', true);
+
+                        while (div !== null && div.getAttribute('contenteditable') !== 'false') {
+                            div = div.getAscendant('div', false);
+                        };
+                        if (div !== null) {
+                            element = div;
+                        };
+                        return this.origSelectElement(element);
+                    };
+                };
+            })();
+
             /**
              * Support for the reference widget inside CKEditor.
              */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.