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 pyjamas.ui.RichTextAreaImpl import RichTextAreaImpl 
 24  from pyjamas.ui import RichTextAreaConsts 
 25   
 26  elem_focussers = {} 
 27   
 28  """* 
 29  * Basic rich text platform implementation. 
 30  """ 
31 -class RichTextAreaImplStandard (RichTextAreaImpl):
32
33 - def __init__(self):
34 RichTextAreaImpl.__init__(self) 35 """* 36 * Holds a cached copy of any user setHTML/setText actions until the real 37 * text area is fully initialized. Becomes <code>None</code> after init. 38 """ 39 self.beforeInitPlaceholder = DOM.createDiv() 40 41 """* 42 * Set to True when the {@link RichTextArea} is attached to the page and 43 * {@link #initElement()} is called. If the {@link RichTextArea} is detached 44 * before {@link #onElementInitialized()} is called, this will be set to 45 * False. See issue 1897 for details. 46 """ 47 self.initializing = False 48 self.css_styling = False
49
50 - def createElement(self):
51 return DOM.createElement('iframe')
52 55
56 - def getBackColor(self):
57 return self.queryCommandValue("BackColor")
58
59 - def getForeColor(self):
60 return self.queryCommandValue("ForeColor")
61
62 - def getHTML(self):
63 if self.beforeInitPlaceholder is None: 64 return self.getHTMLImpl() 65 return DOM.getInnerHTML(self.beforeInitPlaceholder)
66
67 - def getText(self):
68 if self.beforeInitPlaceholder is None: 69 return self.getTextImpl() 70 return DOM.getInnerText(self.beforeInitPlaceholder)
71
72 - def onTimer(self, tid):
73 print "initialise timer done", tid 74 self.elem.contentWindow.document.designMode = 'On' 75 76 # Send notification that the iframe has reached design mode. 77 self.onElementInitialized()
78
79 - def initElement(self):
80 # Most browsers don't like setting designMode until slightly _after_ 81 # the iframe becomes attached to the DOM. Any non-zero timeout will do 82 # just fine. 83 print "initElement" 84 self.initializing = True 85 Timer(50, self)
86
87 - def insertHorizontalRule(self):
88 self.execCommand("InsertHorizontalRule", '')
89
90 - def insertImage(self, url):
91 self.execCommand("InsertImage", url)
92
93 - def insertOrderedList(self):
94 self.execCommand("InsertOrderedList", '')
95
96 - def insertUnorderedList(self):
97 self.execCommand("InsertUnorderedList", '')
98
99 - def isBasicEditingSupported(self):
100 return True
101
102 - def isBold(self):
103 return self.queryCommandState("Bold")
104
106 return True
107
108 - def isItalic(self):
109 return self.queryCommandState("Italic")
110
111 - def isStrikethrough(self):
112 return self.queryCommandState("Strikethrough")
113
114 - def isSubscript(self):
115 return self.queryCommandState("Subscript")
116
117 - def isSuperscript(self):
118 return self.queryCommandState("Superscript")
119
120 - def isUnderlined(self):
121 return self.queryCommandState("Underline")
122
123 - def leftIndent(self):
124 self.execCommand("Outdent", '')
125
126 - def removeFormat(self):
127 self.execCommand("RemoveFormat", '')
128 131
132 - def rightIndent(self):
133 self.execCommand("Indent", '')
134
135 - def selectAll(self):
136 self.execCommand("SelectAll", '')
137
138 - def setBackColor(self, color):
139 self.execCommand("BackColor", color)
140
141 - def setFocus(self, focused):
142 if focused: 143 self.elem.contentWindow.focus() 144 else: 145 self.elem.contentWindow.blur()
146
147 - def setFontName(self, name):
148 self.execCommand("FontName", name)
149
150 - def setFontSize(self, fontSize):
151 self.execCommand("FontSize", str(fontSize))
152
153 - def setForeColor(self, color):
154 self.execCommand("ForeColor", color)
155
156 - def setHTML(self, html):
157 if self.beforeInitPlaceholder is None: 158 self.setHTMLImpl(html) 159 else: 160 DOM.setInnerHTML(self.beforeInitPlaceholder, html)
161
162 - def setJustification(self, justification):
163 if justification == RichTextAreaConsts.CENTER: 164 self.execCommand("JustifyCenter", '') 165 elif justification == RichTextAreaConsts.LEFT: 166 self.execCommand("JustifyLeft", '') 167 elif justification == RichTextAreaConsts.RIGHT: 168 self.execCommand("JustifyRight", '')
169
170 - def setText(self, text):
171 if self.beforeInitPlaceholder is None: 172 self.setTextImpl(text) 173 else: 174 DOM.setInnerText(self.beforeInitPlaceholder, text)
175
176 - def toggleBold(self):
177 self.execCommand("Bold", "False")
178
179 - def toggleItalic(self):
180 self.execCommand("Italic", "False")
181
182 - def toggleStrikethrough(self):
183 self.execCommand("Strikethrough", "False")
184
185 - def toggleSubscript(self):
186 self.execCommand("Subscript", "False")
187
188 - def toggleSuperscript(self):
189 self.execCommand("Superscript", "False")
190
191 - def toggleUnderline(self):
192 self.execCommand("Underline", "False")
193
194 - def uninitElement(self):
195 # Issue 1897: initElement uses a timeout, so its possible to call this 196 # method after calling initElement, but before the event system is in 197 # place. 198 if self.initializing: 199 self.initializing = False 200 return 201 202 # Unhook all custom event handlers when the element is detached. 203 self.unhookEvents() 204 205 # Recreate the placeholder element and store the iframe's contents in it. 206 # This is necessary because some browsers will wipe the iframe's contents 207 # when it is removed from the DOM. 208 html = self.getHTML() 209 self.beforeInitPlaceholder = DOM.createDiv() 210 DOM.setInnerHTML(self.beforeInitPlaceholder, html) 211 self.elem.contentWindow.document.designMode = 'Off'
212
213 - def getHTMLImpl(self):
214 return self.elem.contentWindow.document.body.innerHTML
215
216 - def getTextImpl(self):
217 return self.elem.contentWindow.document.body.textContent
218
219 - def __gwt_handler(self, view, evt, from_window):
220 221 listener = DOM.get_listener(self.elem) 222 if listener is not None: 223 DOM.dispatchEvent(evt, self.elem, listener)
224
225 - def __gwt_focus_handler(self, view, evt, from_window):
226 227 if elem_focussers.get(self.elem, False): 228 return 229 230 elem_focussers[self.elem] = True 231 self.__gwt_handler(view, evt, from_window)
232
233 - def __gwt_blur_handler(self, view, evt, from_window):
234 235 if not elem_focussers.get(self.elem, False): 236 return 237 238 elem_focussers[self.elem] = False 239 self.__gwt_handler(view, evt, from_window)
240
241 - def hookEvents(self):
242 print self, "hook events weirdly" 243 244 elem = self.elem; 245 win = elem.contentWindow; 246 247 mf = get_main_frame() 248 mf._addWindowEventListener('keydown', self.__gwt_handler, win) 249 mf._addWindowEventListener('keyup', self.__gwt_handler, win) 250 mf._addWindowEventListener('keypress', self.__gwt_handler, win) 251 mf._addWindowEventListener('mousedown', self.__gwt_handler, win) 252 mf._addWindowEventListener('mouseup', self.__gwt_handler, win) 253 mf._addWindowEventListener('mousemove', self.__gwt_handler, win) 254 mf._addWindowEventListener('mouseover', self.__gwt_handler, win) 255 mf._addWindowEventListener('mouseout', self.__gwt_handler, win) 256 mf._addWindowEventListener('click', self.__gwt_handler, win) 257 258 mf._addWindowEventListener('focus', self.__gwt_focus_handler, win) 259 mf._addWindowEventListener('blur', self.__gwt_blur_handler, win)
260
261 - def onElementInitialized(self):
262 # Issue 1897: This method is called after a timeout, during which time the 263 # element might by detached. 264 if not self.initializing: 265 return 266 267 print "onElementInit", DOM.getInnerHTML(self.beforeInitPlaceholder) 268 self.initializing = False 269 270 RichTextAreaImpl.onElementInitialized(self) 271 272 # clone styles from main document 273 if self.css_styling: 274 elem = self.elem; 275 _doc = elem.contentWindow.document 276 fragment = _doc.createDocumentFragment() 277 nl = doc().getElementsByTagName("style") 278 for i in range(nl.length): 279 n = nl.item(i) 280 fragment.appendChild(n.cloneNode(True)) 281 _doc.getElementsByTagName("head").item(0).appendChild(fragment) 282 283 # When the iframe is ready, ensure cached content is set. 284 if self.beforeInitPlaceholder is not None: 285 self.setHTMLImpl(DOM.getInnerHTML(self.beforeInitPlaceholder)) 286 self.beforeInitPlaceholder = None
287
288 - def setHTMLImpl(self, html):
289 self.elem.contentWindow.document.body.innerHTML = html;
290
291 - def setTextImpl(self, text):
292 self.elem.contentWindow.document.body.textContent = text;
293
294 - def unhookEvents(self):
295 print """ TODO: RichTextEditor.unhookEvents: 296 var elem = this.elem; 297 var wnd = elem.contentWindow; 298 299 wnd.removeEventListener('keydown', elem.__gwt_handler, true); 300 wnd.removeEventListener('keyup', elem.__gwt_handler, true); 301 wnd.removeEventListener('keypress', elem.__gwt_handler, true); 302 wnd.removeEventListener('mousedown', elem.__gwt_handler, true); 303 wnd.removeEventListener('mouseup', elem.__gwt_handler, true); 304 wnd.removeEventListener('mousemove', elem.__gwt_handler, true); 305 wnd.removeEventListener('mouseover', elem.__gwt_handler, true); 306 wnd.removeEventListener('mouseout', elem.__gwt_handler, true); 307 wnd.removeEventListener('click', elem.__gwt_handler, true); 308 309 wnd.removeEventListener('focus', elem.__gwt_focusHandler, true); 310 wnd.removeEventListener('blur', elem.__gwt_blurHandler, true); 311 312 elem.__gwt_handler = null; 313 elem.__gwt_focusHandler = null; 314 elem.__gwt_blurHandler = null; 315 """
316
317 - def execCommand(self, cmd, param):
318 if self.isRichEditingActive(self.elem): 319 # When executing a command, focus the iframe first, since some commands 320 # don't take properly when it's not focused. 321 self.setFocus(True) 322 self.execCommandAssumingFocus(cmd, param)
323
324 - def execCommandAssumingFocus(self, cmd, param):
325 self.elem.contentWindow.document.execCommand(cmd, False, param)
326
327 - def isRichEditingActive(self, e):
328 return str(e.contentWindow.document.designMode).upper() == 'ON'
329
330 - def queryCommandState(self, cmd):
331 if self.isRichEditingActive(self.elem): 332 # When executing a command, focus the iframe first, since some commands 333 # don't take properly when it's not focused. 334 self.setFocus(True) 335 return self.queryCommandStateAssumingFocus(cmd) 336 else: 337 return False
338
339 - def queryCommandStateAssumingFocus(self, cmd):
340 return self.elem.contentWindow.document.queryCommandState(cmd)
341
342 - def queryCommandValue(self, cmd):
343 # When executing a command, focus the iframe first, since some commands 344 # don't take properly when it's not focused. 345 self.setFocus(True) 346 return self.queryCommandValueAssumingFocus(cmd)
347
348 - def queryCommandValueAssumingFocus(self, cmd):
349 return self.elem.contentWindow.document.queryCommandValue(cmd)
350
351 - def setCssStyling(self):
352 self.css_styling = True
353