Commits

Roger Haase committed 89563f0

rework auto-scroll edit textarea, support docbook, minor enhancements

  • Participants
  • Parent commits 16972ad

Comments (0)

Files changed (7)

         flaskg.current_lang = app.cfg.language_default
 
         setup_jinja_env()
+
+        # request.user_agent == '' if this is pytest
+        flaskg.add_lineno_attr = request.user_agent and flaskg.user.edit_on_doubleclick
     finally:
         flaskg.clock.stop('init')
 

MoinMoin/converter/_util.py

 
 from __future__ import absolute_import, division
 
-from flask import request
-from flask import g as flaskg
+try:
+    from flask import g as flaskg
+except ImportError:
+    # in case converters become an independent package
+    flaskg = None
 from emeraldtree import ElementTree as ET
 
 from MoinMoin.constants.misc import URI_SCHEMES
         """
         Add a custom attribute (data-lineno=nn) that will be used by Javascript to scroll edit textarea.
         """
-        if request.user_agent and flaskg.user.edit_on_doubleclick:
-            # this is not py.test and user has option to edit on doubleclick
-            # TODO: move the 2 lines above and 2 related import statements outside of the converters
-            # (this is needed for a standalone converter)
-            if self.last_lineno != self.iter_content.lineno:
-                # avoid adding same lineno to parent and multiple children or grand-children
-                elem.attrib[html.data_lineno] = self.iter_content.lineno
-                self.last_lineno = self.iter_content.lineno
+        if flaskg and flaskg.add_lineno_attr:
+                if self.last_lineno != self.iter_content.lineno:
+                    # avoid adding same lineno to parent and multiple children or grand-children
+                    elem.attrib[html.data_lineno] = self.iter_content.lineno
+                    self.last_lineno = self.iter_content.lineno
 
     def clear(self):
         del self._list[1:]

MoinMoin/converter/docbook_in.py

 import re
 
 from emeraldtree import ElementTree as ET
+try:
+    from flask import g as flaskg
+except ImportError:
+    # in case converters become an independent package
+    flaskg = None
 
 from MoinMoin import log
 logging = log.getLogger(__name__)
     pass
 
 
+def XML(text, parser=None):
+    """
+    Copied from EmeraldTree/tree.py to force use of local XMLParser class override.
+    """
+    if not parser:
+        parser = XMLParser(target=ET.TreeBuilder())
+    parser.feed(text)
+    return parser.close()
+
+
+class XMLParser(ET.XMLParser):
+    """
+    Override EmeraldTree/tree.py XMLParser class. Required to add auto-scroll textarea feature.
+
+    There is no need to subclass all tree.py classes and procedures with stubs because this
+    modified _start_list is only needed for the initial construction of the DOM when
+    flaskg.add_lineno_attr may be True.
+    """
+    def _start_list(self, tag, attrib_in):
+        elem = super(XMLParser, self)._start_list(tag, attrib_in)
+        if flaskg and flaskg.add_lineno_attr:
+            elem.attrib[html.data_lineno] = self._parser.CurrentLineNumber
+        return elem
+
+
 class Converter(object):
     """
     Converter application/docbook+xml -> x.moin.document
         # We will create an element tree from the DocBook content
         try:
             # XXX: The XML parser need bytestring.
-            tree = ET.XML(docbook_str.encode('utf-8'))
+            tree = XML(docbook_str.encode('utf-8'))  # using local XML override, not ET.XML
         except ET.ParseError as detail:
             return self.error(str(detail))
 
         """
         result = {}
         for key, value in element.attrib.iteritems():
-            if key.uri == xml and key.name in ['id', 'base', 'lang']:
+            if key.uri == xml and key.name in ['id', 'base', 'lang'] or key.name == 'data-lineno':
                 result[key] = value
         if result:
             # We clear standard_attribute, if ancestror attribute
         attrib[key] = "footnote"
         children = self.new(moin_page('note-body'), attrib={},
                             children=self.do_children(element, depth))
+        # must delete lineno because footnote will be placed near end of page and out of sequence
+        children._children[1].attrib.pop(html.data_lineno, None)
         return self.new(moin_page.note, attrib=attrib, children=[children])
 
     def visit_docbook_formalpara(self, element, depth):

MoinMoin/converter/include.py

                                 # get attributes from page node;
                                 # we expect {class: "moin-transclusion"; data-href: "http://some.org/somepage"}
                                 attrib = Attributes(ret).convert()
+                                # current elem will likely be replaced by container so we need to copy data-lineno attr
+                                if html.data_lineno in elem.attrib:
+                                    attrib[html.data_lineno] = elem.attrib[html.data_lineno]
                                 # make new div node to hold transclusion, copy children, and save in container
                                 div = ET.Element(moin_page.div, attrib=attrib, children=body[:])
                                 container.append(div)  # new_trans_ptr is index to this

MoinMoin/converter/rst_in.py

 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from flask import request
-from flask import g as flaskg
+try:
+    from flask import g as flaskg
+except ImportError:
+    # in case converters become an independent package
+    flaskg = None
 
 from MoinMoin import config
 from MoinMoin.util.iri import Iri
         pass
 
     def open_moin_page_node(self, mointree_element):
-        if request.user_agent and flaskg.user.edit_on_doubleclick:
-            # add data-lineno attribute for auto-scrolling edit textarea (user_agent is None when running tests)
+        if flaskg and flaskg.add_lineno_attr:
+            # add data-lineno attribute for auto-scrolling edit textarea
             if self.last_lineno < self.current_lineno:
                 mointree_element.attrib[html.data_lineno] = self.current_lineno
                 self.last_lineno = self.current_lineno

MoinMoin/items/content.py

 
     def _expand_document(self, doc):
         from MoinMoin.converter import default_registry as reg
+        flaskg.add_lineno_attr = False  # do not add data-lineno attr for transclusions, footnotes, etc.
         include_conv = reg.get(type_moin_document, type_moin_document, includes='expandall')
         macro_conv = reg.get(type_moin_document, type_moin_document, macros='expandall')
         link_conv = reg.get(type_moin_document, type_moin_document, links='extern')

MoinMoin/static/js/common.js

                 $('#moin-content').dblclick(function (e) {
                     // get clicked line number, save, and go to +modify page
                     lineno = findLineNo(e.target);
-                    sessionStorage.moinDoubleLineNo = lineno;
+                    if (lineno > 0 || $("*[data-lineno]").length > 0) {
+                        // do only if there were data-lineno attrs - do not give "you missed" message to html or image items
+                        sessionStorage.moinDoubleLineNo = lineno;
+
+
                     document.location = modifyButton.href;
                 });
             }