Welcome

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

What next?
1. Bookmark us with del.icio.us or Digg Us!
2. Subscribe to this site's RSS feed
3. Browse the site.
4. Post your own code snippets to the site!

Examine CSS selectors in JSP files

// Processe a directory of JSP source files, looks for regex matches, and reports on the number and location of matches. For detecting deprecated attributes in XHTML.

Uses Mail::Outlook to send an email. Requires you to click "ok" each time a notification is sent, but gets around firewalls.


#! /usr/bin/perl -w
use strict;
use Mail::Outlook 'Attach';    #Use Outlook for notification, since port 25 is blocked.

=item usage
for MyEcom Redesign:
cd /d X:\storm\main\webapps\neb\src\webapp\WEB-INF\jsp
find \( -name "*jsp" -o -name "*jspf" \) | xargs perl z:\noah\standards\cssSelector\csel.pl

for MyDev Redesign:
cd /d X:\storm\nw2.0\webapps\neb\src\webapp\WEB-INF\jsp
find \( -name "*jsp" -o -name "*jspf" \) | xargs perl z:\noah\standards\cssSelector\csel.pl
=cut

=item toDo
- do the whole find-pipe-xargs thing inside this script
--- check that we are searching the right directory
- exclude directories or files by regex
- name the output file after today's date
- if there is a previous output file, compare the failure counts in that file to the current failure count; and notify of the difference.
- make verbose command line option
- toggle "send email" from the command line
--- print the email body to STDOUT if not sending email
- with a command line switch, append to or replace the list of "send to" addresses
- optionally generate only ONE list, of all files that failed ANY test
- generate the report in a more readable format, like HTML
=cut

#valid Outlook addresses:
my $recipients = "MyDev Redesign Team;nsussman";


my (%longClass,  %digits, %cssPropName, %tooShort, %JSprotocol, %obtrusiveJS);
my $failed = 0;
my $warned = 0;
my $failCount = 0;
my $warnCount = 0;
my $failedLines = 0;
my $warnedLines = 0;
my $fileHasFailed = 0;
my $fileWasWarned = 0;
my $verbose = 1;
my $send_email = 1;
my $outfile = "z:\\Noah\\esCssRefactor\\CSS_best_practices_autoEvaluation.txt";
my $zipped_outfile = "z:\\Noah\\esCssRefactor\\CSS_best_practices_autoEvaluation.zip";
#my appname = "MyEcom Redesign";
my $appname = "MyDev Redesign";

checking_files:
foreach my $input_file (@ARGV) {

    open(FILE, $input_file) or next checking_files;

    $. = 0;
    $fileHasFailed = 0;
    $fileWasWarned = 0;

    while (<FILE>) {
#FAILURE CHECKS
	if (m/class=("[^"<]*(fnt|pad|mar|txt|teal|aqua)[^"<]*")/) {
	    $cssPropName{ $input_file } .= "ln:$.: $1\n        ";
            $failedLines++ unless ($failed == 1);
	    $failed = 1;
	}
	if (m/class=("[^"<]{1,2}(\s+[^"<]+)*")/) {
	    $tooShort{ $input_file } .= "ln:$.: $1\n        ";
            $failedLines++ unless ($failed == 1);
	    $failed = 1;
	}

	if (m/class=("[^"<]*\d\d[^"<]*")/) {
	    $digits{ $input_file } .= "ln:$.: $1\n        ";
            $failedLines++ unless ($failed == 1);
	    $failed = 1;
	}
	if (m/class=("([^"<]+\s){2,}[^<"]+")/) {
	    $longClass{ $input_file } .= "ln:$.: $1\n        ";
            $failedLines++ unless ($failed == 1);
	    $failed = 1;
	}

#WARNING CHECKS
	if ((m/^\s*(.*javascript:.*)\s*$/) && $warned !=1) {
	    $JSprotocol{ $input_file } .= "ln:$.: $1\n        ";  #should trim whitespace when including entire line
            $warnedLines++;
	    $warned = 1;
	}

	if ((m/^\s*(.*\W(onabort|onblur|onchange|onclick|ondblclick|onerror|onfocus|onkeydown|onkeypress|onkeyup|onload|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onreset|onresize|onselect|onsubmit|onunload).*)\s*$/i)  && $warned !=1) {
	    $obtrusiveJS{ $input_file } .= "ln:$.: $1\n        ";
            $warnedLines++;
	    $warned = 1;
	}


#Keep track of failures
	if ($failed == 1) {
            if ($fileHasFailed == 0) {
              $failCount++;
              $fileHasFailed = 1;
            }
            $failedLines++;
            $failed = 0;
	}

#Keep track of warnings
	if ($warned == 1) {
            if ($fileWasWarned == 0) {
              $warnCount++;
              $fileWasWarned = 1;
            }
            $warnedLines++;
            $warned = 0;
	}
    }
}


