git-svn-id: svn://euphorik.ch/pompage@45 02bbb61a-6d21-0410-aba0-cb053bdfd66a
[pompage.git] / doc / webdeveloper / common / validation / css.js
1 // Constructs a validate CSS object
2 function WebDeveloperValidateCSS()
3 {
4 this.file = null;
5 this.validationRequest = null;
6 }
7
8 // Cleans up
9 WebDeveloperValidateCSS.prototype.cleanUp = function()
10 {
11 // If the file is set
12 if(this.file)
13 {
14 // Try to delete the file
15 try
16 {
17 this.file.remove(false);
18 }
19 catch(exception)
20 {
21 // Do nothing
22 }
23
24 this.file = null;
25 }
26
27 // If the validation request is set
28 if(this.validationRequest)
29 {
30 this.validationRequest.abort();
31 }
32 }
33
34 // Creates a source file
35 WebDeveloperValidateCSS.prototype.createSourceFile = function(uri)
36 {
37 var temporaryDirectory = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
38
39 // If the temporary directory exists, is a directory and is writable
40 if(temporaryDirectory.exists() && temporaryDirectory.isDirectory() && temporaryDirectory.isWritable())
41 {
42 var fileName = "";
43 var sourceFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
44
45 // Try to get the host
46 try
47 {
48 fileName = uri.host;
49 }
50 catch(exception)
51 {
52 // Do nothing
53 }
54
55 temporaryDirectory.append("webdeveloper_" + fileName + "_" + new Date().getTime() + ".css");
56 sourceFile.initWithPath(temporaryDirectory.path);
57
58 return sourceFile;
59 }
60 else
61 {
62 webdeveloper_error(document.getElementById("webdeveloper-string-bundle").getFormattedString("webdeveloper_tempDirectoryFailed", [temporaryDirectory.path]));
63
64 return null;
65 }
66 }
67
68 // Parses the validation results by type
69 WebDeveloperValidateCSS.prototype.parseValidationResultsByType = function(type)
70 {
71 var count = 0;
72 var resultsHTML = this.validationRequest.responseText;
73 var startPosition = resultsHTML.indexOf('<div id="' + type + '">');
74
75 // If the start position is greater than 0
76 if(startPosition > 0)
77 {
78 var endPosition = resultsHTML.indexOf("</div>", startPosition);
79
80 // If the end position is greater than 0
81 if(endPosition > 0)
82 {
83 count = resultsHTML.slice(startPosition, endPosition).split("<li>").length;
84 }
85 }
86
87 // If the count is greater than 0
88 if(count > 0)
89 {
90 return count - 1;
91 }
92
93 return 0;
94 }
95
96 // Retrieves the CSS for the given document list
97 WebDeveloperValidateCSS.prototype.retrieveCSS = function(documentList)
98 {
99 var documentLength = documentList.length;
100 var documentURL = null;
101 var pageDocument = null;
102 var stringBundle = document.getElementById("webdeveloper-string-bundle");
103 var styleSheet = null;
104 var styleSheetHref = null;
105 var styleSheetLength = null;
106 var styleSheetList = null;
107 var styleText = "";
108 var styleElement = null;
109
110 // Loop through the documents
111 for(var i = 0; i < documentLength; i++)
112 {
113 pageDocument = documentList[i];
114 documentURL = pageDocument.documentURI;
115 styleSheetList = pageDocument.getElementsByTagName("style");
116 styleSheetLength = styleSheetList.length;
117
118 // Loop through the style sheets
119 for(var j = 0; j < styleSheetLength; j++)
120 {
121 styleElement = styleSheetList[j];
122 styleSheet = styleElement.sheet;
123
124 // If this is a valid style sheet
125 if(webdeveloper_isValidStyleSheet(styleSheet))
126 {
127 styleText += "/* " + stringBundle.getFormattedString("webdeveloper_embeddedStylesFrom", [styleSheet.href]) + " */\n\n";
128 styleText += styleElement.innerHTML.trim() + "\n\n";
129 }
130 }
131
132 styleSheetList = webdeveloper_getStyleSheetsForDocument(pageDocument, true, true);
133 styleSheetLength = styleSheetList.length;
134
135 // Loop through the style sheets
136 for(j = 0; j < styleSheetLength; j++)
137 {
138 styleSheetHref = styleSheetList[j].href;
139
140 // If this is not an inline style sheet
141 if(styleSheetHref != documentURL)
142 {
143 styleText += webdeveloper_retrieveSource(styleSheetHref);
144 }
145 }
146 }
147
148 return styleText;
149 }
150
151 // Validate the CSS from the given URI and document list in the background
152 WebDeveloperValidateCSS.prototype.validateBackgroundCSS = function(uri, documentList)
153 {
154 var boundaryString = new Date().getTime();
155 var boundary = "--" + boundaryString;
156 var requestBody = boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"css.css\"\r\n";
157
158 // If the validation request is not set
159 if(!this.validationRequest)
160 {
161 this.validationRequest = new XMLHttpRequest();
162 }
163
164 this.validationRequest.onreadystatechange = webdeveloper_updatePageCSSValidationDetails;
165
166 requestBody += "Content-Type: text/css\r\n\r\n";
167 requestBody += this.retrieveCSS(documentList) + "\r\n";
168 requestBody += boundary + "\r\n";
169 requestBody += "Content-Disposition: form-data; name=\"profile\"\r\n\r\n" + webdeveloper_getStringPreference("webdeveloper.validate.local.css.profile", true) + "\r\n";
170 requestBody += boundary + "\r\n";
171 requestBody += "Content-Disposition: form-data; name=\"usermedium\"\r\n\r\nall\r\n";
172 requestBody += boundary + "\r\n";
173 requestBody += "Content-Disposition: form-data; name=\"warning\"\r\n\r\n0\r\n";
174 requestBody += boundary + "--";
175
176 this.validationRequest.open("post", "http://jigsaw.w3.org/css-validator/validator", true);
177
178 // Try to set the request header
179 try
180 {
181 this.validationRequest.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundaryString);
182 this.validationRequest.send(requestBody);
183 }
184 catch(exception)
185 {
186 // Reset the validation request
187 this.validationRequest = new XMLHttpRequest();
188 }
189 }
190
191 // Validate the CSS from the given URI and document list
192 WebDeveloperValidateCSS.prototype.validateCSS = function(uri, documentList)
193 {
194 var oldTab = getBrowser().selectedTab;
195 var generatedDocument = webdeveloper_generateDocument("");
196 var bodyElement = webdeveloper_getDocumentBodyElement(generatedDocument);
197 var formElement = generatedDocument.createElement("form");
198 var imageElement = generatedDocument.createElement("img");
199 var inputElement = null;
200 var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
201 var pElement = generatedDocument.createElement("p");
202 var scriptElement = generatedDocument.createElement("script");
203 var stringBundle = document.getElementById("webdeveloper-string-bundle");
204 var styleText = null;
205
206 generatedDocument.title = stringBundle.getString("webdeveloper_validateCSS");
207 this.file = this.createSourceFile(uri);
208
209 webdeveloper_addGeneratedStyles(generatedDocument);
210
211 imageElement.setAttribute("alt", "loading");
212 imageElement.setAttribute("src", "chrome://webdeveloper/content/images/content/loading.gif");
213 pElement.appendChild(imageElement);
214 pElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_contactingValidator")));
215 pElement.setAttribute("class", "loading");
216 bodyElement.appendChild(pElement);
217
218 styleText = this.retrieveCSS(documentList);
219
220 this.file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 00644);
221 outputStream.init(this.file, 0x04 | 0x08 | 0x20 | 0x40, 00644, null);
222
223 outputStream.write(styleText, styleText.length);
224 outputStream.close();
225
226 formElement.setAttribute("action", "http://jigsaw.w3.org/css-validator/validator");
227 formElement.setAttribute("enctype", "multipart/form-data");
228 formElement.setAttribute("method", "post");
229 formElement.setAttribute("style", "display: none");
230
231 inputElement = generatedDocument.createElement("input");
232
233 inputElement.setAttribute("name", "profile");
234 inputElement.setAttribute("type", "hidden");
235 inputElement.setAttribute("value", webdeveloper_getStringPreference("webdeveloper.validate.local.css.profile", true));
236 formElement.appendChild(inputElement);
237
238 inputElement = generatedDocument.createElement("input");
239
240 inputElement.setAttribute("name", "usermedium");
241 inputElement.setAttribute("type", "hidden");
242 inputElement.setAttribute("value", "all");
243 formElement.appendChild(inputElement);
244
245 inputElement = generatedDocument.createElement("input");
246
247 inputElement.setAttribute("name", "warning");
248 inputElement.setAttribute("type", "hidden");
249 inputElement.setAttribute("value", "0");
250 formElement.appendChild(inputElement);
251
252 inputElement = generatedDocument.createElement("input")
253
254 inputElement.setAttribute("name", "file");
255 inputElement.setAttribute("type", "file");
256
257 inputElement.value = this.file.path;
258
259 formElement.appendChild(inputElement);
260 bodyElement.appendChild(formElement);
261 formElement.submit();
262
263 // If the open tabs in background preference is set to true
264 if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
265 {
266 getBrowser().selectedTab = oldTab;
267 }
268 }