/addons/RichTextEditor.py

http://pyjamas.googlecode.com/ · Python · 131 lines · 89 code · 17 blank · 25 comment · 6 complexity · 3a7ce446004d28b6580dfb8d9a077aca MD5 · raw file

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