[Rt-devel] Re: [rt-users] maintainably tagging custom fields for CSS

Nicholas Clark nick at ccl4.org
Tue Aug 21 12:54:26 EDT 2007


On Fri, Aug 17, 2007 at 09:49:52AM +0200, Espen Wiborg wrote:
> Nicholas Clark <nick at ccl4.org> writes:

> > Mmm. Are they serious that upper case ASCII is only allowed in nmstart and
> > not nmchar?
> 
> I should think not. :)
> 
> And, indeed, http://www.w3.org/TR/REC-CSS2/grammar.html section D.2
> includes the crucial '%option case-insensitive'.  IIUC, CSS doesn't
> really care about case, except in quoted strings.

Thanks.

I've attached a suggested implementation, as a diff from 3.6-RELEASE

Nicholas Clark
-------------- next part --------------
Index: html/Ticket/Elements/EditCustomFields
===================================================================
--- html/Ticket/Elements/EditCustomFields	(revision 8671)
+++ html/Ticket/Elements/EditCustomFields	(working copy)
@@ -54,8 +54,10 @@
 <tr>
 % }
 <td width="50%">
+% my $class = RT::Interface::Web::SanitizeCSSIdentifier('CF-Edit-' . $CustomField->Name);
+% $class = qq{ class="$class"} if length $class;
 <table>
-  <tr id="CF-<%$CustomField->id%>-EditRow">
+  <tr id="CF-<%$CustomField->id%>-EditRow"<% $class | n %>>
     <td class="labeltop">
       <b><%$CustomField->Name%></b><br />
       <i><%$CustomField->FriendlyType%></i>
Index: html/Elements/ShowCustomFields
===================================================================
--- html/Elements/ShowCustomFields	(revision 8663)
+++ html/Elements/ShowCustomFields	(working copy)
@@ -49,7 +49,9 @@
 % while ( my $CustomField = $CustomFields->Next ) {
 % my $Values = $Object->CustomFieldValues( $CustomField->Id );
 % my $count = $Values->Count;
-  <tr id="CF-<%$CustomField->id%>-ShowRow">
+% my $class = RT::Interface::Web::SanitizeCSSIdentifier('CF-Show-' . $CustomField->Name);
+% $class = qq{ class="$class"} if length $class;
+  <tr id="CF-<%$CustomField->id%>-ShowRow"<% $class | n %>>
     <td class="label"><% $CustomField->Name %>:</td>
     <td class="value">
 % unless ( $count ) {
Index: lib/t/regression/28-rt-interface-web.t
===================================================================
--- lib/t/regression/28-rt-interface-web.t	(revision 0)
+++ lib/t/regression/28-rt-interface-web.t	(revision 0)
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Test::More;
+
+my @tests = (['Pie', 'Pie', 'ASCII'],
+	     ['Square pie', 'Square-pie', 'spaces'],
+	     ['Mmm, pie', 'Mmm-pie', 'comma'],
+	     ['  gap', 'gap', 'leading space'],
+	     [' 0a', 'a', 'leading illegal'],
+	     [' a0', 'a0', 'trailing illegal'],
+	     [' 0a:0 ', 'a0-', 'many illegals'],
+	     ["\xA3!", "\xA3", '8 bit characters are fine'],
+	     ["_\x{100}", "\x{100}", 'Unicode characters are fine'],
+	     );
+
+plan ( tests => 1 + @tests );
+
+use_ok('RT::Interface::Web');
+
+foreach ( @tests ) {
+    my ($in, $expect, $name) = @$_;
+    is( RT::Interface::Web::SanitizeCSSIdentifier ( $in ), $expect, $name );
+}
Index: lib/RT/Interface/Web.pm
===================================================================
--- lib/RT/Interface/Web.pm	(revision 8663)
+++ lib/RT/Interface/Web.pm	(working copy)
@@ -118,6 +118,48 @@
 
 # }}}
 
+# {{{ SanitizeCSSIdentifier
+
+=head2 SanitizeCSSIdentifier STRING
+
+Sanitizes a string to create a valid CSS identifier for a class, by removing
+all disallowed characters. (Whitespace, most ASCII symbols, and leading digits)
+The assumption is that the STRING is the text description of something, such as
+a custom field, and hence will contain sufficient meaningful text to be
+distinct from all others.
+
+=cut
+
+sub SanitizeCSSIdentifier {
+    my $name = shift;
+
+    # From http://www.w3.org/TR/REC-CSS2/syndata.html#tokenization
+    # ident     {nmstart}{nmchar}*
+    # name      {nmchar}+
+    # nmstart   [a-zA-Z]|{nonascii}|{escape}
+    # nonascii  [^\0-\177]
+    # unicode   \\[0-9a-f]{1,6}[ \n\r\t\f]?
+    # escape    {unicode}|\\[ -~\200-\4177777]
+    # nmchar    [a-z0-9-]|{nonascii}|{escape}
+
+    # Whilst it would be legal to escape everything, I suspect that it's better
+    # to
+    # 1: convert spaces to - signs
+    # 2: strip out all the non-nmchar characters
+    # 3: strip off any leading non-nmstart characters
+    # and not escape anything else
+
+    $name =~ tr/ /-/;
+    # As I can't use an unbounded range \200-INF and then tr///c that, I have to
+    # manually invert - 0-9 A-Z a-z to the ranges below.
+    $name =~ tr!\0-,.-/:-@[-`{-\177!!d; # Sorry, broken for EBCDIC platforms
+    $name =~ s/^[-0-9]+//;
+
+    return $name;
+}
+
+# }}}
+
 # {{{ WebCanonicalizeInfo
 
 =head2 WebCanonicalizeInfo();


More information about the Rt-devel mailing list