annotate browser/sat_browser/editor_widget.py @ 1208:584e29d9510a

pages: display a warning instead or raising exception if write fails: request.write sometimes raise an AttributeError. This case happens most of time when browser tab is closed or reloaded before the page has been written. fix 214
author Goffi <goffi@goffi.org>
date Fri, 19 Jul 2019 18:01:38 +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)