Ejemplo n.º 1
0
    def sendEditor(self, **kw):
        """
        Send the editor form page.

        @keyword preview: if given, show this text in preview mode
        @keyword staytop: don't go to #preview
        @keyword comment: comment field (when preview is true)
        """
        from MoinMoin import i18n
        try:
            from MoinMoin.action import SpellCheck
        except ImportError:
            SpellCheck = None

        request = self.request
        form = self.request.form
        _ = self._
        self.request.disableHttpCaching(level=2)
        self.request.http_headers()

        raw_body = ''
        msg = None
        conflict_msg = None
        edit_lock_message = None
        preview = kw.get('preview', None)
        staytop = kw.get('staytop', 0)

        # check edit permissions
        if not self.request.user.may.write(self.page_name):
            msg = _('You are not allowed to edit this page.')
        elif not self.isWritable():
            msg = _('Page is immutable!')
        elif self.rev:
            # Trying to edit an old version, this is not possible via
            # the web interface, but catch it just in case...
            msg = _('Cannot edit old revisions!')
        else:
            # try to acquire edit lock
            ok, edit_lock_message = self.lock.acquire()
            if not ok:
                # failed to get the lock
                if preview is not None:
                    edit_lock_message = _('The lock you held timed out. Be prepared for editing conflicts!'
                        ) + "<br>" + edit_lock_message
                else:
                    msg = edit_lock_message

        # Did one of the prechecks fail?
        if msg:
            self.send_page(self.request, msg=msg)
            return

        # Check for preview submit
        if preview is None:
            title = _('Edit "%(pagename)s"')
        else:
            title = _('Preview of "%(pagename)s"')
            self.set_raw_body(preview, modified=1)

        # send header stuff
        lock_timeout = self.lock.timeout / 60
        lock_page = wikiutil.escape(self.page_name, quote=1)
        lock_expire = _("Your edit lock on %(lock_page)s has expired!") % {'lock_page': lock_page}
        lock_mins = _("Your edit lock on %(lock_page)s will expire in # minutes.") % {'lock_page': lock_page}
        lock_secs = _("Your edit lock on %(lock_page)s will expire in # seconds.") % {'lock_page': lock_page}
                
        # get request parameters
        try:
            text_rows = int(form['rows'][0])
        except StandardError:
            text_rows = self.cfg.edit_rows
            if self.request.user.valid:
                text_rows = int(self.request.user.edit_rows)

        if preview is not None:
            # Propagate original revision
            rev = int(form['rev'][0])
            
            # Check for editing conflicts
            if not self.exists():
                # page does not exist, are we creating it?
                if rev:
                    conflict_msg = _('Someone else deleted this page while you were editing!')
            elif rev != self.current_rev():
                conflict_msg = _('Someone else changed this page while you were editing!')
                if self.mergeEditConflict(rev):
                    conflict_msg = _("""Someone else saved this page while you were editing!
Please review the page and save then. Do not save this page as it is!
Have a look at the diff of %(difflink)s to see what has been changed.""") % {
                        'difflink': self.link_to(self.request,
                                                 querystr='action=diff&rev=%d' % rev)
                        }
                    rev = self.current_rev()
            if conflict_msg:
                # We don't show preview when in conflict
                preview = None
                
        elif self.exists():
            # revision of existing page
            rev = self.current_rev()
        else:
            # page creation
            rev = 0

        # Page editing is done using user language
        self.request.setContentLanguage(self.request.lang)

        # Setup status message
        status = [kw.get('msg', ''), conflict_msg, edit_lock_message]
        status = [msg for msg in status if msg]
        status = ' '.join(status)
        status = Status(self.request, content=status)
        
        wikiutil.send_title(self.request,
            title % {'pagename': self.split_title(self.request),},
            page=self,
            pagename=self.page_name, msg=status,
            html_head=self.lock.locktype and (
                PageEditor._countdown_js % {
                     'countdown_script': self.request.theme.externalScript('countdown'),
                     'lock_timeout': lock_timeout,
                     'lock_expire': lock_expire,
                     'lock_mins': lock_mins,
                     'lock_secs': lock_secs,
                    }) or '',
            editor_mode=1,
        )
        
        self.request.write(self.request.formatter.startContent("content"))

        # Get the text body for the editor field.
        # TODO: what about deleted pages? show the text of the last revision or use the template?
        if preview is not None:
            raw_body = self.get_raw_body()
        elif self.exists():
            # If the page exists, we get the text from the page.
            # TODO: maybe warn if template argument was ignored because the page exists?
            raw_body = self.get_raw_body()
        elif form.has_key('template'):
            # If the page does not exists, we try to get the content from the template parameter.
            template_page = wikiutil.unquoteWikiname(form['template'][0])
            if self.request.user.may.read(template_page):
                raw_body = Page(self.request, template_page).get_raw_body()
                if raw_body:
                    self.request.write(_("[Content of new page loaded from %s]") % (template_page,), '<br>')
                else:
                    self.request.write(_("[Template %s not found]") % (template_page,), '<br>')
            else:
                self.request.write(_("[You may not read %s]") % (template_page,), '<br>')

        # Make backup on previews - but not for new empty pages
        if preview and raw_body:
            self._make_backup(raw_body)

        # Generate default content for new pages
        if not raw_body:
            raw_body = _('Describe %s here.') % (self.page_name,)

        # send form
        self.request.write('<form id="editor" method="post" action="%s/%s#preview">' % (
            self.request.getScriptname(),
            wikiutil.quoteWikinameURL(self.page_name),
            ))

        # yet another weird workaround for broken IE6 (it expands the text
        # editor area to the right after you begin to type...). IE sucks...
        # http://fplanque.net/2003/Articles/iecsstextarea/
        self.request.write('<fieldset style="border:none;padding:0;">')
        
        self.request.write(unicode(html.INPUT(type="hidden", name="action", value="edit")))

        # Send revision of the page our edit is based on
        self.request.write('<input type="hidden" name="rev" value="%d">' % (rev,))

        # Create and send a ticket, so we can check the POST
        self.request.write('<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket(self.request))

        # Save backto in a hidden input
        backto = form.get('backto', [None])[0]
        if backto:
            self.request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))

        # button bar
        button_spellcheck = (SpellCheck and
            '<input class="button" type="submit" name="button_spellcheck" value="%s">'
                % _('Check Spelling')) or ''

        save_button_text = _('Save Changes')
        cancel_button_text = _('Cancel')
        
        if self.cfg.page_license_enabled:
            self.request.write('<p><em>', _(
"""By hitting '''%(save_button_text)s''' you put your changes under the %(license_link)s.
If you don't want that, hit '''%(cancel_button_text)s''' to cancel your changes.""") % {
                'save_button_text': save_button_text,
                'cancel_button_text': cancel_button_text,
                'license_link': wikiutil.getSysPage(self.request, self.cfg.page_license_page).link_to(self.request),
            }, '</em></p>')

        self.request.write('''
<input class="button" type="submit" name="button_save" value="%s">
<input class="button" type="submit" name="button_preview" value="%s">
<input class="button" type="submit" name="button_switch" value="%s">
%s
<input class="button" type="submit" name="button_cancel" value="%s">
<input type="hidden" name="editor" value="gui">
''' % (save_button_text, _('Preview'), _('Text mode'), button_spellcheck, cancel_button_text,))

        self.sendconfirmleaving() # TODO update state of flgChange to make this work, see PageEditor

        # Add textarea with page text

        # TODO: currently self.language is None at this point. We have
        # to do processing instructions parsing earlier, or move page
        # language into meta file.
        lang = self.language or self.request.cfg.language_default
        contentlangdirection = i18n.getDirection(lang) # 'ltr' or 'rtl'
        uilanguage = self.request.lang
        url_prefix = self.request.cfg.url_prefix
        wikipage = wikiutil.quoteWikinameURL(self.page_name)
        fckbasepath = url_prefix + '/applets/FCKeditor'
        wikiurl = request.getScriptname()
        if not wikiurl or wikiurl[-1] != '/':
            wikiurl += '/'
        themepath = '%s/%s' % (url_prefix, self.request.theme.name)
        smileypath = themepath + '/img'
        # auto-generating a list for SmileyImages does NOT work from here!
        editor_size = int(request.user.edit_rows) * 22 # 22 height_pixels/line
        word_rule = self.word_rule() 

        self.request.write("""
<script type="text/javascript" src="%(fckbasepath)s/fckeditor.js"></script>
<script type="text/javascript">
<!--
    var oFCKeditor = new FCKeditor( 'savetext', '100%%', %(editor_size)s, 'MoinDefault' ) ;
    oFCKeditor.BasePath= '%(fckbasepath)s/' ;
    oFCKeditor.Config['WikiBasePath'] = '%(wikiurl)s' ;
    oFCKeditor.Config['WikiPage'] = '%(wikipage)s' ;
    oFCKeditor.Config['PluginsPath'] = '%(url_prefix)s/applets/moinFCKplugins/' ;
    oFCKeditor.Config['CustomConfigurationsPath'] = '%(url_prefix)s/applets/moinfckconfig.js'  ;
    oFCKeditor.Config['WordRule'] = %(word_rule)s ;
    oFCKeditor.Config['SmileyPath'] = '%(smileypath)s/' ;
    oFCKeditor.Config['EditorAreaCSS'] = '%(themepath)s/css/common.css' ;
    oFCKeditor.Config['SkinPath'] = '%(fckbasepath)s/editor/skins/silver/' ;
    oFCKeditor.Config['AutoDetectLanguage'] = false ;
    oFCKeditor.Config['DefaultLanguage'] = '%(uilanguage)s' ;
    oFCKeditor.Config['ContentLangDirection']  = '%(contentlangdirection)s' ;
    oFCKeditor.Value= """ % locals())

        from MoinMoin.formatter.text_gedit import Formatter
        self.formatter = Formatter(request)
        self.formatter.page = self
        output = request.redirectedOutput(self.send_page_content, request, Parser, raw_body, do_cache=False)
        output = repr(output)
        if output[0] == 'u':
            output = output[1:]
        request.write(output)
        self.request.write(""" ;
    oFCKeditor.Create() ;
//-->
</script>
""")
        self.request.write("<p>")
        self.request.write(_("Comment:"),
            ' <input id="editor-comment" type="text" name="comment" value="%s" maxlength="200">' % (
                wikiutil.escape(kw.get('comment', ''), 1), ))
        self.request.write("</p>")

        # Category selection
        filter = re.compile(self.cfg.page_category_regex, re.UNICODE).search
        cat_pages = self.request.rootpage.getPageList(filter=filter)
        cat_pages.sort()
        cat_pages = [wikiutil.pagelinkmarkup(p) for p in cat_pages]
        cat_pages.insert(0, ('', _('<No addition>', formatted=False)))
        self.request.write("<p>")
        self.request.write(_('Add to: %(category)s') % {
            'category': unicode(util.web.makeSelection('category', cat_pages)),
        })
        if self.cfg.mail_enabled:
            self.request.write('''
&nbsp;
<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s>
<label for="chktrivial">%(label)s</label> ''' % {
                'checked': ('', 'checked')[form.get('trivial',['0'])[0] == '1'],
                'label': _("Trivial change"),
                })

        self.request.write('''
&nbsp;
<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
<label for="chkrstrip">%(label)s</label>
</p> ''' % {
            'checked': ('', 'checked')[form.get('rstrip',['0'])[0] == '1'],
            'label': _('Remove trailing whitespace from each line')
            })

        self.request.write("</p>")

        badwords_re = None
        if preview is not None:
            if SpellCheck and (
                    form.has_key('button_spellcheck') or
                    form.has_key('button_newwords')):
                badwords, badwords_re, msg = SpellCheck.checkSpelling(self, self.request, own_form=0)
                self.request.write("<p>%s</p>" % msg)
        self.request.write('</fieldset>')
        self.request.write("</form>")
        

        if preview is not None:
            if staytop:
                content_id = 'previewbelow'
            else:
                content_id = 'preview'
            self.send_page(self.request, content_id=content_id, content_only=1,
                           hilite_re=badwords_re)

        self.request.write(self.request.formatter.endContent()) # end content div
        wikiutil.send_footer(self.request, self.page_name)
