summaryrefslogtreecommitdiff
path: root/chimere/static/jme/utils
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/static/jme/utils')
-rw-r--r--chimere/static/jme/utils/a11y-slider.ext.js119
-rw-r--r--chimere/static/jme/utils/enterLeave.js79
-rw-r--r--chimere/static/jme/utils/jme-debug.js83
-rw-r--r--chimere/static/jme/utils/jmeEmbedControls.js41
-rw-r--r--chimere/static/jme/utils/reinitjme.js63
-rw-r--r--chimere/static/jme/utils/useractivity.js108
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