diff options
Diffstat (limited to 'wiki/lib/plugins/styling/iris.js')
-rw-r--r-- | wiki/lib/plugins/styling/iris.js | 1488 |
1 files changed, 0 insertions, 1488 deletions
diff --git a/wiki/lib/plugins/styling/iris.js b/wiki/lib/plugins/styling/iris.js deleted file mode 100644 index 4eda502..0000000 --- a/wiki/lib/plugins/styling/iris.js +++ /dev/null @@ -1,1488 +0,0 @@ -/*! Iris Color Picker - v1.0.7 - 2014-11-28 -* https://github.com/Automattic/Iris -* Copyright (c) 2014 Matt Wiebe; Licensed GPLv2 */ -(function( $, undef ){ - var _html, nonGradientIE, gradientType, vendorPrefixes, _css, Iris, UA, isIE, IEVersion; - - _html = '<div class="iris-picker"><div class="iris-picker-inner"><div class="iris-square"><a class="iris-square-value" href="#"><span class="iris-square-handle ui-slider-handle"></span></a><div class="iris-square-inner iris-square-horiz"></div><div class="iris-square-inner iris-square-vert"></div></div><div class="iris-slider iris-strip"><div class="iris-slider-offset"></div></div></div></div>'; - _css = '.iris-picker{display:block;position:relative}.iris-picker,.iris-picker *{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input+.iris-picker{margin-top:4px}.iris-error{background-color:#ffafaf}.iris-border{border-radius:3px;border:1px solid #aaa;width:200px;background-color:#fff}.iris-picker-inner{position:absolute;top:0;right:0;left:0;bottom:0}.iris-border .iris-picker-inner{top:10px;right:10px;left:10px;bottom:10px}.iris-picker .iris-square-inner{position:absolute;left:0;right:0;top:0;bottom:0}.iris-picker .iris-square,.iris-picker .iris-slider,.iris-picker .iris-square-inner,.iris-picker .iris-palette{border-radius:3px;box-shadow:inset 0 0 5px rgba(0,0,0,.4);height:100%;width:12.5%;float:left;margin-right:5%}.iris-picker .iris-square{width:76%;margin-right:10%;position:relative}.iris-picker .iris-square-inner{width:auto;margin:0}.iris-ie-9 .iris-square,.iris-ie-9 .iris-slider,.iris-ie-9 .iris-square-inner,.iris-ie-9 .iris-palette{box-shadow:none;border-radius:0}.iris-ie-9 .iris-square,.iris-ie-9 .iris-slider,.iris-ie-9 .iris-palette{outline:1px solid rgba(0,0,0,.1)}.iris-ie-lt9 .iris-square,.iris-ie-lt9 .iris-slider,.iris-ie-lt9 .iris-square-inner,.iris-ie-lt9 .iris-palette{outline:1px solid #aaa}.iris-ie-lt9 .iris-square .ui-slider-handle{outline:1px solid #aaa;background-color:#fff;-ms-filter:"alpha(Opacity=30)"}.iris-ie-lt9 .iris-square .iris-square-handle{background:0;border:3px solid #fff;-ms-filter:"alpha(Opacity=50)"}.iris-picker .iris-strip{margin-right:0;position:relative}.iris-picker .iris-strip .ui-slider-handle{position:absolute;background:0;margin:0;right:-3px;left:-3px;border:4px solid #aaa;border-width:4px 3px;width:auto;height:6px;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.2);opacity:.9;z-index:5;cursor:ns-resize}.iris-strip .ui-slider-handle:before{content:" ";position:absolute;left:-2px;right:-2px;top:-3px;bottom:-3px;border:2px solid #fff;border-radius:3px}.iris-picker .iris-slider-offset{position:absolute;top:11px;left:0;right:0;bottom:-3px;width:auto;height:auto;background:transparent;border:0;border-radius:0}.iris-picker .iris-square-handle{background:transparent;border:5px solid #aaa;border-radius:50%;border-color:rgba(128,128,128,.5);box-shadow:none;width:12px;height:12px;position:absolute;left:-10px;top:-10px;cursor:move;opacity:1;z-index:10}.iris-picker .ui-state-focus .iris-square-handle{opacity:.8}.iris-picker .iris-square-handle:hover{border-color:#999}.iris-picker .iris-square-value:focus .iris-square-handle{box-shadow:0 0 2px rgba(0,0,0,.75);opacity:.8}.iris-picker .iris-square-handle:hover::after{border-color:#fff}.iris-picker .iris-square-handle::after{position:absolute;bottom:-4px;right:-4px;left:-4px;top:-4px;border:3px solid #f9f9f9;border-color:rgba(255,255,255,.8);border-radius:50%;content:" "}.iris-picker .iris-square-value{width:8px;height:8px;position:absolute}.iris-ie-lt9 .iris-square-value,.iris-mozilla .iris-square-value{width:1px;height:1px}.iris-palette-container{position:absolute;bottom:0;left:0;margin:0;padding:0}.iris-border .iris-palette-container{left:10px;bottom:10px}.iris-picker .iris-palette{margin:0;cursor:pointer}.iris-square-handle,.ui-slider-handle{border:0;outline:0}'; - - // Even IE9 dosen't support gradients. Elaborate sigh. - UA = navigator.userAgent.toLowerCase(); - isIE = navigator.appName === 'Microsoft Internet Explorer'; - IEVersion = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0; - nonGradientIE = ( isIE && IEVersion < 10 ); - gradientType = false; - - // we don't bother with an unprefixed version, as it has a different syntax - vendorPrefixes = [ '-moz-', '-webkit-', '-o-', '-ms-' ]; - - // Bail for IE <= 7 - if ( nonGradientIE && IEVersion <= 7 ) { - $.fn.iris = $.noop; - $.support.iris = false; - return; - } - - $.support.iris = true; - - function testGradientType() { - var el, base, - bgImageString = 'backgroundImage'; - - if ( nonGradientIE ) { - gradientType = 'filter'; - } - else { - el = $( '<div id="iris-gradtest" />' ); - base = 'linear-gradient(top,#fff,#000)'; - $.each( vendorPrefixes, function( i, val ){ - el.css( bgImageString, val + base ); - if ( el.css( bgImageString ).match( 'gradient' ) ) { - gradientType = i; - return false; - } - }); - // check for legacy webkit gradient syntax - if ( gradientType === false ) { - el.css( 'background', '-webkit-gradient(linear,0% 0%,0% 100%,from(#fff),to(#000))' ); - if ( el.css( bgImageString ).match( 'gradient' ) ) { - gradientType = 'webkit'; - } - } - el.remove(); - } - - } - - /** - * Only for CSS3 gradients. oldIE will use a separate function. - * - * Accepts as many color stops as necessary from 2nd arg on, or 2nd - * arg can be an array of color stops - * - * @param {string} origin Gradient origin - top or left, defaults to left. - * @return {string} Appropriate CSS3 gradient string for use in - */ - function createGradient( origin, stops ) { - origin = ( origin === 'top' ) ? 'top' : 'left'; - stops = $.isArray( stops ) ? stops : Array.prototype.slice.call( arguments, 1 ); - if ( gradientType === 'webkit' ) { - return legacyWebkitGradient( origin, stops ); - } else { - return vendorPrefixes[ gradientType ] + 'linear-gradient(' + origin + ', ' + stops.join(', ') + ')'; - } - } - - /** - * Stupid gradients for a stupid browser. - */ - function stupidIEGradient( origin, stops ) { - var type, self, lastIndex, filter, startPosProp, endPosProp, dimensionProp, template, html; - - origin = ( origin === 'top' ) ? 'top' : 'left'; - stops = $.isArray( stops ) ? stops : Array.prototype.slice.call( arguments, 1 ); - // 8 hex: AARRGGBB - // GradientType: 0 vertical, 1 horizontal - type = ( origin === 'top' ) ? 0 : 1; - self = $( this ); - lastIndex = stops.length - 1; - filter = 'filter'; - startPosProp = ( type === 1 ) ? 'left' : 'top'; - endPosProp = ( type === 1 ) ? 'right' : 'bottom'; - dimensionProp = ( type === 1 ) ? 'height' : 'width'; - template = '<div class="iris-ie-gradient-shim" style="position:absolute;' + dimensionProp + ':100%;' + startPosProp + ':%start%;' + endPosProp + ':%end%;' + filter + ':%filter%;" data-color:"%color%"></div>'; - html = ''; - // need a positioning context - if ( self.css('position') === 'static' ) { - self.css( {position: 'relative' } ); - } - - stops = fillColorStops( stops ); - $.each(stops, function( i, startColor ) { - var endColor, endStop, filterVal; - - // we want two at a time. if we're on the last pair, bail. - if ( i === lastIndex ) { - return false; - } - - endColor = stops[ i + 1 ]; - //if our pairs are at the same color stop, moving along. - if ( startColor.stop === endColor.stop ) { - return; - } - - endStop = 100 - parseFloat( endColor.stop ) + '%'; - startColor.octoHex = new Color( startColor.color ).toIEOctoHex(); - endColor.octoHex = new Color( endColor.color ).toIEOctoHex(); - - filterVal = 'progid:DXImageTransform.Microsoft.Gradient(GradientType=' + type + ', StartColorStr=\'' + startColor.octoHex + '\', EndColorStr=\'' + endColor.octoHex + '\')'; - html += template.replace( '%start%', startColor.stop ).replace( '%end%', endStop ).replace( '%filter%', filterVal ); - }); - self.find( '.iris-ie-gradient-shim' ).remove(); - $( html ).prependTo( self ); - } - - function legacyWebkitGradient( origin, colorList ) { - var stops = []; - origin = ( origin === 'top' ) ? '0% 0%,0% 100%,' : '0% 100%,100% 100%,'; - colorList = fillColorStops( colorList ); - $.each( colorList, function( i, val ){ - stops.push( 'color-stop(' + ( parseFloat( val.stop ) / 100 ) + ', ' + val.color + ')' ); - }); - return '-webkit-gradient(linear,' + origin + stops.join(',') + ')'; - } - - function fillColorStops( colorList ) { - var colors = [], - percs = [], - newColorList = [], - lastIndex = colorList.length - 1; - - $.each( colorList, function( index, val ) { - var color = val, - perc = false, - match = val.match( /1?[0-9]{1,2}%$/ ); - - if ( match ) { - color = val.replace( /\s?1?[0-9]{1,2}%$/, '' ); - perc = match.shift(); - } - colors.push( color ); - percs.push( perc ); - }); - - // back fill first and last - if ( percs[0] === false ) { - percs[0] = '0%'; - } - - if ( percs[lastIndex] === false ) { - percs[lastIndex] = '100%'; - } - - percs = backFillColorStops( percs ); - - $.each( percs, function( i ){ - newColorList[i] = { color: colors[i], stop: percs[i] }; - }); - return newColorList; - } - - function backFillColorStops( stops ) { - var first = 0, - last = stops.length - 1, - i = 0, - foundFirst = false, - incr, - steps, - step, - firstVal; - - if ( stops.length <= 2 || $.inArray( false, stops ) < 0 ) { - return stops; - } - while ( i < stops.length - 1 ) { - if ( ! foundFirst && stops[i] === false ) { - first = i - 1; - foundFirst = true; - } else if ( foundFirst && stops[i] !== false ) { - last = i; - i = stops.length; - } - i++; - } - steps = last - first; - firstVal = parseInt( stops[first].replace('%'), 10 ); - incr = ( parseFloat( stops[last].replace('%') ) - firstVal ) / steps; - i = first + 1; - step = 1; - while ( i < last ) { - stops[i] = ( firstVal + ( step * incr ) ) + '%'; - step++; - i++; - } - return backFillColorStops( stops ); - } - - $.fn.gradient = function() { - var args = arguments; - return this.each( function() { - // this'll be oldishIE - if ( nonGradientIE ) { - stupidIEGradient.apply( this, args ); - } else { - // new hotness - $( this ).css( 'backgroundImage', createGradient.apply( this, args ) ); - } - }); - }; - - $.fn.raninbowGradient = function( origin, args ) { - var opts, template, i, steps; - - origin = origin || 'top'; - opts = $.extend( {}, { s: 100, l: 50 }, args ); - template = 'hsl(%h%,' + opts.s + '%,' + opts.l + '%)'; - i = 0; - steps = []; - while ( i <= 360 ) { - steps.push( template.replace('%h%', i) ); - i += 30; - } - return this.each(function() { - $(this).gradient( origin, steps ); - }); - }; - - // the colorpicker widget def. - Iris = { - options: { - color: false, - mode: 'hsl', - controls: { - horiz: 's', // horizontal defaults to saturation - vert: 'l', // vertical defaults to lightness - strip: 'h' // right strip defaults to hue - }, - hide: true, // hide the color picker by default - border: true, // draw a border around the collection of UI elements - target: false, // a DOM element / jQuery selector that the element will be appended within. Only used when called on an input. - width: 200, // the width of the collection of UI elements - palettes: false // show a palette of basic colors beneath the square. - }, - _color: '', - _palettes: [ '#000', '#fff', '#d33', '#d93', '#ee2', '#81d742', '#1e73be', '#8224e3' ], - _inited: false, - _defaultHSLControls: { - horiz: 's', - vert: 'l', - strip: 'h' - }, - _defaultHSVControls: { - horiz: 'h', - vert: 'v', - strip: 's' - }, - _scale: { - h: 360, - s: 100, - l: 100, - v: 100 - }, - _create: function() { - var self = this, - el = self.element, - color = self.options.color || el.val(); - - if ( gradientType === false ) { - testGradientType(); - } - - if ( el.is( 'input' ) ) { - if ( self.options.target ) { - self.picker = $( _html ).appendTo( self.options.target ); - } else { - self.picker = $( _html ).insertAfter( el ); - } - - self._addInputListeners( el ); - } else { - el.append( _html ); - self.picker = el.find( '.iris-picker' ); - } - - // Browsers / Versions - // Feature detection doesn't work for these, and $.browser is deprecated - if ( isIE ) { - if ( IEVersion === 9 ) { - self.picker.addClass( 'iris-ie-9' ); - } else if ( IEVersion <= 8 ) { - self.picker.addClass( 'iris-ie-lt9' ); - } - } else if ( UA.indexOf('compatible') < 0 && UA.indexOf('khtml') < 0 && UA.match( /mozilla/ ) ) { - self.picker.addClass( 'iris-mozilla' ); - } - - if ( self.options.palettes ) { - self._addPalettes(); - } - - self._color = new Color( color ).setHSpace( self.options.mode ); - self.options.color = self._color.toString(); - - // prep 'em for re-use - self.controls = { - square: self.picker.find( '.iris-square' ), - squareDrag: self.picker.find( '.iris-square-value' ), - horiz: self.picker.find( '.iris-square-horiz' ), - vert: self.picker.find( '.iris-square-vert' ), - strip: self.picker.find( '.iris-strip' ), - stripSlider: self.picker.find( '.iris-strip .iris-slider-offset' ) - }; - - // small sanity check - if we chose hsv, change default controls away from hsl - if ( self.options.mode === 'hsv' && self._has('l', self.options.controls) ) { - self.options.controls = self._defaultHSVControls; - } else if ( self.options.mode === 'hsl' && self._has('v', self.options.controls) ) { - self.options.controls = self._defaultHSLControls; - } - - // store it. HSL gets squirrely - self.hue = self._color.h(); - - if ( self.options.hide ) { - self.picker.hide(); - } - - if ( self.options.border ) { - self.picker.addClass( 'iris-border' ); - } - - self._initControls(); - self.active = 'external'; - self._dimensions(); - self._change(); - }, - _has: function(needle, haystack) { - var ret = false; - $.each(haystack, function(i,v){ - if ( needle === v ) { - ret = true; - // exit the loop - return false; - } - }); - return ret; - }, - _addPalettes: function () { - var container = $( '<div class="iris-palette-container" />' ), - palette = $( '<a class="iris-palette" tabindex="0" />' ), - colors = $.isArray( this.options.palettes ) ? this.options.palettes : this._palettes; - - // do we have an existing container? Empty and reuse it. - if ( this.picker.find( '.iris-palette-container' ).length ) { - container = this.picker.find( '.iris-palette-container' ).detach().html( '' ); - } - - $.each(colors, function(index, val) { - palette.clone().data( 'color', val ) - .css( 'backgroundColor', val ).appendTo( container ) - .height( 10 ).width( 10 ); - }); - - this.picker.append(container); - }, - _paint: function() { - var self = this; - self._paintDimension( 'top', 'strip' ); - self._paintDimension( 'top', 'vert' ); - self._paintDimension( 'left', 'horiz' ); - }, - _paintDimension: function( origin, control ) { - var self = this, - c = self._color, - mode = self.options.mode, - color = self._getHSpaceColor(), - target = self.controls[ control ], - controlOpts = self.options.controls, - stops; - - // don't paint the active control - if ( control === self.active || ( self.active === 'square' && control !== 'strip' ) ) { - return; - } - - switch ( controlOpts[ control ] ) { - case 'h': - if ( mode === 'hsv' ) { - color = c.clone(); - switch ( control ) { - case 'horiz': - color[controlOpts.vert](100); - break; - case 'vert': - color[controlOpts.horiz](100); - break; - case 'strip': - color.setHSpace('hsl'); - break; - } - stops = color.toHsl(); - } else { - if ( control === 'strip' ) { - stops = { s: color.s, l: color.l }; - } else { - stops = { s: 100, l: color.l }; - } - } - - target.raninbowGradient( origin, stops ); - break; - case 's': - if ( mode === 'hsv' ) { - if ( control === 'vert' ) { - stops = [ c.clone().a(0).s(0).toCSS('rgba'), c.clone().a(1).s(0).toCSS('rgba') ]; - } else if ( control === 'strip' ) { - stops = [ c.clone().s(100).toCSS('hsl'), c.clone().s(0).toCSS('hsl') ]; - } else if ( control === 'horiz' ) { - stops = [ '#fff', 'hsl(' + color.h + ',100%,50%)' ]; - } - } else { // implicit mode === 'hsl' - if ( control === 'vert' && self.options.controls.horiz === 'h' ) { - stops = ['hsla(0, 0%, ' + color.l + '%, 0)', 'hsla(0, 0%, ' + color.l + '%, 1)']; - } else { - stops = ['hsl('+ color.h +',0%,50%)', 'hsl(' + color.h + ',100%,50%)']; - } - } - - - target.gradient( origin, stops ); - break; - case 'l': - if ( control === 'strip' ) { - stops = ['hsl(' + color.h + ',100%,100%)', 'hsl(' + color.h + ', ' + color.s + '%,50%)', 'hsl('+ color.h +',100%,0%)']; - } else { - stops = ['#fff', 'rgba(255,255,255,0) 50%', 'rgba(0,0,0,0) 50%', 'rgba(0,0,0,1)']; - } - target.gradient( origin, stops ); - break; - case 'v': - if ( control === 'strip' ) { - stops = [ c.clone().v(100).toCSS(), c.clone().v(0).toCSS() ]; - } else { - stops = ['rgba(0,0,0,0)', '#000']; - } - target.gradient( origin, stops ); - break; - default: - break; - } - }, - - _getHSpaceColor: function() { - return ( this.options.mode === 'hsv' ) ? this._color.toHsv() : this._color.toHsl(); - }, - - _dimensions: function( reset ) { - // whatever size - var self = this, - opts = self.options, - controls = self.controls, - square = controls.square, - strip = self.picker.find( '.iris-strip' ), - squareWidth = '77.5%', - stripWidth = '12%', - totalPadding = 20, - innerWidth = opts.border ? opts.width - totalPadding : opts.width, - controlsHeight, - paletteCount = $.isArray( opts.palettes ) ? opts.palettes.length : self._palettes.length, - paletteMargin, paletteWidth, paletteContainerWidth; - - if ( reset ) { - square.css( 'width', '' ); - strip.css( 'width', '' ); - self.picker.css( {width: '', height: ''} ); - } - - squareWidth = innerWidth * ( parseFloat( squareWidth ) / 100 ); - stripWidth = innerWidth * ( parseFloat( stripWidth ) / 100 ); - controlsHeight = opts.border ? squareWidth + totalPadding : squareWidth; - - square.width( squareWidth ).height( squareWidth ); - strip.height( squareWidth ).width( stripWidth ); - self.picker.css( { width: opts.width, height: controlsHeight } ); - - if ( ! opts.palettes ) { - return self.picker.css( 'paddingBottom', '' ); - } - - // single margin at 2% - paletteMargin = squareWidth * 2 / 100; - paletteContainerWidth = squareWidth - ( ( paletteCount - 1 ) * paletteMargin ); - paletteWidth = paletteContainerWidth / paletteCount; - self.picker.find('.iris-palette').each( function( i ) { - var margin = i === 0 ? 0 : paletteMargin; - $( this ).css({ - width: paletteWidth, - height: paletteWidth, - marginLeft: margin - }); - }); - self.picker.css( 'paddingBottom', paletteWidth + paletteMargin ); - strip.height( paletteWidth + paletteMargin + squareWidth ); - }, - - _addInputListeners: function( input ) { - var self = this, - debounceTimeout = 100, - callback = function( event ){ - var color = new Color( input.val() ), - val = input.val().replace( /^#/, '' ); - - input.removeClass( 'iris-error' ); - // we gave a bad color - if ( color.error ) { - // don't error on an empty input - we want those allowed - if ( val !== '' ) { - input.addClass( 'iris-error' ); - } - } else { - if ( color.toString() !== self._color.toString() ) { - // let's not do this on keyup for hex shortcodes - if ( ! ( event.type === 'keyup' && val.match( /^[0-9a-fA-F]{3}$/ ) ) ) { - self._setOption( 'color', color.toString() ); - } - } - } - }; - - input.on( 'change', callback ).on( 'keyup', self._debounce( callback, debounceTimeout ) ); - - // If we initialized hidden, show on first focus. The rest is up to you. - if ( self.options.hide ) { - input.one( 'focus', function() { - self.show(); - }); - } - }, - - _initControls: function() { - var self = this, - controls = self.controls, - square = controls.square, - controlOpts = self.options.controls, - stripScale = self._scale[controlOpts.strip]; - - controls.stripSlider.slider({ - orientation: 'vertical', - max: stripScale, - slide: function( event, ui ) { - self.active = 'strip'; - // "reverse" for hue. - if ( controlOpts.strip === 'h' ) { - ui.value = stripScale - ui.value; - } - - self._color[controlOpts.strip]( ui.value ); - self._change.apply( self, arguments ); - } - }); - - controls.squareDrag.draggable({ - containment: controls.square.find( '.iris-square-inner' ), - zIndex: 1000, - cursor: 'move', - drag: function( event, ui ) { - self._squareDrag( event, ui ); - }, - start: function() { - square.addClass( 'iris-dragging' ); - $(this).addClass( 'ui-state-focus' ); - }, - stop: function() { - square.removeClass( 'iris-dragging' ); - $(this).removeClass( 'ui-state-focus' ); - } - }).on( 'mousedown mouseup', function( event ) { - var focusClass = 'ui-state-focus'; - event.preventDefault(); - if (event.type === 'mousedown' ) { - self.picker.find( '.' + focusClass ).removeClass( focusClass ).blur(); - $(this).addClass( focusClass ).focus(); - } else { - $(this).removeClass( focusClass ); - } - }).on( 'keydown', function( event ) { - var container = controls.square, - draggable = controls.squareDrag, - position = draggable.position(), - distance = self.options.width / 100; // Distance in pixels the draggable should be moved: 1 "stop" - - // make alt key go "10" - if ( event.altKey ) { - distance *= 10; - } - - // Reposition if one of the directional keys is pressed - switch ( event.keyCode ) { - case 37: position.left -= distance; break; // Left - case 38: position.top -= distance; break; // Up - case 39: position.left += distance; break; // Right - case 40: position.top += distance; break; // Down - default: return true; // Exit and bubble - } - - // Keep draggable within container - position.left = Math.max( 0, Math.min( position.left, container.width() ) ); - position.top = Math.max( 0, Math.min( position.top, container.height() ) ); - - draggable.css(position); - self._squareDrag( event, { position: position }); - event.preventDefault(); - }); - - // allow clicking on the square to move there and keep dragging - square.mousedown( function( event ) { - var squareOffset, pos; - // only left click - if ( event.which !== 1 ) { - return; - } - - // prevent bubbling from the handle: no infinite loops - if ( ! $( event.target ).is( 'div' ) ) { - return; - } - - squareOffset = self.controls.square.offset(); - pos = { - top: event.pageY - squareOffset.top, - left: event.pageX - squareOffset.left - }; - event.preventDefault(); - self._squareDrag( event, { position: pos } ); - event.target = self.controls.squareDrag.get(0); - self.controls.squareDrag.css( pos ).trigger( event ); - }); - - // palettes - if ( self.options.palettes ) { - self._paletteListeners(); - } - }, - - _paletteListeners: function() { - var self = this; - self.picker.find('.iris-palette-container').on('click.palette', '.iris-palette', function() { - self._color.fromCSS( $(this).data('color') ); - self.active = 'external'; - self._change(); - }).on( 'keydown.palette', '.iris-palette', function( event ) { - if ( ! ( event.keyCode === 13 || event.keyCode === 32 ) ) { - return true; - } - event.stopPropagation(); - $( this ).click(); - }); - }, - - _squareDrag: function( event, ui ) { - var self = this, - controlOpts = self.options.controls, - dimensions = self._squareDimensions(), - vertVal = Math.round( ( dimensions.h - ui.position.top ) / dimensions.h * self._scale[controlOpts.vert] ), - horizVal = self._scale[controlOpts.horiz] - Math.round( ( dimensions.w - ui.position.left ) / dimensions.w * self._scale[controlOpts.horiz] ); - - self._color[controlOpts.horiz]( horizVal )[controlOpts.vert]( vertVal ); - - self.active = 'square'; - self._change.apply( self, arguments ); - }, - - _setOption: function( key, value ) { - var self = this, - oldValue = self.options[key], - doDimensions = false, - hexLessColor, - newColor, - method; - - // ensure the new value is set. We can reset to oldValue if some check wasn't met. - self.options[key] = value; - - switch(key) { - case 'color': - // cast to string in case we have a number - value = '' + value; - hexLessColor = value.replace( /^#/, '' ); - newColor = new Color( value ).setHSpace( self.options.mode ); - if ( newColor.error ) { - self.options[key] = oldValue; - } else { - self._color = newColor; - self.options.color = self.options[key] = self._color.toString(); - self.active = 'external'; - self._change(); - } - break; - case 'palettes': - doDimensions = true; - - if ( value ) { - self._addPalettes(); - } else { - self.picker.find('.iris-palette-container').remove(); - } - - // do we need to add events? - if ( ! oldValue ) { - self._paletteListeners(); - } - break; - case 'width': - doDimensions = true; - break; - case 'border': - doDimensions = true; - method = value ? 'addClass' : 'removeClass'; - self.picker[method]('iris-border'); - break; - case 'mode': - case 'controls': - // if nothing's changed, let's bail, since this causes re-rendering the whole widget - if ( oldValue === value ) { - return; - } - - // we're using these poorly named variables because they're already scoped. - // method is the element that Iris was called on. oldValue will be the options - method = self.element; - oldValue = self.options; - oldValue.hide = ! self.picker.is( ':visible' ); - self.destroy(); - self.picker.remove(); - return $(self.element).iris(oldValue); - } - - // Do we need to recalc dimensions? - if ( doDimensions ) { - self._dimensions(true); - } - }, - - _squareDimensions: function( forceRefresh ) { - var square = this.controls.square, - dimensions, - control; - - if ( forceRefresh !== undef && square.data('dimensions') ) { - return square.data('dimensions'); - } - - control = this.controls.squareDrag; - dimensions = { - w: square.width(), - h: square.height() - }; - square.data( 'dimensions', dimensions ); - return dimensions; - }, - - _isNonHueControl: function( active, type ) { - if ( active === 'square' && this.options.controls.strip === 'h' ) { - return true; - } else if ( type === 'external' || ( type === 'h' && active === 'strip' ) ) { - return false; - } - - return true; - }, - - _change: function() { - var self = this, - controls = self.controls, - color = self._getHSpaceColor(), - actions = [ 'square', 'strip' ], - controlOpts = self.options.controls, - type = controlOpts[self.active] || 'external', - oldHue = self.hue; - - if ( self.active === 'strip' ) { - // take no action on any of the square sliders if we adjusted the strip - actions = []; - } else if ( self.active !== 'external' ) { - // for non-strip, non-external, strip should never change - actions.pop(); // conveniently the last item - } - - $.each( actions, function(index, item) { - var value, dimensions, cssObj; - if ( item !== self.active ) { - switch ( item ) { - case 'strip': - // reverse for hue - value = ( controlOpts.strip === 'h' ) ? self._scale[controlOpts.strip] - color[controlOpts.strip] : color[controlOpts.strip]; - controls.stripSlider.slider( 'value', value ); - break; - case 'square': - dimensions = self._squareDimensions(); - cssObj = { - left: color[controlOpts.horiz] / self._scale[controlOpts.horiz] * dimensions.w, - top: dimensions.h - ( color[controlOpts.vert] / self._scale[controlOpts.vert] * dimensions.h ) - }; - - self.controls.squareDrag.css( cssObj ); - break; - } - } - }); - - // Ensure that we don't change hue if we triggered a hue reset - if ( color.h !== oldHue && self._isNonHueControl( self.active, type ) ) { - self._color.h(oldHue); - } - - // store hue for repeating above check next time - self.hue = self._color.h(); - - self.options.color = self._color.toString(); - - // only run after the first time - if ( self._inited ) { - self._trigger( 'change', { type: self.active }, { color: self._color } ); - } - - if ( self.element.is( ':input' ) && ! self._color.error ) { - self.element.removeClass( 'iris-error' ); - if ( self.element.val() !== self._color.toString() ) { - self.element.val( self._color.toString() ); - } - } - - self._paint(); - self._inited = true; - self.active = false; - }, - // taken from underscore.js _.debounce method - _debounce: function( func, wait, immediate ) { - var timeout, result; - return function() { - var context = this, - args = arguments, - later, - callNow; - - later = function() { - timeout = null; - if ( ! immediate) { - result = func.apply( context, args ); - } - }; - - callNow = immediate && !timeout; - clearTimeout( timeout ); - timeout = setTimeout( later, wait ); - if ( callNow ) { - result = func.apply( context, args ); - } - return result; - }; - }, - show: function() { - this.picker.show(); - }, - hide: function() { - this.picker.hide(); - }, - toggle: function() { - this.picker.toggle(); - }, - color: function(newColor) { - if ( newColor === true ) { - return this._color.clone(); - } else if ( newColor === undef ) { - return this._color.toString(); - } - this.option('color', newColor); - } - }; - // initialize the widget - $.widget( 'a8c.iris', Iris ); - // add CSS - $( '<style id="iris-css">' + _css + '</style>' ).appendTo( 'head' ); - -}( jQuery )); -/*! Color.js - v0.9.11 - 2013-08-09 -* https://github.com/Automattic/Color.js -* Copyright (c) 2013 Matt Wiebe; Licensed GPLv2 */ -(function(global, undef) { - - var Color = function( color, type ) { - if ( ! ( this instanceof Color ) ) - return new Color( color, type ); - - return this._init( color, type ); - }; - - Color.fn = Color.prototype = { - _color: 0, - _alpha: 1, - error: false, - // for preserving hue/sat in fromHsl().toHsl() flows - _hsl: { h: 0, s: 0, l: 0 }, - // for preserving hue/sat in fromHsv().toHsv() flows - _hsv: { h: 0, s: 0, v: 0 }, - // for setting hsl or hsv space - needed for .h() & .s() functions to function properly - _hSpace: 'hsl', - _init: function( color ) { - var func = 'noop'; - switch ( typeof color ) { - case 'object': - // alpha? - if ( color.a !== undef ) - this.a( color.a ); - func = ( color.r !== undef ) ? 'fromRgb' : - ( color.l !== undef ) ? 'fromHsl' : - ( color.v !== undef ) ? 'fromHsv' : func; - return this[func]( color ); - case 'string': - return this.fromCSS( color ); - case 'number': - return this.fromInt( parseInt( color, 10 ) ); - } - return this; - }, - - _error: function() { - this.error = true; - return this; - }, - - clone: function() { - var newColor = new Color( this.toInt() ), - copy = ['_alpha', '_hSpace', '_hsl', '_hsv', 'error']; - for ( var i = copy.length - 1; i >= 0; i-- ) { - newColor[ copy[i] ] = this[ copy[i] ]; - } - return newColor; - }, - - setHSpace: function( space ) { - this._hSpace = ( space === 'hsv' ) ? space : 'hsl'; - return this; - }, - - noop: function() { - return this; - }, - - fromCSS: function( color ) { - var list, - leadingRE = /^(rgb|hs(l|v))a?\(/; - this.error = false; - - // whitespace and semicolon trim - color = color.replace(/^\s+/, '').replace(/\s+$/, '').replace(/;$/, ''); - - if ( color.match(leadingRE) && color.match(/\)$/) ) { - list = color.replace(/(\s|%)/g, '').replace(leadingRE, '').replace(/,?\);?$/, '').split(','); - - if ( list.length < 3 ) - return this._error(); - - if ( list.length === 4 ) { - this.a( parseFloat( list.pop() ) ); - // error state has been set to true in .a() if we passed NaN - if ( this.error ) - return this; - } - - for (var i = list.length - 1; i >= 0; i--) { - list[i] = parseInt(list[i], 10); - if ( isNaN( list[i] ) ) - return this._error(); - } - - if ( color.match(/^rgb/) ) { - return this.fromRgb( { - r: list[0], - g: list[1], - b: list[2] - } ); - } else if ( color.match(/^hsv/) ) { - return this.fromHsv( { - h: list[0], - s: list[1], - v: list[2] - } ); - } else { - return this.fromHsl( { - h: list[0], - s: list[1], - l: list[2] - } ); - } - } else { - // must be hex amirite? - return this.fromHex( color ); - } - }, - - fromRgb: function( rgb, preserve ) { - if ( typeof rgb !== 'object' || rgb.r === undef || rgb.g === undef || rgb.b === undef ) - return this._error(); - - this.error = false; - return this.fromInt( parseInt( ( rgb.r << 16 ) + ( rgb.g << 8 ) + rgb.b, 10 ), preserve ); - }, - - fromHex: function( color ) { - color = color.replace(/^#/, '').replace(/^0x/, ''); - if ( color.length === 3 ) { - color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]; - } - - // rough error checking - this is where things go squirrely the most - this.error = ! /^[0-9A-F]{6}$/i.test( color ); - return this.fromInt( parseInt( color, 16 ) ); - }, - - fromHsl: function( hsl ) { - var r, g, b, q, p, h, s, l; - - if ( typeof hsl !== 'object' || hsl.h === undef || hsl.s === undef || hsl.l === undef ) - return this._error(); - - this._hsl = hsl; // store it - this._hSpace = 'hsl'; // implicit - h = hsl.h / 360; s = hsl.s / 100; l = hsl.l / 100; - if ( s === 0 ) { - r = g = b = l; // achromatic - } - else { - q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s; - p = 2 * l - q; - r = this.hue2rgb( p, q, h + 1/3 ); - g = this.hue2rgb( p, q, h ); - b = this.hue2rgb( p, q, h - 1/3 ); - } - return this.fromRgb( { - r: r * 255, - g: g * 255, - b: b * 255 - }, true ); // true preserves hue/sat - }, - - fromHsv: function( hsv ) { - var h, s, v, r, g, b, i, f, p, q, t; - if ( typeof hsv !== 'object' || hsv.h === undef || hsv.s === undef || hsv.v === undef ) - return this._error(); - - this._hsv = hsv; // store it - this._hSpace = 'hsv'; // implicit - - h = hsv.h / 360; s = hsv.s / 100; v = hsv.v / 100; - i = Math.floor( h * 6 ); - f = h * 6 - i; - p = v * ( 1 - s ); - q = v * ( 1 - f * s ); - t = v * ( 1 - ( 1 - f ) * s ); - - switch( i % 6 ) { - case 0: - r = v; g = t; b = p; - break; - case 1: - r = q; g = v; b = p; - break; - case 2: - r = p; g = v; b = t; - break; - case 3: - r = p; g = q; b = v; - break; - case 4: - r = t; g = p; b = v; - break; - case 5: - r = v; g = p; b = q; - break; - } - - return this.fromRgb( { - r: r * 255, - g: g * 255, - b: b * 255 - }, true ); // true preserves hue/sat - - }, - // everything comes down to fromInt - fromInt: function( color, preserve ) { - this._color = parseInt( color, 10 ); - - if ( isNaN( this._color ) ) - this._color = 0; - - // let's coerce things - if ( this._color > 16777215 ) - this._color = 16777215; - else if ( this._color < 0 ) - this._color = 0; - - // let's not do weird things - if ( preserve === undef ) { - this._hsv.h = this._hsv.s = this._hsl.h = this._hsl.s = 0; - } - // EVENT GOES HERE - return this; - }, - - hue2rgb: function( p, q, t ) { - if ( t < 0 ) { - t += 1; - } - if ( t > 1 ) { - t -= 1; - } - if ( t < 1/6 ) { - return p + ( q - p ) * 6 * t; - } - if ( t < 1/2 ) { - return q; - } - if ( t < 2/3 ) { - return p + ( q - p ) * ( 2/3 - t ) * 6; - } - return p; - }, - - toString: function() { - var hex = parseInt( this._color, 10 ).toString( 16 ); - if ( this.error ) - return ''; - // maybe left pad it - if ( hex.length < 6 ) { - for (var i = 6 - hex.length - 1; i >= 0; i--) { - hex = '0' + hex; - } - } - return '#' + hex; - }, - - toCSS: function( type, alpha ) { - type = type || 'hex'; - alpha = parseFloat( alpha || this._alpha ); - switch ( type ) { - case 'rgb': - case 'rgba': - var rgb = this.toRgb(); - if ( alpha < 1 ) { - return "rgba( " + rgb.r + ", " + rgb.g + ", " + rgb.b + ", " + alpha + " )"; - } - else { - return "rgb( " + rgb.r + ", " + rgb.g + ", " + rgb.b + " )"; - } - break; - case 'hsl': - case 'hsla': - var hsl = this.toHsl(); - if ( alpha < 1 ) { - return "hsla( " + hsl.h + ", " + hsl.s + "%, " + hsl.l + "%, " + alpha + " )"; - } - else { - return "hsl( " + hsl.h + ", " + hsl.s + "%, " + hsl.l + "% )"; - } - break; - default: - return this.toString(); - } - }, - - toRgb: function() { - return { - r: 255 & ( this._color >> 16 ), - g: 255 & ( this._color >> 8 ), - b: 255 & ( this._color ) - }; - }, - - toHsl: function() { - var rgb = this.toRgb(); - var r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255; - var max = Math.max( r, g, b ), min = Math.min( r, g, b ); - var h, s, l = ( max + min ) / 2; - - if ( max === min ) { - h = s = 0; // achromatic - } else { - var d = max - min; - s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ); - switch ( max ) { - case r: h = ( g - b ) / d + ( g < b ? 6 : 0 ); - break; - case g: h = ( b - r ) / d + 2; - break; - case b: h = ( r - g ) / d + 4; - break; - } - h /= 6; - } - - // maintain hue & sat if we've been manipulating things in the HSL space. - h = Math.round( h * 360 ); - if ( h === 0 && this._hsl.h !== h ) { - h = this._hsl.h; - } - s = Math.round( s * 100 ); - if ( s === 0 && this._hsl.s ) { - s = this._hsl.s; - } - - return { - h: h, - s: s, - l: Math.round( l * 100 ) - }; - - }, - - toHsv: function() { - var rgb = this.toRgb(); - var r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255; - var max = Math.max( r, g, b ), min = Math.min( r, g, b ); - var h, s, v = max; - var d = max - min; - s = max === 0 ? 0 : d / max; - - if ( max === min ) { - h = s = 0; // achromatic - } else { - switch( max ){ - case r: - h = ( g - b ) / d + ( g < b ? 6 : 0 ); - break; - case g: - h = ( b - r ) / d + 2; - break; - case b: - h = ( r - g ) / d + 4; - break; - } - h /= 6; - } - - // maintain hue & sat if we've been manipulating things in the HSV space. - h = Math.round( h * 360 ); - if ( h === 0 && this._hsv.h !== h ) { - h = this._hsv.h; - } - s = Math.round( s * 100 ); - if ( s === 0 && this._hsv.s ) { - s = this._hsv.s; - } - - return { - h: h, - s: s, - v: Math.round( v * 100 ) - }; - }, - - toInt: function() { - return this._color; - }, - - toIEOctoHex: function() { - // AARRBBGG - var hex = this.toString(); - var AA = parseInt( 255 * this._alpha, 10 ).toString(16); - if ( AA.length === 1 ) { - AA = '0' + AA; - } - return '#' + AA + hex.replace(/^#/, '' ); - }, - - toLuminosity: function() { - var rgb = this.toRgb(); - return 0.2126 * Math.pow( rgb.r / 255, 2.2 ) + 0.7152 * Math.pow( rgb.g / 255, 2.2 ) + 0.0722 * Math.pow( rgb.b / 255, 2.2); - }, - - getDistanceLuminosityFrom: function( color ) { - if ( ! ( color instanceof Color ) ) { - throw 'getDistanceLuminosityFrom requires a Color object'; - } - var lum1 = this.toLuminosity(); - var lum2 = color.toLuminosity(); - if ( lum1 > lum2 ) { - return ( lum1 + 0.05 ) / ( lum2 + 0.05 ); - } - else { - return ( lum2 + 0.05 ) / ( lum1 + 0.05 ); - } - }, - - getMaxContrastColor: function() { - var lum = this.toLuminosity(); - var hex = ( lum >= 0.5 ) ? '000000' : 'ffffff'; - return new Color( hex ); - }, - - getReadableContrastingColor: function( bgColor, minContrast ) { - if ( ! bgColor instanceof Color ) { - return this; - } - - // you shouldn't use less than 5, but you might want to. - var targetContrast = ( minContrast === undef ) ? 5 : minContrast; - // working things - var contrast = bgColor.getDistanceLuminosityFrom( this ); - var maxContrastColor = bgColor.getMaxContrastColor(); - var maxContrast = maxContrastColor.getDistanceLuminosityFrom( bgColor ); - - // if current max contrast is less than the target contrast, we had wishful thinking. - // still, go max - if ( maxContrast <= targetContrast ) { - return maxContrastColor; - } - // or, we might already have sufficient contrast - else if ( contrast >= targetContrast ) { - return this; - } - - var incr = ( 0 === maxContrastColor.toInt() ) ? -1 : 1; - while ( contrast < targetContrast ) { - this.l( incr, true ); // 2nd arg turns this into an incrementer - contrast = this.getDistanceLuminosityFrom( bgColor ); - // infininite loop prevention: you never know. - if ( this._color === 0 || this._color === 16777215 ) { - break; - } - } - - return this; - - }, - - a: function( val ) { - if ( val === undef ) - return this._alpha; - - var a = parseFloat( val ); - - if ( isNaN( a ) ) - return this._error(); - - this._alpha = a; - return this; - }, - - // TRANSFORMS - - darken: function( amount ) { - amount = amount || 5; - return this.l( - amount, true ); - }, - - lighten: function( amount ) { - amount = amount || 5; - return this.l( amount, true ); - }, - - saturate: function( amount ) { - amount = amount || 15; - return this.s( amount, true ); - }, - - desaturate: function( amount ) { - amount = amount || 15; - return this.s( - amount, true ); - }, - - toGrayscale: function() { - return this.setHSpace('hsl').s( 0 ); - }, - - getComplement: function() { - return this.h( 180, true ); - }, - - getSplitComplement: function( step ) { - step = step || 1; - var incr = 180 + ( step * 30 ); - return this.h( incr, true ); - }, - - getAnalog: function( step ) { - step = step || 1; - var incr = step * 30; - return this.h( incr, true ); - }, - - getTetrad: function( step ) { - step = step || 1; - var incr = step * 60; - return this.h( incr, true ); - }, - - getTriad: function( step ) { - step = step || 1; - var incr = step * 120; - return this.h( incr, true ); - }, - - _partial: function( key ) { - var prop = shortProps[key]; - return function( val, incr ) { - var color = this._spaceFunc('to', prop.space); - - // GETTER - if ( val === undef ) - return color[key]; - - // INCREMENT - if ( incr === true ) - val = color[key] + val; - - // MOD & RANGE - if ( prop.mod ) - val = val % prop.mod; - if ( prop.range ) - val = ( val < prop.range[0] ) ? prop.range[0] : ( val > prop.range[1] ) ? prop.range[1] : val; - - // NEW VALUE - color[key] = val; - - return this._spaceFunc('from', prop.space, color); - }; - }, - - _spaceFunc: function( dir, s, val ) { - var space = s || this._hSpace, - funcName = dir + space.charAt(0).toUpperCase() + space.substr(1); - return this[funcName](val); - } - }; - - var shortProps = { - h: { - mod: 360 - }, - s: { - range: [0,100] - }, - l: { - space: 'hsl', - range: [0,100] - }, - v: { - space: 'hsv', - range: [0,100] - }, - r: { - space: 'rgb', - range: [0,255] - }, - g: { - space: 'rgb', - range: [0,255] - }, - b: { - space: 'rgb', - range: [0,255] - } - }; - - for ( var key in shortProps ) { - if ( shortProps.hasOwnProperty( key ) ) - Color.fn[key] = Color.fn._partial(key); - } - - // play nicely with Node + browser - if ( typeof exports === 'object' ) - module.exports = Color; - else - global.Color = Color; - -}(this)); |