diff options
Diffstat (limited to 'chimere/static/jme/utils')
| -rw-r--r-- | chimere/static/jme/utils/a11y-slider.ext.js | 119 | ||||
| -rw-r--r-- | chimere/static/jme/utils/enterLeave.js | 79 | ||||
| -rw-r--r-- | chimere/static/jme/utils/jme-debug.js | 83 | ||||
| -rw-r--r-- | chimere/static/jme/utils/jmeEmbedControls.js | 41 | ||||
| -rw-r--r-- | chimere/static/jme/utils/reinitjme.js | 63 | ||||
| -rw-r--r-- | chimere/static/jme/utils/useractivity.js | 108 |
6 files changed, 493 insertions, 0 deletions
diff --git a/chimere/static/jme/utils/a11y-slider.ext.js b/chimere/static/jme/utils/a11y-slider.ext.js new file mode 100644 index 0000000..f20bb1d --- /dev/null +++ b/chimere/static/jme/utils/a11y-slider.ext.js @@ -0,0 +1,119 @@ +/** + * @author alexander.farkas + * + * Extends: jQuery UI's Slider with WAI-Aria for a11y + */ +(function($){ + var sup = $.ui.slider.prototype, + uID = 0, + min = function(i, style){ + return (style === '0px') ? '1px' : style; + }, + inline = function(i, style){ + return (style === 'inline') ? 'inline-block' : style; + } + ; + + $.support.valueText = (!$.browser.msie || parseInt($.browser.version, 10) > 8); + $.widget('ui.a11ySlider', $.ui.slider, { + options: { + textValue: '{value} %', + roundValue: true + }, + widgetEventPrefix: "slide", + _create: function(){ + var o = this.options, + that = this + ; + + this.element + .attr('role', 'application') + .bind('slidechange', $.proxy(this, '_updateA11yValues') ) + ; + + sup._create.apply(this, arguments); + + this.handles + .removeAttr('href') + .attr({ + tabindex: '0', + role: 'slider', + 'aria-valuemin': this._valueMax(), + 'aria-valuemax': this._valueMin() + }) + .css({ + display: inline, + minHeight: min, + minWidth: min + }) + .each(function(i){ + that._updateA11yValues(i, {value: that.values(i), handle: this}); + }) + ; + $('.handle-label', this.element) + .hide() + .each(function(i){ + var id = this.id; + if(!id){ + uID++; + id = 'slider-label-'+uID; + this.id = id; + } + that.handles + .filter(':eq('+ i +')') + .attr('aria-labelledby', id) + ; + }) + ; + //this._updateA11yValues(); + }, + _setOption: function( key, value ) { + sup._setOption.apply(this, arguments); + if ( key === "disabled" ) { + this.handles + .attr({ + 'aria-disabled': String( value ), + tabindex: (value) ? '-1' : '0' + }) + ; + } + return this; + }, + _updateA11yValues: function(i, ui){ + var that = this, + o = this.options + ; + + if(!ui){ + ui = { + handle: this.handles.get(i), + value: this.values(i) + }; + } + + var handle = $(ui.handle), + now = ui.value, + textValue + ; + if(o.roundValue && isFinite(now)){ + now = Math.round(now * 100) / 100; + } + if($.isFunction(o.textValue)){ + textValue = o.textValue(now, i, handle); + } else { + textValue = $.isArray(o.textValue) ? o.textValue[i] : o.textValue; + textValue = textValue.replace('{value}', now); + } + + handle + .attr({ + 'aria-valuenow': ($.support.valueText) ? now : textValue, + 'aria-valuetext': textValue + }) + ; + + + + } + }); +})(jQuery);
\ No newline at end of file diff --git a/chimere/static/jme/utils/enterLeave.js b/chimere/static/jme/utils/enterLeave.js new file mode 100644 index 0000000..07d96cc --- /dev/null +++ b/chimere/static/jme/utils/enterLeave.js @@ -0,0 +1,79 @@ +(function($){ + /* + * enterLeave + * similiar to hover, but more accessible + * hover = focusblur + */ + var inReg = /focusin|focus$|mouseenter|mouseover/; + $.fn.enterLeave = function(enter, out, opts){ + opts = $.extend({}, $.fn.enterLeave.defaults, opts); + + var eventTypes = 'mouseenter mouseleave focusin focusout', + selector = this.selector, + context = this.context + ; + + if(opts.useEventTypes === 'mouse'){ + eventTypes = 'mouseenter mouseleave'; + } else if(opts.useEventTypes === 'focus'){ + eventTypes = 'focusin focusout'; + } + + + + this + .each(function(){ + var inOutData = {inEvents: 0}; + function handler(e){ + var fn, + params, + elem = this, + evt + ; + if(inReg.test(e.type)){ + fn = enter; + params = [1, 'in', true]; + //webkit autoblur prevention + if(opts.useWebkitAutoBlur){ + inOutData.autoBlur = true; + setTimeout(function(){ + inOutData.autoBlur = false; + }, 0); + } + } else { + fn = out; + params = [-1, 'out', false]; + if(inOutData.autoBlur){ + return; + } + } + + clearTimeout(inOutData.inOutTimer); + inOutData.inEvents = Math.max(inOutData.inEvents + params[0], 0); + inOutData.inOutTimer = setTimeout(function(){ + if(params[2] != inOutData.inOutState && + (params[2] || !opts.bothOut || !inOutData.inEvents)){ + + inOutData.inOutState = params[2]; + evt = $.Event(params[1]); + evt.originalEvent = e; + fn.call(elem, evt); + } + }, /focus/.test(e.type) ? opts.keyDelay : opts.mouseDelay); + } + $(this)[opts.bindStyle](eventTypes, handler); + }); + return this; + }; + + $.fn.enterLeave.defaults = { + mouseDelay: 0, + bindStyle: 'bind', // bind | live | bubbleLive + keyDelay: 1, + bothOut: false, + useEventTypes: 'both', // both || mouse || focus + useWebkitAutoBlur: false + }; + + $.fn.inOut = $.fn.enterLeave; +})(jQuery); diff --git a/chimere/static/jme/utils/jme-debug.js b/chimere/static/jme/utils/jme-debug.js new file mode 100644 index 0000000..417151a --- /dev/null +++ b/chimere/static/jme/utils/jme-debug.js @@ -0,0 +1,83 @@ +/* + * include this script into your html-document, if you have problems to get startet with your jme-project. + * it will print some infos to your JavaScript console (Firebug or other build in Development-Tools) + */ + +(function($){ + if(!window.console && !console.log){return;} + + function init(){ + $('video, audio') + .bind('jmeBeforeEmbed', addBindings) + .filter(function(){ + return ( $.data( this, 'mediaElemSupport' ) ) ? this : false ; + }) + .each(addBindings) + ; + } + + var con = { + log: console.log, + error: (console.error) ? console.error : function(a, b, c){ + console.log('!!!'+ a, b, c); + }, + warn: (console.warn) ? console.warn : function(a, b, c){ + console.log('!'+ a, b, c); + } + }; + + function addBindings(){ + var errorTimer, + elem = $(this) + ; + + var errorTimeout = function(){ + if( !elem.isJMEReady() ){ + con.warn($(elem).getMediaAPI()+ "-api isn't ready for long time", elem[0], elem.getJMEVisual()[0]); + if(!elem.getJMEVisual().height() && !elem.getJMEVisual().width()){ + con.log(":-) API-Element seems to be in a hidden area. Until it is hidden, the API can't get ready, but will be initialized right it gets visible"); + } + if($(elem).getMediaAPI() === "jwPlayer"){ + if( location.protocol === 'file:' ){ + con.warn('If you work local you have to add your development directory to the local-trusted security sandbox: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html'); + } + var api = elem.getJMEAPI(); + con.warn("Check the path to your swf files. Is this the correct path to your jwplayer?: "+ ( (api) ? api.embedOpts.jwPlayer.path : '???' ) ); + } + } + }; + + $(this) + .bind('mmAPIReady', function(e, data){ + clearTimeout(errorTimer); + con.log(':-) everything seems fine: '+ data.mediaAPI +'-API is ready', e.target); + var url = elem.getCurrentSrc(); + if(data.mediaAPI === 'jwPlayer' && location.protocol === 'file:' && url.indexOf('youtube.com') !== -1 ){ + con.warn('youtube videos can only be played in a http-enviroment, not local.'); + } + }) + .bind('jmeflashRefresh', function(e, data){ + con.log(':-) flash was refreshed due to a reframe bug, but everything seems fine now', e.target); + }) + .bind('apiActivated', function(e, data){ + if( $(this).isJMEReady() ){ + con.log(':-) everything seems fine: '+ data.mediaAPI +'-API was changed and is ready', e.target); + } else { + con.log(data.mediaAPI +'-API is activated and is waiting to get ready', e.target); + if(data.mediaAPI === 'jwPlayer' && location.protocol === 'file:'){ + con.warn('Add your development-directory to the local-trusted security sandbox: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html'); + } + clearTimeout(errorTimer); + errorTimer = setTimeout(errorTimeout, 4000); + } + }) + .bind('totalerror', function(e, data){ + con.error('an error occured: no source is playable by any player', data, e.target); + }) + ; + clearTimeout(errorTimer); + errorTimer = setTimeout(errorTimeout, 4000); + } + + $(init); +})(jQuery); diff --git a/chimere/static/jme/utils/jmeEmbedControls.js b/chimere/static/jme/utils/jmeEmbedControls.js new file mode 100644 index 0000000..99d9a0f --- /dev/null +++ b/chimere/static/jme/utils/jmeEmbedControls.js @@ -0,0 +1,41 @@ +/* + * This script is a very simple utility to add predefined control-markup for rapid/quick start development with jme. + * Feel free to extend and change this markup for your needs. + */ +(function($){ + + var playerControls = '<div class="media-controls-wrapper"> \ + <div class="media-controls" lang="en"> \ + <a class="play-pause button"><span class="ui-icon ui-icon-play"> </span><span class="button-text">play / pause</span></a> \ + <span class="current-time player-display"></span> \ + <div class="timeline-slider"> \ + <span class="handle-label">play position</span> \ + <div class="progressbar"></div> \ + </div> \ + <span class="duration player-display"></span> \ + <a class="mute-unmute button"><span class="ui-icon ui-icon-volume-on"> </span><span class="button-text">mute / unmute</span></a> \ + <div class="volume-slider"><span class="handle-label">volume control</span></div> \ + </div> \ + </div>' + ; + var fullscreenBtn = '<a class="fullscreen button"><span class="ui-icon ui-icon-circle-zoomin"> </span><span class="button-text">zoomin / zoomout</span></a>'; + + $.fn.jmeEmbedControls = function(o){ + return this + //append standard controls + .append(playerControls) + //add extra video controls + .each(function(){ + //media-state makes only sense with video not audio + var hasVideo = $('video', this).after('<div class="media-state" />'); + //include fullscreenn button only if plugin is included and we have a video-element + if( $.fn.enterFullWindow && hasVideo[0] ) { + $('div.media-controls', this).append(fullscreenBtn); + } + }) + //register controls with jmeConttrol + .jmeControl(o) + ; + }; + +})(jQuery);
\ No newline at end of file diff --git a/chimere/static/jme/utils/reinitjme.js b/chimere/static/jme/utils/reinitjme.js new file mode 100644 index 0000000..9d78206 --- /dev/null +++ b/chimere/static/jme/utils/reinitjme.js @@ -0,0 +1,63 @@ +/** + * reinitMedia reinitiaizes the video/audio in the JWPlayer. This is sometimes needed, because of a Flash-Bug + * + */ + +(function($){ + $.fn.reinitMedia = (function(){ + var cacheID = 0, + reg = /jme-nocache-\d+/, + addID = function(src){ + if(!src){return '';} + cacheID++; + if(reg.test(src)){ + return src.replace(reg, function(){ + return 'jme-nocache-'+cacheID; + }); + } + src += (src.indexOf('?') !== -1) ? '&' : '?'; + return src + 'jme-nocache-'+cacheID; + } + ; + + return function(o){ + o = $.extend({}, $.fn.reinitMedia.defaults, o); + + var reinit = { + msie: function(elem){ + elem = $(elem); + var source = []; + $.each(elem.attr('srces'), function(i, src){ + source.push($.extend(src, {src: addID(src.src)})); + }); + elem.loadSrc(source, addID(elem.attr('poster') || undefined)); + } + }; + + return this.each(function(){ + var jme = $.data(this, 'mediaElemSupport'); + if(!jme){return;} + var elem = this; + if(jme.name == 'jwPlayer' && o.msie && $.browser.msie && jme.apis.jwPlayer.apiElem && $.support.flashVersion >= 10.1){ + if(o.queue){ + var oldReady = jme.apis.jwPlayer.isAPIReady; + jme.apis.jwPlayer.isAPIReady = false; + setTimeout(function(){ + jme.apis.jwPlayer.isAPIReady = oldReady; + reinit.msie(elem); + if(oldReady){ + $(elem).triggerHandler('jmeflashRefresh'); + } + }, 0); + } else { + reinit.msie(elem); + } + } + }); + }; + })(); + $.fn.reinitMedia.defaults = { + msie: true, + queue: false + }; +})(jQuery); diff --git a/chimere/static/jme/utils/useractivity.js b/chimere/static/jme/utils/useractivity.js new file mode 100644 index 0000000..862996d --- /dev/null +++ b/chimere/static/jme/utils/useractivity.js @@ -0,0 +1,108 @@ +(function($){ + /** + * helps you to detect user activity/userinactivity in an html-area + * + * usage: + * + * $('div.my-element') + * .bind('useractive', function(e){ + * // user is active in this area + * }) + * .bind('userinactive', function(e){ + * // user is inactive in this area + * }) + * ; + * + * more advanced usage: + * + * $('div.my-element') + * .bind('useractive', function(e){ + * // user is active in this area + * }) + * .bind('userinactive', {idletime: 1500}, function(e){ + * // user is inactive in this area + * }) + * ; + */ + if(!$.support.opacity && !$.opacityRemoveFix){ + var oldStyle = $.style; + $.style = function(elem, name, value){ + var ret = oldStyle(elem, name, value); + if(name === 'opacity' && value == 1){ + elem.style.filter = (elem.style.filter || '').replace('alpha(opacity=100)', ''); + } + return ret; + }; + $.opacityRemoveFix = true; + } + var activity = { + add: function(elem, cfg, name){ + var data = $.data(elem, 'jmeuseractivity') || $.data(elem, 'jmeuseractivity', {idletime: 2500, idle: true, trigger: {}}), + jElm = $(elem), + setInactive = function(){ + if(!data.idle){ + data.idle = true; + if ( data.trigger.userinactive ) { + jElm.trigger('userinactive'); + } + } + }, + setActive = function(e){ + if(!e || (e.type === 'mousemove' && e.pageX === x && e.pageY === y)){return;} + if(e.type === 'mousemove'){ + x = e.pageX; + y = e.pageY; + } + if(data.idleTimer){ + clearTimeout(data.idleTimer); + } + data.idleTimer = setTimeout(setInactive, data.idletime); + if(data.idle){ + data.idle = false; + if( data.trigger.useractive ){ + jElm.trigger('useractive'); + } + } + }, + x, y + ; + + data.idletime = (cfg || {}).idletime || data.idletime; + if(cfg && 'idle' in cfg){ + data.idle = cfg.idle; + } + data.trigger[name] = true; + + if( !data.bound ){ + jElm + .bind('mouseleave.jmeuseractivity', setInactive) + .bind('mousemove.jmeuseractivity focusin.jmeuseractivity mouseenter.jmeuseractivity keydown.jmeuseractivity keyup.jmeuseractivity mousedown.jmeuseractivity', setActive) + ; + data.bound = true; + } + if(!data.idle){ + setActive({type: 'initunidled'}); + } + }, + remove: function(elem, name){ + var data = $.data(elem, 'jmeuseractivity') || $.data(elem, 'jmeuseractivity', {idletime: 2500, idle: true, trigger: {}}); + data.trigger[name] = false; + if(!data.trigger.useractive && !data.trigger.userinactive){ + $(elem).unbind('.jmeuseractivity'); + data.bound = false; + } + } + }; + $.each(['useractive', 'userinactive'], function(i, name){ + $.event.special[name] = { + setup: function(cfg){ + activity.add(this, cfg, name); + }, + teardown: function(){ + activity.remove(this, name); + } + }; + }); + + +})(jQuery);
\ No newline at end of file |