open(OUTFILE, ">$outfile") or die("Couldn't open $outfile\n");    # > before $name opens $name for writing


my $summary = <<"SUMMARY";

$appname automatic report:

Spaghetti Code alerts:
Files flagged: $failCount
Lines flagged: $failedLines

Deprecation warnings:
Files warned:  $warnCount
Lines warned: $warnedLines

This validator enforces browser code best practices as developed by the JAG Web 2.0 team.
Note that the validator checks every file in the source directory, so some of the files flagged here may not actually be part of the live app.  If you notice superfluous files in the list, please let us know so we can correct the problem.

Spaghetti Code alerts (very bad):
 - More than three selectors in one CLASS declaration.
 - Selector names descriptive of CSS properties, for example: 'fnt, pad, teal'
 - Digits (0-9) in a selector name.  Currently we think _one_ digit is OK.
 - selectors of less than 3 characters in length.

Deprecation warnings (arguably not so bad):
 - "Obtrusive JavaScript".  See http://jibbering.com/faq/#FAQ4_24 and http://www.kryogenix.org/code/browser/aqlists/
 --- Use of the "javascript:" protocol.
 --- Some, but not all, uses of inline event handlers (onclick, onload, onmouseover, etc.) instead of event listeners.
SUMMARY

print OUTFILE $summary;

print OUTFILE "Files that failed to validate are listed below.  ";
print OUTFILE "Each file is followed by a list of the lines that were problematic." if ($verbose == 1);
print OUTFILE "\n";

print OUTFILE "\n========================\ntoo many selectors in a CLASS declaration:\n";

foreach my $key ( keys(%longClass)){
    print OUTFILE "    $key \n";
if ($verbose == 1) {
    print OUTFILE "            $longClass{$key}\n";
}
}

print OUTFILE "\n========================\nSelector is less than 3 characters long:\n";
foreach my $key ( keys(%tooShort)){
    print OUTFILE "    $key \n";
if ($verbose == 1) {
    print OUTFILE "            $tooShort{$key}\n";
}
}

print OUTFILE "\n========================\n'mar, pad, teal' or other string that describes a CSS property, in a selector:\n";
foreach my $key ( keys(%cssPropName)){
    print OUTFILE "    $key \n";
if ($verbose == 1) {
    print OUTFILE "            $cssPropName{$key}\n";
}
}

print OUTFILE "\n========================\ndigits (0-9) in a selector:\n";
foreach my $key ( keys(%digits)){
    print OUTFILE "    $key \n";
if ($verbose == 1) {
    print OUTFILE "            $digits{$key}\n";
}
}

print OUTFILE "\n|||||||||||||||||||| Only warnings below here |||||||||||||||||||||\n";

print OUTFILE "\n||||||||||||||||||||||||\nUses of the \"javascript:\" protocol:\n";
foreach my $key ( keys(%JSprotocol)){
    print OUTFILE "    $key \n";
if ($verbose == 1) {
    print OUTFILE "            $JSprotocol{$key}\n";
}
}

print OUTFILE "\n||||||||||||||||||||||||\nUses of inline event handlers:\n";
foreach my $key ( keys(%obtrusiveJS)){
    print OUTFILE "    $key \n";
if ($verbose == 1) {
    print OUTFILE "            $obtrusiveJS{$key}\n";
}
}




#manage notification

if ($send_email) {

system("rm -r $zipped_outfile") if -e $zipped_outfile;
system("zip -j $zipped_outfile $outfile");


  my $outlook = new Mail::Outlook();
my @attachments;
 $attachments[0] = $zipped_outfile;

  # create a message for sending
  my $message = $outlook->create();
  $message->To($recipients);
  $message->Cc('');
  $message->Bcc('');
  $message->Subject("$failCount files in $appname are becoming Spaghetti Code.");
  $message->Body("$summary\n\nA full report is attached.");
  $message->Attach(@attachments);
  $message->send;

}


#here are useful greps
#
# CLASS declaration with 3 or more selectors
# grep -niP 'class="([^("<)]+\s){2,}[^(<")]+"' advsearch.jsp
#

Safely Get and Operate Upon An Element

// Pass this an ID or an object reference, as well as any number of functions that take the referenced object as a parameter. This wrapper is intended to provide a sanity check against missing DOM elements.

function safeGet () {
  var o;
  var ioj = arguments[0];
  if (typeof ioj == 'string') {
    o = document.getElementById(ioj);
  } else {
    o = ioj;   
  }
  if (typeof ioj != 'object') return;
  for (var i=1; i< arguments.length; i++) {
    arguments[i](o);
  }
  return true;
}

