[javascriptlint-commit] SF.net SVN: javascriptlint:[276] trunk
Status: Beta
Brought to you by:
matthiasmiller
|
From: <mat...@us...> - 2009-10-08 13:54:36
|
Revision: 276
http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=276&view=rev
Author: matthiasmiller
Date: 2009-10-08 13:54:28 +0000 (Thu, 08 Oct 2009)
Log Message:
-----------
www: implement the online lint
Modified Paths:
--------------
trunk/www/online_lint.php
trunk/www.py
Added Paths:
-----------
trunk/www/_jsl_online.inc
trunk/www/_lint_front.inc
Added: trunk/www/_jsl_online.inc
===================================================================
--- trunk/www/_jsl_online.inc (rev 0)
+++ trunk/www/_jsl_online.inc 2009-10-08 13:54:28 UTC (rev 276)
@@ -0,0 +1,221 @@
+<?php
+ /* This script assumes the following configuration settings:
+ * +output-format __LINE__,__COL__,__ERROR_NAME__,__ERROR_PREFIX__,__ERROR_MSGENC__
+ *
+ * Example Code:
+ * require_once("_jsl_online.php");
+ * $engine = new JSLEngine('.priv/jsl', '.priv/jsl.server.conf');
+ * $result = $engine->Lint($g_sScript);
+ * if ($result === true)
+ * OutputLintHTML($engine);
+ * else
+ * echo '<b>' . htmlentities($result) . '</b>';
+ *
+ * Suggestions or revisions can be sent to In...@Ja...
+ */
+
+ class JSLMessage {
+ var $_line;
+ var $_char;
+ var $_errname;
+ var $_type;
+ var $_message;
+
+ function JSLMessage($line) {
+ $info = explode(",", $line);
+ if (count($info) >= 4) {
+ $this->_line = ($info[0]*1);
+ $this->_char = is_numeric($info[1]) ? ($info[1]*1) : -1;
+ $this->_errname = $info[2];
+ $this->_type = $info[3];
+ $this->_message = implode(",", array_slice($info, 4));
+ }
+ }
+
+ function getLine() { return $this->_line; }
+ function getChar() { return $this->_char; }
+ function getErrName() { return $this->_errname; }
+ function getType() { return $this->_type; }
+ function getMessage() { return $this->_message; }
+ }
+
+ class JSLEngine {
+ var $_binarypath, $_confpath;
+ var $_scriptlines, $_scriptmsgsGeneral, $_scriptmsgsSpecific;
+
+ function JSLEngine($binarypath, $confpath) {
+ $this->_binarypath = $binarypath;
+ $this->_confpath = $confpath;
+
+ $this->_scriptlines = Array();
+ $this->_scriptmsgsGeneral = Array();
+ $this->_scriptmsgsSpecific = Array();
+ }
+
+ /* returns error on failure; returns true on success */
+ function Lint($code, $maxCodeLengthKB=128) {
+ if (strlen($code) > $maxCodeLengthKB*1024)
+ return 'Please limit scripts to ' . $maxCodeLengthKB . 'KB';
+
+ if (!$this->_launchLintBinary($code, $output))
+ return 'The JavaScript Lint online service is currently unavailable.';
+
+ /* parse the script */
+ $this->_scriptlines = explode("\n", str_replace("\r\n", "\n", $code));
+
+ /* parse the output */
+ $output_lines = explode("\n", str_replace("\r\n", "\n", $output));
+ foreach ($output_lines as $line) {
+ /* skip blank lines */
+ if (strlen($line) > 0) {
+ /* store in associative array by 0-based line number */
+ $msg = new JSLMessage($line);
+
+ if ($msg->getChar() == -1)
+ $this->_scriptmsgsGeneral[$msg->getLine()-1][] = $msg;
+ else
+ $this->_scriptmsgsSpecific[$msg->getLine()-1][] = $msg;
+ }
+ }
+
+ return true;
+ }
+
+ function getNumLines() {
+ return count($this->_scriptlines);
+ }
+
+ function getLineText($i) {
+ return $this->_scriptlines[$i];
+ }
+
+ function getLineMessages($i) {
+ /* messages that do not point to a specific character should come first */
+ if (isset($this->_scriptmsgsGeneral[$i]) &&
+ isset($this->_scriptmsgsSpecific[$i])) {
+ return array_merge($this->_scriptmsgsGeneral[$i], $this->_scriptmsgsSpecific[$i]);
+ }
+
+ if (isset($this->_scriptmsgsGeneral[$i]))
+ return $this->_scriptmsgsGeneral[$i];
+
+ if (isset($this->_scriptmsgsSpecific[$i]))
+ return $this->_scriptmsgsSpecific[$i];
+
+ return Array();
+ }
+
+ /* assumes path and that SERVER_SOFTWARE env is set */
+ function _launchLintBinary($input, &$output) {
+ $descriptorspec = array(
+ 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
+ 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
+ 2 => array("pipe", "w")
+ );
+
+ /* launch process */
+ $path = escapeshellcmd($this->_binarypath) . ' --nologo --nosummary --stdin -context --conf ' . escapeshellarg($this->_confpath);
+ $process = proc_open($path, $descriptorspec, $pipes);
+ if (!is_resource($process))
+ return false;
+
+ // $pipes now looks like this:
+ // 0 => writeable handle connected to child stdin
+ // 1 => readable handle connected to child stdout
+ // 2 => readable handle connected to child stdout
+ fwrite($pipes[0], $input);
+ fclose($pipes[0]);
+
+ $output = '';
+ while (!feof($pipes[1]))
+ $output .= fgets($pipes[1], 1024);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+
+ // It is important that you close any pipes before calling
+ // proc_close in order to avoid a deadlock
+ $return_value = proc_close($process);
+ return true;
+ }
+ };
+
+ function getEncodedText($text)
+ {
+ $enc = htmlentities($text);
+ $enc = str_replace("\n", '<br/>', $enc);
+ $enc = str_replace(' ', ' ', $enc);
+ return $enc;
+ }
+
+ function OutputLintHTML($engine)
+ {
+?>
+ <style type="text/css">
+ div#code
+ {
+ color: #999;
+ font-family: monospace;
+ }
+ div#code div
+ {
+ color: black;
+ background-color: #EEE;
+ }
+ div#code div span
+ {
+ font-weight: bold;
+ font-family: Arial;
+ white-space: auto;
+ font-size: .9em;
+ color: #F00;
+ }
+ </style>
+<?php
+
+ /* output script */
+ $hasWarnedSemicolon = false;
+
+ $numlines = $engine->getNumLines();
+ $widthOfLineNo = strlen($numlines);
+ $lineNoSpacer = str_pad("", $widthOfLineNo, " ") . ' ';
+
+ echo '<div id="code">';
+ for ($lineno = 0; $lineno < $numlines; $lineno++)
+ {
+ /* format code */
+ $text = $engine->getLineText($lineno);
+ $text = str_replace("\t", str_pad("", 4/*tab width*/, " "), $text);
+ echo getEncodedText(str_pad($lineno+1, $widthOfLineNo, " ", STR_PAD_LEFT) . ' ' . $text . "\n");
+
+ /* show errors */
+ $errors = $engine->getLineMessages($lineno);
+ foreach ($errors as $Error) {
+ /* only show this warning once */
+ if (strcasecmp($Error->getErrName(), "missing_semicolon") == 0) {
+ if ($hasWarnedSemicolon)
+ continue;
+ $hasWarnedSemicolon = true;
+ }
+
+ echo '<div>';
+
+ /* point to the error position, if available */
+ if ($Error->getChar() > -1)
+ echo getEncodedText($lineNoSpacer . str_pad("", $Error->getChar()-1, "=") . "^\n");
+
+ /* output error type/message */
+ echo getEncodedText($lineNoSpacer) . '<span>';
+ if ($Error->getType())
+ echo getEncodedText($Error->getType() . ': ');
+ echo getEncodedText($Error->getMessage());
+ echo '</span>' . getEncodedText("\n");
+
+ echo '</div>';
+ }
+
+ if ($lineno % 1000 == 0)
+ flush();
+ }
+ echo '</div>';
+ }
+?>
Property changes on: trunk/www/_jsl_online.inc
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/www/_lint_front.inc
===================================================================
--- trunk/www/_lint_front.inc (rev 0)
+++ trunk/www/_lint_front.inc 2009-10-08 13:54:28 UTC (rev 276)
@@ -0,0 +1,64 @@
+<?php
+ // Get the posted script/URL
+ if (isset($_POST['script']))
+ $_Script = stripslashes($_POST['script']);
+ else
+ $_Script = "";
+
+ function _DownloadURL($url) {
+ $cUrl = curl_init();
+ curl_setopt($cUrl, CURLOPT_URL, $url);
+ curl_setopt($cUrl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($cUrl, CURLOPT_TIMEOUT, 5);
+ $PageContent = curl_exec($cUrl);
+ if (curl_errno($cUrl))
+ return false;
+ return $PageContent;
+ }
+
+ function _OutputError($error) {
+ echo '<p style="color: #F00; font-weight: bold">' . htmlentities($error) . '</p>';
+ }
+
+ function _isURL($url) {
+ if (strstr($url, "\n") !== FALSE)
+ return false;
+ if (strstr($url, "\r\n") !== FALSE)
+ return false;
+ if (!preg_match('!^((ht|f)tps?\:\/\/)?([\w\-]+\.)+([\w]{2,5})((/(.*))?)$!i', $url))
+ return false;
+ return true;
+ }
+
+ function outputscript() {
+ global $_Script;
+ echo htmlentities($_Script);
+ }
+
+ function outputlint() {
+ global $_Script;
+ if (strlen($_Script) > 0) {
+ // set up the new engine
+ require_once("_jsl_online.inc");
+ $engine = new JSLEngine('../jsl-cgi-bin/jsl', '../jsl-cgi-bin/jsl.server.conf');
+
+ if (_isURL(trim($_Script))) {
+ // Download and lint the URL
+ $code = _DownloadURL(trim($_Script));
+ if ($code !== false)
+ $result = $engine->Lint($code);
+ else
+ $result = "The URL could not be downloaded: " . $_Script;
+ }
+ else
+ $result = $engine->Lint($_Script);
+
+ // output the results
+ if ($result === true)
+ OutputLintHTML($engine);
+ else
+ _OutputError($result);
+ }
+ }
+?>
+
Property changes on: trunk/www/_lint_front.inc
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/www/online_lint.php
===================================================================
--- trunk/www/online_lint.php 2009-10-08 13:31:52 UTC (rev 275)
+++ trunk/www/online_lint.php 2009-10-08 13:54:28 UTC (rev 276)
@@ -3,6 +3,8 @@
@title=The Online Lint
-->
+<?php require('_lint_front.inc') ?>
+
Online Lint
===========
@@ -14,10 +16,12 @@
<form method="POST" action="">
<p>Paste your JavaScript, HTML, or URL into the box below:</p>
<p>
- <textarea name="script" rows="15" cols="75" style="width: 100%"></textarea>
+ <textarea name="script" rows="15" cols="75" style="width: 100%"><?php outputscript(); ?></textarea>
</p>
<p>
<input type="submit" value="Lint"/>
+</p>
-</p>
+<?php outputlint(); ?>
+
</form>
Modified: trunk/www.py
===================================================================
--- trunk/www.py 2009-10-08 13:31:52 UTC (rev 275)
+++ trunk/www.py 2009-10-08 13:54:28 UTC (rev 276)
@@ -267,6 +267,8 @@
return 'image/gif', source
elif path.endswith('.png'):
return 'image/png', source
+ elif path.endswith('.inc'):
+ return 'text/plain', source
elif path.endswith('.rss'):
settings, source = _preprocess(path)
return 'text/xml', _gen_rss(host, path, source,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|