Commits

Luke Plant committed 0b2a8e2

Introduced PresentationInfo class to clean up code

  • Participants
  • Parent commits c18928a

Comments (0)

Files changed (5)

File semanticeditor/media/semanticeditor/javascript/wymeditor/plugins/semantic/wymeditor.semantic.js

 		    // TODO name, value
 		    // TODO - tooltip with description
 		    // TODO event handlers
-		    self.optsbox.append("<div style=\"clear: left;\"><div><label><input type=\"checkbox\" value=\"\"> " + escapeHtml(item.name) + "</label></div></div>");
+		    self.optsbox.append("<div style=\"clear: left;\"><div><label><input type=\"checkbox\" value=\"\"> " + escapeHtml(item.verbose_name) + "</label></div></div>");
     });
 };
 

File semanticeditor/models.py

 from django.db import models
 
 class CssClass(models.Model):
-    class_name = models.CharField("CSS class name", max_length=255, unique=True,
+    name = models.CharField("CSS class name", max_length=255, unique=True,
                                   help_text="The name as it appears in the CSS file")
-    name = models.CharField("Name", max_length=255, blank=False, unique=True,
-                            help_text="User-visible name of the style.")
+    verbose_name = models.CharField("Human name", max_length=255, blank=False, unique=True,
+                                    help_text="User-visible name of the style.")
     description = models.TextField("Description", max_length=255, blank=True,
                                    help_text="This is displayed as a 'tooltip' "
                                    "when the user hovers over the name in the "

File semanticeditor/tests.py

 
 from django.test import TestCase
 from semanticeditor.utils import extract_headings, InvalidHtml, IncorrectHeadings, format_html, parse, get_parent, get_index, BadStructure, TooManyColumns, NEWROW, NEWCOL, extract_presentation
+from semanticeditor.utils.presentation import PresentationInfo, PresentationClass
+
+PC = PresentationClass
 
 class TestExtract(TestCase):
     def test_extract_headings(self):
     def test_rejects_duplicate_headings(self):
         self.assertRaises(IncorrectHeadings, extract_headings, "<h1>Hello</h1><h2>Hello</h2>")
 
+class TestPresentationInfo(TestCase):
+    def test_equality(self):
+        p1 = PresentationInfo(prestype="command", name="foo", verbose_name="blah")
+        p2 = PresentationInfo(prestype="command", name="foo")
+        p3 = PresentationInfo(prestype="command", name="bar")
+        self.assertEqual(p1, p2)
+        self.assertNotEqual(p2, p3)
+        self.assertEqual(set([p1]), set([p2]))
+
 class TestFormat(TestCase):
     def test_no_headings(self):
         html = "<p>Test</p>"
     def test_add_css_classes(self):
         html = "<h1>Hello <em>you</em></h1><h2>Hi</h2>"
         outh = "<div class=\"myclass\"><h1>Hello <em>you</em></h1><div class=\"c1 c2\"><h2>Hi</h2></div></div>"
-        self.assertEqual(outh, format_html(html, {'Hello you':['class:myclass'],
-                                                  'Hi':['class:c1', 'class:c2']}))
+        self.assertEqual(outh, format_html(html, {'Hello you':[PC('myclass')],
+                                                  'Hi':[PC('c1'), PC('c2')]}))
 
     def test_sanity_check_sections(self):
         html = "<h1>Hello</h1><blockquote><h2>Hi</h2></blockquote>"
 
 
 class TestExtractPresentation(TestCase):
-    def test_extract_style(self):
+    def test_extract_presentation(self):
         html = "<div class=\"foo\"><h1>Heading 1</h1><div class=\"bar baz\"><h2>Heading 2</h2></div></div>"
         pres = extract_presentation(html)
-        self.assertEqual({'Heading 1':set(['class:foo']),
-                          'Heading 2':set(['class:bar', 'class:baz'])
+        self.assertEqual({'Heading 1':set([PC('foo')]),
+                          'Heading 2':set([PC('bar'), PC('baz')])
                           }, pres)
 
     # Lazy method - assume that combine works and check the round-trip.
             "<h1>3</h1>" \
             "<h1>4</h1>"
 
-        presentation = {'1':set(['class:myclass1']),
+        presentation = {'1':set([PC('myclass1')]),
                         '2':set([]),
                         '2.1':set([NEWROW]),
                         '2.2':set([NEWCOL]),
                         '2.3':set([NEWROW]),
-                        '2.4':set([NEWCOL, 'class:myclass2']),
+                        '2.4':set([NEWCOL, PC('myclass2')]),
                         '3':set([NEWROW]),
                         '4':set([NEWCOL]),
                         }

File semanticeditor/utils/presentation.py

 ### Definitions ###
 
 headingdef = ['h1','h2','h3','h4','h5','h6']
-NEWROW = 'command:newrow'
-NEWCOL = 'command:newcolumn'
-
-
-NEWROW_detail = dict(class_name=NEWROW,
-                     name="New row",
-                     description="TODO")
-
-NEWCOL_detail = dict(class_name=NEWCOL,
-                     name="New column",
-                     description="TODO")
 
 MAXCOLS = 4
 COLUMNCLASS = 'col'
 ### Semantic editor functionality ###
 
 ## Presentation dictionary utilities
-def _pres_get_class(x):
-    return x[6:]
 
-def _pres_make_class(c):
-    return 'class:' + c
+class PresentationInfo(object):
+    """
+    Encapsulates a piece of presentation information.
+    """
+    def __init__(self, prestype=None, name=None, verbose_name="", description=""):
+        self.prestype = prestype
+        self.name = name
+        # The verbose_name and description are additional pieces of
+        # information that are only needed when the client is
+        # requesting a list of styles.  In other sitations these
+        # objects may not have these attributes filled in.
+        self.verbose_name = verbose_name
+        self.description = description
 
-def _pres_is_class(x):
-    return x.startswith('class:')
+    def __eq__(self, other):
+        return self.prestype == other.prestype and self.name == other.name
+
+    def __hash__(self):
+        return hash(self.prestype) ^ hash(self.name)
+
+    def __repr__(self):
+        return "PresentationInfo(prestype=\"%s\", name=\"%s\")" % (self.prestype, self.name)
+
+def PresentationClass(name, verbose_name="", description=""):
+    """
+    Shortcut for creating CSS classes
+    """
+    return PresentationInfo(prestype="class",  name=name,
+                            verbose_name=verbose_name, description=description)
+
+def PresentationCommand(name, verbose_name="", description=""):
+    """
+    Shortcut for creating commands
+    """
+    return PresentationInfo(prestype="command",  name=name,
+                            verbose_name=verbose_name, description=description)
+
+NEWROW = PresentationCommand('newrow',
+                             verbose_name = "New row",
+                             description = "TODO")
+
+NEWCOL = PresentationCommand('newcol',
+                             verbose_name = "New column",
+                             description = "TODO")
 
 ## General utilities
 
 
 ## Main functions and sub functions
 
-
 def extract_headings(content):
     """
     Extracts H1, H2, etc headings, and returns a list of tuples
         newdiv = wrap_elements_in_tag(parent, first_elem, last_elem, "div")
 
         # Apply css styles
-        classes = [_pres_get_class(s) for s in styleinfo[name] if _pres_is_class(s)]
+        classes = [s.name for s in styleinfo[name] if s.prestype == "class"]
         classes.sort()
         if classes:
             newdiv.set("class", " ".join(classes))
 
         # Section - extract classes
         for c in _get_classes_for_node(section_node):
-            pres[name].add(_pres_make_class(c))
+            pres[name].add(PresentationClass(c))
 
         # Parent/grandparent of section - newcol/newrow
         p = get_parent(root, section_node)

File semanticeditor/views.py

 from django.utils import simplejson
 from django.core.mail import mail_admins
 from django.utils.translation import ugettext as _
-from semanticeditor.utils import extract_headings, InvalidHtml, IncorrectHeadings, NEWROW_detail, NEWCOL_detail
+from semanticeditor.utils import extract_headings, InvalidHtml, IncorrectHeadings, NEWROW, NEWCOL, PresentationClass
 from semanticeditor.models import CssClass
 import sys
 
 
     return success(headings)
 
+
+def PI_to_dict(pi):
+    """
+    Converts a PresentationInfo to a dictionary
+    for use client side
+    """
+    return pi.__dict__
+
 @json_view
 def retrieve_styles(request):
-    retval = [NEWROW_detail, NEWCOL_detail]
-    retval += [dict(class_name = "class:" + c.class_name,
-                    name = c.name,
-                    description = c.description)
-               for c in CssClass.objects.all()]
-    return success(retval)
+    retval = [NEWROW, NEWCOL]
+    retval += [PresentationClass(c.name,
+                                 verbose_name=c.verbose_name,
+                                 description=c.description)
+               for c in CssClass.objects.all().order_by('verbose_name')]
+    return success(map(PI_to_dict,retval))