Ejemplo n.º 2
0
    def sendEditor(self, **kw):
        """ Send the editor form page.

        @keyword preview: if given, show this text in preview mode
        @keyword staytop: don't go to #preview
        @keyword comment: comment field (when preview is true)
        """
        from MoinMoin import i18n
        from MoinMoin.action import SpellCheck

        request = self.request
        form = request.form
        _ = self._

        raw_body = ''
        msg = None
        conflict_msg = None
        edit_lock_message = None
        preview = kw.get('preview', None)
        staytop = kw.get('staytop', 0)

        # check edit permissions
        if not request.user.may.write(self.page_name):
            msg = _('You are not allowed to edit this page.')
        elif not self.isWritable():
            msg = _('Page is immutable!')
        elif self.rev:
            # Trying to edit an old version, this is not possible via
            # the web interface, but catch it just in case...
            msg = _('Cannot edit old revisions!')
        else:
            # try to acquire edit lock
            ok, edit_lock_message = self.lock.acquire()
            if not ok:
                # failed to get the lock
                if preview is not None:
                    edit_lock_message = _('The lock you held timed out. Be prepared for editing conflicts!'
                        ) + "<br>" + edit_lock_message
                else:
                    msg = edit_lock_message

        # Did one of the prechecks fail?
        if msg:
            request.theme.add_msg(msg, "error")
            self.send_page()
            return

        # Emit http_headers after checks (send_page)
        request.disableHttpCaching(level=2)

        # check if we want to load a draft
        use_draft = None
        if 'button_load_draft' in form:
            wanted_draft_timestamp = int(form.get('draft_ts', '0'))
            if wanted_draft_timestamp:
                draft = self._load_draft()
                if draft is not None:
                    draft_timestamp, draft_rev, draft_text = draft
                    if draft_timestamp == wanted_draft_timestamp:
                        use_draft = draft_text

        # Check for draft / normal / preview submit
        if use_draft is not None:
            title = _('Draft of "%(pagename)s"')
            # Propagate original revision
            rev = int(form['draft_rev'])
            self.set_raw_body(use_draft, modified=1)
            preview = use_draft
        elif preview is None:
            title = _('Edit "%(pagename)s"')
        else:
            title = _('Preview of "%(pagename)s"')
            # Propagate original revision
            rev = request.rev
            self.set_raw_body(preview, modified=1)

        # send header stuff
        lock_timeout = self.lock.timeout / 60
        lock_page = wikiutil.escape(self.page_name, quote=1)
        lock_expire = _("Your edit lock on %(lock_page)s has expired!") % {'lock_page': lock_page}
        lock_mins = _("Your edit lock on %(lock_page)s will expire in # minutes.") % {'lock_page': lock_page}
        lock_secs = _("Your edit lock on %(lock_page)s will expire in # seconds.") % {'lock_page': lock_page}

        # get request parameters
        try:
            text_rows = int(form['rows'])
        except StandardError:
            text_rows = self.cfg.edit_rows
            if request.user.valid:
                text_rows = int(request.user.edit_rows)

        if preview is not None:
            # Check for editing conflicts
            if not self.exists():
                # page does not exist, are we creating it?
                if rev:
                    conflict_msg = _('Someone else deleted this page while you were editing!')
            elif rev != self.current_rev():
                conflict_msg = _('Someone else changed this page while you were editing!')
                if self.mergeEditConflict(rev):
                    conflict_msg = _("""Someone else saved this page while you were editing!
Please review the page and save then. Do not save this page as it is!""")
                    rev = self.current_rev()
            if conflict_msg:
                # We don't show preview when in conflict
                preview = None

        elif self.exists():
            # revision of existing page
            rev = self.current_rev()
        else:
            # page creation
            rev = 0

        self.setConflict(bool(conflict_msg))

        # Page editing is done using user language
        request.setContentLanguage(request.lang)

        # Get the text body for the editor field.
        # TODO: what about deleted pages? show the text of the last revision or use the template?
        if preview is not None:
            raw_body = self.get_raw_body()
            if use_draft:
                request.write(_("[Content loaded from draft]"), '<br>')
        elif self.exists():
            # If the page exists, we get the text from the page.
            # TODO: maybe warn if template argument was ignored because the page exists?
            raw_body = self.get_raw_body()
        elif 'template' in request.values:
            # If the page does not exist, we try to get the content from the template parameter.
            template_page = wikiutil.unquoteWikiname(request.values['template'])
            template_page_escaped = wikiutil.escape(template_page)
            if request.user.may.read(template_page):
                raw_body = Page(request, template_page).get_raw_body()
                if raw_body:
                    request.write(_("[Content of new page loaded from %s]") % (template_page_escaped, ), '<br>')
                else:
                    request.write(_("[Template %s not found]") % (template_page_escaped, ), '<br>')
            else:
                request.write(_("[You may not read %s]") % (template_page_escaped, ), '<br>')

        # Make backup on previews - but not for new empty pages
        if not use_draft and preview and raw_body:
            self._save_draft(raw_body, rev)

        draft_message = None
        loadable_draft = False
        if preview is None:
            draft = self._load_draft()
            if draft is not None:
                draft_timestamp, draft_rev, draft_text = draft
                if draft_text != raw_body:
                    loadable_draft = True
                    page_rev = rev
                    draft_timestamp_str = request.user.getFormattedDateTime(draft_timestamp)
                    draft_message = _(u"'''<<BR>>Your draft based on revision %(draft_rev)d (saved %(draft_timestamp_str)s) can be loaded instead of the current revision %(page_rev)d by using the load draft button - in case you lost your last edit somehow without saving it.''' A draft gets saved for you when you do a preview, cancel an edit or unsuccessfully save.", wiki=True, percent=True) % locals()

        # Setup status message
        status = [kw.get('msg', ''), conflict_msg, edit_lock_message, draft_message]
        status = [msg for msg in status if msg]
        status = ' '.join(status)
        status = Status(request, content=status)

        request.theme.add_msg(status, "error")
        request.theme.send_title(
            title % {'pagename': self.split_title(), },
            page=self,
            html_head=self.lock.locktype and (
                PageEditor._countdown_js % {
                     'countdown_script': request.theme.externalScript('countdown'),
                     'lock_timeout': lock_timeout,
                     'lock_expire': lock_expire,
                     'lock_mins': lock_mins,
                     'lock_secs': lock_secs,
                    }) or '',
            editor_mode=1,
            allow_doubleclick=1,
        )

        request.write(request.formatter.startContent("content"))

        # Generate default content for new pages
        if not raw_body:
            raw_body = _('Describe %s here.') % (self.page_name, )

        # send form
        request.write('<form id="editor" method="post" action="%s#preview">' % (
                request.href(self.page_name)
            ))

        # yet another weird workaround for broken IE6 (it expands the text
        # editor area to the right after you begin to type...). IE sucks...
        # http://fplanque.net/2003/Articles/iecsstextarea/
        request.write('<fieldset style="border:none;padding:0;">')

        request.write(unicode(html.INPUT(type="hidden", name="action", value="edit")))

        # Send revision of the page our edit is based on
        request.write('<input type="hidden" name="rev" value="%d">' % (rev, ))

        # Add src format (e.g. 'wiki') into a hidden form field, so that
        # we can load the correct converter after POSTing.
        request.write('<input type="hidden" name="format" value="%s">' % self.pi['format'])

        # Create and send a ticket, so we can check the POST
        request.write('<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket(request))

        # Save backto in a hidden input
        backto = request.values.get('backto')
        if backto:
            request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))

        # button bar
        button_spellcheck = '<input class="button" type="submit" name="button_spellcheck" value="%s">' % _('Check Spelling')

        save_button_text = _('Save Changes')
        cancel_button_text = _('Cancel')

        if self.cfg.page_license_enabled:
            request.write('<p><em>', _(
"""By hitting '''%(save_button_text)s''' you put your changes under the %(license_link)s.
If you don't want that, hit '''%(cancel_button_text)s''' to cancel your changes.""", wiki=True) % {
                'save_button_text': save_button_text,
                'cancel_button_text': cancel_button_text,
                'license_link': wikiutil.getLocalizedPage(request, self.cfg.page_license_page).link_to(request),
            }, '</em></p>')

        request.write('''
<input class="button" type="submit" name="button_save" value="%s">
<input class="button" type="submit" name="button_preview" value="%s">
<input class="button" type="submit" name="button_switch" value="%s">
''' % (save_button_text, _('Preview'), _('Text mode'), ))

        if loadable_draft:
            request.write('''
<input class="button" type="submit" name="button_load_draft" value="%s" onClick="flgChange = false;">
<input type="hidden" name="draft_ts" value="%d">
<input type="hidden" name="draft_rev" value="%d">
''' % (_('Load Draft'), draft_timestamp, draft_rev))

        request.write('''
%s
<input class="button" type="submit" name="button_cancel" value="%s">
<input type="hidden" name="editor" value="gui">
''' % (button_spellcheck, cancel_button_text, ))
        if self.cfg.mail_enabled:
            request.write('''
<script type="text/javascript">
    function toggle_trivial(CheckedBox)
    {
        TrivialBoxes = document.getElementsByName("trivial");
        for (var i = 0; i < TrivialBoxes.length; i++)
            TrivialBoxes[i].checked = CheckedBox.checked;
    }
</script>
&nbsp;
<input type="checkbox" name="trivial" id="chktrivialtop" value="1" %(checked)s onclick="toggle_trivial(this)">
<label for="chktrivialtop">%(label)s</label>
''' % {
          'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
          'label': _("Trivial change"),
       })

        from MoinMoin.security.textcha import TextCha
        request.write(TextCha(request).render())

        self.sendconfirmleaving() # TODO update state of flgChange to make this work, see PageEditor

        # Add textarea with page text
        lang = self.pi.get('language', request.cfg.language_default)
        contentlangdirection = i18n.getDirection(lang) # 'ltr' or 'rtl'
        uilanguage = request.lang
        url_prefix_static = request.cfg.url_prefix_static
        url_prefix_local = request.cfg.url_prefix_local
        wikipage = wikiutil.quoteWikinameURL(self.page_name)
        fckbasepath = request.cfg.url_prefix_fckeditor
        wikiurl = request.script_root + '/'
        themepath = '%s/%s' % (url_prefix_static, request.theme.name)
        smileypath = themepath + '/img'
        # auto-generating a list for SmileyImages does NOT work from here!
        text_rows = int(request.user.edit_rows)
        if not text_rows:
            # if no specific value is given for editor height, but 0, we
            # compute the rows from the raw_body line count plus some
            # extra rows for adding new text in the editor. Maybe this helps
            # with the "double slider" usability issue, esp. for devices like
            # the iphone where you can't operate both sliders.
            current_rows = len(raw_body.split('\n'))
            text_rows = max(10, int(current_rows * 1.5))
        editor_size = text_rows * 22 # 22 height_pixels/line
        word_rule = self.word_rule()

        request.write("""
<script type="text/javascript" src="%(fckbasepath)s/fckeditor.js"></script>
<script type="text/javascript">
<!--
    var oFCKeditor = new FCKeditor( 'savetext', '100%%', %(editor_size)s, 'MoinDefault' ) ;
    oFCKeditor.BasePath= '%(fckbasepath)s/' ;
    oFCKeditor.Config['WikiBasePath'] = '%(wikiurl)s' ;
    oFCKeditor.Config['WikiPage'] = '%(wikipage)s' ;
    oFCKeditor.Config['PluginsPath'] = '%(url_prefix_local)s/applets/moinFCKplugins/' ;
    oFCKeditor.Config['CustomConfigurationsPath'] = '%(url_prefix_local)s/applets/moinfckconfig.js'  ;
    oFCKeditor.Config['WordRule'] = %(word_rule)s ;
    oFCKeditor.Config['SmileyPath'] = '%(smileypath)s/' ;
    oFCKeditor.Config['EditorAreaCSS'] = '%(themepath)s/css/common.css' ;
    oFCKeditor.Config['SkinPath'] = '%(fckbasepath)s/editor/skins/silver/' ;
    oFCKeditor.Config['AutoDetectLanguage'] = false ;
    oFCKeditor.Config['DefaultLanguage'] = '%(uilanguage)s' ;
    oFCKeditor.Config['ContentLangDirection']  = '%(contentlangdirection)s' ;
    oFCKeditor.Value= """ % locals())

        from MoinMoin.formatter.text_gedit import Formatter
        self.formatter = Formatter(request)
        self.formatter.page = self
        output = request.redirectedOutput(self.send_page_content, request, raw_body, format=self.pi['format'], do_cache=False)
        output = repr(output)
        if output[0] == 'u':
            output = output[1:]
        request.write(output)
        request.write(""" ;
    oFCKeditor.Create() ;
//-->
</script>
""")
        request.write("<p>")
        request.write(_("Comment:"),
            ' <input id="editor-comment" type="text" name="comment" value="%s" size="80" maxlength="200">' % (
                wikiutil.escape(kw.get('comment', ''), 1), ))
        request.write("</p>")

        # Category selection
        filterfn = self.cfg.cache.page_category_regexact.search
        cat_pages = request.rootpage.getPageList(filter=filterfn)
        cat_pages.sort()
        cat_pages = [wikiutil.pagelinkmarkup(p) for p in cat_pages]
        cat_pages.insert(0, ('', _('<No addition>')))
        request.write("<p>")
        request.write(_('Add to: %(category)s') % {
            'category': unicode(web.makeSelection('category', cat_pages)),
        })
        if self.cfg.mail_enabled:
            request.write('''
&nbsp;
<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s onclick="toggle_trivial(this)">
<label for="chktrivial">%(label)s</label> ''' % {
                'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
                'label': _("Trivial change"),
                })

        request.write('''
&nbsp;
<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
<label for="chkrstrip">%(label)s</label>
</p> ''' % {
            'checked': ('', 'checked')[form.get('rstrip', '0') == '1'],
            'label': _('Remove trailing whitespace from each line')
            })

        request.write("</p>")

        badwords_re = None
        if preview is not None:
            if 'button_spellcheck' in form or 'button_newwords' in form:
                badwords, badwords_re, msg = SpellCheck.checkSpelling(self, request, own_form=0)
                request.write("<p>%s</p>" % msg)
        request.write('</fieldset>')
        request.write("</form>")

        if preview is not None:
            if staytop:
                content_id = 'previewbelow'
            else:
                content_id = 'preview'
            self.send_page(content_id=content_id, content_only=1, hilite_re=badwords_re)

        request.write(request.formatter.endContent()) # end content div
        request.theme.send_footer(self.page_name)
        request.theme.send_closing_html()
