git-svn-id: svn://euphorik.ch/pompage@45 02bbb61a-6d21-0410-aba0-cb053bdfd66a
[pompage.git] / doc / webdeveloper / common / validation / css.js
diff --git a/doc/webdeveloper/common/validation/css.js b/doc/webdeveloper/common/validation/css.js
new file mode 100644 (file)
index 0000000..a2fcc20
--- /dev/null
@@ -0,0 +1,268 @@
+// Constructs a validate CSS object
+function WebDeveloperValidateCSS()
+{
+    this.file              = null;
+    this.validationRequest = null;
+}
+
+// Cleans up
+WebDeveloperValidateCSS.prototype.cleanUp = function()
+{
+    // If the file is set
+    if(this.file)
+    {
+        // Try to delete the file
+        try
+        {
+            this.file.remove(false);
+        }
+        catch(exception)
+        {
+            // Do nothing
+        }
+
+        this.file = null;
+    }
+
+    // If the validation request is set
+    if(this.validationRequest)
+    {
+        this.validationRequest.abort();
+    }
+}
+
+// Creates a source file
+WebDeveloperValidateCSS.prototype.createSourceFile = function(uri)
+{
+    var temporaryDirectory = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
+
+    // If the temporary directory exists, is a directory and is writable
+    if(temporaryDirectory.exists() && temporaryDirectory.isDirectory() && temporaryDirectory.isWritable())
+    {
+        var fileName   = "";
+        var sourceFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+
+        // Try to get the host
+        try
+        {
+            fileName = uri.host;
+        }
+        catch(exception)
+        {
+            // Do nothing
+        }
+
+        temporaryDirectory.append("webdeveloper_" + fileName + "_" + new Date().getTime() + ".css");
+        sourceFile.initWithPath(temporaryDirectory.path);
+
+        return sourceFile;
+    }
+    else
+    {
+        webdeveloper_error(document.getElementById("webdeveloper-string-bundle").getFormattedString("webdeveloper_tempDirectoryFailed", [temporaryDirectory.path]));
+
+        return null;
+    }
+}
+
+// Parses the validation results by type
+WebDeveloperValidateCSS.prototype.parseValidationResultsByType = function(type)
+{
+    var count         = 0;
+    var resultsHTML   = this.validationRequest.responseText;
+    var startPosition = resultsHTML.indexOf('<div id="' + type + '">');
+
+    // If the start position is greater than 0
+    if(startPosition > 0)
+    {
+        var endPosition = resultsHTML.indexOf("</div>", startPosition);
+
+        // If the end position is greater than 0
+        if(endPosition > 0)
+        {
+            count = resultsHTML.slice(startPosition, endPosition).split("<li>").length;
+        }
+    }
+
+    // If the count is greater than 0
+    if(count > 0)
+    {
+        return count - 1;
+    }
+
+    return 0;
+}
+
+// Retrieves the CSS for the given document list
+WebDeveloperValidateCSS.prototype.retrieveCSS = function(documentList)
+{
+    var documentLength   = documentList.length;
+    var documentURL      = null;
+    var pageDocument     = null;
+    var stringBundle     = document.getElementById("webdeveloper-string-bundle");
+    var styleSheet       = null;
+    var styleSheetHref   = null;
+    var styleSheetLength = null;
+    var styleSheetList   = null;
+    var styleText        = "";
+    var styleElement     = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument     = documentList[i];
+        documentURL      = pageDocument.documentURI;
+        styleSheetList   = pageDocument.getElementsByTagName("style");
+        styleSheetLength = styleSheetList.length;
+
+        // Loop through the style sheets
+        for(var j = 0; j < styleSheetLength; j++)
+        {
+            styleElement = styleSheetList[j];
+            styleSheet   = styleElement.sheet;
+
+            // If this is a valid style sheet
+            if(webdeveloper_isValidStyleSheet(styleSheet))
+            {
+                styleText += "/* " + stringBundle.getFormattedString("webdeveloper_embeddedStylesFrom", [styleSheet.href]) + " */\n\n";
+                styleText += styleElement.innerHTML.trim() + "\n\n";
+            }
+        }
+
+        styleSheetList   = webdeveloper_getStyleSheetsForDocument(pageDocument, true, true);
+        styleSheetLength = styleSheetList.length;
+
+        // Loop through the style sheets
+        for(j = 0; j < styleSheetLength; j++)
+        {
+            styleSheetHref = styleSheetList[j].href;
+
+            // If this is not an inline style sheet
+            if(styleSheetHref != documentURL)
+            {
+                styleText += webdeveloper_retrieveSource(styleSheetHref);
+            }
+        }
+    }
+
+    return styleText;
+}
+
+// Validate the CSS from the given URI and document list in the background
+WebDeveloperValidateCSS.prototype.validateBackgroundCSS = function(uri, documentList)
+{
+    var boundaryString = new Date().getTime();
+    var boundary       = "--" + boundaryString;
+    var requestBody    = boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"css.css\"\r\n";
+
+    // If the validation request is not set
+    if(!this.validationRequest)
+    {
+        this.validationRequest = new XMLHttpRequest();
+    }
+
+    this.validationRequest.onreadystatechange = webdeveloper_updatePageCSSValidationDetails;
+
+    requestBody += "Content-Type: text/css\r\n\r\n";
+    requestBody += this.retrieveCSS(documentList) + "\r\n";
+    requestBody += boundary + "\r\n";
+    requestBody += "Content-Disposition: form-data; name=\"profile\"\r\n\r\n" + webdeveloper_getStringPreference("webdeveloper.validate.local.css.profile", true) + "\r\n";
+    requestBody += boundary + "\r\n";
+    requestBody += "Content-Disposition: form-data; name=\"usermedium\"\r\n\r\nall\r\n";
+    requestBody += boundary + "\r\n";
+    requestBody += "Content-Disposition: form-data; name=\"warning\"\r\n\r\n0\r\n";
+    requestBody += boundary + "--";
+
+    this.validationRequest.open("post", "http://jigsaw.w3.org/css-validator/validator", true);
+
+    // Try to set the request header
+    try
+    {
+        this.validationRequest.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundaryString);
+        this.validationRequest.send(requestBody);
+    }
+    catch(exception)
+    {
+        // Reset the validation request
+        this.validationRequest = new XMLHttpRequest();
+    }
+}
+
+// Validate the CSS from the given URI and document list
+WebDeveloperValidateCSS.prototype.validateCSS = function(uri, documentList)
+{
+    var oldTab            = getBrowser().selectedTab;
+    var generatedDocument = webdeveloper_generateDocument("");
+    var bodyElement       = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var formElement       = generatedDocument.createElement("form");
+    var imageElement      = generatedDocument.createElement("img");
+    var inputElement      = null;
+    var outputStream      = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+    var pElement          = generatedDocument.createElement("p");
+    var scriptElement     = generatedDocument.createElement("script");
+    var stringBundle      = document.getElementById("webdeveloper-string-bundle");
+    var styleText         = null;
+
+    generatedDocument.title = stringBundle.getString("webdeveloper_validateCSS");
+    this.file               = this.createSourceFile(uri);
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    imageElement.setAttribute("alt", "loading");
+    imageElement.setAttribute("src", "chrome://webdeveloper/content/images/content/loading.gif");
+    pElement.appendChild(imageElement);
+    pElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_contactingValidator")));
+    pElement.setAttribute("class", "loading");
+    bodyElement.appendChild(pElement);
+
+    styleText = this.retrieveCSS(documentList);
+
+    this.file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 00644);
+    outputStream.init(this.file, 0x04 | 0x08 | 0x20 | 0x40, 00644, null);
+
+    outputStream.write(styleText, styleText.length);
+    outputStream.close();
+
+    formElement.setAttribute("action", "http://jigsaw.w3.org/css-validator/validator");
+    formElement.setAttribute("enctype", "multipart/form-data");
+    formElement.setAttribute("method", "post");
+    formElement.setAttribute("style", "display: none");
+
+    inputElement = generatedDocument.createElement("input");
+
+    inputElement.setAttribute("name", "profile");
+    inputElement.setAttribute("type", "hidden");
+    inputElement.setAttribute("value", webdeveloper_getStringPreference("webdeveloper.validate.local.css.profile", true));
+    formElement.appendChild(inputElement);
+
+    inputElement = generatedDocument.createElement("input");
+
+    inputElement.setAttribute("name", "usermedium");
+    inputElement.setAttribute("type", "hidden");
+    inputElement.setAttribute("value", "all");
+    formElement.appendChild(inputElement);
+
+    inputElement = generatedDocument.createElement("input");
+
+    inputElement.setAttribute("name", "warning");
+    inputElement.setAttribute("type", "hidden");
+    inputElement.setAttribute("value", "0");
+    formElement.appendChild(inputElement);
+
+    inputElement = generatedDocument.createElement("input")
+
+    inputElement.setAttribute("name", "file");
+    inputElement.setAttribute("type", "file");
+
+    inputElement.value = this.file.path;
+
+    formElement.appendChild(inputElement);
+    bodyElement.appendChild(formElement);
+    formElement.submit();
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}