6452d26fa138fe780c3c154230093585c2ed1e8d
[jalviewjs.git] / site / js / SwingJSjQueryExt.js
1 // SwingJSjQueryExt.js
2 // BH 7/24/2015 7:24:30 AM renamed from JSmoljQueryExt.js
3 // 9/2/2013 7:43:12 AM BH Opera/Safari fix for binary file reading
4 // 3/11/2014 6:31:01 AM BH fix for MSIE not working locally
5
6 ;(function($) {
7
8         function createXHR(isMSIE) {
9                 try {
10                         return (isMSIE ? new window.ActiveXObject( "Microsoft.XMLHTTP" ) : new window.XMLHttpRequest());
11                 } catch( e ) {}
12         }
13
14  $.ajaxSettings.xhr = (window.ActiveXObject === undefined ? createXHR :  
15         function() {
16                 return (this.url == document.location || this.url.indexOf("http") == 0 || !this.isLocal) &&  // BH MSIE fix
17                         /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
18                         createXHR() || createXHR(1);
19         });
20
21
22 // Bind script tag hack transport
23                 $.ajaxTransport( "+script", function(s) {
24
25         // This transport only deals with cross domain requests
26         // BH: No! This is not compatible with Chrome
27         if ( true || s.crossDomain ) {
28
29                 var script,
30                         head = document.head || jQuery("head")[0] || document.documentElement;
31
32                 return {
33
34                         send: function( _, callback ) {
35                                 script = document.createElement("script");
36                                 //script.async = true;
37
38                                 if ( s.scriptCharset ) {
39                                         script.charset = s.scriptCharset;
40                                 }
41
42                                 script.src = s.url;
43
44                                 // Attach handlers for all browsers
45                                 script.onload = script.onreadystatechange = function( _, isAbort ) {
46
47                                         if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
48
49                                                 // Handle memory leak in IE
50                                                 script.onload = script.onreadystatechange = null;
51                                                 // Remove the script
52                                                 if ( script.parentNode ) {
53                                                         script.parentNode.removeChild( script );
54                                                 }
55
56                                                 // Dereference the script
57                                                 script = null;
58
59                                                 // Callback if not abort
60                                                 if ( !isAbort ) {
61                                                         callback( 200, "success" );
62                                                 }
63                                         }
64                                 };
65
66                                 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
67                                 // Use native DOM manipulation to avoid our domManip AJAX trickery
68                                 head.insertBefore( script, head.firstChild );
69                         },
70
71                         abort: function() {
72                                 if ( script ) {
73                                         script.onload( undefined, true );
74                                 }
75                         }
76                 };
77         }
78 });
79  
80         // incorporates jquery.iecors MSIE asynchronous cross-domain request for MSIE < 10
81
82         $.extend( $.support, { iecors: !!window.XDomainRequest });
83
84         if ($.support.iecors) {
85                 // source: https://github.com/dkastner/jquery.iecors
86                 // author: Derek Kastner dkastner@gmail.com http://dkastner.github.com    
87                 $.ajaxTransport(function(s) {
88                 
89                         return {
90                                 send: function( headers, complete ) {                           
91                                         // Note that xdr is not synchronous.
92                                         // This is only being used in JSmol for transport of java code packages.
93                                         var xdr = new window.XDomainRequest();
94                                         xdr.onload = function() {          
95                                                 var headers = { 'Content-Type': xdr.contentType };
96                                                 complete(200, 'OK', { text: xdr.responseText }, headers);
97                                         };
98                                         if ( s.xhrFields ) {
99                                                 xdr.onerror = s.xhrFields.error;
100                                                 xdr.ontimeout = s.xhrFields.timeout;
101                                         }
102                                         xdr.open( s.type, s.url );
103                                         xdr.send( ( s.hasContent && s.data ) || null );
104                                 },
105                                 abort: function() {        
106                                         xdr.abort();
107                                 }
108                         };
109                 });
110
111         } else {
112
113         // adds support for synchronous binary file reading
114
115                 $.ajaxSetup({
116                         accepts: { binary: "text/plain; charset=x-user-defined" },
117                         responseFields: { binary: "response" }
118                 })
119
120
121                 $.ajaxTransport('binary', function(s) {
122                 
123                         var callback;
124                         return {
125                                 // synchronous or asynchronous binary transfer only
126                                 send: function( headers, complete ) {        
127                                         var xhr = s.xhr();
128                                         console.log("xhr.open binary async=" + s.async + " url=" + s.url);
129                                         xhr.open( s.type, s.url, s.async );                                     
130                                         var isOK = false;
131                                         try {
132                                                 if (xhr.hasOwnProperty("responseType")) {
133                                                                 xhr.responseType = "arraybuffer";
134                                                                 isOK = true;
135                                                 } 
136                                         } catch(e) {
137                                           //
138                                         }
139                                         try {
140                                                 if (!isOK && xhr.overrideMimeType) {
141                                                         xhr.overrideMimeType('text/plain; charset=x-user-defined');
142                                                 }
143                                         } catch(e) {
144                                                         //
145                                         }
146                                         if ( !s.crossDomain && !headers["X-Requested-With"] ) {
147                                                 headers["X-Requested-With"] = "XMLHttpRequest";
148                                         }
149                                         try {
150                                                 for (var i in headers )
151                                                         xhr.setRequestHeader( i, headers[ i ] );
152                                         } catch(_) {}
153
154                                         xhr.send( ( s.hasContent && s.data ) || null );
155
156                                         // Listener
157                                         callback = function( _, isAbort ) {
158
159                                         var 
160                                                 status = xhr.status,
161                                                 statusText = "",
162                                                 responseHeaders = xhr.getAllResponseHeaders(),
163                                                 responses = {},
164                                                 xml;
165
166                                         try {
167
168                                                 // Firefox throws exceptions when accessing properties
169                                                 // of an xhr when a network error occured
170                                                 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
171                                                 // Was never called and is aborted or complete
172                                                 if ( callback && ( xhr.readyState === 4 ) ) {
173
174                                                         // Only called once
175                                                         callback = undefined;
176
177                                                         // When requesting binary data, IE6-9 will throw an exception
178                                                         // on any attempt to access responseText (#11426)
179                                                         try {
180                                                                 responses.text = (typeof xhr.responseText === "string" ? xhr.responseText : null);
181                                                         } catch( _ ) {
182                                                         }
183                                                         try {
184                                                                 responses.binary = xhr.response;
185                                                         } catch( _ ) {
186                                                         }
187
188                                                         // Firefox throws an exception when accessing
189                                                         // statusText for faulty cross-domain requests
190                                                         try {
191                                                                 statusText = xhr.statusText;
192                                                         } catch( _ ) {
193                                                                 // We normalize with Webkit giving an empty statusText
194                                                                 statusText = "";
195                                                         }
196                                                         // Filter status for non standard behaviors
197
198                                                         // If the request is local and we have data: assume a success
199                                                         // (success with no data won't get notified, that's the best we
200                                                         // can do given current implementations)
201                                                         if ( !status && s.isLocal && !s.crossDomain ) {
202                                                                 status = (responses.text ? 200 : 404);
203                                                         // IE - #1450: sometimes returns 1223 when it should be 204
204                                                         } else if ( status === 1223 ) {
205                                                                 status = 204;
206                                                         }
207                                                         complete( status, statusText, responses, responseHeaders );
208                                                 }
209                                         } catch( e ) {
210                                                 alert(e)
211                                                 complete( -1, e );
212                                         }
213                                         };
214                                         
215                                         if ( !s.async ) {
216                                                 // if we're in sync mode we fire the callback
217                                                 callback();
218                                         } else if ( xhr.readyState === 4 ) {
219                                                 // (IE6 & IE7) if it's in cache and has been
220                                                 // retrieved directly we need to fire the callback
221                                                 setTimeout( callback );
222                                         } else {
223                                                 // Add to the list of active xhr callbacks
224                                                 xhr.onreadystatechange = callback;
225                                         }
226                                         
227                                 },
228                                 abort: function() {}
229                         };
230                 });
231         }
232 })( jQuery );
233          
234 /*
235  * jQuery outside events - v1.1 - 3/16/2010
236  * http://benalman.com/projects/jquery-outside-events-plugin/
237  * 
238  * Copyright (c) 2010 "Cowboy" Ben Alman
239  * Dual licensed under the MIT and GPL licenses.
240  * http://benalman.com/about/license/
241  * 
242  * Modified by Bob Hanson for JSmol-specific events and to add parameter reference to actual jQuery event.
243  * Used for closing the pop-up menu.
244  *   
245  */
246
247 ;(function($,doc,eventList,id){  
248         // was 'click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup'
249         $.map(
250                 eventList.split(' '),
251                 function( event_name ) { jq_addOutsideEvent( event_name ); }
252         );
253         jq_addOutsideEvent( 'focusin',  'focus' + id );
254         jq_addOutsideEvent( 'focusout', 'blur' + id );
255         function jq_addOutsideEvent( event_name, outside_event_name ) {
256                 outside_event_name = outside_event_name || event_name + id;
257                 var elems = $(),
258                         event_namespaced = event_name + '.' + outside_event_name + '-special-event';
259                 $.event.special[ outside_event_name ] = {    
260                         setup: function(){
261                                 elems = elems.add( this );
262                                 if ( elems.length === 1 ) {
263                                         $(doc).bind( event_namespaced, handle_event );
264                                 }
265                         },
266                         teardown: function(){
267                                 self.Jmol && Jmol._setMouseOwner(null);
268                                 elems = elems.not( this );
269                                 if ( elems.length === 0 ) {
270                                         $(doc).unbind( event_namespaced );
271                                 }
272                         },
273                         add: function( handleObj ) {
274                                 var old_handler = handleObj.handler;
275                                 handleObj.handler = function( event, elem ) {
276                                         event.target = elem;
277                                         old_handler.apply( this, arguments );
278                                 };
279                         }
280                 };
281                 function handle_event( event ) {
282                         $(elems).each(function(){
283                                 self.Jmol && (outside_event_name.indexOf("mouseup") >= 0 || outside_event_name.indexOf("touchend") >= 0) && Jmol._setMouseOwner(null);
284                                 var elem = $(this);
285                                 if ( this !== event.target && !elem.has(event.target).length ) {
286                                         //BH: adds event to pass that along to our handler as well.
287                                         elem.triggerHandler( outside_event_name, [ event.target, event ] );
288                                 }
289                         });
290                 };
291         };
292 })(jQuery,document,"click mousemove mouseup touchmove touchend", "outjsmol");