//use it like this
safeGet (document.body, 
	 function (o) {
	   o.style.background='black';
	 },
	 function (o) {
	   o.style.color='white';
	 }
);
//misuse it like this, but it won't throw an error
safeGet ('someIdThatDontExist', 
	 function (o) {
	   o.style.background='black';
	 },
	 function (o) {
	   o.style.color='white';
	 }
);

install a spell-checking program

// Install the spell-checking program of your choice. Just update the path

;spell-checking
(setq-default ispell-program-name "/Program Files/Aspell/bin/aspell.exe")

starter Perl module

// Put this in the file MyPackage.pm, and call it with Use::MyPackage

package MyPackage;

#module code goes here...

1;

submit a POST query with parameters

// from The Perl Black Book, Holzner, p. 1247

#! /usr/bin/perl -w
use strict;
use HTTP::Request::Common;
use LWP::UserAgent;
#The Perl Black Book, Holzner, p. 1247


=item how to call submit_query():
#Method 1.
my %example = (test1 => 'noah', test2 => 'sussman');
submit_query("http://suburbanangst.com/reg.php", %example);

#Method 2.
submit_query("http://suburbanangst.com/reg.php?test1=foo&test2=bar;");
=cut

sub submit_query {
    my ($file, %query) = @_;
    my $user_agent = LWP::UserAgent->new;
    $user_agent->agent("MSIE/5.5 " . $user_agent->agent);
    my $request = POST
    #'http://suburbanangst.com/reg.php',
    $file,
    [%query];
    my $response = $user_agent->request($request);
    print $response->as_string;
}

click on an element across browsers

// If you have assigned an event handler to a container, you might want to remotely trigger it as if a child of the container had been clicked. That is, you might want to manually set the target of the 'event' object that is passed to the event handler on the container.

//assuming that 'menu' has an appropriate onclick handler:
    function simulateClick( itemToClick, menu) {
      if ( ! itemToClick.click ) {
	//== Non-IE:
	menu.onclick({target: itemToClick});
      } else {
	//== IE:
	itemToClick.click()
      }
    }


This helps to keep the number of event handlers down.

Yahoo General Header (XHTML)


<div id="yahooHeader">
	<a href="#" class="yahooBranch">Yahoo!</a>
	<ul>
		<li><a href="#" title="Home">Home</a> - </li>
		<li><a href="#" title="Help">Help</a></li>
	</ul>
</div><!-- close yahooHeader -->

heredoc xhtml 1.0 strict page template


<?php

$content = <<<HTML
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi in sapien interdum purus volutpat placerat. Sed ornare nisi eu magna. Cras vulputate. Phasellus vel lorem vel magna placerat iaculis. Aenean tortor leo, ultricies ut, dictum non, blandit nec, odio. Morbi vel odio. Etiam venenatis turpis suscipit nibh. Suspendisse tincidunt, metus vel consequat gravida, neque enim egestas est, et interdum diam tellus vel lorem. In hac habitasse platea dictumst. Fusce vitae velit. Suspendisse a libero et risus imperdiet tincidunt.
HTML;

$html = <<<HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>title</title>
	<link rel="stylesheet" href="./css/screen.css" type="text/css" media="screen" />

</head>
<body>
<div id="wrap">
	$content
</div>
</body>
</html>
HTML;

echo $html;

?>

Search bar for sites based on XSLT as target for results

// A rough search form based on usage with googleboxes and xslt templates for results.

<div id="searchbar">
 <form action="http://domain.com/search" method="get"> 
  <input type="text" name="q" value="Search Our Site" size="20" maxlength="120" id="searchInput" onfocus="if(this.value == 'Search Our Site'){this.value='';}">
  <input type="hidden" name="site" value="externalSearch">                    
  <input type="hidden" name="client" value="externalSearch">                  
  <input type="hidden" name="restrict" value="wwwexternal">  
  <input type="hidden" name="proxystylesheet" value="http://domain.com/searchStyle.xslt">                                             
  <input type="hidden" name="output" value="xml_no_dtd">     

  <input type="submit" name="btnG" value="Search" id="searchSubmit">
 </form>
</div>

Scrape Google from the command line

// This code is POC only -- actually using it would violate Google's TOS, which forbids scraping. It is published here for educational value only.

Hypothetically, the following command should return a list of the top 500 or so hits in Google for onemorebug.com.

The results will be prepended with digits, followed by a dot and some whitespace (Lynx adds these).

You must have Lynx and Wget installed on your system for this to work.

Keep in mind that *nix shells don't like it when you double-quote strings, see the comments.


perl -e "$i=0;while($i<1000){sleep 1; open(WGET,qq/|xargs lynx -dump/);printf WGET qq{http://www.google.com/search?q=site:onemorebug.com&hl=en&start=$i&sa=N},$i+=10}" | grep "\/\/[^/]*onemorebug.com\/"