r109857 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r109856‎ | r109857 | r109858 >
Date:22:05, 23 January 2012
Author:dale
Status:ok (Comments)
Tags:
Comment:
follow up to r109856 added missing spinner.js
Modified paths:
  • /trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/jquery.loadingSpinner/spinner.js (added) (history)

Diff [purge]

Index: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/jquery.loadingSpinner/spinner.js
@@ -0,0 +1,287 @@
 2+(function(window, document, undefined) {
 3+
 4+/**
 5+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
 6+ * Licensed under the MIT license
 7+ * https://github.com/fgnass/spin.js
 8+ */
 9+
 10+ var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
 11+ animations = {}, /* Animation rules keyed by their name */
 12+ useCssAnimations;
 13+
 14+ /**
 15+ * Utility function to create elements. If no tag name is given,
 16+ * a DIV is created. Optionally properties can be passed.
 17+ */
 18+ function createEl(tag, prop) {
 19+ var el = document.createElement(tag || 'div'),
 20+ n;
 21+
 22+ for(n in prop) {
 23+ el[n] = prop[n];
 24+ }
 25+ return el;
 26+ }
 27+
 28+ /**
 29+ * Inserts child1 before child2. If child2 is not specified,
 30+ * child1 is appended. If child2 has no parentNode, child2 is
 31+ * appended first.
 32+ */
 33+ function ins(parent, child1, child2) {
 34+ if(child2 && !child2.parentNode) ins(parent, child2);
 35+ parent.insertBefore(child1, child2||null);
 36+ return parent;
 37+ }
 38+
 39+ /**
 40+ * Insert a new stylesheet to hold the @keyframe or VML rules.
 41+ */
 42+ //ins(document.getElementsByTagName('head')[0], createEl('style'));
 43+ //var sheet = document.styleSheets[document.styleSheets.length-1];
 44+ var sheet = (function() {
 45+ var style = document.createElement('style');
 46+ style['title'] = 'spinjs';
 47+ document.getElementsByTagName('head')[0].appendChild(style);
 48+ if (!window.createPopup) { /* For Safari */
 49+ style.appendChild(document.createTextNode(''));
 50+ }
 51+ return document.styleSheets[document.styleSheets.length - 1];
 52+ })();
 53+
 54+ /**
 55+ * Creates an opacity keyframe animation rule and returns its name.
 56+ * Since most mobile Webkits have timing issues with animation-delay,
 57+ * we create separate rules for each line/segment.
 58+ */
 59+ function addAnimation(alpha, trail, i, lines) {
 60+ var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
 61+ start = 0.01 + i/lines*100,
 62+ z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
 63+ prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
 64+ pre = prefix && '-'+prefix+'-' || '';
 65+
 66+ if (!animations[name]) {
 67+ sheet.insertRule(
 68+ '@' + pre + 'keyframes ' + name + '{' +
 69+ '0%{opacity:'+z+'}' +
 70+ start + '%{opacity:'+ alpha + '}' +
 71+ (start+0.01) + '%{opacity:1}' +
 72+ (start+trail)%100 + '%{opacity:'+ alpha + '}' +
 73+ '100%{opacity:'+ z + '}' +
 74+ '}', 0);
 75+ animations[name] = 1;
 76+ }
 77+ return name;
 78+ }
 79+
 80+ /**
 81+ * Tries various vendor prefixes and returns the first supported property.
 82+ **/
 83+ function vendor(el, prop) {
 84+ var s = el.style,
 85+ pp,
 86+ i;
 87+
 88+ if(s[prop] !== undefined) return prop;
 89+ prop = prop.charAt(0).toUpperCase() + prop.slice(1);
 90+ for(i=0; i<prefixes.length; i++) {
 91+ pp = prefixes[i]+prop;
 92+ if(s[pp] !== undefined) return pp;
 93+ }
 94+ }
 95+
 96+ /**
 97+ * Sets multiple style properties at once.
 98+ */
 99+ function css(el, prop) {
 100+ for (var n in prop) {
 101+ el.style[vendor(el, n)||n] = prop[n];
 102+ }
 103+ return el;
 104+ }
 105+
 106+ /**
 107+ * Fills in default values.
 108+ */
 109+ function defaults(obj, def) {
 110+ for (var n in def) {
 111+ if (obj[n] === undefined) obj[n] = def[n];
 112+ }
 113+ return obj;
 114+ }
 115+
 116+ /**
 117+ * Returns the absolute page-offset of the given element.
 118+ */
 119+ function pos(el) {
 120+ var o = {x:el.offsetLeft, y:el.offsetTop};
 121+ while((el = el.offsetParent)) {
 122+ o.x+=el.offsetLeft;
 123+ o.y+=el.offsetTop;
 124+ }
 125+ return o;
 126+ }
 127+
 128+ /** The constructor */
 129+ var Spinner = function Spinner(o) {
 130+ this.opts = defaults(o || {}, {
 131+ lines: 12, // The number of lines to draw
 132+ length: 7, // The length of each line
 133+ width: 5, // The line thickness
 134+ radius: 10, // The radius of the inner circle
 135+ color: '#000', // #rbg or #rrggbb
 136+ speed: 1, // Rounds per second
 137+ trail: 100, // Afterglow percentage
 138+ opacity: 1/4
 139+ });
 140+ },
 141+ proto = Spinner.prototype = {
 142+ spin: function(target) {
 143+ var self = this,
 144+ el = self.el = css(createEl(), {position: 'relative'}),
 145+ ep, // element position
 146+ tp; // target position
 147+
 148+ if (target) {
 149+ tp = pos(ins(target, el, target.firstChild));
 150+ ep = pos(el);
 151+ css(el, {
 152+ left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
 153+ top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
 154+ });
 155+ }
 156+ self.lines(el, self.opts);
 157+ if (!useCssAnimations) {
 158+ // No CSS animation support, use setTimeout() instead
 159+ var o = self.opts,
 160+ i = 0,
 161+ f = 20/o.speed,
 162+ ostep = (1-o.opacity)/(f*o.trail / 100),
 163+ astep = f/o.lines;
 164+
 165+ (function anim() {
 166+ i++;
 167+ for (var s=o.lines; s; s--) {
 168+ var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
 169+ self.opacity(el, o.lines-s, alpha, o);
 170+ }
 171+ self.timeout = self.el && setTimeout(anim, 50);
 172+ })();
 173+ }
 174+ return self;
 175+ },
 176+ stop: function() {
 177+ var self = this,
 178+ el = self.el;
 179+
 180+ clearTimeout(self.timeout);
 181+ if (el && el.parentNode) el.parentNode.removeChild(el);
 182+ self.el = undefined;
 183+ return self;
 184+ }
 185+ };
 186+ proto.lines = function(el, o) {
 187+ var i = 0,
 188+ seg;
 189+
 190+ function fill(color, shadow) {
 191+ return css(createEl(), {
 192+ position: 'absolute',
 193+ width: (o.length+o.width) + 'px',
 194+ height: o.width + 'px',
 195+ background: color,
 196+ boxShadow: shadow,
 197+ transformOrigin: 'left',
 198+ transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
 199+ borderRadius: (o.width>>1) + 'px'
 200+ });
 201+ }
 202+ for (; i < o.lines; i++) {
 203+ seg = css(createEl(), {
 204+ position: 'absolute',
 205+ top: 1+~(o.width/2) + 'px',
 206+ transform: 'translate3d(0,0,0)',
 207+ opacity: o.opacity,
 208+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
 209+ });
 210+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
 211+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
 212+ }
 213+ return el;
 214+ };
 215+ proto.opacity = function(el, i, val) {
 216+ el.childNodes[i].style.opacity = val;
 217+ };
 218+
 219+ /////////////////////////////////////////////////////////////////////////
 220+ // VML rendering for IE
 221+ /////////////////////////////////////////////////////////////////////////
 222+
 223+ /**
 224+ * Check and init VML support
 225+ */
 226+ (function() {
 227+ var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
 228+ i;
 229+
 230+ if (!vendor(s, 'transform') && s.adj) {
 231+
 232+ // VML support detected. Insert CSS rules ...
 233+ for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
 234+
 235+ proto.lines = function(el, o) {
 236+ var r = o.length+o.width,
 237+ s = 2*r;
 238+
 239+ function grp() {
 240+ return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
 241+ }
 242+
 243+ var g = grp(),
 244+ margin = ~(o.length+o.radius+o.width)+'px',
 245+ i;
 246+
 247+ function seg(i, dx, filter) {
 248+ ins(g,
 249+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
 250+ ins(css(createEl('roundrect', {arcsize: 1}), {
 251+ width: r,
 252+ height: o.width,
 253+ left: o.radius,
 254+ top: -o.width>>1,
 255+ filter: filter
 256+ }),
 257+ createEl('fill', {color: o.color, opacity: o.opacity}),
 258+ createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
 259+ )
 260+ )
 261+ );
 262+ }
 263+
 264+ if (o.shadow) {
 265+ for (i = 1; i <= o.lines; i++) {
 266+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
 267+ }
 268+ }
 269+ for (i = 1; i <= o.lines; i++) {
 270+ seg(i);
 271+ }
 272+ return ins(css(el, {
 273+ margin: margin + ' 0 0 ' + margin
 274+ }), g);
 275+ };
 276+ proto.opacity = function(el, i, val, o) {
 277+ o = o.shadow && o.lines || 0;
 278+ el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
 279+ };
 280+ }
 281+ else {
 282+ useCssAnimations = vendor(s, 'animation');
 283+ }
 284+ })();
 285+
 286+ window.Spinner = Spinner;
 287+
 288+})(window, document);
\ No newline at end of file
Property changes on: trunk/extensions/MwEmbedSupport/MwEmbedModules/MwEmbedSupport/jquery.loadingSpinner/spinner.js
___________________________________________________________________
Added: svn:mime-type
1289 + text/plain

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r109856* switched loading spinner over to spinner.js ( all js much nicer solution )...dale21:58, 23 January 2012

Comments

#Comment by Mdale (talk | contribs)   23:38, 23 January 2012

demon we are in the process of brining TMH up for deployment, please don't mark as deferred as Ian or Neil has to review.

Status & tagging log