/
RichTextEditor.py
153 lines (124 loc) · 4.43 KB
/
RichTextEditor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""
A rich text editor using FCKeditor.
Pass "-j fckeditor/fckeditor.js" to build.py in order to include the
FCKeditor javascript.
"""
from BoundMethod import BoundMethod
from pyjamas import logging
from pyjamas import DOM
from pyjamas import Window
from pyjamas.ui.Widget import Widget
from __pyjamas__ import JS
log = logging.getAppendLogger(__name__, logging.DEBUG, logging.PLAIN_FORMAT)
def createFCK(name):
JS("""
return new @{{!FCKeditor}}(@{{name}});
""")
JS("""
$wnd.FCKeditor_OnComplete = function(editorInstance )
{
var pyjsObject = $doc.getElementById(editorInstance.Name.substr(3)).__listener;
if(pyjsObject)
pyjsObject.onFCKLoaded(editorInstance);
}
""")
class RichTextEditor(Widget):
def __init__(self, initialValue="", target="", method="POST",
basePath=None, **kwargs):
self.id = "rte" + str(hash(self))
self.setElement(DOM.createForm())
DOM.setAttribute(self.element, "method", method)
DOM.setAttribute(self.element, "target", target)
if not kwargs.has_key('ID'): kwargs['ID'] = self.id
if not kwargs.has_key('StyleName'): kwargs['StyleName'] = "gwt-RichTextEditor"
if not kwargs.has_key('Height'): kwargs['Height'] = "600px"
if not kwargs.has_key('Width'): kwargs['Width'] = "100%"
Widget.__init__(self, **kwargs)
JS("""
var rte = this;
this.element.onsubmit = function() {
$wnd.setTimeout(function() { rte.onSave.call(rte) }, 0);
return false;
}
""")
if basePath is None:
basePath = "fckeditor/"
if not basePath.endswith("/"):
basePath += "/"
fck = createFCK("fck" + self.id)
fck.Height = self.getHeight()
fck.Width = self.getWidth()
fck.Value = initialValue
fck.BasePath = basePath
fck.Config.CustomConfigurationsPath = "../../fckconfig.js"
fck.pyjsObject = self
self.loaded = False
self.saveListeners = []
self.pendingHTML = None
html = fck.CreateHtml()
DOM.setInnerHTML(self.getElement(), html)
def addSaveListener(self, listener):
"""
When the user clicks the save button, your listener will be
notified.
Either pass a function (e.g. a BoundMethod) or an object with
an onSave() method. Either will be passed the RichtTextEditor
instance.
"""
self.saveListeners.append(listener)
def removeSaveListener(self, listener):
"""
Remove a previously added listener.
"""
self.saveListeners.remove(listener)
def onFCKLoaded(self, fck):
"""
Called when the FCK editor has loaded, and it is ready for use.
"""
self.loaded = True
self.fck = fck
fck.Events.AttachEvent('OnSelectionChange',
BoundMethod(self, self.onSelectionChange))
fck.Events.AttachEvent('OnBlur', BoundMethod(self, self.onBlur))
fck.Events.AttachEvent('OnFocus', BoundMethod(self, self.onFocus))
fck.Events.AttachEvent('OnPaste', BoundMethod(self, self.onPaste))
if self.pendingHTML:
fck.SetHTML(self.pendingHTML)
self.pendingHTML = None
def onSelectionChange(self, sender):
pass#log.debug("onSelectionChange!")
def onBlur(self, sender):
pass#log.debug("onBlur!")
def onFocus(self, sender):
pass#log.debug("onFocus!")
def onPaste(self, sender):
pass#log.debug("onPaste!")
def onSave(self):
"""
Handle the save click and pass it onto the listeners.
"""
log.debug("onSave() in %s", Window.getLocation().getHref())
for listener in self.saveListeners:
if hasattr(listener, "onSave"):
listener.onSave(self)
else:
listener(self)
return False
def setHTML(self, html):
"""
Call this to change the html showing in the editor.
"""
if self.loaded:
self.fck.SetHTML(html)
else:
self.pendingHTML = html
def getHTML(self):
"""
Call this to retrieve the HTML showing in the editor (e.g. to
save/preview it).
"""
return self.fck.GetXHTML(True)
def getDOM(self):
return self.fck.EditorDocument()
def getWindow(self):
return self.fck.EditorWindow()