annotate browser/sat_browser/editor_widget.py @ 1203:251eba911d4d

server (websockets): fixed websocket handling on HTTPS connections: Original request used to retrieve a page was stored on dynamic pages, but after the end of it, the channel was deleted, resulting in a isSecure() always returning False, and troubles in chain leading to the the use of the wrong session object. This patch fixes this by reworking the way original request is used, and creating a new wrapping class allowing to keep an API similar to iweb.IRequest, with data coming from both the original request and the websocket request. fix 327
author Goffi <goffi@goffi.org>
date Sun, 14 Jul 2019 14:45:51 +0200
parents 3048bd137aaf
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/python
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
3
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
4 # Libervia: a Salut à Toi frontend
1144
2af117bfe6cc dates update
Goffi <goffi@goffi.org>
parents: 1124
diff changeset
5 # Copyright (C) 2011-2019 Jérôme Poisson <goffi@goffi.org>
18
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
6
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
7 # This program is free software: you can redistribute it and/or modify
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
10 # (at your option) any later version.
18
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
11
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
12 # This program is distributed in the hope that it will be useful,
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
15 # GNU Affero General Public License for more details.
18
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
16
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 323
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
19
439
d52f529a6d42 browser side: use of new log system (first draft):
Goffi <goffi@goffi.org>
parents: 433
diff changeset
20 from sat.core.log import getLogger
d52f529a6d42 browser side: use of new log system (first draft):
Goffi <goffi@goffi.org>
parents: 433
diff changeset
21 log = getLogger(__name__)
784
f3cd261ea12f browser side: workaround for a pyjamas bug which freeze the browser in some case with addURLToText regex
Goffi <goffi@goffi.org>
parents: 716
diff changeset
22 from sat_browser import strings
449
981ed669d3b3 /!\ reorganize all the file hierarchy, move the code and launching script to src:
souliane <souliane@mailoo.org>
parents: 439
diff changeset
23
33
e70521e6d803 browser side, misc stuffs
Goffi <goffi@goffi.org>
parents: 27
diff changeset
24 from pyjamas.ui.HTML import HTML
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
25 from pyjamas.ui.SimplePanel import SimplePanel
346
82f9e92379b0 browser_side: move TitlePanel from richtext.py to base_panels.py
souliane <souliane@mailoo.org>
parents: 342
diff changeset
26 from pyjamas.ui.TextArea import TextArea
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
27 from pyjamas.ui import KeyboardListener as keyb
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
28 from pyjamas.ui.FocusListener import FocusHandler
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
29 from pyjamas.ui.ClickListener import ClickHandler
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
30 from pyjamas.ui.MouseListener import MouseHandler
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
31 from pyjamas.Timer import Timer
18
795d144fc1d2 moved panels and menu in a separate file
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from pyjamas import DOM
323
0b7934e75e76 misc: reorganization of the file panels.py + clean the modules import:
souliane <souliane@mailoo.org>
parents: 322
diff changeset
33
467
97c72fe4a5f2 browser_side: import fixes:
Goffi <goffi@goffi.org>
parents: 449
diff changeset
34 import html_tools
647
e0021d571eef browser side: moved ContactBox, ContactsPanel, ContactLabeland ContactMenuBar to base_widget/base_panels so they can be reused outside of contact_list module
Goffi <goffi@goffi.org>
parents: 600
diff changeset
35
e0021d571eef browser side: moved ContactBox, ContactsPanel, ContactLabeland ContactMenuBar to base_widget/base_panels so they can be reused outside of contact_list module
Goffi <goffi@goffi.org>
parents: 600
diff changeset
36
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
37 class MessageBox(TextArea):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
38 """A basic text area for entering messages"""
241
86055ccf69c3 browser_side: added class PopupMenuPanel to manage more complex context menu
souliane <souliane@mailoo.org>
parents: 239
diff changeset
39
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
40 def __init__(self, host):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
41 TextArea.__init__(self)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
42 self.host = host
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
43 self.size = (0, 0)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
44 self.setStyleName('messageBox')
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
45 self.addKeyboardListener(self)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
46 MouseHandler.__init__(self)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
47 self.addMouseListener(self)
264
2a93f8e6f989 browser_side: added class ToggleStackPanel
souliane <souliane@mailoo.org>
parents: 261
diff changeset
48
2a93f8e6f989 browser_side: added class ToggleStackPanel
souliane <souliane@mailoo.org>
parents: 261
diff changeset
49 def onBrowserEvent(self, event):
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
50 # XXX: woraroung a pyjamas bug: self.currentEvent is not set
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
51 # so the TextBox's cancelKey doens't work. This is a workaround
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
52 # FIXME: fix the bug upstream
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
53 self.currentEvent = event
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
54 TextArea.onBrowserEvent(self, event)
264
2a93f8e6f989 browser_side: added class ToggleStackPanel
souliane <souliane@mailoo.org>
parents: 261
diff changeset
55
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
56 def onKeyPress(self, sender, keycode, modifiers):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
57 _txt = self.getText()
346
82f9e92379b0 browser_side: move TitlePanel from richtext.py to base_panels.py
souliane <souliane@mailoo.org>
parents: 342
diff changeset
58
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
59 def history_cb(text):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
60 self.setText(text)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
61 Timer(5, lambda timer: self.setCursorPos(len(text)))
346
82f9e92379b0 browser_side: move TitlePanel from richtext.py to base_panels.py
souliane <souliane@mailoo.org>
parents: 342
diff changeset
62
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
63 if keycode == keyb.KEY_ENTER:
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
64 if _txt:
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
65 self.host.selected_widget.onTextEntered(_txt)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
66 self.host._updateInputHistory(_txt) # FIXME: why using a global variable ?
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
67 self.setText('')
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
68 sender.cancelKey()
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
69 elif keycode == keyb.KEY_UP:
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
70 self.host._updateInputHistory(_txt, -1, history_cb)
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
71 elif keycode == keyb.KEY_DOWN:
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
72 self.host._updateInputHistory(_txt, +1, history_cb)
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
73 else:
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
74 self._onComposing()
346
82f9e92379b0 browser_side: move TitlePanel from richtext.py to base_panels.py
souliane <souliane@mailoo.org>
parents: 342
diff changeset
75
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
76 def _onComposing(self):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
77 """Callback when the user is composing a text."""
684
e876f493dccc browser_side: follow changes made on quick_frontend for chat states and MUC symbols + minor fixes following the refactorisation:
souliane <souliane@mailoo.org>
parents: 648
diff changeset
78 self.host.selected_widget.chat_state_machine._onEvent("composing")
346
82f9e92379b0 browser_side: move TitlePanel from richtext.py to base_panels.py
souliane <souliane@mailoo.org>
parents: 342
diff changeset
79
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
80 def onMouseUp(self, sender, x, y):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
81 size = (self.getOffsetWidth(), self.getOffsetHeight())
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
82 if size != self.size:
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
83 self.size = size
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
84 self.host.resize()
346
82f9e92379b0 browser_side: move TitlePanel from richtext.py to base_panels.py
souliane <souliane@mailoo.org>
parents: 342
diff changeset
85
648
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
86 def onSelectedChange(self, selected):
6d3142b782c3 browser_side: classes reorganisation:
Goffi <goffi@goffi.org>
parents: 647
diff changeset
87 self._selected_cache = selected
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
88
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
89
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
90 class BaseTextEditor(object):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
91 """Basic definition of a text editor. The method edit gets a boolean parameter which
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
92 should be set to True when you want to edit the text and False to only display it."""
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
93
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
94 def __init__(self, content=None, strproc=None, modifiedCb=None, afterEditCb=None):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
95 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
96 Remark when inheriting this class: since the setContent method could be
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
97 overwritten by the child class, you should consider calling this __init__
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
98 after all the parameters affecting this setContent method have been set.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
99 @param content: dict with at least a 'text' key
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
100 @param strproc: method to be applied on strings to clean the content
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
101 @param modifiedCb: method to be called when the text has been modified.
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
102 This method can return:
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
103 - True: the modification will be saved and afterEditCb called;
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
104 - False: the modification won't be saved and afterEditCb called;
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
105 - None: the modification won't be saved and afterEditCb not called.
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
106 @param afterEditCb: method to be called when the edition is done
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
107 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
108 if content is None:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
109 content = {'text': ''}
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
110 assert 'text' in content
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
111 if strproc is None:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
112 def strproc(text):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
113 try:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
114 return text.strip()
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
115 except (TypeError, AttributeError):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
116 return text
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
117 self.strproc = strproc
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
118 self._modifiedCb = modifiedCb
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
119 self._afterEditCb = afterEditCb
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
120 self.initialized = False
362
019e1e706e74 browser_side: display the popup notifying the message's recipient when you edit the blog entry's bubble.
souliane <souliane@mailoo.org>
parents: 358
diff changeset
121 self.edit_listeners = []
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
122 self.setContent(content)
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
123
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
124 def setContent(self, content=None):
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
125 """Set the editable content.
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
126 The displayed content, which is set from the child class, could differ.
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
127
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
128 @param content (dict): content data, need at least a 'text' key
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
129 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
130 if content is None:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
131 content = {'text': ''}
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
132 elif not isinstance(content, dict):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
133 content = {'text': content}
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
134 assert 'text' in content
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
135 self._original_content = {}
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
136 for key in content:
1156
3048bd137aaf server, browser: changed blog items serialisation following changes in backend
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
137 if isinstance(content[key], list):
3048bd137aaf server, browser: changed blog items serialisation following changes in backend
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
138 self._original_content[key] = [self.strproc(s) for s in content[key]]
3048bd137aaf server, browser: changed blog items serialisation following changes in backend
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
139 else:
3048bd137aaf server, browser: changed blog items serialisation following changes in backend
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
140 self._original_content[key] = self.strproc(content[key])
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
141
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
142 def getContent(self):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
143 """Get the current edited or editable content.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
144 @return: dict with at least a 'text' key
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
145 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
146 raise NotImplementedError
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
147
395
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
148 def setOriginalContent(self, content):
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
149 """Use this method with care! Content initialization should normally be
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
150 done with self.setContent. This method exists to let you trick the editor,
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
151 e.g. for self.modified to return True also when nothing has been modified.
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
152 @param content: dict
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
153 """
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
154 self._original_content = content
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
155
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
156 def getOriginalContent(self):
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
157 """
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
158 @return (dict): the original content before modification (i.e. content given in __init__)
395
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
159 """
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
160 return self._original_content
98cd5387d291 browser_side: new microblogs are not using the rich text editor by default:
souliane <souliane@mailoo.org>
parents: 370
diff changeset
161
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
162 def modified(self, content=None):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
163 """Check if the content has been modified.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
164 Remark: we don't use the direct comparison because we want to ignore empty elements
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
165 @content: content to be check against the original content or None to use the current content
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
166 @return: True if the content has been modified.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
167 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
168 if content is None:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
169 content = self.getContent()
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
170 # the following method returns True if one non empty element exists in a but not in b
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
171 diff1 = lambda a, b: [a[key] for key in set(a.keys()).difference(b.keys()) if a[key]] != []
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
172 # the following method returns True if the values for the common keys are not equals
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
173 diff2 = lambda a, b: [1 for key in set(a.keys()).intersection(b.keys()) if a[key] != b[key]] != []
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
174 # finally the combination of both to return True if a difference is found
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
175 diff = lambda a, b: diff1(a, b) or diff1(b, a) or diff2(a, b)
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
176
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
177 return diff(content, self._original_content)
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
178
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
179 def edit(self, edit, abort=False):
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
180 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
181 Remark: the editor must be visible before you call this method.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
182 @param edit: set to True to edit the content or False to only display it
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
183 @param abort: set to True to cancel the edition and loose the changes.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
184 If edit and abort are both True, self.abortEdition can be used to ask for a
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
185 confirmation. When edit is False and abort is True, abortion is actually done.
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
186 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
187 if edit:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
188 self.setFocus(True)
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
189 if abort:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
190 content = self.getContent()
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
191 if not self.modified(content) or self.abortEdition(content): # e.g: ask for confirmation
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
192 self.edit(False, True)
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
193 return
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
194 else:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
195 if not self.initialized:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
196 return
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
197 content = self.getContent()
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
198 if abort:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
199 self._afterEditCb(content)
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
200 return
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
201 if self._modifiedCb and self.modified(content):
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
202 result = self._modifiedCb(content) # e.g.: send a message or update something
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
203 if result is not None:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
204 if self._afterEditCb:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
205 self._afterEditCb(content) # e.g.: restore the display mode
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
206 if result is True:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
207 self.setContent(content)
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
208 elif self._afterEditCb:
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
209 self._afterEditCb(content)
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
210
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
211 self.initialized = True
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
212
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
213 def setFocus(self, focus):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
214 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
215 @param focus: set to True to focus the editor
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
216 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
217 raise NotImplementedError
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
218
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
219 def abortEdition(self, content):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
220 return True
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
221
362
019e1e706e74 browser_side: display the popup notifying the message's recipient when you edit the blog entry's bubble.
souliane <souliane@mailoo.org>
parents: 358
diff changeset
222 def addEditListener(self, listener):
019e1e706e74 browser_side: display the popup notifying the message's recipient when you edit the blog entry's bubble.
souliane <souliane@mailoo.org>
parents: 358
diff changeset
223 """Add a method to be called whenever the text is edited.
019e1e706e74 browser_side: display the popup notifying the message's recipient when you edit the blog entry's bubble.
souliane <souliane@mailoo.org>
parents: 358
diff changeset
224 @param listener: method taking two arguments: sender, keycode"""
019e1e706e74 browser_side: display the popup notifying the message's recipient when you edit the blog entry's bubble.
souliane <souliane@mailoo.org>
parents: 358
diff changeset
225 self.edit_listeners.append(listener)
019e1e706e74 browser_side: display the popup notifying the message's recipient when you edit the blog entry's bubble.
souliane <souliane@mailoo.org>
parents: 358
diff changeset
226
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
227
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
228 class SimpleTextEditor(BaseTextEditor, FocusHandler, keyb.KeyboardHandler, ClickHandler):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
229 """Base class for manage a simple text editor."""
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
230
803
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
231 CONVERT_NEW_LINES = True
838
ab87da500820 browser: validate the status with ENTER (fixes bug 111)
souliane <souliane@mailoo.org>
parents: 818
diff changeset
232 VALIDATE_WITH_SHIFT_ENTER = True
803
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
233
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
234 def __init__(self, content=None, modifiedCb=None, afterEditCb=None, options=None):
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
235 """
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
236 @param content
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
237 @param modifiedCb
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
238 @param afterEditCb
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
239 @param options (dict): can have the following value:
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
240 - no_xhtml: set to True to clean any xhtml content.
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
241 - enhance_display: if True, the display text will be enhanced with strings.addURLToText
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
242 - listen_keyboard: set to True to terminate the edition with <enter> or <escape>.
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
243 - listen_focus: set to True to terminate the edition when the focus is lost.
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
244 - listen_click: set to True to start the edition when you click on the widget.
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
245 """
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
246 self.options = {'no_xhtml': False,
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
247 'enhance_display': True,
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
248 'listen_keyboard': True,
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
249 'listen_focus': False,
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
250 'listen_click': False
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
251 }
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
252 if options:
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
253 self.options.update(options)
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
254 if self.options['listen_focus']:
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
255 FocusHandler.__init__(self)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
256 if self.options['listen_click']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
257 ClickHandler.__init__(self)
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
258 keyb.KeyboardHandler.__init__(self)
468
830b50593597 browser_side: fixes issues from the refactoring
souliane <souliane@mailoo.org>
parents: 467
diff changeset
259 strproc = lambda text: html_tools.html_sanitize(html_tools.html_strip(text)) if self.options['no_xhtml'] else html_tools.html_strip(text)
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
260 BaseTextEditor.__init__(self, content, strproc, modifiedCb, afterEditCb)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
261 self.textarea = self.display = None
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
262
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
263 def setContent(self, content=None):
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
264 BaseTextEditor.setContent(self, content)
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
265
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
266 def getContent(self):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
267 raise NotImplementedError
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
268
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
269 def edit(self, edit, abort=False):
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
270 BaseTextEditor.edit(self, edit)
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
271 if edit:
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
272 if self.options['listen_focus'] and self not in self.textarea._focusListeners:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
273 self.textarea.addFocusListener(self)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
274 if self.options['listen_click']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
275 self.display.clearClickListener()
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
276 if self not in self.textarea._keyboardListeners:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
277 self.textarea.addKeyboardListener(self)
347
f1ba38043d78 browser_side: status panel is based on a new class LightTextEditor which uses HTML5 "editablecontent" property
souliane <souliane@mailoo.org>
parents: 346
diff changeset
278 else:
349
f488692c4903 browser_side: LightTextEditor inheritates from BaseTextEditor + display URL in the status
souliane <souliane@mailoo.org>
parents: 347
diff changeset
279 self.setDisplayContent()
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
280 if self.options['listen_focus']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
281 try:
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
282 self.textarea.removeFocusListener(self)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
283 except ValueError:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
284 pass
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
285 if self.options['listen_click'] and self not in self.display._clickListeners:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
286 self.display.addClickListener(self)
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
287 try:
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
288 self.textarea.removeKeyboardListener(self)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
289 except ValueError:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
290 pass
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
291
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
292 def setDisplayContent(self):
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
293 text = self._original_content['text']
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
294 if not self.options['no_xhtml']:
467
97c72fe4a5f2 browser_side: import fixes:
Goffi <goffi@goffi.org>
parents: 449
diff changeset
295 text = strings.addURLToImage(text)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
296 if self.options['enhance_display']:
467
97c72fe4a5f2 browser_side: import fixes:
Goffi <goffi@goffi.org>
parents: 449
diff changeset
297 text = strings.addURLToText(text)
803
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
298 if self.CONVERT_NEW_LINES:
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
299 text = html_tools.convertNewLinesToXHTML(text)
849
d32b754265a0 browser (strings, editor): add javascript version of fixXHTMLLinks and use it for displaying the rich blog messages (add links' missing scheme and open them in new tab)
souliane <souliane@mailoo.org>
parents: 838
diff changeset
300 text = strings.fixXHTMLLinks(text)
803
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
301 self.display.setHTML(text)
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
302
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
303 def setFocus(self, focus):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
304 raise NotImplementedError
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
305
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
306 def onKeyDown(self, sender, keycode, modifiers):
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
307 for listener in self.edit_listeners:
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
308 listener(self.textarea, keycode, modifiers) # FIXME: edit_listeners must either be removed, or send an action instead of keycode/modifiers
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
309 if not self.options['listen_keyboard']:
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
310 return
838
ab87da500820 browser: validate the status with ENTER (fixes bug 111)
souliane <souliane@mailoo.org>
parents: 818
diff changeset
311 if keycode == keyb.KEY_ENTER and (not self.VALIDATE_WITH_SHIFT_ENTER or modifiers & keyb.MODIFIER_SHIFT):
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
312 self.textarea.setFocus(False)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
313 if not self.options['listen_focus']:
401
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
314 self.edit(False)
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
315
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
316 def onLostFocus(self, sender):
ea03f898067f browser_side: LightTextEditor renamed to HTMLTextEditor, new class LightTextEditor based on TextArea
souliane <souliane@mailoo.org>
parents: 400
diff changeset
317 """Finish the edition when focus is lost"""
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
318 if self.options['listen_focus']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
319 self.edit(False)
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
320
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
321 def onClick(self, sender=None):
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
322 """Start the edition when the widget is clicked"""
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
323 if self.options['listen_click']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
324 self.edit(True)
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
325
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
326 def onBrowserEvent(self, event):
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
327 if self.options['listen_focus']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
328 FocusHandler.onBrowserEvent(self, event)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
329 if self.options['listen_click']:
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
330 ClickHandler.onBrowserEvent(self, event)
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
331 keyb.KeyboardHandler.onBrowserEvent(self, event)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
332
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
333
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
334 class HTMLTextEditor(SimpleTextEditor, HTML, FocusHandler, keyb.KeyboardHandler):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
335 """Manage a simple text editor with the HTML 5 "contenteditable" property."""
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
336
803
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
337 CONVERT_NEW_LINES = False # overwrite definition in SimpleTextEditor
89a0cd2aa763 browser_side: convertNewLinesToXHTML should only be called on raw text messages:
souliane <souliane@mailoo.org>
parents: 784
diff changeset
338
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
339 def __init__(self, content=None, modifiedCb=None, afterEditCb=None, options=None):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
340 HTML.__init__(self)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
341 SimpleTextEditor.__init__(self, content, modifiedCb, afterEditCb, options)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
342 self.textarea = self.display = self
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
343
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
344 def getContent(self):
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
345 text = DOM.getInnerHTML(self.getElement())
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
346 return {'text': self.strproc(text) if text else ''}
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
347
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
348 def edit(self, edit, abort=False):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
349 if edit:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
350 self.textarea.setHTML(self._original_content['text'])
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
351 self.getElement().setAttribute('contenteditable', 'true' if edit else 'false')
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
352 SimpleTextEditor.edit(self, edit, abort)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
353
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
354 def setFocus(self, focus):
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
355 if focus:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
356 self.getElement().focus()
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
357 else:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
358 self.getElement().blur()
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
359
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
360
716
3b91225b457a server + browser side: blogging refactoring (draft), huge commit sorry:
Goffi <goffi@goffi.org>
parents: 696
diff changeset
361 class LightTextEditor(SimpleTextEditor, SimplePanel, FocusHandler, keyb.KeyboardHandler):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
362 """Manage a simple text editor with a TextArea for editing, HTML for display."""
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
363
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
364 def __init__(self, content=None, modifiedCb=None, afterEditCb=None, options=None):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
365 SimplePanel.__init__(self)
404
c393e7dc9ae6 browser_side: refactorize SimpleTextEditor init parameters
souliane <souliane@mailoo.org>
parents: 403
diff changeset
366 SimpleTextEditor.__init__(self, content, modifiedCb, afterEditCb, options)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
367 self.textarea = TextArea()
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
368 self.display = HTML()
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
369
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
370 def getContent(self):
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
371 text = self.textarea.getText()
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
372 return {'text': self.strproc(text) if text else ''}
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
373
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
374 def edit(self, edit, abort=False):
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
375 if edit:
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
376 self.textarea.setText(self._original_content['text'])
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
377 self.setWidget(self.textarea if edit else self.display)
696
c2f22ca12e23 browser and server side: remove unibox
souliane <souliane@mailoo.org>
parents: 685
diff changeset
378 SimpleTextEditor.edit(self, edit, abort)
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
379
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
380 def setFocus(self, focus):
491
c97fe4059f71 browser side: fixes NS_ERROR_FAILURE while opening microblog panels (bug from rev 442 - changeset 17259c2ff96f in MicroblogPanel.refresh)
souliane <souliane@mailoo.org>
parents: 468
diff changeset
381 if focus and self.isAttached():
403
ec6f7581b453 browser_side: microblogs edition: <shift> + <enter> makes a new line, <esc> finishes the edition
souliane <souliane@mailoo.org>
parents: 402
diff changeset
382 self.textarea.setCursorPos(len(self.textarea.getText()))
402
d7e78cb78dfc browser_side: HTMLTextEditor and LightTextEditor factorization
souliane <souliane@mailoo.org>
parents: 401
diff changeset
383 self.textarea.setFocus(focus)