diff src/browser/sat_browser/editor_widget.py @ 716:3b91225b457a

server + browser side: blogging refactoring (draft), huge commit sorry: /!\ everything is not working yet, group blog is not working for now - adaptation to backend changes - frontend commons part of blog have been moved to QuickFrontend - (editors) button "WYSIWYG edition" renamed to "preview" - (editors) Shift + [ENTER] is now used to send a text message, [ENTER] to finish a ligne normally - (editors) fixed modifiers handling - global simplification, resulting of the refactoring - with backend refactoring, we are now using PEP again, XEP-0277 compatibility is restored \o/
author Goffi <goffi@goffi.org>
date Sun, 16 Aug 2015 01:51:12 +0200
parents c2f22ca12e23
children f3cd261ea12f
line wrap: on
line diff
--- a/src/browser/sat_browser/editor_widget.py	Tue Jul 28 22:22:10 2015 +0200
+++ b/src/browser/sat_browser/editor_widget.py	Sun Aug 16 01:51:12 2015 +0200
@@ -24,7 +24,7 @@
 from pyjamas.ui.HTML import HTML
 from pyjamas.ui.SimplePanel import SimplePanel
 from pyjamas.ui.TextArea import TextArea
-from pyjamas.ui.KeyboardListener import KEY_ENTER, KEY_SHIFT, KEY_UP, KEY_DOWN, KeyboardHandler
+from pyjamas.ui import KeyboardListener as keyb
 from pyjamas.ui.FocusListener import FocusHandler
 from pyjamas.ui.ClickListener import ClickHandler
 from pyjamas.ui.MouseListener import MouseHandler
@@ -60,15 +60,15 @@
             self.setText(text)
             Timer(5, lambda timer: self.setCursorPos(len(text)))
 
-        if keycode == KEY_ENTER:
+        if keycode == keyb.KEY_ENTER:
             if _txt:
                 self.host.selected_widget.onTextEntered(_txt)
                 self.host._updateInputHistory(_txt) # FIXME: why using a global variable ?
             self.setText('')
             sender.cancelKey()
-        elif keycode == KEY_UP:
+        elif keycode == keyb.KEY_UP:
             self.host._updateInputHistory(_txt, -1, history_cb)
-        elif keycode == KEY_DOWN:
+        elif keycode == keyb.KEY_DOWN:
             self.host._updateInputHistory(_txt, +1, history_cb)
         else:
             self._onComposing()
@@ -99,15 +99,15 @@
         @param content: dict with at least a 'text' key
         @param strproc: method to be applied on strings to clean the content
         @param modifiedCb: method to be called when the text has been modified.
-        If this method returns:
-        - True: the modification will be saved and afterEditCb called;
-        - False: the modification won't be saved and afterEditCb called;
-        - None: the modification won't be saved and afterEditCb not called.
+            This method can return:
+                - True: the modification will be saved and afterEditCb called;
+                - False: the modification won't be saved and afterEditCb called;
+                - None: the modification won't be saved and afterEditCb not called.
         @param afterEditCb: method to be called when the edition is done
         """
         if content is None:
             content = {'text': ''}
-        assert('text' in content)
+        assert 'text' in content
         if strproc is None:
             def strproc(text):
                 try:
@@ -115,21 +115,23 @@
                 except (TypeError, AttributeError):
                     return text
         self.strproc = strproc
-        self.__modifiedCb = modifiedCb
+        self._modifiedCb = modifiedCb
         self._afterEditCb = afterEditCb
         self.initialized = False
         self.edit_listeners = []
         self.setContent(content)
 
     def setContent(self, content=None):
-        """Set the editable content. The displayed content, which is set from the child class, could differ.
-        @param content: dict with at least a 'text' key
+        """Set the editable content.
+        The displayed content, which is set from the child class, could differ.
+
+        @param content (dict): content data, need at least a 'text' key
         """
         if content is None:
             content = {'text': ''}
         elif not isinstance(content, dict):
             content = {'text': content}
-        assert('text' in content)
+        assert 'text' in content
         self._original_content = {}
         for key in content:
             self._original_content[key] = self.strproc(content[key])
@@ -150,7 +152,7 @@
 
     def getOriginalContent(self):
         """
-        @return the original content before modification (dict)
+        @return (dict): the original content before modification (i.e. content given in __init__)
         """
         return self._original_content
 
@@ -193,8 +195,8 @@
             if abort:
                 self._afterEditCb(content)
                 return
