Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Steven Wilber 103 posts 98 karma points
    Feb 23, 2010 @ 14:16
    Steven Wilber
    0

    Adding a class to the first HTML tag automatically.

    I don't know if this will help anyone in the future, but since I've just spent some time working on this I thought that I would record it for posterity.

    Problem

    IE6 does not support the CSS pseudo selector of first-child. In some situations it is good to be able to identify to the first item on a page to, for example, remove the top margin/padding. There are various javascripty solutions to this, but I preferred to have the first tag assigned a class so that I didn't have to bother with browser compatibility issues, esp. for my current client where we have to assume that there is no JavaScript.

    Solution

    Using an event, look out for the datatype in question and then using regular expressions clear out the old class value (in case it has moved down the page) and add in the new class value.

    Now my regular expressions are a little rough around the edges, but the solution is valid, which I'm happy about (if anyone has any better regexp, please let me know).

    The event is simple as below (apologies for the VB.Net, client requirement)

        Private Sub UpdateSetContentClassFirst(ByVal sender As Document, ByVal e As SaveEventArgs)
    'search for richtext editor fields and add the value 'first' to the class of the first tag

    Dim excludedDocTypes As String = ConfigurationManager.AppSettings.Get("EnableMediaBeforeSaveHandler")
    Dim dataTypeNames As String = ConfigurationManager.AppSettings.Get("UpdateSetContentClassFirstDataTypeNames")
    Dim className As String = ConfigurationManager.AppSettings.Get("UpdateSetContentClassFirstClassName")
    Dim propertyValue As String = Nothing

    'tidy up and wrap the strings
    If Not String.IsNullOrEmpty(excludedDocTypes) Then excludedDocTypes = String.Concat("|", excludedDocTypes.Replace("| ", "|").Replace(" |", "|"), "|")
    If Not String.IsNullOrEmpty(dataTypeNames) Then dataTypeNames = String.Concat("|", dataTypeNames.Replace("| ", "|").Replace(" |", "|"), "|")

    If Not excludedDocTypes.Contains("|" & sender.ContentType.Alias & "|") Then

    'first strip out any existing instances of the class attribute
    Dim patternRemove As String = "(?<pre><\w*\s.*?class=(?<open>('|"")).*?)((\s+|(?<=\k<open>))" & className & "(\s+|(?=\k<open>)))(?<post>.*?\k<open>)"
    Dim replaceRemove As String = "${pre} ${post}"

    'run the regular expression to insert the class attribute
    Dim patternInsert As String = "\A\s*(<(?<tag>\w*\s)\s*class=(?<open>('|""))(?<class>.*?)\k<open>\s*(?<post>.*?)>|<(?<tag>\w*\s)\s*(?<pre>.*?\s)class=(?<open>('|""))(?<class>.*?)\k<open>(?<post>\s.*?)>|<(?<tag>\w*\s)(?<pre>.*?)>|<(?<tag>\w*)>)"
    Dim replaceInsert As String = "<${tag} class=""${class} " & className & """ ${pre}${post}>"

    'loop through the properties looking for those of a certain type
    For Each [prop] As [Property] In sender.getProperties
    'if of a suitable type
    If dataTypeNames.Contains("|" & prop.PropertyType.DataTypeDefinition.DataType.DataTypeName & "|") Then
    propertyValue = prop.Value.ToString()
    propertyValue = Regex.Replace(propertyValue, patternRemove, replaceRemove)
    propertyValue = Regex.Replace(propertyValue, patternInsert, replaceInsert)
    prop.Value = propertyValue
    End If
    Next
    End If
    End Sub

    The string tidying up section at the top is just to cope with me putting in spaces in the future in the config values. I've had to use | instead of comma as some of the data type names have commas in them.

    The values for excluded document types and data type names to look out for are configured in the web.config as is the setting to turn off the event if required.

    So that's it really.

    Hopefully that helps someone in future, possibly me.

    Cheers

    Steve

Please Sign in or register to post replies

Write your reply to:

Draft