Ejemplo n.º 3
0
    def sendEditor(self, **kw):
        """
        Send the editor form page.

        @keyword preview: if given, show this text in preview mode
        @keyword staytop: don't go to #preview
        @keyword comment: comment field (when preview is true)
        """
        from MoinMoin import i18n
        try:
            from MoinMoin.action import SpellCheck
        except ImportError:
            SpellCheck = None

        form = self.request.form
        _ = self._
        self.request.http_headers(self.request.nocache)

        msg = None
        conflict_msg = None
        edit_lock_message = None
        preview = kw.get('preview', None)
        emit_anchor = not kw.get('staytop', 0)

        from MoinMoin.formatter.text_html import Formatter
        self.request.formatter = Formatter(self.request, store_pagelinks=1)

        # check edit permissions
        if not self.request.user.may.write(self.page_name):
            msg = _('You are not allowed to edit this page.')
        elif not self.isWritable():
            msg = _('Page is immutable!')
        elif self.rev:
            # Trying to edit an old version, this is not possible via
            # the web interface, but catch it just in case...
            msg = _('Cannot edit old revisions!')
        else:
            # try to acquire edit lock
            ok, edit_lock_message = self.lock.aquire()
            if not ok:
                # failed to get the lock
                if preview is not None:
                    edit_lock_message = _('The lock you held timed out, be prepared for editing conflicts!'
                        ) + "<br>" + edit_lock_message
                else:
                    msg = edit_lock_message

        # Did one of the prechecks fail?
        if msg:
            self.send_page(self.request, msg=msg)
            return

        # Check for preview submit
        if preview is None:
            title = _('Edit "%(pagename)s"')
        else:
            title = _('Preview of "%(pagename)s"')
            self.set_raw_body(preview, modified=1)

        # send header stuff
        lock_timeout = self.lock.timeout / 60
        lock_page = wikiutil.escape(self.page_name, quote=1)
        lock_expire = _("Your edit lock on %(lock_page)s has expired!") % {'lock_page': lock_page}
        lock_mins = _("Your edit lock on %(lock_page)s will expire in # minutes.") % {'lock_page': lock_page}
        lock_secs = _("Your edit lock on %(lock_page)s will expire in # seconds.") % {'lock_page': lock_page}
                
        # get request parameters
        try:
            text_rows = int(form['rows'][0])
        except StandardError:
            text_rows = self.cfg.edit_rows
            if self.request.user.valid:
                text_rows = int(self.request.user.edit_rows)

        if preview is not None:
            # Propagate original revision
            rev = int(form['rev'][0])
            
            # Check for editing conflicts
            if not self.exists():
                # page does not exist, are we creating it?
                if rev:
                    conflict_msg = _('Someone else deleted this page while you were editing!')
            elif rev != self.current_rev():
                conflict_msg = _('Someone else changed this page while you were editing!')
                if self.mergeEditConflict(rev):
                    conflict_msg = _("""Someone else saved this page while you were editing!
Please review the page and save then. Do not save this page as it is!
Have a look at the diff of %(difflink)s to see what has been changed.""") % {
                        'difflink': self.link_to(self.request,
                                                 querystr='action=diff&rev=%d' % rev)
                        }
                    rev = self.current_rev()
            if conflict_msg:
                # We don't show preview when in conflict
                preview = None
                
        elif self.exists():
            # revision of existing page
            rev = self.current_rev()
        else:
            # page creation
            rev = 0

        # Page editing is done using user language
        self.request.setContentLanguage(self.request.lang)

        # Setup status message
        status = [kw.get('msg', ''), conflict_msg, edit_lock_message]
        status = [msg for msg in status if msg]
        status = ' '.join(status)
        status = Status(self.request, content=status)
        
        wikiutil.send_title(self.request,
            title % {'pagename': self.split_title(self.request),},
            page=self,
            pagename=self.page_name, msg=status,
            body_onload=self.lock.locktype and 'countdown()' or '', # broken / bug in Mozilla 1.5, when using #preview
            html_head=self.lock.locktype and (
                _countdown_js % {
                     'lock_timeout': lock_timeout,
                     'lock_expire': lock_expire,
                     'lock_mins': lock_mins,
                     'lock_secs': lock_secs,
                    }) or ''
        )
        
        self.request.write(self.request.formatter.startContent("content"))
        
        # get the text body for the editor field
        if form.has_key('template'):
            # "template" parameter contains the name of the template page
            template_page = wikiutil.unquoteWikiname(form['template'][0])
            if self.request.user.may.read(template_page):
                raw_body = Page(self.request, template_page).get_raw_body()
                if raw_body:
                    self.request.write(_("[Content of new page loaded from %s]") % (template_page,), '<br>')
                else:
                    self.request.write(_("[Template %s not found]") % (template_page,), '<br>')
            else:
                raw_body = ''
                self.request.write(_("[You may not read %s]") % (template_page,), '<br>')
        else:
            raw_body = self.get_raw_body()

        # send text above text area
        template_param = ''
        if form.has_key('template'):
            template_param = '&amp;template=' + form['template'][0]
        self.request.write('<p>')
        self.request.write(wikiutil.getSysPage(self.request, 'HelpOnFormatting').link_to(self.request))
        self.request.write(" | ", wikiutil.getSysPage(self.request, 'InterWiki').link_to(self.request))
        if preview is not None and emit_anchor:
            self.request.write(' | <a href="#preview">%s</a>' % _('Skip to preview'))
        self.request.write(' ')
        self.request.write(_('[current page size \'\'\'%(size)d\'\'\' bytes]') % {'size': self.size()})
        self.request.write('</p>')
        
        # send form
        self.request.write('<form id="editor" method="post" action="%s/%s#preview">' % (
            self.request.getScriptname(),
            wikiutil.quoteWikinameURL(self.page_name),
            ))

        # yet another weird workaround for broken IE6 (it expands the text
        # editor area to the right after you begin to type...). IE sucks...
        # http://fplanque.net/2003/Articles/iecsstextarea/
        self.request.write('<fieldset style="border:none;padding:0;">')
        
        self.request.write('<p>')
        self.request.write(unicode(html.INPUT(type="hidden", name="action", value="savepage")))

        # Save backto in a hidden input
        backto = form.get('backto', [None])[0]
        if backto:
            self.request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))

        # Make backup on previews - but not for new empty pages
        if preview and raw_body:
            self._make_backup(raw_body)

        # Generate default content for new pages
        if not raw_body:
            raw_body = _('Describe %s here.') % (self.page_name,)

        # Send revision of the page our edit is based on
        self.request.write('<input type="hidden" name="rev" value="%d">' % (rev,))

        # Add textarea with page text

        # TODO: currently self.language is None at this point. We have
        # to do processing instructions parsing earlier, or move page
        # language into meta file.
        lang = self.language or self.request.cfg.default_lang

        self.request.write(
            u'<textarea id="editor-textarea" name="savetext" lang="%(lang)s" dir="%(dir)s"'
            u' rows="%(rows)d">' % {
            'lang': lang,
            'dir': i18n.getDirection(lang),
            'rows': text_rows,
            }
            )
        self.request.write(wikiutil.escape(raw_body))
        self.request.write(u'</textarea>')

        self.request.write('</p>')

        self.request.write("<p>", _("Optional comment about this change"),
            '<br><input id="editor-comment" type="text" name="comment" value="%s" maxlength="80"></p>' % (
                wikiutil.escape(kw.get('comment', ''), 1), ))

        # Category selection
        filter = re.compile(self.cfg.page_category_regex, re.UNICODE).search
        cat_pages = self.request.rootpage.getPageList(filter=filter)
        cat_pages.sort()
        cat_pages = [wikiutil.pagelinkmarkup(p) for p in cat_pages]
        cat_pages.insert(0, ('', _('<No addition>', formatted=False)))
        self.request.write("<p>", _('Make this page belong to category %(category)s') % {
            'category': unicode(util.web.makeSelection('category', cat_pages)),
        })

        # button bar
        button_spellcheck = (SpellCheck and
            '<input type="submit" name="button_spellcheck" value="%s">'
                % _('Check Spelling')) or ''

        save_button_text = _('Save Changes')
        cancel_button_text = _('Cancel')
        
        self.request.write("</p>")
            
        if self.cfg.page_license_enabled:
            self.request.write('<p><em>', _(
"""By hitting '''%(save_button_text)s''' you put your changes under the %(license_link)s.
If you don't want that, hit '''%(cancel_button_text)s''' to cancel your changes.""") % {
                'save_button_text': save_button_text,
                'cancel_button_text': cancel_button_text,
                'license_link': wikiutil.getSysPage(self.request, self.cfg.page_license_page).link_to(self.request),
            }, '</em></p>')

        self.request.write('''
<p>
<input type="submit" name="button_save" value="%s">
<input type="submit" name="button_preview" value="%s"> %s
<input type="submit" name="button_cancel" value="%s">
</p>
<p>
''' % (save_button_text, _('Preview'), button_spellcheck, cancel_button_text,))

        if self.cfg.mail_smarthost:
            self.request.write('''
<input type="checkbox" name="trivial" value="1" %(checked)s>
<label>%(label)s</label> ''' % {
                'checked': ('', 'checked')[form.get('trivial',['0'])[0] == '1'],
                'label': _("Trivial change"),
                })

        self.request.write('''
<input type="checkbox" name="rstrip" value="1" %(checked)s>
<label>%(label)s</label>
</p> ''' % {
            'checked': ('', 'checked')[form.get('rstrip',['0'])[0] == '1'],
            'label': _('Remove trailing whitespace from each line')
            })

        badwords_re = None
        if preview is not None:
            if SpellCheck and (
                    form.has_key('button_spellcheck') or
                    form.has_key('button_newwords')):
                badwords, badwords_re, msg = SpellCheck.checkSpelling(self, self.request, own_form=0)
                self.request.write("<p>%s</p>" % msg)
        self.request.write('</fieldset>')
        self.request.write("</form>")
        
        # QuickHelp originally by Georg Mischler <*****@*****.**>
        self.request.write('<hr>\n<dl>' + _(""" Emphasis:: [[Verbatim('')]]''italics''[[Verbatim('')]]; [[Verbatim(''')]]'''bold'''[[Verbatim(''')]]; [[Verbatim(''''')]]'''''bold italics'''''[[Verbatim(''''')]]; [[Verbatim('')]]''mixed ''[[Verbatim(''')]]'''''bold'''[[Verbatim(''')]] and italics''[[Verbatim('')]]; [[Verbatim(----)]] horizontal rule.
 Headings:: [[Verbatim(=)]] Title 1 [[Verbatim(=)]]; [[Verbatim(==)]] Title 2 [[Verbatim(==)]]; [[Verbatim(===)]] Title 3 [[Verbatim(===)]];   [[Verbatim(====)]] Title 4 [[Verbatim(====)]]; [[Verbatim(=====)]] Title 5 [[Verbatim(=====)]].
 Lists:: space and one of: * bullets; 1., a., A., i., I. numbered items; 1.#n start numbering at n; space alone indents.
 Links:: [[Verbatim(JoinCapitalizedWords)]]; [[Verbatim(["brackets and double quotes"])]]; url; [url]; [url label].
 Tables:: || cell text |||| cell text spanning 2 columns ||;    no trailing white space allowed after tables or titles.""")
 + '</dl>')

        if preview is not None:
            self.send_page(self.request, content_id='preview', content_only=1,
                           hilite_re=badwords_re)

        self.request.write(self.request.formatter.endContent()) # end content div
        self.request.theme.emit_custom_html(self.cfg.page_footer1)
        self.request.theme.emit_custom_html(self.cfg.page_footer2)