X-Git-Url: https://scm.cri.ensmp.fr/git/Epoz.git/blobdiff_plain/e12f4a95372036c721467827829f60a68ef92048..36a8f50734b56b213436c3f09afc80509c20cc16:/Products/Epoz/__init__.py diff --git a/Products/Epoz/__init__.py b/Products/Epoz/__init__.py new file mode 100755 index 0000000..dcb18dd --- /dev/null +++ b/Products/Epoz/__init__.py @@ -0,0 +1,347 @@ +##### +### Epoz - a cross-browser-wysiwyg-editor for Zope +## Copyright (C) 2005 Maik Jablonski (maik.jablonski@uni-bielefeld.de) +# +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +## WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +### FOR A PARTICULAR PURPOSE. +#### + +import re +import urlparse +import cgi + +# try to import mxTidy as default +try: + from mx import Tidy + mxTidyIsAvailable = 1 +except: + mxTidyIsAvailable = 0 + +# try to import uTidylib as fallback +try: + import tidy + uTidyIsAvailable = 1 +except ImportError: + uTidyIsAvailable = 0 + +import Globals +from Products.PageTemplates.PageTemplateFile import PageTemplateFile +from App.ImageFile import ImageFile + +# Regexp for snipping the body of a document +HTML_BODY = re.compile(']*?>(.*)]*?>', re.DOTALL|re.IGNORECASE) +MSO_CLASS = re.compile(r'<(\w+)\W+(class="Mso.*?")>', re.IGNORECASE) +EPOZ_SCRIPT = re.compile(r'', '') + + # Quote newlines and single quotes, so the Epoz-JavaScript won't break. + # Needs to be a list and no dictionary, cause we need order!!! + + quotes = (("\\","\\\\"), ("\n","\\n"), ("\r","\\r"), ("'","\\'")) + + for item in quotes: + js_data = js_data.replace(item[0], item[1]) + + # Determine the correct path for VirtualHostMonsters & PCGI & etc.pp. + if not path: + path = "%s/misc_/Epoz/" % (self.REQUEST.get('BASEPATH1',''),) + + if not pageurl: + pageurl = self.REQUEST.get('URL1','') + + if lang == 'auto' : + i18n='' % {'path' : path, 'charset' : charset} + else : + i18n='' % (path,) + if lang<>'en': + i18n += '' % (path, lang) + + if not widget: + widget = "%sepoz_script_widget.js" % path + + # This is just a dummy page for test-iframe + # to prevent IE complaining when using Epoz via https + iframesrc = pageurl+'/epoz_blank_iframe.html' + + # Return the HTML-Code for the Epoz-Rich-Text-Editor + return """ +%(i18n)s + + + + + + + +""" % { + 'i18n': i18n, + 'widget': widget, + 'path': path, + 'name': name, + 'js_data': js_data, + 'toolbox': toolbox, + 'style': style, + 'button': button, + 'css': css, + 'customcss': customcss, + 'charset': charset, + 'data': data, + 'pageurl': pageurl, + 'iframesrc': iframesrc + } + + + +def EpozTidy(self, html, pageurl): + """ Take html and deliver xhtml if mxTidy is installed; + call EpozPostTidy for html-postprocessings before returning the result + """ + + errors = 0 + output = html + errordata = "" + + input = html.encode("utf-8") + input = EPOZ_SCRIPT.sub('') + + if mxTidyIsAvailable: + (errors, warnings, output, errordata) = Tidy.tidy( + input, drop_empty_paras=1, indent_spaces=1, indent="auto", + output_xhtml=1, word_2000=1, wrap=79, char_encoding="utf8") + if errors: + output = html + elif uTidyIsAvailable: + parsed = tidy.parseString( + input, drop_empty_paras=1, indent_spaces=1, indent="auto", + output_xhtml=1, word_2000=1, wrap=79, char_encoding="utf8", + add_xml_decl=0, doctype="omit", indent_attributes=1, + drop_proprietary_attributes=1, bare=1, clean=1, + enclose_text=1, tidy_mark=0) + reports = parsed.get_errors() + all_errors = [str(x) for x in reports if x.severity != 'W'] + errors = len(all_errors) + errordata = '\n'.join(all_errors) + if errors: + output = html + else: + output = str(parsed) + + output = MSO_CLASS.sub(r"<\1>", output) + result = HTML_BODY.search(output) + if result: + output = result.group(1) + + # Call External Method / PythonScript for postprocessing + # The script should expect two parameters: + # self = called context (=server) + # html = the htmlbody to postprocess + # pathname = path of edited object (maybe with template!) + # The script should return the new htmlbody + + EpozPostTidy = getattr(self, 'EpozPostTidy', None) + if EpozPostTidy is not None: + output = EpozPostTidy(self, output, pageurl) + + return (errors, output, errordata) + + +def EpozGetRelativeUrl(self, pageUrl, targetUrl): + """ Returns relative path from targetUrl to pageUrl. """ + + # Just some shortcuts... + SCHEME, HOSTNAME, PATH, PARAMS, QUERY, FRAGMENT = range(6) + + pageUnits = urlparse.urlparse(pageUrl) + targetUnits = urlparse.urlparse(targetUrl) + + if pageUnits[:PATH] != targetUnits[:PATH]: + # Scheme (http) or host:port (www.comain.com) are different + # -> no possible relative URL + return targetUrl + + afterPath = targetUnits[PARAMS:] + + pagePath = pageUnits[PATH].split('/') + pagePath.reverse() + + targetPath = targetUnits[PATH].split('/') + targetPath.reverse() + + # Remove parts which are equal (['a', 'b'] ['a', 'c'] --> ['c']) + while (len(pagePath) > 0 + and len(targetPath) > 0 + and pagePath[-1] == targetPath[-1]): + pagePath.pop() + last_pop = targetPath.pop() + if len(pagePath) == 0 and len(targetPath) == 0: + # Special case: link to itself (http://foo/a http://foo/a -> a) + targetPath.append(last_pop) + if len(pagePath) == 1 and pagePath[0] == "" and len(targetPath) == 0: + # Special case: (http://foo/a/ http://foo/a -> ../a) + pagePath.append(last_pop) + targetPath.append(last_pop) + + targetPath.reverse() + + relativeUrl = ['..'] * (len(pagePath) -1) + relativeUrl = ('', '', '/'.join(relativeUrl + targetPath)) + tuple(afterPath) + + return urlparse.urlunparse(relativeUrl) + + +# Make sure the Epoz method is replaceable in the Products folder +Epoz.__replaceable__ = Globals.REPLACEABLE + +# Register Epoz as global method +# Register EpozTidy as global method for XMLRPC +# Register EpozGetRelativeUrl as global method +# Register epoz_blank_iframe.html as global PageTemplate + +methods = { +'Epoz': Epoz, +'Epoz__roles__': None, + +'EpozTidy': EpozTidy, +'EpozTidy__roles__': None, + +'EpozGetRelativeUrl': EpozGetRelativeUrl, +'EpozGetRelativeUrl__roles__': None, + +'epoz_blank_iframe.html': PageTemplateFile('epoz/epoz_core/epoz_blank_iframe.html.pt', globals()), +'epoz_blank_iframe.html__roles__': None, +} + + +# And now try to register Epoz for CMF/Plone + +try: + from Products.CMFCore.DirectoryView import registerDirectory + + global cmfepoz_globals + cmfepoz_globals=globals() + + def initialize(context): + registerDirectory('epoz', cmfepoz_globals) +except: + pass + \ No newline at end of file