Package pyjamas :: Package ui :: Module RichTextAreaImplStandard
[hide private]
[frames] | no frames]

Source Code for Module pyjamas.ui.RichTextAreaImplStandard

  1  """ 
  2  * Copyright 2008 Google Inc. 
  3  # Copyright (C) 2009 Luke Kenneth Casson Leighton <lkcl@lkcl.net> 
  4  * 
  5  * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  6  * use this file except in compliance with the License. You may obtain a copy of 
  7  * the License at 
  8  * 
  9  * http:#www.apache.org/licenses/LICENSE-2.0 
 10  * 
 11  * Unless required by applicable law or agreed to in writing, software 
 12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 14  * License for the specific language governing permissions and limitations under 
 15  * the License. 
 16  """ 
 17   
 18  from __pyjamas__ import doc, wnd, get_main_frame, JS 
 19   
 20  from pyjamas import DOM 
 21  from pyjamas.Timer import Timer 
 22   
 23  from RichTextAreaImpl import RichTextAreaImpl 
 24  from pyjamas.ui import FontSize 
 25  from pyjamas.ui import Justification 
 26   
 27  elem_focussers = {} 
 28   
 29  """* 
 30  * Basic rich text platform implementation. 
 31  """ 
32 -class RichTextAreaImplStandard (RichTextAreaImpl):
33
34 - def __init__(self):
35 RichTextAreaImpl.__init__(self) 36 """* 37 * Holds a cached copy of any user setHTML/setText actions until the real 38 * text area is fully initialized. Becomes <code>None</code> after init. 39 """ 40 self.beforeInitPlaceholder = DOM.createDiv() 41 42 """* 43 * Set to True when the {@link RichTextArea} is attached to the page and 44 * {@link #initElement()} is called. If the {@link RichTextArea} is detached 45 * before {@link #onElementInitialized()} is called, this will be set to 46 * False. See issue 1897 for details. 47 """ 48 self.initializing = False
49
50 - def createElement(self):
51 return DOM.createElement('iframe')
52 55 56
57 - def getBackColor(self):
58 return self.queryCommandValue("BackColor")
59 60
61 - def getForeColor(self):
62 return self.queryCommandValue("ForeColor")
63 64
65 - def getHTML(self):
66 if self.beforeInitPlaceholder is None: 67 return self.getHTMLImpl() 68 return DOM.getInnerHTML(self.beforeInitPlaceholder)
69 70
71 - def getText(self):
72 if self.beforeInitPlaceholder is None: 73 return self.getTextImpl() 74 return DOM.getInnerText(self.beforeInitPlaceholder)
75
76 - def onTimer(self, tid):
77 self.elem.contentWindow.document.designMode = 'On' 78 79 # Send notification that the iframe has reached design mode. 80 self.onElementInitialized()
81
82 - def initElement(self):
83 # Most browsers don't like setting designMode until slightly _after_ 84 # the iframe becomes attached to the DOM. Any non-zero timeout will do 85 # just fine. 86 print "initElement" 87 self.initializing = True 88 Timer(50, self)
89
90 - def insertHorizontalRule(self):
91 self.execCommand("InsertHorizontalRule", None)
92 93
94 - def insertImage(self, url):
95 self.execCommand("InsertImage", url)
96 97
98 - def insertOrderedList(self):
99 self.execCommand("InsertOrderedList", None)
100 101
102 - def insertUnorderedList(self):
103 self.execCommand("InsertUnorderedList", None)
104 105
106 - def isBasicEditingSupported(self):
107 return True
108 109
110 - def isBold(self):
111 return self.queryCommandState("Bold")
112 113
115 return True
116 117
118 - def isItalic(self):
119 return self.queryCommandState("Italic")
120 121
122 - def isStrikethrough(self):
123 return self.queryCommandState("Strikethrough")
124 125
126 - def isSubscript(self):
127 return self.queryCommandState("Subscript")
128 129
130 - def isSuperscript(self):
131 return self.queryCommandState("Superscript")
132 133
134 - def isUnderlined(self):
135 return self.queryCommandState("Underline")
136 137
138 - def leftIndent(self):
139 self.execCommand("Outdent", None)
140 141
142 - def removeFormat(self):
143 self.execCommand("RemoveFormat", None)
144 145 148 149
150 - def rightIndent(self):
151 self.execCommand("Indent", None)
152 153
154 - def selectAll(self):
155 self.execCommand("SelectAll", None)
156 157
158 - def setBackColor(self, color):
159 self.execCommand("BackColor", color)
160 161
162 - def setFocus(self, focused):
163 if focused: 164 self.elem.contentWindow.focus() 165 else: 166 self.elem.contentWindow.blur()
167 168
169 - def setFontName(self, name):
170 self.execCommand("FontName", name)
171 172
173 - def setFontSize(self, fontSize):
174 self.execCommand("FontSize", str(fontSize))
175 176
177 - def setForeColor(self, color):
178 self.execCommand("ForeColor", color)
179 180
181 - def setHTML(self, html):
182 if self.beforeInitPlaceholder is None: 183 self.setHTMLImpl(html) 184 else: 185 DOM.setInnerHTML(self.beforeInitPlaceholder, html)
186 187 188
189 - def setJustification(self, justification):
190 if justification == Justification.CENTER: 191 self.execCommand("JustifyCenter", None) 192 elif justification == Justification.LEFT: 193 self.execCommand("JustifyLeft", None) 194 elif justification == Justification.RIGHT: 195 self.execCommand("JustifyRight", None)
196 197 198
199 - def setText(self, text):
200 if self.beforeInitPlaceholder is None: 201 self.setTextImpl(text) 202 else: 203 DOM.setInnerText(self.beforeInitPlaceholder, text)
204 205 206
207 - def toggleBold(self):
208 self.execCommand("Bold", "False")
209 210
211 - def toggleItalic(self):
212 self.execCommand("Italic", "False")
213 214
215 - def toggleStrikethrough(self):
216 self.execCommand("Strikethrough", "False")
217 218
219 - def toggleSubscript(self):
220 self.execCommand("Subscript", "False")
221 222
223 - def toggleSuperscript(self):
224 self.execCommand("Superscript", "False")
225 226
227 - def toggleUnderline(self):
228 self.execCommand("Underline", "False")
229 230
231 - def uninitElement(self):
232 # Issue 1897: initElement uses a timeout, so its possible to call this 233 # method after calling initElement, but before the event system is in 234 # place. 235 if self.initializing: 236 self.initializing = False 237 return 238 239 240 # Unhook all custom event handlers when the element is detached. 241 self.unhookEvents() 242 243 # Recreate the placeholder element and store the iframe's contents in it. 244 # This is necessary because some browsers will wipe the iframe's contents 245 # when it is removed from the DOM. 246 html = self.getHTML() 247 self.beforeInitPlaceholder = DOM.createDiv() 248 DOM.setInnerHTML(self.beforeInitPlaceholder, html)
249 250
251 - def getHTMLImpl(self):
252 return self.elem.contentWindow.document.body.innerHTML
253 254
255 - def getTextImpl(self):
256 return self.elem.contentWindow.document.body.textContent
257
258 - def __gwt_handler(self, view, evt, from_window):
259 try: 260 evt = get_main_frame().gobject_wrap(evt) # webkit HACK! 261 except: 262 pass 263 264 listener = DOM.get_listener(self.elem) 265 if listener: 266 listener.onBrowserEvent(evt);
267
268 - def __gwt_focus_handler(self, view, evt, from_window):
269 270 if elem_focussers.get(self.elem, False): 271 return 272 273 elem_focussers[self.elem] = True 274 self.__gwt_handler(view, evt, from_window)
275
276 - def __gwt_blur_handler(self, view, evt, from_window):
277 278 if not elem_focussers.get(self.elem, False): 279 return 280 281 elem_focussers[self.elem] = False 282 self.__gwt_handler(view, evt, from_window)
283
284 - def hookEvents(self):
285 elem = self.elem; 286 win = elem.contentWindow; 287 288 mf = get_main_frame() 289 mf._addWindowEventListener('keydown', self.__gwt_handler, win) 290 mf._addWindowEventListener('keyup', self.__gwt_handler, win) 291 mf._addWindowEventListener('keypress', self.__gwt_handler, win) 292 mf._addWindowEventListener('mousedown', self.__gwt_handler, win) 293 mf._addWindowEventListener('mouseup', self.__gwt_handler, win) 294 mf._addWindowEventListener('mousemove', self.__gwt_handler, win) 295 mf._addWindowEventListener('mouseover', self.__gwt_handler, win) 296 mf._addWindowEventListener('mouseout', self.__gwt_handler, win) 297 mf._addWindowEventListener('click', self.__gwt_handler, win) 298 299 mf._addWindowEventListener('focus', self.__gwt_focus_handler, win) 300 mf._addWindowEventListener('blur', self.__gwt_blur_handler, win)
301 302
303 - def onElementInitialized(self):
304 # Issue 1897: This method is called after a timeout, during which time the 305 # element might by detached. 306 if not self.initializing: 307 return 308 309 print "onElementInit", DOM.getInnerHTML(self.beforeInitPlaceholder) 310 self.initializing = False 311 312 RichTextAreaImpl.onElementInitialized(self) 313 314 # When the iframe is ready, ensure cached content is set. 315 if self.beforeInitPlaceholder is not None: 316 self.setHTMLImpl(DOM.getInnerHTML(self.beforeInitPlaceholder)) 317 self.beforeInitPlaceholder = None
318 319 320
321 - def setHTMLImpl(self, html):
322 self.elem.contentWindow.document.body.innerHTML = html;
323 324
325 - def setTextImpl(self, text):
326 self.elem.contentWindow.document.body.textContent = text;
327 328
329 - def unhookEvents(self):
330 print """ TODO: RichTextEditor.unhookEvents: 331 var elem = this.elem; 332 var wnd = elem.contentWindow; 333 334 wnd.removeEventListener('keydown', elem.__gwt_handler, true); 335 wnd.removeEventListener('keyup', elem.__gwt_handler, true); 336 wnd.removeEventListener('keypress', elem.__gwt_handler, true); 337 wnd.removeEventListener('mousedown', elem.__gwt_handler, true); 338 wnd.removeEventListener('mouseup', elem.__gwt_handler, true); 339 wnd.removeEventListener('mousemove', elem.__gwt_handler, true); 340 wnd.removeEventListener('mouseover', elem.__gwt_handler, true); 341 wnd.removeEventListener('mouseout', elem.__gwt_handler, true); 342 wnd.removeEventListener('click', elem.__gwt_handler, true); 343 344 wnd.removeEventListener('focus', elem.__gwt_focusHandler, true); 345 wnd.removeEventListener('blur', elem.__gwt_blurHandler, true); 346 347 elem.__gwt_handler = null; 348 elem.__gwt_focusHandler = null; 349 elem.__gwt_blurHandler = null; 350 """
351 352
353 - def execCommand(self, cmd, param):
354 if self.isRichEditingActive(elem): 355 # When executing a command, focus the iframe first, since some commands 356 # don't take properly when it's not focused. 357 setFocus(True) 358 self.execCommandAssumingFocus(cmd, param)
359 360 361
362 - def execCommandAssumingFocus(self, cmd, param):
363 self.elem.contentWindow.document.execCommand(cmd, False, param)
364 365
366 - def isRichEditingActive(self, e):
367 return str(e.contentWindow.document.designMode).upper() == 'ON'
368 369
370 - def queryCommandState(self, cmd):
371 if isRichEditingActive(elem): 372 # When executing a command, focus the iframe first, since some commands 373 # don't take properly when it's not focused. 374 setFocus(True) 375 return self.queryCommandStateAssumingFocus(cmd) 376 else: 377 return False
378 379 380
381 - def queryCommandStateAssumingFocus(self, cmd):
382 return self.elem.contentWindow.document.queryCommandState(cmd)
383 384
385 - def queryCommandValue(self, cmd):
386 # When executing a command, focus the iframe first, since some commands 387 # don't take properly when it's not focused. 388 self.setFocus(True) 389 return self.queryCommandValueAssumingFocus(cmd)
390 391
392 - def queryCommandValueAssumingFocus(self, cmd):
393 return self.elem.contentWindow.document.queryCommandValue(cmd)
394