wp/wp-admin/js/svg-painter.js
changeset 5 5e2f62d02dcd
child 9 177826044cd9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wp/wp-admin/js/svg-painter.js	Tue Jun 09 03:35:32 2015 +0200
@@ -0,0 +1,240 @@
+/**
+ * Attempt to re-color SVG icons used in the admin menu or the toolbar
+ *
+ */
+
+window.wp = window.wp || {};
+
+wp.svgPainter = ( function( $, window, document, undefined ) {
+	'use strict';
+	var selector, base64, painter,
+		colorscheme = {},
+		elements = [];
+
+	$(document).ready( function() {
+		// detection for browser SVG capability
+		if ( document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' ) ) {
+			$( document.body ).removeClass( 'no-svg' ).addClass( 'svg' );
+			wp.svgPainter.init();
+		}
+	});
+
+	/**
+	 * Needed only for IE9
+	 *
+	 * Based on jquery.base64.js 0.0.3 - https://github.com/yckart/jquery.base64.js
+	 *
+	 * Based on: https://gist.github.com/Yaffle/1284012
+	 *
+	 * Copyright (c) 2012 Yannick Albert (http://yckart.com)
+	 * Licensed under the MIT license
+	 * http://www.opensource.org/licenses/mit-license.php
+	 */
+	base64 = ( function() {
+		var c,
+			b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
+			a256 = '',
+			r64 = [256],
+			r256 = [256],
+			i = 0;
+
+		function init() {
+			while( i < 256 ) {
+				c = String.fromCharCode(i);
+				a256 += c;
+				r256[i] = i;
+				r64[i] = b64.indexOf(c);
+				++i;
+			}
+		}
+
+		function code( s, discard, alpha, beta, w1, w2 ) {
+			var tmp, length,
+				buffer = 0,
+				i = 0,
+				result = '',
+				bitsInBuffer = 0;
+
+			s = String(s);
+			length = s.length;
+
+			while( i < length ) {
+				c = s.charCodeAt(i);
+				c = c < 256 ? alpha[c] : -1;
+
+				buffer = ( buffer << w1 ) + c;
+				bitsInBuffer += w1;
+
+				while( bitsInBuffer >= w2 ) {
+					bitsInBuffer -= w2;
+					tmp = buffer >> bitsInBuffer;
+					result += beta.charAt(tmp);
+					buffer ^= tmp << bitsInBuffer;
+				}
+				++i;
+			}
+
+			if ( ! discard && bitsInBuffer > 0 ) {
+				result += beta.charAt( buffer << ( w2 - bitsInBuffer ) );
+			}
+
+			return result;
+		}
+
+		function btoa( plain ) {
+			if ( ! c ) {
+				init();
+			}
+
+			plain = code( plain, false, r256, b64, 8, 6 );
+			return plain + '===='.slice( ( plain.length % 4 ) || 4 );
+		}
+
+		function atob( coded ) {
+			var i;
+
+			if ( ! c ) {
+				init();
+			}
+
+			coded = coded.replace( /[^A-Za-z0-9\+\/\=]/g, '' );
+			coded = String(coded).split('=');
+			i = coded.length;
+
+			do {
+				--i;
+				coded[i] = code( coded[i], true, r64, a256, 6, 8 );
+			} while ( i > 0 );
+
+			coded = coded.join('');
+			return coded;
+		}
+
+		return {
+			atob: atob,
+			btoa: btoa
+		};
+	})();
+
+	return {
+		init: function() {
+			painter = this;
+			selector = $( '#adminmenu .wp-menu-image, #wpadminbar .ab-item' );
+
+			this.setColors();
+			this.findElements();
+			this.paint();
+		},
+
+		setColors: function( colors ) {
+			if ( typeof colors === 'undefined' && typeof window._wpColorScheme !== 'undefined' ) {
+				colors = window._wpColorScheme;
+			}
+
+			if ( colors && colors.icons && colors.icons.base && colors.icons.current && colors.icons.focus ) {
+				colorscheme = colors.icons;
+			}
+		},
+
+		findElements: function() {
+			selector.each( function() {
+				var $this = $(this), bgImage = $this.css( 'background-image' );
+
+				if ( bgImage && bgImage.indexOf( 'data:image/svg+xml;base64' ) != -1 ) {
+					elements.push( $this );
+				}
+			});
+		},
+
+		paint: function() {
+			// loop through all elements
+			$.each( elements, function( index, $element ) {
+				var $menuitem = $element.parent().parent();
+
+				if ( $menuitem.hasClass( 'current' ) || $menuitem.hasClass( 'wp-has-current-submenu' ) ) {
+					// paint icon in 'current' color
+					painter.paintElement( $element, 'current' );
+				} else {
+					// paint icon in base color
+					painter.paintElement( $element, 'base' );
+
+					// set hover callbacks
+					$menuitem.hover(
+						function() {
+							painter.paintElement( $element, 'focus' );
+						},
+						function() {
+							// Match the delay from hoverIntent
+							window.setTimeout( function() {
+								painter.paintElement( $element, 'base' );
+							}, 100 );
+						}
+					);
+				}
+			});
+		},
+
+		paintElement: function( $element, colorType ) {
+			var xml, encoded, color;
+
+			if ( ! colorType || ! colorscheme.hasOwnProperty( colorType ) ) {
+				return;
+			}
+
+			color = colorscheme[ colorType ];
+
+			// only accept hex colors: #101 or #101010
+			if ( ! color.match( /^(#[0-9a-f]{3}|#[0-9a-f]{6})$/i ) ) {
+				return;
+			}
+
+			xml = $element.data( 'wp-ui-svg-' + color );
+
+			if ( xml === 'none' ) {
+				return;
+			}
+
+			if ( ! xml ) {
+				encoded = $element.css( 'background-image' ).match( /.+data:image\/svg\+xml;base64,([A-Za-z0-9\+\/\=]+)/ );
+
+				if ( ! encoded || ! encoded[1] ) {
+					$element.data( 'wp-ui-svg-' + color, 'none' );
+					return;
+				}
+
+				try {
+					if ( 'atob' in window ) {
+						xml = window.atob( encoded[1] );
+					} else {
+						xml = base64.atob( encoded[1] );
+					}
+				} catch ( error ) {}
+
+				if ( xml ) {
+					// replace `fill` attributes
+					xml = xml.replace( /fill="(.+?)"/g, 'fill="' + color + '"');
+
+					// replace `style` attributes
+					xml = xml.replace( /style="(.+?)"/g, 'style="fill:' + color + '"');
+
+					// replace `fill` properties in `<style>` tags
+					xml = xml.replace( /fill:.*?;/g, 'fill: ' + color + ';');
+
+					if ( 'btoa' in window ) {
+						xml = window.btoa( xml );
+					} else {
+						xml = base64.btoa( xml );
+					}
+
+					$element.data( 'wp-ui-svg-' + color, xml );
+				} else {
+					$element.data( 'wp-ui-svg-' + color, 'none' );
+					return;
+				}
+			}
+
+			$element.attr( 'style', 'background-image: url("data:image/svg+xml;base64,' + xml + '") !important;' );
+		}
+	};
+
+})( jQuery, window, document );