git-svn-id: svn://euphorik.ch/pompage@45 02bbb61a-6d21-0410-aba0-cb053bdfd66a
[pompage.git] / doc / webdeveloper / common / validation / html.js
1 // Constructs a validate HTML object
2 function WebDeveloperValidateHTML()
3 {
4 this.file = null;
5 this.fileElement = null;
6 this.formElement = null;
7 this.validationRequest = null;
8 }
9
10 // Cleans up
11 WebDeveloperValidateHTML.prototype.cleanUp = function()
12 {
13 // If the file is set
14 if(this.file)
15 {
16 // Try to delete the file
17 try
18 {
19 this.file.remove(false);
20 }
21 catch(exception)
22 {
23 // Do nothing
24 }
25
26 this.file = null;
27 }
28
29 // If the validation request is set
30 if(this.validationRequest)
31 {
32 this.validationRequest.abort();
33 }
34 }
35
36 // Creates a source file
37 WebDeveloperValidateHTML.prototype.createSourceFile = function(uri)
38 {
39 var temporaryDirectory = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
40
41 // If the temporary directory exists, is a directory and is writable
42 if(temporaryDirectory.exists() && temporaryDirectory.isDirectory() && temporaryDirectory.isWritable())
43 {
44 var fileName = "";
45 var sourceFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
46
47 // Try to get the host
48 try
49 {
50 fileName = uri.host;
51 }
52 catch(exception)
53 {
54 // Do nothing
55 }
56
57 temporaryDirectory.append("webdeveloper_" + fileName + "_" + new Date().getTime() + ".html");
58 sourceFile.initWithPath(temporaryDirectory.path);
59
60 return sourceFile;
61 }
62 else
63 {
64 webdeveloper_error(document.getElementById("webdeveloper-string-bundle").getFormattedString("webdeveloper_tempDirectoryFailed", [temporaryDirectory.path]));
65
66 return null;
67 }
68 }
69
70 // Returns the post data
71 WebDeveloperValidateHTML.prototype.getPostData = function()
72 {
73 // Try to get the post data
74 try
75 {
76 var sessionHistory = getWebNavigation().sessionHistory;
77 var entry = sessionHistory.getEntryAtIndex(sessionHistory.index, false).QueryInterface(Components.interfaces.nsISHEntry);
78
79 return entry.postData;
80 }
81 catch(exception)
82 {
83 return null;
84 }
85 }
86
87 // Saves the HTML
88 WebDeveloperValidateHTML.prototype.saveHTML = function(uri)
89 {
90 var webBrowserPersistInterface = Components.interfaces.nsIWebBrowserPersist;
91 var webBrowserPersist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(webBrowserPersistInterface);
92
93 webBrowserPersist.persistFlags = webBrowserPersistInterface.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION | webBrowserPersistInterface.PERSIST_FLAGS_FROM_CACHE | webBrowserPersistInterface.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
94 webBrowserPersist.progressListener = this;
95
96 webBrowserPersist.saveURI(uri, null, uri, this.getPostData(), null, this.file);
97 }
98
99 // Submits the background request to validate the HTML
100 WebDeveloperValidateHTML.prototype.submitBackgroundRequest = function()
101 {
102 var boundaryString = new Date().getTime();
103 var boundary = "--" + boundaryString;
104 var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
105 var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
106 var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
107 var requestBody = boundary + "\r\nContent-Disposition: form-data; name=\"uploaded_file\"; filename=\"" + this.file.leafName + "\"\r\n";
108
109 converter.charset = webdeveloper_getContentDocument().characterSet;
110 this.validationRequest.onreadystatechange = webdeveloper_updatePageHTMLValidationDetails;
111
112 inputStream.init(this.file, 0x01, 0444, null);
113 scriptableStream.init(inputStream);
114
115 requestBody += "Content-Type: text/html\r\n\r\n";
116 requestBody += converter.ConvertToUnicode(scriptableStream.read(scriptableStream.available())) + "\r\n";
117 requestBody += boundary + "--";
118
119 scriptableStream.close();
120 inputStream.close();
121
122 this.validationRequest.open("post", "http://validator.w3.org/check", true);
123
124 // Try to set the request header
125 try
126 {
127 this.validationRequest.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundaryString);
128 this.validationRequest.send(requestBody);
129 }
130 catch(exception)
131 {
132 // Reset the validation request
133 this.validationRequest = new XMLHttpRequest();
134 }
135 }
136
137 // Submits the form to validate the HTML
138 WebDeveloperValidateHTML.prototype.submitForm = function()
139 {
140 this.fileElement.value = this.file.path;
141
142 this.formElement.submit();
143 }
144
145 // Validate the HTML from the given URI in the background
146 WebDeveloperValidateHTML.prototype.validateBackgroundHTML = function(uri)
147 {
148 this.file = this.createSourceFile(uri);
149
150 // If the validation request is not set
151 if(!this.validationRequest)
152 {
153 this.validationRequest = new XMLHttpRequest();
154 }
155
156 this.saveHTML(uri);
157 }
158
159 // Validate the HTML from the given URI
160 WebDeveloperValidateHTML.prototype.validateHTML = function(uri)
161 {
162 var oldTab = getBrowser().selectedTab;
163 var oldURL = getBrowser().currentURI.spec;
164 var generatedDocument = webdeveloper_generateDocument("");
165 var bodyElement = webdeveloper_getDocumentBodyElement(generatedDocument);
166 var imageElement = generatedDocument.createElement("img");
167 var inputElement = null;
168 var pElement = generatedDocument.createElement("p");
169 var stringBundle = document.getElementById("webdeveloper-string-bundle");
170
171 generatedDocument.title = stringBundle.getString("webdeveloper_validateHTML");
172 this.file = this.createSourceFile(uri);
173 this.formElement = generatedDocument.createElement("form");
174
175 webdeveloper_addGeneratedStyles(generatedDocument);
176
177 imageElement.setAttribute("alt", "loading");
178 imageElement.setAttribute("src", "chrome://webdeveloper/content/images/content/loading.gif");
179 pElement.appendChild(imageElement);
180 pElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_contactingValidator")));
181 pElement.setAttribute("class", "loading");
182 bodyElement.appendChild(pElement);
183
184 this.formElement.setAttribute("action", "http://validator.w3.org/check");
185 this.formElement.setAttribute("enctype", "multipart/form-data");
186 this.formElement.setAttribute("method", "post");
187 this.formElement.setAttribute("style", "display: none");
188
189 // If the show outline preference is set
190 if(webdeveloper_getBooleanPreference("webdeveloper.validate.local.html.show.outline", true))
191 {
192 inputElement = generatedDocument.createElement("input");
193
194 inputElement.setAttribute("name", "outline");
195 inputElement.setAttribute("type", "hidden");
196 inputElement.setAttribute("value", "1");
197 this.formElement.appendChild(inputElement);
198 }
199
200 // If the show parse tree preference is set
201 if(webdeveloper_getBooleanPreference("webdeveloper.validate.local.html.show.parse.tree", true))
202 {
203 inputElement = generatedDocument.createElement("input");
204
205 inputElement.setAttribute("name", "sp");
206 inputElement.setAttribute("type", "hidden");
207 inputElement.setAttribute("value", "1");
208 this.formElement.appendChild(inputElement);
209 }
210
211 // If the show source preference is set
212 if(webdeveloper_getBooleanPreference("webdeveloper.validate.local.html.show.source", true))
213 {
214 inputElement = generatedDocument.createElement("input");
215
216 inputElement.setAttribute("name", "ss");
217 inputElement.setAttribute("type", "hidden");
218 inputElement.setAttribute("value", "1");
219 this.formElement.appendChild(inputElement);
220 }
221
222 inputElement = generatedDocument.createElement("input");
223
224 inputElement.setAttribute("name", "verbose");
225 inputElement.setAttribute("type", "hidden");
226 inputElement.setAttribute("value", "1");
227 this.formElement.appendChild(inputElement);
228
229 this.fileElement = generatedDocument.createElement("input");
230
231 this.fileElement.setAttribute("name", "uploaded_file");
232 this.fileElement.setAttribute("type", "file");
233 this.formElement.appendChild(this.fileElement);
234 bodyElement.appendChild(this.formElement);
235
236 // If the open tabs in background preference is set to true
237 if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
238 {
239 getBrowser().selectedTab = oldTab;
240 }
241
242 this.saveHTML(uri);
243 }
244
245 // Called when the progress state changes
246 WebDeveloperValidateHTML.prototype.onStateChange = function(webProgress, request, stateFlags, status)
247 {
248 // If the progress has stopped
249 if(stateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
250 {
251 // If the file is set and exists
252 if(this.file && this.file.exists())
253 {
254 // If the validation request is set
255 if(this.validationRequest)
256 {
257 this.submitBackgroundRequest();
258 }
259 else
260 {
261 this.submitForm();
262 }
263 }
264 }
265 }
266
267 // Indicates the interfaces this object supports
268 WebDeveloperValidateHTML.prototype.QueryInterface = function(id)
269 {
270 // If the query is for a supported interface
271 if(id.equals(Components.interfaces.nsISupports) || id.equals(Components.interfaces.nsIWebProgressListener))
272 {
273 return this;
274 }
275
276 throw Components.results.NS_NOINTERFACE;
277 }
278
279 // Dummy methods requiring implementations
280 WebDeveloperValidateHTML.prototype.onLocationChange = function(webProgress, request, location) {}
281 WebDeveloperValidateHTML.prototype.onProgressChange = function(webProgress, request, currentSelfProgress, maximumSelfProgress, currentTotalProgress, maximumTotalProgress) {}
282 WebDeveloperValidateHTML.prototype.onSecurityChange = function(webProgress, request, state) {}
283 WebDeveloperValidateHTML.prototype.onStatusChange = function(webProgress, request, status, message) {}