-rwxr-xr-x | src/components/xriProtocolHandler.js | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/src/components/xriProtocolHandler.js b/src/components/xriProtocolHandler.js index 7046cde..1105874 100755 --- a/src/components/xriProtocolHandler.js +++ b/src/components/xriProtocolHandler.js | |||
@@ -126,385 +126,385 @@ function getString(doc, context, expr) | |||
126 | return res.stringValue; | 126 | return res.stringValue; |
127 | return null; | 127 | return null; |
128 | } | 128 | } |
129 | 129 | ||
130 | function getNode(doc, context, expr) | 130 | function getNode(doc, context, expr) |
131 | { | 131 | { |
132 | var res = runExpr(doc, context, expr, XP_FIRST_ORDERED_NODE_TYPE); | 132 | var res = runExpr(doc, context, expr, XP_FIRST_ORDERED_NODE_TYPE); |
133 | if (res) | 133 | if (res) |
134 | return res.singleNodeValue; | 134 | return res.singleNodeValue; |
135 | return null; | 135 | return null; |
136 | } | 136 | } |
137 | 137 | ||
138 | 138 | ||
139 | function getFinalXRD(doc) | 139 | function getFinalXRD(doc) |
140 | { | 140 | { |
141 | var lastNode = doc.firstChild; | 141 | var lastNode = doc.firstChild; |
142 | while (true) { | 142 | while (true) { |
143 | var node = getNode(doc, lastNode, "xrds:XRDS[position()=last()]"); | 143 | var node = getNode(doc, lastNode, "xrds:XRDS[position()=last()]"); |
144 | if (!node) | 144 | if (!node) |
145 | break; | 145 | break; |
146 | lastNode = node; | 146 | lastNode = node; |
147 | } | 147 | } |
148 | 148 | ||
149 | return getNode(doc, lastNode, "xrd:XRD[position()=last()]"); | 149 | return getNode(doc, lastNode, "xrd:XRD[position()=last()]"); |
150 | } | 150 | } |
151 | 151 | ||
152 | 152 | ||
153 | function isIName(xri) | 153 | function isIName(xri) |
154 | { | 154 | { |
155 | if (xri.match('^xri://.!', 'i')) { | 155 | if (xri.match('^xri://.!', 'i')) { |
156 | return false; | 156 | return false; |
157 | } | 157 | } |
158 | if (xri.match('^.!', 'i')) { | 158 | if (xri.match('^.!', 'i')) { |
159 | return false; | 159 | return false; |
160 | } | 160 | } |
161 | return true; | 161 | return true; |
162 | } | 162 | } |
163 | 163 | ||
164 | 164 | ||
165 | function arraySearch(a, re) | 165 | function arraySearch(a, re) |
166 | { | 166 | { |
167 | var returnArr = new Array(); | 167 | var returnArr = new Array(); |
168 | var i; | 168 | var i; |
169 | for (i = 0; i < a.length; i++) { | 169 | for (i = 0; i < a.length; i++) { |
170 | if (a[i].match(re)) { | 170 | if (a[i].match(re)) { |
171 | returnArr.push(a[i]); | 171 | returnArr.push(a[i]); |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | return returnArr; | 175 | return returnArr; |
176 | } | 176 | } |
177 | 177 | ||
178 | 178 | ||
179 | function renderService(srv, doc, qxri) | 179 | function renderService(srv, doc, qxri) |
180 | { | 180 | { |
181 | var html_types = ''; | 181 | var html_types = ''; |
182 | var html_paths = ''; | 182 | var html_paths = ''; |
183 | var html_mediatypes = ''; | 183 | var html_mediatypes = ''; |
184 | var html_uris = ''; | 184 | var html_uris = ''; |
185 | var html_actions = ''; | 185 | var html_actions = ''; |
186 | 186 | ||
187 | var serviceName = friendlyServiceName(null); | 187 | var serviceName = friendlyServiceName(null); |
188 | var serviceType; // the last non-null Type | 188 | var serviceType; // the last non-null Type |
189 | var knownServiceType; // first recognized service type | 189 | var knownServiceType; // first recognized service type |
190 | 190 | ||
191 | // get the types | 191 | // get the types |
192 | var res = runExpr(doc, srv, "xrd:Type/text()"); | 192 | var res = runExpr(doc, srv, "xrd:Type/text()"); |
193 | var t; | 193 | var t; |
194 | while (t = res.iterateNext()) { | 194 | while (t = res.iterateNext()) { |
195 | if (t.nodeValue) { | 195 | if (t.nodeValue) { |
196 | if (!knownServiceType && isKnownServiceType(t.nodeValue)) { | 196 | if (!knownServiceType && isKnownServiceType(t.nodeValue)) { |
197 | knownServiceType = t.nodeValue; | 197 | knownServiceType = t.nodeValue; |
198 | } | 198 | } |
199 | 199 | ||
200 | serviceType = t.nodeValue; | 200 | serviceType = t.nodeValue; |
201 | html_types += "<strong>Type:</strong> " + t.nodeValue + "<br/>"; | 201 | html_types += "<strong>Type:</strong> " + t.nodeValue + "<br/>"; |
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | // get the paths | 205 | // get the paths |
206 | res = runExpr(doc, srv, "xrd:Path/text()"); | 206 | res = runExpr(doc, srv, "xrd:Path/text()"); |
207 | var p; | 207 | var p; |
208 | var qxri_prefix = qxri; | 208 | var qxri_prefix = qxri; |
209 | if (qxri_prefix.charAt(qxri_prefix.length - 1) != '/') { | 209 | if (qxri_prefix.charAt(qxri_prefix.length - 1) != '/') { |
210 | qxri_prefix += '/'; | 210 | qxri_prefix += '/'; |
211 | } | 211 | } |
212 | 212 | ||
213 | while (p = res.iterateNext()) { | 213 | while (p = res.iterateNext()) { |
214 | if (p.nodeValue) { | 214 | if (p.nodeValue) { |
215 | html_paths += "<strong>Path:</strong> " + p.nodeValue | 215 | html_paths += "<strong>Path:</strong> " + p.nodeValue |
216 | + " [ <tt><a href=\"" + qxri_prefix + p.nodeValue + "\">" | 216 | + " [ <tt><a href=\"" + qxri_prefix + p.nodeValue + "\">" |
217 | + qxri_prefix + p.nodeValue + "</a></tt> ]" | 217 | + qxri_prefix + p.nodeValue + "</a></tt> ]" |
218 | + "<br/>\n"; | 218 | + "<br/>\n"; |
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | 222 | ||
223 | // get the mediatypes | 223 | // get the mediatypes |
224 | mediaTypes = new Array(); | 224 | mediaTypes = new Array(); |
225 | res = runExpr(doc, srv, "xrd:MediaType/text()"); | 225 | res = runExpr(doc, srv, "xrd:MediaType/text()"); |
226 | var m; | 226 | var m; |
227 | while (m = res.iterateNext()) { | 227 | while (m = res.iterateNext()) { |
228 | if (!knownServiceType) { | 228 | if (!knownServiceType) { |
229 | var srvType = guessServiceTypeByMime(m.nodeValue); | 229 | var srvType = guessServiceTypeByMime(m.nodeValue); |
230 | knownServiceType = srvType? srvType : null; | 230 | knownServiceType = srvType? srvType : null; |
231 | } | 231 | } |
232 | 232 | ||
233 | mediaTypes.push(m.nodeValue); | 233 | mediaTypes.push(m.nodeValue); |
234 | if (m.nodeValue) { | 234 | if (m.nodeValue) { |
235 | html_mediatypes += "<strong>Media Type:</strong> " + m.nodeValue + "<br/>"; | 235 | html_mediatypes += "<strong>Media Type:</strong> " + m.nodeValue + "<br/>"; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | 239 | ||
240 | res = runExpr(doc, srv, "xrd:URI/text()"); | 240 | res = runExpr(doc, srv, "xrd:URI/text()"); |
241 | var u; | 241 | var u; |
242 | while (u = res.iterateNext()) { | 242 | while (u = res.iterateNext()) { |
243 | if (!u.nodeValue) | 243 | if (!u.nodeValue) |
244 | continue; | 244 | continue; |
245 | 245 | ||
246 | var srvType = guessServiceTypeByURI(u.nodeValue); | 246 | var srvType = guessServiceTypeByURI(u.nodeValue); |
247 | if (!knownServiceType) { | 247 | if (!knownServiceType) { |
248 | knownServiceType = srvType; | 248 | knownServiceType = srvType; |
249 | } | 249 | } |
250 | 250 | ||
251 | html_uris += "<div class=\"" + getServiceClass(srvType) + "\">"; | 251 | html_uris += "<div class=\"" + getServiceClass(srvType) + "\">"; |
252 | 252 | ||
253 | var linkContent = u.nodeValue; | 253 | var linkContent = u.nodeValue; |
254 | var uriParts = u.nodeValue.match('^(.*):(.*)$'); | 254 | var uriParts = u.nodeValue.match('^(.*):(.*)$'); |
255 | if (!uriParts) | 255 | if (!uriParts) |
256 | continue; | 256 | continue; |
257 | 257 | ||
258 | if (uriParts[1] == 'data') { | 258 | if (uriParts[1] == 'data') { |
259 | uriParts = uriParts[2].match('^(.*/.*),(.*)'); | 259 | uriParts = uriParts[2].match('^(.*/.*),(.*)'); |
260 | if (uriParts && uriParts[1].match('^image/', 'i')) { | 260 | if (uriParts && uriParts[1].match('^image/', 'i')) { |
261 | linkContent = "<img src=\"" + u.nodeValue + "\"/>"; | 261 | linkContent = "<img src=\"" + u.nodeValue + "\"/>"; |
262 | } | 262 | } |
263 | else if (uriParts) { | 263 | else if (uriParts) { |
264 | linkContent = uriParts[1] + " data"; | 264 | linkContent = uriParts[1] + " data"; |
265 | } | 265 | } |
266 | } | 266 | } |
267 | else if (uriParts[1] == 'skype') { | 267 | else if (uriParts[1] == 'skype') { |
268 | uriParts = uriParts[2].match('^(.*)\\?(.*)'); | 268 | uriParts = uriParts[2].match('^(.*)\\?(.*)'); |
269 | if (uriParts) { | 269 | if (uriParts) { |
270 | if (uriParts[2] == "call") { | 270 | if (uriParts[2] == "call") { |
271 | linkContent = "<img src=\"chrome://foxri/content/skype_call_large.png\" alt=\"Call " + uriParts[1] + "\"/>"; | 271 | linkContent = "<img src=\"chrome://foxri/content/skype_call_large.png\" alt=\"Call " + uriParts[1] + "\"/>"; |
272 | } | 272 | } |
273 | else if (uriParts[2] == "chat") { | 273 | else if (uriParts[2] == "chat") { |
274 | linkContent = "<img src=\"chrome://foxri/content/skype_chat_large.png\" alt=\"Chat with " + uriParts[1] + "\"/>"; | 274 | linkContent = "<img src=\"chrome://foxri/content/skype_chat_large.png\" alt=\"Chat with " + uriParts[1] + "\"/>"; |
275 | } | 275 | } |
276 | else if (uriParts[2] == "add") { | 276 | else if (uriParts[2] == "add") { |
277 | linkContent = "<img src=\"chrome://foxri/content/skype_add_large.png\" alt=\"Add " + uriParts[1] + " to Skype\"/>"; | 277 | linkContent = "<img src=\"chrome://foxri/content/skype_add_large.png\" alt=\"Add " + uriParts[1] + " to Skype\"/>"; |
278 | } | 278 | } |
279 | } | 279 | } |
280 | } | 280 | } |
281 | else if (uriParts[1] == 'aim') { | 281 | else if (uriParts[1] == 'aim') { |
282 | uriParts = uriParts[2].match('^(.*)\\?.*screenname=([^&]*)', 'i'); | 282 | uriParts = uriParts[2].match('^(.*)\\?.*screenname=([^&]*)', 'i'); |
283 | if (uriParts) { | 283 | if (uriParts) { |
284 | linkContent = "<img src=\"chrome://foxri/content/aim_logo.gif\" alt=\"Chat with " + uriParts[2] + "\"/> Chat with " + uriParts[2]; | 284 | linkContent = "<img src=\"chrome://foxri/content/aim_logo.gif\" alt=\"Chat with " + uriParts[2] + "\"/> Chat with " + uriParts[2]; |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | html_uris += "<a href=\""+u.nodeValue+"\">" | 288 | html_uris += "<a href=\""+u.nodeValue+"\">" |
289 | + linkContent + "</a>"; | 289 | + linkContent + "</a>"; |
290 | html_uris += "</div>"; | 290 | html_uris += "</div>"; |
291 | } | 291 | } |
292 | 292 | ||
293 | var html = "<div class=\"service srv_" + getServiceClass(knownServiceType) + "\">\n"; | 293 | var html = "<div class=\"service srv_" + getServiceClass(knownServiceType) + "\">\n"; |
294 | html += html_types; | 294 | html += html_types; |
295 | html += html_paths; | 295 | html += html_paths; |
296 | html += html_mediatypes; | 296 | html += html_mediatypes; |
297 | if (html_uris) { | 297 | if (html_uris) { |
298 | html += "<strong>URI(s):</strong><br/>\n"; | 298 | html += "<strong>URI(s):</strong><br/>\n"; |
299 | html += html_uris; | 299 | html += html_uris; |
300 | } | 300 | } |
301 | html += "</div>"; | 301 | html += "</div>"; |
302 | 302 | ||
303 | return html; | 303 | return html; |
304 | } | 304 | } |
305 | 305 | ||
306 | 306 | ||
307 | 307 | ||
308 | function isKnownServiceType(type) | 308 | function isKnownServiceType(type) |
309 | { | 309 | { |
310 | if (type.toLowerCase() in SERVICE_CLASSES) { | 310 | if (type.toLowerCase() in SERVICE_CLASSES) { |
311 | return true; | 311 | return true; |
312 | } | 312 | } |
313 | return false; | 313 | return false; |
314 | } | 314 | } |
315 | 315 | ||
316 | function getServiceClass(type) | 316 | function getServiceClass(type) |
317 | { | 317 | { |
318 | if (isKnownServiceType(type)) { | 318 | if (type && isKnownServiceType(type)) { |
319 | return SERVICE_CLASSES[type.toLowerCase()]; | 319 | return SERVICE_CLASSES[type.toLowerCase()]; |
320 | } | 320 | } |
321 | return type; | 321 | return type; |
322 | } | 322 | } |
323 | 323 | ||
324 | 324 | ||
325 | function guessServiceTypeByURI(uri) | 325 | function guessServiceTypeByURI(uri) |
326 | { | 326 | { |
327 | if (uri == null || uri == "") { | 327 | if (uri == null || uri == "") { |
328 | return "unknown"; | 328 | return "unknown"; |
329 | } | 329 | } |
330 | if (uri.match(/^https?:/i)) { | 330 | if (uri.match(/^https?:/i)) { |
331 | return "www"; | 331 | return "www"; |
332 | } | 332 | } |
333 | else if (uri.match(/^skype:/i)) { | 333 | else if (uri.match(/^skype:/i)) { |
334 | return "skype"; | 334 | return "skype"; |
335 | } | 335 | } |
336 | else if (uri.match(/^aim:/i)) { | 336 | else if (uri.match(/^aim:/i)) { |
337 | return "aim"; | 337 | return "aim"; |
338 | } | 338 | } |
339 | else if (uri.match(/^xmpp:/i)) { | 339 | else if (uri.match(/^xmpp:/i)) { |
340 | return "jabber"; | 340 | return "jabber"; |
341 | } | 341 | } |
342 | else if (uri.match(/^tel:/i)) { | 342 | else if (uri.match(/^tel:/i)) { |
343 | return "tel"; | 343 | return "tel"; |
344 | } | 344 | } |
345 | else if (uri.match(/^callto:/i)) { | 345 | else if (uri.match(/^callto:/i)) { |
346 | return "callto"; | 346 | return "callto"; |
347 | } | 347 | } |
348 | else if (uri.match(/^telnet:/i)) { | 348 | else if (uri.match(/^telnet:/i)) { |
349 | return "telnet"; | 349 | return "telnet"; |
350 | } | 350 | } |
351 | else if (uri.match(/^news:/i)) { | 351 | else if (uri.match(/^news:/i)) { |
352 | return "news"; | 352 | return "news"; |
353 | } | 353 | } |
354 | else if (uri.match(/^nntp:/i)) { | 354 | else if (uri.match(/^nntp:/i)) { |
355 | return "nntp"; | 355 | return "nntp"; |
356 | } | 356 | } |
357 | else if (uri.match(/^ftp:/i)) { | 357 | else if (uri.match(/^ftp:/i)) { |
358 | return "ftp"; | 358 | return "ftp"; |
359 | } | 359 | } |
360 | else if (uri.match(/^mailto:/i)) { | 360 | else if (uri.match(/^mailto:/i)) { |
361 | return "email"; | 361 | return "email"; |
362 | } | 362 | } |
363 | else if (uri.match(/^urn:/i)) { | 363 | else if (uri.match(/^urn:/i)) { |
364 | return "urn"; | 364 | return "urn"; |
365 | } | 365 | } |
366 | else if (uri.match(/^data:/i)) { | 366 | else if (uri.match(/^data:/i)) { |
367 | return "data"; | 367 | return "data"; |
368 | } | 368 | } |
369 | else if (uri.match(/^feed:/i)) { | 369 | else if (uri.match(/^feed:/i)) { |
370 | return "feed"; | 370 | return "feed"; |
371 | } | 371 | } |
372 | return "unknown"; | 372 | return "unknown"; |
373 | } | 373 | } |
374 | 374 | ||
375 | 375 | ||
376 | function guessServiceTypeByMime(mimeType) | 376 | function guessServiceTypeByMime(mimeType) |
377 | { | 377 | { |
378 | if (mimeType.match(/^application\/(rss|atom)\+xml/i)) { | 378 | if (mimeType.match(/^application\/(rss|atom)\+xml/i)) { |
379 | dump("feed detected!\n"); | 379 | dump("feed detected!\n"); |
380 | return "feed"; | 380 | return "feed"; |
381 | } | 381 | } |
382 | else if (mimeType.match(/^image\//i)) { | 382 | else if (mimeType.match(/^image\//i)) { |
383 | return "image"; | 383 | return "image"; |
384 | } | 384 | } |
385 | return null; | 385 | return null; |
386 | } | 386 | } |
387 | 387 | ||
388 | 388 | ||
389 | 389 | ||
390 | function friendlyServiceName(srvType, uri) | 390 | function friendlyServiceName(srvType, uri) |
391 | { | 391 | { |
392 | if (srvType && srvType == "xri://+i-service*(+contact)*($v*1.0)") { | 392 | if (srvType && srvType == "xri://+i-service*(+contact)*($v*1.0)") { |
393 | return "Contact Service"; | 393 | return "Contact Service"; |
394 | } | 394 | } |
395 | else if (srvType && srvType == "http://openid.net/signon/1.0") { | 395 | else if (srvType && srvType == "http://openid.net/signon/1.0") { |
396 | return "OpenID Authentication Service"; | 396 | return "OpenID Authentication Service"; |
397 | } | 397 | } |
398 | else if (srvType && srvType == "xri://$res*auth*($v*2.0)") { | 398 | else if (srvType && srvType == "xri://$res*auth*($v*2.0)") { |
399 | return "Authority Resolution Service"; | 399 | return "Authority Resolution Service"; |
400 | } | 400 | } |
401 | else { | 401 | else { |
402 | if (uri == null) { | 402 | if (uri == null) { |
403 | return "Generic Service"; | 403 | return "Generic Service"; |
404 | } | 404 | } |
405 | if (uri.match(/^https?:/i)) { | 405 | if (uri.match(/^https?:/i)) { |
406 | return "Web Link"; | 406 | return "Web Link"; |
407 | } | 407 | } |
408 | else if (uri.match(/^skype:/i)) { | 408 | else if (uri.match(/^skype:/i)) { |
409 | var user = uri.substring("skype:".length, uri.indexOf('?')); | 409 | var user = uri.substring("skype:".length, uri.indexOf('?')); |
410 | return "Skype <a href=\"" + uri + "\"><img src=\"chrome://foxri/content/skype_call.png\"></a>"; | 410 | return "Skype <a href=\"" + uri + "\"><img src=\"chrome://foxri/content/skype_call.png\"></a>"; |
411 | } | 411 | } |
412 | else if (uri.match(/^mailto:/i)) { | 412 | else if (uri.match(/^mailto:/i)) { |
413 | var qmark = uri.indexOf('?'); | 413 | var qmark = uri.indexOf('?'); |
414 | var email = (qmark == -1)? | 414 | var email = (qmark == -1)? |
415 | uri.substr("mailto:".length) : | 415 | uri.substr("mailto:".length) : |
416 | uri.substring("mailto:".length, qmark); | 416 | uri.substring("mailto:".length, qmark); |
417 | return "Email (address: " + email + ")"; | 417 | return "Email (address: " + email + ")"; |
418 | } | 418 | } |
419 | else if (srvType != null) { | 419 | else if (srvType != null) { |
420 | return srvType; // return verbatim | 420 | return srvType; // return verbatim |
421 | } | 421 | } |
422 | return "Generic Service"; | 422 | return "Generic Service"; |
423 | } | 423 | } |
424 | } | 424 | } |
425 | 425 | ||
426 | 426 | ||
427 | 427 | ||
428 | 428 | ||
429 | function subHTML(template, vars) | 429 | function subHTML(template, vars) |
430 | { | 430 | { |
431 | for (key in vars) { | 431 | for (key in vars) { |
432 | template = template.replace(key, vars[key], 'g'); | 432 | template = template.replace(key, vars[key], 'g'); |
433 | } | 433 | } |
434 | return template; | 434 | return template; |
435 | } | 435 | } |
436 | 436 | ||
437 | 437 | ||
438 | /// Given the completed XMLHttpRequest object, renders the XRDS | 438 | /// Given the completed XMLHttpRequest object, renders the XRDS |
439 | function renderXRDS(xmlDoc) | 439 | function renderXRDS(xmlDoc) |
440 | { | 440 | { |
441 | var x = xmlDoc; | 441 | var x = xmlDoc; |
442 | var qxri = getString(x, x, "/xrds:XRDS/@ref"); | 442 | var qxri = getString(x, x, "/xrds:XRDS/@ref"); |
443 | 443 | ||
444 | var html = subHTML(HTML_HEAD, { '#QXRI#': qxri }); | 444 | var html = subHTML(HTML_HEAD, { '#QXRI#': qxri }); |
445 | 445 | ||
446 | // TODO: render parents as well | 446 | // TODO: render parents as well |
447 | 447 | ||
448 | var lastNode = getFinalXRD(x); | 448 | var lastNode = getFinalXRD(x); |
449 | if (lastNode) { | 449 | if (lastNode) { |
450 | var stat = getString(x, lastNode, "xrd:Status/@code"); | 450 | var stat = getString(x, lastNode, "xrd:Status/@code"); |
451 | if (stat == "100") { | 451 | if (stat == "100") { |
452 | html += "<h3>Exploring <strong>" + qxri + "</strong></h3>"; | 452 | html += "<h3>Exploring <strong>" + qxri + "</strong></h3>"; |
453 | } | 453 | } |
454 | else { | 454 | else { |
455 | var msg = getString(x, lastNode, "xrd:Status/text()"); | 455 | var msg = getString(x, lastNode, "xrd:Status/text()"); |
456 | html += "<h3 class=\"error\"><strong>" + qxri + "</strong> failed to resolve (reason: " + stat + " - " + msg + ")</h3>"; | 456 | html += "<h3 class=\"error\"><strong>" + qxri + "</strong> failed to resolve (reason: " + stat + " - " + msg + ")</h3>"; |
457 | } | 457 | } |
458 | 458 | ||
459 | html += "<br/>"; | 459 | html += "<br/>"; |
460 | 460 | ||
461 | var services = runExpr(x, lastNode, "xrd:Service"); | 461 | var services = runExpr(x, lastNode, "xrd:Service"); |
462 | var s; | 462 | var s; |
463 | var count = getNumeric(x, lastNode, "count(xrd:Service)"); | 463 | var count = getNumeric(x, lastNode, "count(xrd:Service)"); |
464 | if (count > 0) { | 464 | if (count > 0) { |
465 | while (s = services.iterateNext()) { | 465 | while (s = services.iterateNext()) { |
466 | count++; | 466 | count++; |
467 | html += renderService(s, x, qxri); | 467 | html += renderService(s, x, qxri); |
468 | } | 468 | } |
469 | } | 469 | } |
470 | else if (stat == '222') { | 470 | else if (stat == '222') { |
471 | var xriType = isIName(qxri)? 'I-name' : 'I-number'; | 471 | var xriType = isIName(qxri)? 'I-name' : 'I-number'; |
472 | html += "<p class='error'>" + xriType + " does not exist.</p>\n"; | 472 | html += "<p class='error'>" + xriType + " does not exist.</p>\n"; |
473 | } | 473 | } |
474 | else { | 474 | else { |
475 | html += "<p>No service has been configured for this XRI</p>"; | 475 | html += "<p>No service has been configured for this XRI</p>"; |
476 | } | 476 | } |
477 | 477 | ||
478 | } | 478 | } |
479 | 479 | ||
480 | html += "</html>"; | 480 | html += "</html>"; |
481 | 481 | ||
482 | return html; | 482 | return html; |
483 | } | 483 | } |
484 | 484 | ||
485 | 485 | ||
486 | 486 | ||
487 | 487 | ||
488 | 488 | ||
489 | 489 | ||
490 | /*********************************************************** | 490 | /*********************************************************** |
491 | XriServiceExplorer class definition | 491 | XriServiceExplorer class definition |
492 | ***********************************************************/ | 492 | ***********************************************************/ |
493 | 493 | ||
494 | 494 | ||
495 | function XRIChannel(uri) { | 495 | function XRIChannel(uri) { |
496 | this.URI = uri; | 496 | this.URI = uri; |
497 | var r = uri.spec.indexOf('#'); | 497 | var r = uri.spec.indexOf('#'); |
498 | if (r >= 0) { | 498 | if (r >= 0) { |
499 | this.qxri = uri.spec.substring(0, r); | 499 | this.qxri = uri.spec.substring(0, r); |
500 | this.fragment = uri.spec.substring(r); | 500 | this.fragment = uri.spec.substring(r); |
501 | } | 501 | } |
502 | else { | 502 | else { |
503 | this.qxri = uri.spec; | 503 | this.qxri = uri.spec; |
504 | } | 504 | } |
505 | }; | 505 | }; |
506 | 506 | ||
507 | 507 | ||
508 | XRIChannel.prototype = { | 508 | XRIChannel.prototype = { |
509 | 509 | ||
510 | fragment: null, | 510 | fragment: null, |
@@ -608,421 +608,419 @@ XRIChannel.prototype = { | |||
608 | onStartRequest : function(request, ctx) | 608 | onStartRequest : function(request, ctx) |
609 | { | 609 | { |
610 | dump("\nonStartRequest called\n"); | 610 | dump("\nonStartRequest called\n"); |
611 | // XXX | 611 | // XXX |
612 | 612 | ||
613 | this.copyFields(request); | 613 | this.copyFields(request); |
614 | this.asyncOpenListener.onStartRequest(this, this.asyncOpenContext); | 614 | this.asyncOpenListener.onStartRequest(this, this.asyncOpenContext); |
615 | }, | 615 | }, |
616 | 616 | ||
617 | 617 | ||
618 | onStopRequest : function(request, ctx, status) | 618 | onStopRequest : function(request, ctx, status) |
619 | { | 619 | { |
620 | dump("\nonStopRequest called - status " + status + "\n"); | 620 | dump("\nonStopRequest called - status " + status + "\n"); |
621 | 621 | ||
622 | // XXX | 622 | // XXX |
623 | /* | 623 | /* |
624 | this.asyncOpenListener.onStopRequest(this, this.asyncOpenContext, status); | 624 | this.asyncOpenListener.onStopRequest(this, this.asyncOpenContext, status); |
625 | return; | 625 | return; |
626 | */ | 626 | */ |
627 | 627 | ||
628 | this.copyFields(request); | 628 | this.copyFields(request); |
629 | this.loadDone = true; | 629 | this.loadDone = true; |
630 | 630 | ||
631 | if (status == 0) { | 631 | if (status == 0) { |
632 | 632 | ||
633 | var domParser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser); | 633 | var domParser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser); |
634 | var xmlDoc = domParser.parseFromString(this.buf, "text/xml"); | 634 | var xmlDoc = domParser.parseFromString(this.buf, "text/xml"); |
635 | 635 | ||
636 | // make fake inputstream | 636 | // make fake inputstream |
637 | var renderedHTML = renderXRDS(xmlDoc); | 637 | var renderedHTML = renderXRDS(xmlDoc); |
638 | 638 | ||
639 | this.contentCharset = "UTF-8"; | 639 | this.contentCharset = "UTF-8"; |
640 | this.contentLength = renderedHTML.length; | 640 | this.contentLength = renderedHTML.length; |
641 | this.contentType = "text/html"; | 641 | this.contentType = "text/html"; |
642 | 642 | ||
643 | dump("rendered HTML = \n" + renderedHTML + "\n"); | 643 | dump("rendered HTML = \n" + renderedHTML + "\n"); |
644 | 644 | ||
645 | dump("\nCalling asyncOpenListener.onStartRequest\n\n"); | 645 | dump("\nCalling asyncOpenListener.onStartRequest\n\n"); |
646 | 646 | ||
647 | 647 | ||
648 | var strIStream = Components.classes["@mozilla.org/io/string-input-stream;1"].createInstance(Components.interfaces.nsIStringInputStream); | 648 | var strIStream = Components.classes["@mozilla.org/io/string-input-stream;1"].createInstance(Components.interfaces.nsIStringInputStream); |
649 | if (strIStream) { | 649 | if (strIStream) { |
650 | strIStream.setData(renderedHTML, renderedHTML.length); | 650 | strIStream.setData(renderedHTML, renderedHTML.length); |
651 | /* | 651 | /* |
652 | strIStream.setData(this.buf, this.buf.length); | 652 | strIStream.setData(this.buf, this.buf.length); |
653 | */ | 653 | */ |
654 | dump("\nleftovers in string-input-stream = " + strIStream.available() + "\n"); | 654 | dump("\nleftovers in string-input-stream = " + strIStream.available() + "\n"); |
655 | dump("\nCalling asyncOpenListener.onDataAvailable\n\n"); | 655 | dump("\nCalling asyncOpenListener.onDataAvailable\n\n"); |
656 | this.asyncOpenListener.onDataAvailable(this, this.asyncOpenContext, strIStream, 0, renderedHTML.length); | 656 | this.asyncOpenListener.onDataAvailable(this, this.asyncOpenContext, strIStream, 0, renderedHTML.length); |
657 | /* | 657 | /* |
658 | this.asyncOpenListener.onDataAvailable(this, this.asyncOpenContext, strIStream, 0, this.buf.length); | 658 | this.asyncOpenListener.onDataAvailable(this, this.asyncOpenContext, strIStream, 0, this.buf.length); |
659 | */ | 659 | */ |
660 | 660 | ||
661 | dump("\nleftovers in string-input-stream = " + strIStream.available() + "\n"); | 661 | dump("\nleftovers in string-input-stream = " + strIStream.available() + "\n"); |
662 | } | 662 | } |
663 | } | 663 | } |
664 | else { | 664 | else { |
665 | dump("\nStatus = " + status + "\n"); | 665 | dump("\nStatus = " + status + "\n"); |
666 | dump("Calling asyncOpenListener.onStartRequest\n\n"); | 666 | dump("Calling asyncOpenListener.onStartRequest\n\n"); |
667 | this.asyncOpenListener.onStartRequest(this, this.asyncOpenContext); | 667 | this.asyncOpenListener.onStartRequest(this, this.asyncOpenContext); |
668 | } | 668 | } |
669 | 669 | ||
670 | dump("stopping request for underlying asyncOpenListener\n"); | 670 | dump("stopping request for underlying asyncOpenListener\n"); |
671 | 671 | ||
672 | this.asyncOpenListener.onStopRequest(this, this.asyncOpenContext, status); | 672 | this.asyncOpenListener.onStopRequest(this, this.asyncOpenContext, status); |
673 | 673 | ||
674 | // copied from nsIWyciwygChannel | 674 | // copied from nsIWyciwygChannel |
675 | this.asyncOpenListener = null; | 675 | this.asyncOpenListener = null; |
676 | this.asyncOpenContext = null; | 676 | this.asyncOpenContext = null; |
677 | 677 | ||
678 | /* | 678 | /* |
679 | if (this.loadGroup) { | 679 | if (this.loadGroup) { |
680 | this.loadGroup.removeRequest(request, null, status); | 680 | this.loadGroup.removeRequest(request, null, status); |
681 | } | 681 | } |
682 | */ | 682 | */ |
683 | 683 | ||
684 | this.notificationCallbacks = null; | 684 | this.notificationCallbacks = null; |
685 | this.mChannel = null; | 685 | this.mChannel = null; |
686 | 686 | ||
687 | dump("stopped request\n"); | 687 | dump("stopped request\n"); |
688 | }, | 688 | }, |
689 | 689 | ||
690 | 690 | ||
691 | /* public fields (nsIInputStream implementation) */ | 691 | /* public fields (nsIInputStream implementation) */ |
692 | available: function() | 692 | available: function() |
693 | { | 693 | { |
694 | dump("nsIInputStream::available called\n"); | 694 | dump("nsIInputStream::available called\n"); |
695 | return renderedHTML.length; | 695 | return renderedHTML.length; |
696 | }, | 696 | }, |
697 | 697 | ||
698 | close: function() | 698 | close: function() |
699 | { | 699 | { |
700 | dump("nsIInputStream::close called\n"); | 700 | dump("nsIInputStream::close called\n"); |
701 | }, | 701 | }, |
702 | 702 | ||
703 | isNonBlocking: function() { | 703 | isNonBlocking: function() { |
704 | dump("nsIInputStream::isNonBlocking called\n"); | 704 | dump("nsIInputStream::isNonBlocking called\n"); |
705 | return true; | 705 | return true; |
706 | }, | 706 | }, |
707 | 707 | ||
708 | read: function() { dump("nsIInputStream::read() called!!!\n"); }, | 708 | read: function() { dump("nsIInputStream::read() called!!!\n"); }, |
709 | 709 | ||
710 | 710 | ||
711 | 711 | ||
712 | 712 | ||
713 | 713 | ||
714 | /* public fields (nsIRequest implmentation) */ | 714 | /* public fields (nsIRequest implmentation) */ |
715 | 715 | ||
716 | loadFlags: 0, | 716 | loadFlags: 0, |
717 | 717 | ||
718 | loadGroup: null, | 718 | loadGroup: null, |
719 | 719 | ||
720 | name: "xri://request", | 720 | name: "xri://request", |
721 | 721 | ||
722 | status: 0, | 722 | status: 0, |
723 | 723 | ||
724 | cancel: function(status) { dump("\ncancel called...\n"); }, | 724 | cancel: function(status) { dump("\ncancel called...\n"); }, |
725 | 725 | ||
726 | isPending: function() { | 726 | isPending: function() { |
727 | dump("isPending called\n\n"); | 727 | dump("isPending called\n\n"); |
728 | return !this.loadDone; | 728 | return !this.loadDone; |
729 | }, | 729 | }, |
730 | 730 | ||
731 | resume: function() { dump("resume called\n"); }, | 731 | resume: function() { dump("resume called\n"); }, |
732 | 732 | ||
733 | suspend: function() { dump("suspend called\n"); }, | 733 | suspend: function() { dump("suspend called\n"); }, |
734 | 734 | ||
735 | 735 | ||
736 | 736 | ||
737 | /* public fields (nsIChannel implmentation) */ | 737 | /* public fields (nsIChannel implmentation) */ |
738 | 738 | ||
739 | contentCharset: null, | 739 | contentCharset: null, |
740 | 740 | ||
741 | contentLength: -1, | 741 | contentLength: -1, |
742 | 742 | ||
743 | contentType: null, | 743 | contentType: null, |
744 | 744 | ||
745 | notificationCallbacks: null, | 745 | notificationCallbacks: null, |
746 | 746 | ||
747 | originalURI: null, | 747 | originalURI: null, |
748 | 748 | ||
749 | owner: null, | 749 | owner: null, |
750 | 750 | ||
751 | securityInfo: null, | 751 | securityInfo: null, |
752 | 752 | ||
753 | URI: null, | 753 | URI: null, |
754 | 754 | ||
755 | open: function() | 755 | open: function() |
756 | { | 756 | { |
757 | dump("open not supporteD!!!!!!\n"); | 757 | dump("open not supporteD!!!!!!\n"); |
758 | }, | 758 | }, |
759 | 759 | ||
760 | asyncOpen: function(listener, context) | 760 | asyncOpen: function(listener, context) |
761 | { | 761 | { |
762 | dump("asyncOpen called!!!!!!\n"); | 762 | dump("asyncOpen called!!!!!!\n"); |
763 | this.asyncOpenListener = listener; | 763 | this.asyncOpenListener = listener; |
764 | this.asyncOpenContext = context; | 764 | this.asyncOpenContext = context; |
765 | 765 | ||
766 | var hxri = PROXY_URI + this.qxri | 766 | var hxri = PROXY_URI + this.qxri |
767 | + "?_xrd_r=application/xrds%2Bxml;sep=false"; | 767 | + "?_xrd_r=application/xrds%2Bxml;sep=false"; |
768 | var ioService = Components.classesByID[kIOSERVICE_CID_STR].getService(); | 768 | var ioService = Components.classesByID[kIOSERVICE_CID_STR].getService(); |
769 | ioService = ioService.QueryInterface(nsIIOService); | 769 | ioService = ioService.QueryInterface(nsIIOService); |
770 | var channel = ioService.newChannel(hxri, null, null); | 770 | var channel = ioService.newChannel(hxri, null, null); |
771 | 771 | ||
772 | if (this.scriptableInStream) { | 772 | if (this.scriptableInStream) { |
773 | dump("Hey! You can't possibly be reusing this handler?!\n"); | 773 | dump("Hey! You can't possibly be reusing this handler?!\n"); |
774 | return; | 774 | return; |
775 | } | 775 | } |
776 | 776 | ||
777 | dump("making scriptableInStream\n"); | 777 | dump("making scriptableInStream\n"); |
778 | this.scriptableInStream = Components.classes["@mozilla.org/scriptableinputstream;1"] | 778 | this.scriptableInStream = Components.classes["@mozilla.org/scriptableinputstream;1"] |
779 | .createInstance(Components.interfaces.nsIScriptableInputStream); | 779 | .createInstance(Components.interfaces.nsIScriptableInputStream); |
780 | 780 | ||
781 | this.buf = ''; | 781 | this.buf = ''; |
782 | 782 | ||
783 | dump("notificationCallbacks = " + this.notificationCallbacks + "\n"); | 783 | dump("notificationCallbacks = " + this.notificationCallbacks + "\n"); |
784 | dump("loadFlags = " + this.loadFlags + "\n"); | 784 | dump("loadFlags = " + this.loadFlags + "\n"); |
785 | dump("loadGroup = " + this.loadGroup + "\n"); | 785 | dump("loadGroup = " + this.loadGroup + "\n"); |
786 | dump("owner = " + this.owner + "\n"); | 786 | dump("owner = " + this.owner + "\n"); |
787 | dump("securityInfo = " + this.securityInfo + "\n"); | 787 | dump("securityInfo = " + this.securityInfo + "\n"); |
788 | 788 | ||
789 | // these nsIRequest attributes must be copied to the stub | 789 | // these nsIRequest attributes must be copied to the stub |
790 | // channel that we created | 790 | // channel that we created |
791 | channel.notificationCallbacks = this.notificationCallbacks; | 791 | channel.notificationCallbacks = this.notificationCallbacks; |
792 | channel.loadGroup = this.loadGroup; | 792 | channel.loadGroup = this.loadGroup; |
793 | channel.loadFlags = this.loadFlags; | 793 | channel.loadFlags = this.loadFlags; |
794 | 794 | ||
795 | this.mChannel = channel; | 795 | this.mChannel = channel; |
796 | channel.asyncOpen(this, null); | 796 | channel.asyncOpen(this, null); |
797 | }, | 797 | }, |
798 | 798 | ||
799 | 799 | ||
800 | /* public fields (nsIChannel implmentation) */ | 800 | /* public fields (nsIChannel implementation) */ |
801 | allowPipelining: false, | 801 | allowPipelining: false, |
802 | redirectionLimit: 5, | 802 | redirectionLimit: 5, |
803 | referrer: "", | 803 | referrer: "", |
804 | requestMethod: "GET", | 804 | requestMethod: "GET", |
805 | requestSucceeded: true, | 805 | requestSucceeded: true, |
806 | responseStatus: 200, | 806 | responseStatus: 200, |
807 | responseStatusText: "OK", | 807 | responseStatusText: "OK", |
808 | getRequestHeader: function(header) { | 808 | getRequestHeader: function(header) { |
809 | dump("getRequestHeader(" + header + ")\n"); | 809 | dump("getRequestHeader(" + header + ")\n"); |
810 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); | 810 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); |
811 | 811 | ||
812 | try { | 812 | try { |
813 | var val = httpChannel.getRequestHeader(header); | 813 | var val = httpChannel.getRequestHeader(header); |
814 | dump("getRequestHeader(" + header + ") = " + val + "\n"); | 814 | dump("getRequestHeader(" + header + ") = " + val + "\n"); |
815 | return val; | 815 | return val; |
816 | } | 816 | } |
817 | catch (e) { | 817 | catch (e) { |
818 | dump("getRequestHeader - got exception: " + e + "\n"); | ||
818 | throw e; | 819 | throw e; |
819 | } | 820 | } |
820 | }, | 821 | }, |
821 | getResponseHeader: function(header) { | 822 | getResponseHeader: function(header) { |
822 | dump("getResponseHeader(" + header + ")\n"); | 823 | dump("getResponseHeader(" + header + ")\n"); |
823 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); | 824 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); |
824 | 825 | ||
825 | try { | 826 | try { |
826 | var val = httpChannel.getResponseHeader(header); | 827 | var val = httpChannel.getResponseHeader(header); |
827 | dump("getResponseHeader(" + header + ") = " + val + "\n"); | 828 | dump("getResponseHeader(" + header + ") = " + val + "\n"); |
828 | return val; | 829 | return val; |
829 | } | 830 | } |
830 | catch (e) { | 831 | catch (e) { |
832 | dump("getResponseHeader - got exception: " + e + "\n"); | ||
831 | throw e; | 833 | throw e; |
832 | } | 834 | } |
833 | /* XXX | ||
834 | if (header == "Content-Type") | ||
835 | return "text/html"; | ||
836 | */ | ||
837 | return null; | 835 | return null; |
838 | }, | 836 | }, |
839 | isNoCacheResponse: function() { | 837 | isNoCacheResponse: function() { |
840 | dump("isNoCacheResponse()\n"); | 838 | dump("isNoCacheResponse()\n"); |
841 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); | 839 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); |
842 | return httpChannel.isNoCacheResponse(); | 840 | return httpChannel.isNoCacheResponse(); |
843 | }, | 841 | }, |
844 | isNoStoreResponse: function() { | 842 | isNoStoreResponse: function() { |
845 | dump("isNoStoreResponse()\n"); | 843 | dump("isNoStoreResponse()\n"); |
846 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); | 844 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); |
847 | return httpChannel.isNoStoreResponse(); | 845 | return httpChannel.isNoStoreResponse(); |
848 | return true; | 846 | return true; |
849 | }, | 847 | }, |
850 | setRequestHeader: function(header, value, merge) { | 848 | setRequestHeader: function(header, value, merge) { |
851 | dump("setRequestHeader(" + header + ", " + value + ")\n"); | 849 | dump("setRequestHeader(" + header + ", " + value + ")\n"); |
852 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); | 850 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); |
853 | return httpChannel.setRequestHeader(header, value, merge); | 851 | return httpChannel.setRequestHeader(header, value, merge); |
854 | }, | 852 | }, |
855 | setResponseHeader: function(header, value, merge) { | 853 | setResponseHeader: function(header, value, merge) { |
856 | dump("setResponseHeader(" + header + ", " + value + ")\n"); | 854 | dump("setResponseHeader(" + header + ", " + value + ")\n"); |
857 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); | 855 | var httpChannel = this.mChannel.QueryInterface(nsIHttpChannel); |
858 | return httpChannel.setResponseHeader(header, value, merge); | 856 | return httpChannel.setResponseHeader(header, value, merge); |
859 | }, | 857 | }, |
860 | visitRequestHeaders: function(visitor) { | 858 | visitRequestHeaders: function(visitor) { |
861 | dump("visitRequestHeaders()\n"); | 859 | dump("visitRequestHeaders()\n"); |
862 | }, | 860 | }, |
863 | visitResponseHeaders: function(visitor) { | 861 | visitResponseHeaders: function(visitor) { |
864 | dump("visitResponseHeaders()\n"); | 862 | dump("visitResponseHeaders()\n"); |
865 | }, | 863 | }, |
866 | 864 | ||
867 | QueryInterface: function(iid) | 865 | QueryInterface: function(iid) |
868 | { | 866 | { |
869 | dump("QI.. \n"); | 867 | dump("QI.. \n"); |
870 | if (iid.equals(nsIChannel)) | 868 | if (iid.equals(nsIChannel)) |
871 | dump("QI(nsIChannel)\n"); | 869 | dump("QI(nsIChannel)\n"); |
872 | else if (iid.equals(nsIHttpChannel)) | 870 | else if (iid.equals(nsIHttpChannel)) |
873 | dump("QI(nsIHttpChannel)\n"); | 871 | dump("QI(nsIHttpChannel)\n"); |
874 | else if (iid.equals(Components.interfaces.nsIUploadChannel)) | 872 | else if (iid.equals(Components.interfaces.nsIUploadChannel)) |
875 | dump("QI(nsIUploadChannel) - not supported\n"); | 873 | dump("QI(nsIUploadChannel) - not supported\n"); |
876 | else if (iid.equals(Components.interfaces.nsICachingChannel)) | 874 | else if (iid.equals(Components.interfaces.nsICachingChannel)) |
877 | dump("QI(nsICachingChannel) - not supported\n"); | 875 | dump("QI(nsICachingChannel) - not supported\n"); |
878 | else if (iid.equals(Components.interfaces.nsIClassInfo)) | 876 | else if (iid.equals(Components.interfaces.nsIClassInfo)) |
879 | dump("QI(nsIClassInfo) - not supported\n"); | 877 | dump("QI(nsIClassInfo) - not supported\n"); |
880 | else if (iid.equals(Components.interfaces.nsISecurityCheckedComponent)) | 878 | else if (iid.equals(Components.interfaces.nsISecurityCheckedComponent)) |
881 | dump("QI(nsISecurityCheckedComponent) - not supported\n"); | 879 | dump("QI(nsISecurityCheckedComponent) - not supported\n"); |
882 | else if (iid.equals(Components.interfaces.nsIWyciwygChannel)) | 880 | else if (iid.equals(Components.interfaces.nsIWyciwygChannel)) |
883 | dump("QI(nsIWyciwygChannel) - not supported\n"); | 881 | dump("QI(nsIWyciwygChannel) - not supported\n"); |
884 | else if (iid.equals(Components.interfaces.nsIMultiPartChannel)) | 882 | else if (iid.equals(Components.interfaces.nsIMultiPartChannel)) |
885 | dump("QI(nsIMultiPartChannel) - not supported\n"); | 883 | dump("QI(nsIMultiPartChannel) - not supported\n"); |
886 | else if (iid.equals(Components.interfaces.nsIHttpChannelInternal)) | 884 | else if (iid.equals(Components.interfaces.nsIHttpChannelInternal)) |
887 | dump("QI(nsIHttpChannelInternal) - not supported\n"); | 885 | dump("QI(nsIHttpChannelInternal) - not supported\n"); |
888 | else if (iid.equals(Components.interfaces.nsIWritablePropertyBag2)) | 886 | else if (iid.equals(Components.interfaces.nsIWritablePropertyBag2)) |
889 | dump("QI(nsIWritablePropertyBag2) - not supported\n"); | 887 | dump("QI(nsIWritablePropertyBag2) - not supported\n"); |
890 | else if (iid.equals(nsIRequest)) | 888 | else if (iid.equals(nsIRequest)) |
891 | dump("QI(nsIRequest)\n"); | 889 | dump("QI(nsIRequest)\n"); |
892 | else if (iid.equals(nsIRequestObserver)) | 890 | else if (iid.equals(nsIRequestObserver)) |
893 | dump("QI(nsIRequestObserver)\n"); | 891 | dump("QI(nsIRequestObserver)\n"); |
894 | else if (iid.equals(nsISupports)) | 892 | else if (iid.equals(nsISupports)) |
895 | dump("QI(nsISupports)\n"); | 893 | dump("QI(nsISupports)\n"); |
896 | else if (iid.equals(nsIStreamListener)) | 894 | else if (iid.equals(nsIStreamListener)) |
897 | dump("QI(nsIStreamListener)\n"); | 895 | dump("QI(nsIStreamListener)\n"); |
898 | else | 896 | else |
899 | dump("unknown " + iid + "\n"); | 897 | dump("unknown " + iid + "\n"); |
900 | 898 | ||
901 | if (iid.equals(nsISupports) || | 899 | if (iid.equals(nsISupports) || |
902 | iid.equals(nsIRequest) || | 900 | iid.equals(nsIRequest) || |
903 | iid.equals(nsIRequestObserver) || | 901 | iid.equals(nsIRequestObserver) || |
904 | iid.equals(nsIChannel) || | 902 | iid.equals(nsIChannel) || |
905 | iid.equals(nsIHttpChannel) || | 903 | iid.equals(nsIHttpChannel) || |
906 | iid.equals(nsIStreamListener) | 904 | iid.equals(nsIStreamListener) |
907 | ) { | 905 | ) { |
908 | return this; | 906 | return this; |
909 | } | 907 | } |
910 | 908 | ||
911 | throw Components.results.NS_ERROR_NO_INTERFACE; | 909 | throw Components.results.NS_ERROR_NO_INTERFACE; |
912 | } | 910 | } |
913 | }; | 911 | }; |
914 | 912 | ||
915 | 913 | ||
916 | 914 | ||
917 | /*********************************************************** | 915 | /*********************************************************** |
918 | XriProtocolHandler class definition | 916 | XriProtocolHandler class definition |
919 | ***********************************************************/ | 917 | ***********************************************************/ |
920 | 918 | ||
921 | //class constructor | 919 | //class constructor |
922 | function XriProtocolHandler() { | 920 | function XriProtocolHandler() { |
923 | }; | 921 | }; |
924 | 922 | ||
925 | // class definition | 923 | // class definition |
926 | XriProtocolHandler.prototype = { | 924 | XriProtocolHandler.prototype = { |
927 | defaultPort: 80, // HTTP | 925 | defaultPort: 80, // HTTP |
928 | 926 | ||
929 | protocolFlags : nsIProtocolHandler.ALLOWS_PROXY | nsIProtocolHandler.ALLOWS_PROXY_HTTP, | 927 | protocolFlags : nsIProtocolHandler.ALLOWS_PROXY | nsIProtocolHandler.ALLOWS_PROXY_HTTP, |
930 | 928 | ||
931 | scheme: "xri", | 929 | scheme: "xri", |
932 | 930 | ||
933 | allowPort: function() { | 931 | allowPort: function() { |
934 | return false; // only called for blacklisted ports, should respect | 932 | return false; // only called for blacklisted ports, should respect |
935 | }, | 933 | }, |
936 | 934 | ||
937 | _newHttpChannel: function(aURI) | 935 | _newHttpChannel: function(aURI) |
938 | { | 936 | { |
939 | var HXRI = PROXY_URI + aURI.spec; | 937 | var HXRI = PROXY_URI + aURI.spec; |
940 | var ioService = Components.classesByID[kIOSERVICE_CID_STR].getService(); | 938 | var ioService = Components.classesByID[kIOSERVICE_CID_STR].getService(); |
941 | ioService = ioService.QueryInterface(nsIIOService); | 939 | ioService = ioService.QueryInterface(nsIIOService); |
942 | var channel = ioService.newChannel(HXRI, null, null); | 940 | var channel = ioService.newChannel(HXRI, null, null); |
943 | return channel; | 941 | return channel; |
944 | }, | 942 | }, |
945 | 943 | ||
946 | newChannel: function(aURI) | 944 | newChannel: function(aURI) |
947 | { | 945 | { |
948 | // leave alone if path is not empty or just a single slash or query exists | 946 | // leave alone if path is not empty or just a single slash or query exists |
949 | 947 | ||
950 | dump("path='" + aURI.path + "'\n"); | 948 | dump("path='" + aURI.path + "'\n"); |
951 | dump("query='" + aURI.query + "'\n"); | 949 | dump("query='" + aURI.query + "'\n"); |
952 | dump("spec='" + aURI.spec + "'\n"); | 950 | dump("spec='" + aURI.spec + "'\n"); |
953 | 951 | ||
954 | var slashPos = aURI.spec.indexOf('/', 'xri://'.length); | 952 | var slashPos = aURI.spec.indexOf('/', 'xri://'.length); |
955 | var qmarkPos = aURI.spec.indexOf('?'); | 953 | var qmarkPos = aURI.spec.indexOf('?'); |
956 | dump("slashPos='" + slashPos + "'\n"); | 954 | dump("slashPos='" + slashPos + "'\n"); |
957 | dump("qmarkPos='" + qmarkPos + "'\n"); | 955 | dump("qmarkPos='" + qmarkPos + "'\n"); |
958 | if ((slashPos > 0 && slashPos < aURI.spec.length - 1) || qmarkPos > -1) { | 956 | if ((slashPos > 0 && slashPos < aURI.spec.length - 1) || qmarkPos > -1) { |
959 | return this._newHttpChannel(aURI); | 957 | return this._newHttpChannel(aURI); |
960 | } | 958 | } |
961 | 959 | ||
962 | var explorer = new XRIChannel(aURI); | 960 | var explorer = new XRIChannel(aURI); |
963 | return explorer; | 961 | return explorer; |
964 | }, | 962 | }, |
965 | 963 | ||
966 | 964 | ||
967 | newURI: function(spec, originCharset, baseURI) | 965 | newURI: function(spec, originCharset, baseURI) |
968 | { | 966 | { |
969 | var newSpec = spec; | 967 | var newSpec = spec; |
970 | if (baseURI != null) { | 968 | if (baseURI != null) { |
971 | // standard-url (nsIURL) does not work with @-GCS | 969 | // standard-url (nsIURL) does not work with @-GCS |
972 | var baseURL = Components.classes[CID_URL].createInstance(nsIURL); | 970 | var baseURL = Components.classes[CID_URL].createInstance(nsIURL); |
973 | baseURL.spec = baseURI.spec; | 971 | baseURL.spec = baseURI.spec; |
974 | newSpec = baseURL.resolve(spec); | 972 | newSpec = baseURL.resolve(spec); |
975 | } | 973 | } |
976 | 974 | ||
977 | var uri = Components.classes[CID_URI].createInstance(nsIURI); | 975 | var uri = Components.classes[CID_URI].createInstance(nsIURI); |
978 | uri.spec = newSpec; | 976 | uri.spec = newSpec; |
979 | return uri; | 977 | return uri; |
980 | }, | 978 | }, |
981 | 979 | ||
982 | QueryInterface: function(aIID) | 980 | QueryInterface: function(aIID) |
983 | { | 981 | { |
984 | if (!aIID.equals(nsIProtocolHandler) && | 982 | if (!aIID.equals(nsIProtocolHandler) && |
985 | !aIID.equals(nsISupports)) | 983 | !aIID.equals(nsISupports)) |
986 | throw Components.results.NS_ERROR_NO_INTERFACE; | 984 | throw Components.results.NS_ERROR_NO_INTERFACE; |
987 | return this; | 985 | return this; |
988 | } | 986 | } |
989 | }; | 987 | }; |
990 | 988 | ||
991 | 989 | ||
992 | /*********************************************************** | 990 | /*********************************************************** |
993 | class factory | 991 | class factory |
994 | 992 | ||
995 | This object is a member of the global-scope Components.classes. | 993 | This object is a member of the global-scope Components.classes. |
996 | It is keyed off of the contract ID. Eg: | 994 | It is keyed off of the contract ID. Eg: |
997 | 995 | ||
998 | myXriProtocolHandler = Components.classes["@dietrich.ganx4.com/helloworld;1"]. | 996 | myXriProtocolHandler = Components.classes["@dietrich.ganx4.com/helloworld;1"]. |
999 | createInstance(Components.interfaces.nsIXriProtocolHandler); | 997 | createInstance(Components.interfaces.nsIXriProtocolHandler); |
1000 | 998 | ||
1001 | ***********************************************************/ | 999 | ***********************************************************/ |
1002 | var XriProtocolHandlerFactory = { | 1000 | var XriProtocolHandlerFactory = { |
1003 | createInstance: function (aOuter, aIID) | 1001 | createInstance: function (aOuter, aIID) |
1004 | { | 1002 | { |
1005 | if (aOuter != null) | 1003 | if (aOuter != null) |
1006 | throw Components.results.NS_ERROR_NO_AGGREGATION; | 1004 | throw Components.results.NS_ERROR_NO_AGGREGATION; |
1007 | return (new XriProtocolHandler()).QueryInterface(aIID); | 1005 | return (new XriProtocolHandler()).QueryInterface(aIID); |
1008 | } | 1006 | } |
1009 | }; | 1007 | }; |
1010 | 1008 | ||
1011 | 1009 | ||
1012 | /*********************************************************** | 1010 | /*********************************************************** |
1013 | module definition (xpcom registration) | 1011 | module definition (xpcom registration) |
1014 | ***********************************************************/ | 1012 | ***********************************************************/ |
1015 | var XriProtocolHandlerModule = { | 1013 | var XriProtocolHandlerModule = { |
1016 | 1014 | ||
1017 | _firstTime: true, | 1015 | _firstTime: true, |
1018 | 1016 | ||
1019 | registerSelf: function(aCompMgr, aFileSpec, aLocation, aType) | 1017 | registerSelf: function(aCompMgr, aFileSpec, aLocation, aType) |
1020 | { | 1018 | { |
1021 | if (this._firstTime) { | 1019 | if (this._firstTime) { |
1022 | this._firstTime = false; | 1020 | this._firstTime = false; |
1023 | throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN; | 1021 | throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN; |
1024 | } | 1022 | } |
1025 | aCompMgr = aCompMgr. | 1023 | aCompMgr = aCompMgr. |
1026 | QueryInterface(Components.interfaces.nsIComponentRegistrar); | 1024 | QueryInterface(Components.interfaces.nsIComponentRegistrar); |
1027 | aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, | 1025 | aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, |
1028 | CONTRACT_ID, aFileSpec, aLocation, aType); | 1026 | CONTRACT_ID, aFileSpec, aLocation, aType); |