On Fri, Aug 17, 2007 at 09:49:52AM +0200, Espen Wiborg wrote:
> Nicholas Clark <[EMAIL PROTECTED]> 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
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-,.-/:[EMAIL PROTECTED]; # Sorry, broken for EBCDIC platforms
+    $name =~ s/^[-0-9]+//;
+
+    return $name;
+}
+
+# }}}
+
 # {{{ WebCanonicalizeInfo
 
 =head2 WebCanonicalizeInfo();
_______________________________________________
http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-users

Community help: http://wiki.bestpractical.com
Commercial support: [EMAIL PROTECTED]


Discover RT's hidden secrets with RT Essentials from O'Reilly Media. 
Buy a copy at http://rtbook.bestpractical.com

Reply via email to