/[drupal]/contributions/sandbox/thox/ajax/drupal.js
ViewVC logotype

Contents of /contributions/sandbox/thox/ajax/drupal.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download) (as text)
Thu Mar 30 13:17:37 2006 UTC (3 years, 7 months ago) by thox
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +198 -30 lines
File MIME type: text/javascript
Update to get ajax_chat module working in 4.6.6
1 // $Id: drupal.js,v 1.20 2006/03/24 13:17:17 killes Exp $
2
3 /**
4 * Only enable Javascript functionality if all required features are supported.
5 */
6 function isJsEnabled() {
7 if (typeof document.jsEnabled == 'undefined') {
8 // Note: ! casts to boolean implicitly.
9 document.jsEnabled = !(
10 !document.getElementsByTagName ||
11 !document.createElement ||
12 !document.createTextNode ||
13 !document.documentElement ||
14 !document.getElementById);
15 }
16 return document.jsEnabled;
17 }
18
19 // Global Killswitch on the <html> element
20 if (isJsEnabled()) {
21 document.documentElement.className = 'js';
22 }
23
24 /**
25 * Make IE's XMLHTTP object accessible through XMLHttpRequest()
26 */
27 if (typeof XMLHttpRequest == 'undefined') {
28 XMLHttpRequest = function () {
29 var msxmls = ['MSXML3', 'MSXML2', 'Microsoft']
30 for (var i=0; i < msxmls.length; i++) {
31 try {
32 return new ActiveXObject(msxmls[i]+'.XMLHTTP')
33 }
34 catch (e) { }
35 }
36 throw new Error("No XML component installed!");
37 }
38 }
39
40 /**
41 * Creates an HTTP GET request and sends the response to the callback function.
42 *
43 * Note that dynamic arguments in the URI should be escaped with encodeURIComponent().
44 */
45 function HTTPGet(uri, callbackFunction, callbackParameter) {
46 var xmlHttp = new XMLHttpRequest();
47 var bAsync = true;
48 if (!callbackFunction) {
49 bAsync = false;
50 }
51 xmlHttp.open('GET', uri, bAsync);
52 xmlHttp.send(null);
53
54 if (bAsync) {
55 if (callbackFunction) {
56 xmlHttp.onreadystatechange = function() {
57 if (xmlHttp.readyState == 4) {
58 callbackFunction(xmlHttp.responseText, xmlHttp, callbackParameter);
59 }
60 }
61 }
62 return true;
63 }
64 else {
65 return xmlHttp.responseText;
66 }
67 }
68
69 /**
70 * Creates an HTTP POST request and sends the response to the callback function
71 *
72 * Note: passing null or undefined for 'object' makes the request fail in Opera 8.
73 * Pass an empty string instead.
74 */
75 function HTTPPost(uri, callbackFunction, callbackParameter, object) {
76 var xmlHttp = new XMLHttpRequest();
77 var bAsync = true;
78 if (!callbackFunction) {
79 bAsync = false;
80 }
81 xmlHttp.open('POST', uri, bAsync);
82
83 var toSend = '';
84 if (typeof object == 'object') {
85 xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
86 for (var i in object) {
87 toSend += (toSend ? '&' : '') + i + '=' + encodeURIComponent(object[i]);
88 }
89 }
90 else {
91 toSend = object;
92 }
93 xmlHttp.send(toSend);
94
95 if (bAsync) {
96 if (callbackFunction) {
97 xmlHttp.onreadystatechange = function() {
98 if (xmlHttp.readyState == 4) {
99 callbackFunction(xmlHttp.responseText, xmlHttp, callbackParameter);
100 }
101 }
102 }
103 return true;
104 }
105 else {
106 return xmlHttp.responseText;
107 }
108 }
109
110 /**
111 * Redirects a button's form submission to a hidden iframe and displays the result
112 * in a given wrapper. The iframe should contain a call to
113 * window.parent.iframeHandler() after submission.
114 */
115 function redirectFormButton(uri, button, handler) {
116 // Make sure we have an iframe to target
117 createIframe();
118
119 // Trap the button
120 button.onmouseover = button.onfocus = function() {
121 button.onclick = function() {
122 // Prepare variables for use in anonymous function.
123 var button = this;
124 var action = button.form.action;
125 var target = button.form.target;
126
127 // Redirect form submission
128 this.form.action = uri;
129 this.form.target = 'redirect-target';
130
131 handler.onsubmit();
132
133 // Set iframe handler for later
134 window.iframeHandler = function () {
135 var iframe = $('redirect-target');
136 // Restore form submission
137 button.form.action = action;
138 button.form.target = target;
139
140 // Get response from iframe body
141 try {
142 response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
143 // Firefox 1.0.x hack: Replace control characters
144 response = response.replace(/[\f\n\r\t\v]/g, ' ');
145 if (window.opera) {
146 // Opera-hack: it returns innerHTML sanitized.
147 response = response.replace(/&quot;/g, '"');
148 }
149 }
150 catch (e) {
151 response = null;
152 }
153
154 // Recreate the iframe: re-using an old iframe can sometimes cause browser bugs.
155 createIframe();
156
157 response = parseJson(response);
158 // Check response code
159 if (response.status == 0) {
160 handler.onerror(response.data);
161 return;
162 }
163 handler.oncomplete(response.data);
164 }
165
166 return true;
167 }
168 }
169 button.onmouseout = button.onblur = function() {
170 button.onclick = null;
171 }
172 }
173
174 /**
175 * Adds a function to the window onload event
176 */
177 function addLoadEvent(func) {
178 var oldOnload = window.onload;
179 if (typeof window.onload != 'function') {
180 window.onload = func;
181 }
182 else {
183 window.onload = function() {
184 oldOnload();
185 func();
186 }
187 }
188 }
189
190 /**
191 * Adds a function to a given form's submit event
192 */
193 function addSubmitEvent(form, func) {
194 var oldSubmit = form.onsubmit;
195 if (typeof oldSubmit != 'function') {
196 form.onsubmit = func;
197 }
198 else {
199 form.onsubmit = function() {
200 return oldSubmit() && func();
201 }
202 }
203 }
204
205 /**
206 * Retrieves the absolute position of an element on the screen
207 */
208 function absolutePosition(el) {
209 var sLeft = 0, sTop = 0;
210 var isDiv = /^div$/i.test(el.tagName);
211 if (isDiv && el.scrollLeft) {
212 sLeft = el.scrollLeft;
213 }
214 if (isDiv && el.scrollTop) {
215 sTop = el.scrollTop;
216 }
217 var r = { x: el.offsetLeft - sLeft, y: el.offsetTop - sTop };
218 if (el.offsetParent) {
219 var tmp = absolutePosition(el.offsetParent);
220 r.x += tmp.x;
221 r.y += tmp.y;
222 }
223 return r;
224 };
225
226 function dimensions(el) {
227 return { width: el.offsetWidth, height: el.offsetHeight };
228 }
229
230 /**
231 * Returns true if an element has a specified class name
232 */
233 function hasClass(node, className) {
234 if (node.className == className) {
235 return true;
236 }
237 var reg = new RegExp('(^| )'+ className +'($| )')
238 if (reg.test(node.className)) {
239 return true;
240 }
241 return false;
242 }
243
244 /**
245 * Adds a class name to an element
246 */
247 function addClass(node, className) {
248 if (hasClass(node, className)) {
249 return false;
250 }
251 node.className += ' '+ className;
252 return true;
253 }
254
255 /**
256 * Removes a class name from an element
257 */
258 function removeClass(node, className) {
259 if (!hasClass(node, className)) {
260 return false;
261 }
262 node.className = eregReplace('(^| )'+ className +'($| )', '', node.className);
263 return true;
264 }
265
266 /**
267 * Toggles a class name on or off for an element
268 */
269 function toggleClass(node, className) {
270 if (!removeClass(node, className) && !addClass(node, className)) {
271 return false;
272 }
273 return true;
274 }
275
276 /**
277 * Emulate PHP's ereg_replace function in javascript
278 */
279 function eregReplace(search, replace, subject) {
280 return subject.replace(new RegExp(search,'g'), replace);
281 }
282
283 /**
284 * Removes an element from the page
285 */
286 function removeNode(node) {
287 if (typeof node == 'string') {
288 node = $(node);
289 }
290 if (node && node.parentNode) {
291 return node.parentNode.removeChild(node);
292 }
293 else {
294 return false;
295 }
296 }
297
298 /**
299 * Prevents an event from propagating.
300 */
301 function stopEvent(event) {
302 if (event.preventDefault) {
303 event.preventDefault();
304 event.stopPropagation();
305 }
306 else {
307 event.returnValue = false;
308 event.cancelBubble = true;
309 }
310 }
311
312 /**
313 * Parse a JSON response.
314 *
315 * The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
316 */
317 function parseJson(data) {
318 if (data.substring(0,1) != '{') {
319 return { status: 0, data: data.length ? data : 'Unspecified error' };
320 }
321 return eval('(' + data + ');');
322 }
323
324 /**
325 * Create an invisible iframe for form submissions.
326 */
327 function createIframe() {
328 // Delete any previous iframe
329 deleteIframe();
330 // Note: some browsers require the literal name/id attributes on the tag,
331 // some want them set through JS. We do both.
332 window.iframeHandler = function () {};
333 var div = document.createElement('div');
334 div.id = 'redirect-holder';
335 div.innerHTML = '<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>';
336 var iframe = div.firstChild;
337 with (iframe) {
338 name = 'redirect-target';
339 setAttribute('name', 'redirect-target');
340 id = 'redirect-target';
341 }
342 with (iframe.style) {
343 position = 'absolute';
344 height = '1px';
345 width = '1px';
346 visibility = 'hidden';
347 }
348 document.body.appendChild(div);
349 }
350
351 /**
352 * Delete the invisible iframe for form submissions.
353 */
354 function deleteIframe() {
355 var holder = $('redirect-holder');
356 if (typeof holder != 'undefined') {
357 removeNode(holder);
358 }
359 }
360
361 /**
362 * Wrapper around document.getElementById().
363 */
364 function $(id) {
365 return document.getElementById(id);
366 }

  ViewVC Help
Powered by ViewVC 1.1.2