You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by br...@apache.org on 2014/02/14 18:24:35 UTC
svn commit: r1568367 [2/13] - in /jspwiki/trunk: ./ jspwiki-war/
jspwiki-war/src/main/config/wro/ jspwiki-war/src/main/java/org/apache/wiki/
jspwiki-war/src/main/scripts/dynamic-styles/
jspwiki-war/src/main/scripts/lib/ jspwiki-war/src/main/scripts/moo...
Added: jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.Slimbox.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.Slimbox.js?rev=1568367&view=auto
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.Slimbox.js (added)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.Slimbox.js Fri Feb 14 17:24:32 2014
@@ -0,0 +1,292 @@
+/*
+Plugin: Viewer.Slimbox
+
+ Slimbox clone, refactored for JSPWiki.
+ Added support for iframes, flash video.
+ Todo: html5 video.
+
+Credits:
+ Inspired by Slimbox by Christophe Bleys, (see http://www.digitalia.be/software/slimbox)
+ the mediaboxAdvanced by John Einselen (see http://iaian7.com/webcode/mediaboxAdvanced)
+ and the diabox by Mike Nelson. (see https://github.com/mnelson/diabox)
+
+DOM structure:
+ DOM structure of the JSPWiki Slimbox viewer.
+ (start code)
+ div#slmbx
+ div.modal //semi transparent screen overlay
+ div.viewport(.spin) //img, object or iframe element is inserted here
+ a.controls.caption
+ a.controls.next
+ a.controls.prev
+ a.controls.close
+ (end)
+*/
+Viewer.Slimbox = new Class({
+
+ Implements: Options,
+ Binds: ['attach','key','update','resize'],
+
+ options: {
+ loop: true, // (boolean) affects next/prev at last/first element
+ width: 800, // (int px) default width of the box
+ height: 600, // (int px) default height of the box
+ hints: { // default controls
+ btn: 'Click to view {0}',
+ close: '×',
+ next: '>', //« Next
+ prev: '<', //» Previous
+ nofm: '[{0}/{1}]', //[page/#pages]
+ size: ' ({0}px × {1}px)', // (height x width)
+ caption: ' Go to {0}'
+ },
+ keys: {
+ close: ['esc','x','c'],
+ prev: ['left','up','p'],
+ next: ['enter','space','right','down','n']
+ }
+ },
+
+ initialize: function(options){
+
+ var self = this.setOptions(options),
+ hints = self.options.hints,
+ controls = 'a.controls.';
+
+ //helper function
+ function clickFn(){
+ if( this.match('.next')){ self.update(1); }
+ else if( this.match('.prev')){ self.update(-1); }
+ else { self.attach( /*O=close*/ ); }
+ }
+
+ $(document.body).grab([
+ 'div.slmbx', { attach:self }, [
+ 'div.slmodal',{ events:{ click:clickFn } },
+ 'div.viewport', { attach:[self,'viewport'], events:{ 'click:relay(a)':clickFn } }, [
+ //insert viewable iframe/object/img ...
+ controls+'caption',
+ controls+'next', { html:hints.next },
+ controls+'prev', { html:hints.prev },
+ controls+'close', { html:hints.close }
+ ]
+ ]
+ ].slick());
+
+ },
+
+ /*
+ Function: get
+ Retrieve DOM elements inside the slimbox container, based on a css selector.
+ Example:
+ > this.get('a.next');
+ */
+ get: function( selector ){
+
+ return this.element.getElement(selector);
+
+ },
+
+ /*
+ Function: match
+ Check if the URL is recognized as a viewable object/image/html...
+ */
+ match: function(url){
+
+ return Viewer.match(url,this.options);
+
+ },
+
+ /*
+ Function: watch
+ Install click handlers on a group of images/objects/media links,
+ and optionally add slimbox click-buttons.
+
+ Arguments:
+ elements - set of DOM elements
+ btn - (optional) slick selector to insert a slimbox button after each viewable link
+ Returns
+ set of DOM elements viewable via Slimbox
+ Example
+ > TheSlimbox.watch( $$('.slimbox a','a.slimbox-btn');
+
+ */
+ watch: function(elements, btn){
+
+ var self = this, caption;
+
+ elements = $$(elements).filter( function(el){
+ return self.match( el.src||el.href );
+ });
+
+ return elements.each( function(el,idx){
+
+ caption = el.get('text') || el.title || el.alt;
+
+ if( btn ){
+ el = btn.slick({
+ href:el.src||el.href,
+ title: self.options.hints.btn.xsubs(caption)
+ }).inject(el,'after');
+ }
+
+ el.addEvent('click', function(ev){ ev.stop(); self.show(elements,idx); });
+
+ });
+
+ },
+
+
+ /*
+ Function: show
+ Start the image/media viewer for a set of elements.
+ Arguments
+ elements - set of DOM elements to be viewed
+ cursor - index of first items to be viewed
+ */
+ show: function( elements, cursor ){
+
+ var self = this;
+ self.elements = elements;
+ self.cursor = cursor;
+ self.attach( 1 /*true*/ );
+ self.update( 0 );
+
+ },
+
+ /*
+ Function: attach
+ Attach or de-tach eventhandlers from the slimbox dialogs.
+ Display or hide the modal and viewport. (css class .show)
+ */
+ attach: function( open ){
+
+ var self = this,
+ fn = open ? 'addEvent' : 'removeEvent';
+
+ ['object', Browser.ie6 ? 'select' : 'embed'].each(function(tag) {
+ $$(tag).each( function(el){
+ if( open ) el._slimbox = el.style.visibility;
+ el.style.visibility = open ? 'hidden' : el._slimbox;
+ });
+ });
+
+ self.element.ifClass(open,'active');
+ self.reset();
+
+ document[fn]('keydown', self.key); //checkme: support arrow keys, etc.
+
+ },
+
+ reset: function(){
+
+ this.viewport.getElements(':not(.controls)').destroy();
+ this.preload = null;
+
+ },
+
+ /*
+ Function: key
+ Handle keystrokes.
+ */
+ key: function( event ){
+
+ var self = this,
+ keys = self.options.keys,
+ key = event.key;
+
+ //console.log('keydown ', key);
+ keys.close.contains(key) ? self.attach(/*O=close*/) :
+ keys.next.contains(key) ? self.update(1) :
+ keys.prev.contains(key) ? self.update(-1) :
+ /*otherwise*/ key=0;
+
+ if(key) event.stop();
+
+ },
+
+ /*
+ Function: update
+ Updates the viewport and the controls with caption, next and previous links.
+ Implements cursor loop-around logic.
+
+ Arguments:
+ increment - move the cursor by increment, and display the new content
+ */
+ update: function( increment ){
+
+ var self = this,
+ options = self.options,
+ hints = options.hints,
+ elements = self.elements,
+
+ max = elements.length,
+ many = max > 1,
+
+ incr = function(num){
+ return options.loop ? (num >= max) ? 0 : (num < 0) ? max-1 : num : num;
+ },
+ cursor = incr( self.cursor+increment ).limit( 0, max-1 ), //new cursor value
+
+ el, url;
+
+ if( increment!=0 && (cursor == self.cursor)){ return; }
+
+ self.cursor = cursor;
+ self.get('.prev')[ (many && (incr(cursor-1) >= 0 )) ? 'show' : 'hide']();
+ self.get('.next')[ (many && (incr(cursor+1) < max)) ? 'show' : 'hide']();
+
+ el = elements[cursor];
+ url = el.href||el.src; //url = encodeURIComponent(url);
+
+ self.get('.caption').set({
+ href: url,
+ html:
+ ( many ? hints.nofm.xsubs( cursor+1, max) : '' ) +
+ hints.caption.xsubs( el.title || el.alt || el.get('text')/*||''*/)
+ });
+
+ self.viewport.addClass('loading');
+ //if( self.preload ){ self.preload.destroy(); self.preload = null;}
+ self.reset();
+ //alert('wait');
+ Viewer.preload( url, options, self.resize );
+
+ },
+
+ /*
+ Function: resize
+ Completes the resizing of the viewport, after loading the img, iframe or object.
+ */
+ resize: function( preload ){
+
+ var self = this,
+ isImage = preload.match('img'),
+ viewport = self.viewport,
+
+ wSize = window.getSize(),
+ width = preload.width.toInt().limit( 240, 0.9*wSize.x ).toInt(),
+ height = preload.height.toInt().min( 0.9*wSize.y ).toInt(),
+ caption = self.get('.caption');
+
+ self.preload = preload;
+
+ //append viewport dimensions in px to the caption
+ caption.set('html', caption.get('html') + self.options.hints.size.xsubs(width,height) );
+
+ // viewport has css set to { top:50%, left:50% } for automatic centered positioning
+ viewport
+ .removeClass('loading')
+ .setStyles({
+ backgroundImage: isImage ? 'url(' + preload.src + ')' : 'none',
+ //rely on css3 transitions... iso mootools morph
+ width:width, height:height, marginTop:-height/2, marginLeft:-width/2
+ });
+ //mootools transition, in case css3 would not be available
+ //.morph({ width:width, height:height, marginTop:-height/2, marginLeft:-width/2 });
+
+ if( !isImage ) viewport.grab( preload ); //now include the viewer in the dom
+
+ }
+
+});
\ No newline at end of file
Added: jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.js?rev=1568367&view=auto
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.js (added)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/dynamic-styles/Viewer.js Fri Feb 14 17:24:32 2014
@@ -0,0 +1,293 @@
+/*
+Viewer object
+ match(url,options): function to retrieve the media parms based on a url
+ preload(url,options,callback): preloads (created DOM object) the correct viewer
+ with the correct rendering paramaters (eg: used by Viewer.Slimbox)
+ preloads(elements,options,callback): preloads a set of viewer objects,
+ and calculates the minimals viewer-box dimensions (eg: used by Viewer.Carousel)
+
+ LIB: data-array of pairs [['re1',{parms1}],['re2',{parms2}],..]
+ used by match() and preload() to identify the correct viewer & parameters.
+ This array can be customised and extended.
+
+ regexp - (string) match against the url
+ parms - (function or object) returns the viewer parameters
+ 'img' - to be rendered as IMG, directly in the browser
+ 'url' - to be rendered as OBJECT (eg flash)
+ 'src' - to be rendered as IFRAME
+ other-parameters with additional details
+*/
+!function(){
+
+this.Viewer = {
+
+ LIB: [],
+
+ match: function(url, options){
+
+ var result = {};
+
+ if( typeOf(url)=='element' ) url = url.src || url.href;
+
+ this.LIB.some( function(item){
+
+ return url.test( item[0], 'i' )
+ //item[1] can be a value or a function(url,options)
+ && (result = Function.from(item[1])(url, options) );
+
+ });
+
+ //options.type = 'img'|'url'|'src'
+ //options.type = 'img';
+ //console.log(options.type);
+ if( options.type && !result[options.type] ) return false
+
+
+ return result;
+ },
+
+
+ preload: function(element, options, callback ){
+
+ var match = this.match(element, options),
+ preload;
+
+ function done(){
+ //console.log( match.width, preload.width.toInt(), match.height, preload.height.toInt(), preload);
+ if( callback ) callback( preload, preload.width.toInt(), preload.height.toInt() );
+ }
+
+ options = {
+ id: 'VIEW.' + String.uniqueID(),
+ width:options.width,
+ height:options.height
+ };
+
+ if( match.img ){
+
+ preload = new Image();
+ preload.onload = done; //delayed onload to know height&width of the image
+ preload.alt = element.alt;
+ //preload.title = element.title;
+ preload.src = match.img;
+
+ } else {
+
+ //ffs: add branch for html5 enabled browsers & html5 enabled video sources
+ //if( match.url5 ) ...
+ if( match.url ){
+
+ preload = $(new Swiff( match.url, Object.merge(options, {
+ params: {
+ wmode: 'transparent',//'opaque', //'direct',
+ //bgcolor: '#FFFFFF',
+ allowfullscreen: 'true',
+ allowscriptaccess: 'always'
+ }
+ }, match ) ) );
+
+ } else if( match.src ){
+
+ preload = new IFrame( Object.merge( options, match, { frameborder:0 }));
+ //The actual loading starts only when the iframe gets added to the dom
+ //By default, the iframe is hidden during loading. (see Viewer.less)
+ document.body.adopt(preload);
+
+ } else {
+
+ preload = new Element('p.error[html="Error"]');
+
+ }
+
+ done.delay(1); //sniff callback
+
+ }
+ //console.log("PRELOAD ", typeOf( preload ), preload );
+
+ },
+
+ preloads:function(elements, options, callback){
+
+ var countdown = elements.length, //counting the preloaded objects !
+ preloads = [],
+ w = options.width,
+ h = options.height;
+
+ if( !countdown ) return this.preload(elements, options, callback);
+
+ while( elements[0] ){
+
+ this.preload( elements.shift(), options, function(preload, width, height){
+
+ preloads.push( preload );
+ w = w.max(width);
+ h = h.max(height.toInt());
+//console.log("preloads.length, w,h);
+ if( !--countdown && callback ) callback( preloads, w, h );
+
+ });
+
+ }
+
+ }
+
+}
+
+var AdobeFlashPlayer = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
+
+Viewer.LIB.append([
+
+ ['.(bmp|gif|png|jpg|jpeg|tiff)$', function(url){
+ return { img:url }
+ }],
+
+ //google viewer for common formats
+ ['.(tiff|pdf|doc|docx|xls|xlsx|ppt|pptx|zip|rar)$',function(url){
+ return {
+ src:'http://docs.google.com/viewer?embedded=true&url=' + encodeURIComponent(url), //url,
+ width:850,
+ height:500
+ }
+ }],
+
+ //google maps
+ ['^https?://maps.google.com/maps',function(url){
+
+ //href="https://maps.google.com/maps?q=Atomium,%20City%20of%20Brussels,%20Belgium&output=embed"
+ return {
+ src: url + '&output=embed',
+ width:850,
+ height:500,
+ scrolling:'no'
+ }
+
+ }],
+
+
+ //add some mp3/audio player here
+
+ ['facebook.com', function(url){
+ url = 'http://www.facebook.com/v/' + url.split('v=')[1].split('&')[0];
+ return {
+ url:url,
+ movie:url,
+ classid: AdobeFlashPlayer,
+ width:756, //320,
+ height:424 //240
+ }
+ }],
+
+ ['flickr.com', function(url){
+ return {
+ url: 'http://www.flickr.com/apps/video/stewart.swf',
+ classid: AdobeFlashPlayer,
+ width:500,
+ height:375,
+ params: {flashvars: 'photo_id=' + url.split('/')[5] + '&show_info_box=true' }
+ };
+ }],
+
+ ['youtube.com/watch', function(url){
+ return {
+ //src: 'http://www.youtube.com/embed/'+url.split('v=')[1],
+ url:'http://www.youtube.com/v/'+url.split('v=')[1],
+ width:640,
+ height:385 //385
+ }
+ }],
+
+ //youtube playlist
+ ['youtube.com/view', function(url){
+ return{
+ url:'http://www.youtube.com/p/'+url.split('p=')[1],
+ width:480,
+ height:385
+ };
+ }],
+
+ ['dailymotion.com',function(url){
+ return {
+ src:'http://www.dailymotion.com/embed/video/'+url.split('/')[4].split('_')[0],
+ //url:url,
+ width:480,
+ height:270 //381
+ }
+ }],
+
+ ['metacafe.com/watch', function(url){
+ //http://www.metacafe.com/watch/<id>/<title>/ => http://www.metacafe.com/fplayer/<id>/<title>.swf
+ return {
+ url:'http://www.metacafe.com/fplayer/' + url.split('/')[4] +'/.swf?playerVars=autoPlay=no',
+ //url:'http://www.metacafe.com/fplayer/' + url.split('watch/')[1].slice(0,-1) +'.swf?playerVars=autoPlay=no',
+ width:400, //540 600
+ height:350 //304 338
+ }
+ }],
+
+ ['vids.myspace.com', function(url){
+ return {
+ url:url,
+ width:425, //540 600
+ height:360 //304 338
+ }
+ }],
+
+ ['veoh.com/watch/', function(url){
+ //url: 'http://www.veoh.com/static/swf/webplayer/WebPlayer.swf?version=AFrontend.5.5.2.1001&permalinkId='+url.split('watch/')[1]+'&player=videodetailsembedded&videoAutoPlay=false&id=anonymous',
+ return {
+ url:'http://www.veoh.com/veohplayer.swf?permalinkId='+url.split('watch/')[1]+'&player=videodetailsembedded&videoAutoPlay=false&id=anonymous',
+ width:410,
+ height:341
+ }
+ }],
+
+
+ ['https?://www.ted.com/talks/', function(url){
+ //http://www.ted.com/talks/doris_kim_sung_metal_that_breathes.html
+ //<iframe src="http://embed.ted.com/talks/doris_kim_sung_metal_that_breathes.html" width="560" height="315" frameborder="0" scrolling="no" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
+ return {
+ src:'http://embed.ted.com/talks/'+url.split('/')[4],
+ width:853, //640, //560,
+ height:480, //360, //315
+ scrolling:"no"
+ }
+ }],
+
+ ['viddler.com/', function(url){
+ return {
+ url: url,
+ classid: AdobeFlashPlayer,
+ width: 545, //437,
+ height: 451, //370,
+ params: {id:'viddler_'+url.split('/')[4], movie:url }
+ }
+ }],
+
+ ['http://vimeo.com/', function(url){
+ return {
+ //html5 compatible --- use iframe
+ //src: 'http://player.vimeo.com/video/' + url.split('/')[3],
+ url:'http://www.vimeo.com/moogaloop.swf?server=www.vimeo.com&clip_id='+url.split('/')[3],
+ width:640,
+ height:360
+ }
+ }],
+
+ ['http://jsfiddle.net/',function(url){
+ return {
+ src: url+'embedded/',
+ width:800,
+ height:250
+ }
+ }],
+
+ ['https?://', function(url){
+ return {
+ //default : catch iframe urls ; allow scrolling of eg external site's
+ src:url
+ }
+ }]
+
+]);
+
+}();