Merge branch 'Jalview-JS/jim/JAL-3253-JAL-3418' into Jalview-JS/JAL-3253-applet
[jalview.git] / site-resources / javascript / facebox-1.3.js
1 /*
2  * Facebox (for jQuery)
3  * version: 1.2 (05/05/2008)
4  * @requires jQuery v1.2 or later
5  *
6  * Examples at http://famspam.com/facebox/
7  *
8  * Licensed under the MIT:
9  *   http://www.opensource.org/licenses/mit-license.php
10  *
11  * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
12  *
13  * Usage:
14  *
15  *  jQuery(document).ready(function() {
16  *    jQuery('a[rel*=facebox]').facebox()
17  *  })
18  *
19  *  <a href="#terms" rel="facebox">Terms</a>
20  *    Loads the #terms div in the box
21  *
22  *  <a href="terms.html" rel="facebox">Terms</a>
23  *    Loads the terms.html page in the box
24  *
25  *  <a href="terms.png" rel="facebox">Terms</a>
26  *    Loads the terms.png image in the box
27  *
28  *
29  *  You can also use it programmatically:
30  *
31  *    jQuery.facebox('some html')
32  *    jQuery.facebox('some html', 'my-groovy-style')
33  *
34  *  The above will open a facebox with "some html" as the content.
35  *
36  *    jQuery.facebox(function($) {
37  *      $.get('blah.html', function(data) { $.facebox(data) })
38  *    })
39  *
40  *  The above will show a loading screen before the passed function is called,
41  *  allowing for a better ajaxy experience.
42  *
43  *  The facebox function can also display an ajax page, an image, or the contents of a div:
44  *
45  *    jQuery.facebox({ ajax: 'remote.html' })
46  *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
47  *    jQuery.facebox({ image: 'stairs.jpg' })
48  *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
49  *    jQuery.facebox({ div: '#box' })
50  *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')
51  *
52  *  Want to close the facebox?  Trigger the 'close.facebox' document event:
53  *
54  *    jQuery(document).trigger('close.facebox')
55  *
56  *  Facebox also has a bunch of other hooks:
57  *
58  *    loading.facebox
59  *    beforeReveal.facebox
60  *    reveal.facebox (aliased as 'afterReveal.facebox')
61  *    init.facebox
62  *    afterClose.facebox
63  *
64  *  Simply bind a function to any of these hooks:
65  *
66  *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
67  *
68  */
69 (function($) {
70   $.facebox = function(data, klass) {
71     $.facebox.loading()
72
73     if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
74     else if (data.image) fillFaceboxFromImage(data.image, klass)
75     else if (data.div) fillFaceboxFromHref(data.div, klass)
76     else if ($.isFunction(data)) data.call($)
77     else $.facebox.reveal(data, klass)
78   }
79
80   /*
81    * Public, $.facebox methods
82    */
83
84   $.extend($.facebox, {
85     settings: {
86       opacity      : 0.2,
87       overlay      : true,
88       loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif',
89       closeImage   : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png',
90       imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
91       faceboxHtml  : '\
92     <div id="facebox" style="display:none;"> \
93       <div class="popup"> \
94         <div class="content"> \
95         </div> \
96         <a href="#" class="close"><img src="https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png" title="close" class="close_image" /></a> \
97       </div> \
98     </div>'
99     },
100
101     loading: function() {
102       init()
103       if ($('#facebox .loading').length == 1) return true
104       showOverlay()
105
106       $('#facebox .content').empty()
107       $('#facebox .body').children().hide().end().
108         append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>')
109
110       $('#facebox').css({
111         top:    getPageScroll()[1] + (getPageHeight() / 10),
112         left:   $(window).width() / 2 - 205
113       }).show()
114
115       $(document).bind('keydown.facebox', function(e) {
116         if (e.keyCode == 27) $.facebox.close()
117         return true
118       })
119       $(document).trigger('loading.facebox')
120     },
121
122     reveal: function(data, klass) {
123       $(document).trigger('beforeReveal.facebox')
124       if (klass) $('#facebox .content').addClass(klass)
125       $('#facebox .content').append('<pre><code>'+JSON.stringify(JSON.parse(data),null,4)+'</pre></code>')
126       $('#facebox .loading').remove()
127       $('#facebox .body').children().fadeIn('normal')
128       $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').width() / 2))
129       $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
130     },
131
132     close: function() {
133       $(document).trigger('close.facebox')
134       return false
135     }
136   })
137
138   /*
139    * Public, $.fn methods
140    */
141
142   $.fn.facebox = function(settings) {
143     if ($(this).length == 0) return
144
145     init(settings)
146
147     function clickHandler() {
148       $.facebox.loading(true)
149
150       // support for rel="facebox.inline_popup" syntax, to add a class
151       // also supports deprecated "facebox[.inline_popup]" syntax
152       var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
153       if (klass) klass = klass[1]
154
155       fillFaceboxFromHref(this.href, klass)
156       return false
157     }
158
159     return this.bind('click.facebox', clickHandler)
160   }
161
162   /*
163    * Private methods
164    */
165
166   // called one time to setup facebox on this page
167   function init(settings) {
168     if ($.facebox.settings.inited) return true
169     else $.facebox.settings.inited = true
170
171     $(document).trigger('init.facebox')
172     makeCompatible()
173
174     var imageTypes = $.facebox.settings.imageTypes.join('|')
175     $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i')
176
177     if (settings) $.extend($.facebox.settings, settings)
178     $('body').append($.facebox.settings.faceboxHtml)
179
180     var preload = [ new Image(), new Image() ]
181     preload[0].src = $.facebox.settings.closeImage
182     preload[1].src = $.facebox.settings.loadingImage
183
184     $('#facebox').find('.b:first, .bl').each(function() {
185       preload.push(new Image())
186       preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
187     })
188
189     $('#facebox .close').click($.facebox.close)
190     $('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
191   }
192
193   // getPageScroll() by quirksmode.com
194   function getPageScroll() {
195     var xScroll, yScroll;
196     if (self.pageYOffset) {
197       yScroll = self.pageYOffset;
198       xScroll = self.pageXOffset;
199     } else if (document.documentElement && document.documentElement.scrollTop) {         // Explorer 6 Strict
200       yScroll = document.documentElement.scrollTop;
201       xScroll = document.documentElement.scrollLeft;
202     } else if (document.body) {// all other Explorers
203       yScroll = document.body.scrollTop;
204       xScroll = document.body.scrollLeft;
205     }
206     return new Array(xScroll,yScroll)
207   }
208
209   // Adapted from getPageSize() by quirksmode.com
210   function getPageHeight() {
211     var windowHeight
212     if (self.innerHeight) {     // all except Explorer
213       windowHeight = self.innerHeight;
214     } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
215       windowHeight = document.documentElement.clientHeight;
216     } else if (document.body) { // other Explorers
217       windowHeight = document.body.clientHeight;
218     }
219     return windowHeight
220   }
221
222   // Backwards compatibility
223   function makeCompatible() {
224     var $s = $.facebox.settings
225
226     $s.loadingImage = $s.loading_image || $s.loadingImage
227     $s.closeImage = $s.close_image || $s.closeImage
228     $s.imageTypes = $s.image_types || $s.imageTypes
229     $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
230   }
231
232   // Figures out what you want to display and displays it
233   // formats are:
234   //     div: #id
235   //   image: blah.extension
236   //    ajax: anything else
237   function fillFaceboxFromHref(href, klass) {
238     // div
239     if (href.match(/#/)) {
240       var url    = window.location.href.split('#')[0]
241       var target = href.replace(url,'')
242       if (target == '#') return
243       $.facebox.reveal($(target).html(), klass)
244
245     // image
246     } else if (href.match($.facebox.settings.imageTypesRegexp)) {
247       fillFaceboxFromImage(href, klass)
248     // ajax
249     } else {
250       fillFaceboxFromAjax(href, klass)
251     }
252   }
253
254   function fillFaceboxFromImage(href, klass) {
255     var image = new Image()
256     image.onload = function() {
257       $.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
258     }
259     image.src = href
260   }
261
262   function fillFaceboxFromAjax(href, klass) {
263     $.get(href, function(data) { $.facebox.reveal(data, klass) })
264   }
265
266   function skipOverlay() {
267     return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
268   }
269
270   function showOverlay() {
271     if (skipOverlay()) return
272
273     if ($('#facebox_overlay').length == 0)
274       $("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')
275
276     $('#facebox_overlay').hide().addClass("facebox_overlayBG")
277       .css('opacity', $.facebox.settings.opacity)
278       .click(function() { $(document).trigger('close.facebox') })
279       .fadeIn(200)
280     return false
281   }
282
283   function hideOverlay() {
284     if (skipOverlay()) return
285
286     $('#facebox_overlay').fadeOut(200, function(){
287       $("#facebox_overlay").removeClass("facebox_overlayBG")
288       $("#facebox_overlay").addClass("facebox_hide")
289       $("#facebox_overlay").remove()
290     })
291
292     return false
293   }
294
295   /*
296    * Bindings
297    */
298
299   $(document).bind('close.facebox', function() {
300     $(document).unbind('keydown.facebox')
301     $('#facebox').fadeOut(function() {
302       $('#facebox .content').removeClass().addClass('content')
303       $('#facebox .loading').remove()
304       $(document).trigger('afterClose.facebox')
305     })
306     hideOverlay()
307   })
308
309 })(jQuery);