-            if self.__modifiedCb and self.modified(content):
-                result = self.__modifiedCb(content)  # e.g.: send a message or update something
+            if self._modifiedCb and self.modified(content):
+                result = self._modifiedCb(content)  # e.g.: send a message or update something
                 if result is not None:
                     if self._afterEditCb:
                         self._afterEditCb(content)  # e.g.: restore the display mode
@@ -220,7 +222,7 @@
         self.edit_listeners.append(listener)
 
 
-class SimpleTextEditor(BaseTextEditor, FocusHandler, KeyboardHandler, ClickHandler):
+class SimpleTextEditor(BaseTextEditor, FocusHandler, keyb.KeyboardHandler, ClickHandler):
     """Base class for manage a simple text editor."""
 
     def __init__(self, content=None, modifiedCb=None, afterEditCb=None, options=None):
@@ -228,12 +230,12 @@
         @param content
         @param modifiedCb
         @param afterEditCb
-        @param options: dict with the following value:
-        - no_xhtml: set to True to clean any xhtml content.
-        - enhance_display: if True, the display text will be enhanced with strings.addURLToText
-        - listen_keyboard: set to True to terminate the edition with <enter> or <escape>.
-        - listen_focus: set to True to terminate the edition when the focus is lost.
-        - listen_click: set to True to start the edition when you click on the widget.
+        @param options (dict): can have the following value:
+            - no_xhtml: set to True to clean any xhtml content.
+            - enhance_display: if True, the display text will be enhanced with strings.addURLToText
+            - listen_keyboard: set to True to terminate the edition with <enter> or <escape>.
+            - listen_focus: set to True to terminate the edition when the focus is lost.
+            - listen_click: set to True to start the edition when you click on the widget.
         """
         self.options = {'no_xhtml': False,
                         'enhance_display': True,
@@ -243,12 +245,11 @@
                         }
         if options:
             self.options.update(options)
-        self.__shift_down = False
         if self.options['listen_focus']:
             FocusHandler.__init__(self)
         if self.options['listen_click']:
             ClickHandler.__init__(self)
-        KeyboardHandler.__init__(self)
+        keyb.KeyboardHandler.__init__(self)
         strproc = lambda text: html_tools.html_sanitize(html_tools.html_strip(text)) if self.options['no_xhtml'] else html_tools.html_strip(text)
         BaseTextEditor.__init__(self, content, strproc, modifiedCb, afterEditCb)
         self.textarea = self.display = None
@@ -295,21 +296,14 @@
 
     def onKeyDown(self, sender, keycode, modifiers):
         for listener in self.edit_listeners:
-            listener(self.textarea, keycode)
+            listener(self.textarea, keycode, modifiers) # FIXME: edit_listeners must either be removed, or send an action instead of keycode/modifiers
         if not self.options['listen_keyboard']:
             return
-        if keycode == KEY_SHIFT or self.__shift_down:  # allow input a new line with <shift> + <enter>
-            self.__shift_down = True
-            return
-        if keycode == KEY_ENTER:  # finish the edition
+        if keycode == keyb.KEY_ENTER and modifiers & keyb.MODIFIER_SHIFT:
             self.textarea.setFocus(False)
             if not self.options['listen_focus']:
                 self.edit(False)
 
-    def onKeyUp(self, sender, keycode, modifiers):
-        if keycode == KEY_SHIFT:
-            self.__shift_down = False
-
     def onLostFocus(self, sender):
         """Finish the edition when focus is lost"""
         if self.options['listen_focus']:
@@ -325,10 +319,10 @@
             FocusHandler.onBrowserEvent(self, event)
         if self.options['listen_click']:
             ClickHandler.onBrowserEvent(self, event)
-        KeyboardHandler.onBrowserEvent(self, event)
+        keyb.KeyboardHandler.onBrowserEvent(self, event)
 
 
-class HTMLTextEditor(SimpleTextEditor, HTML, FocusHandler, KeyboardHandler):
+class HTMLTextEditor(SimpleTextEditor, HTML, FocusHandler, keyb.KeyboardHandler):
     """Manage a simple text editor with the HTML 5 "contenteditable" property."""
 
     def __init__(self, content=None, modifiedCb=None, afterEditCb=None, options=None):
@@ -353,7 +347,7 @@
             self.getElement().blur()
 
 
-class LightTextEditor(SimpleTextEditor, SimplePanel, FocusHandler, KeyboardHandler):
+class LightTextEditor(SimpleTextEditor, SimplePanel, FocusHandler, keyb.KeyboardHandler):
     """Manage a simple text editor with a TextArea for editing, HTML for display."""
 
     def __init__(self, content=None, modifiedCb=None, afterEditCb=None, options=None):