Browse Source

Merge branch 'v2-develop' of https://github.com/causefx/Organizr into v2-develop

Rob Gökemeijer 8 years ago
parent
commit
f9bbffa3a4
8 changed files with 728 additions and 41 deletions
  1. 7 0
      api/config/default.php
  2. 72 7
      api/functions/organizr-functions.php
  3. 2 0
      index.php
  4. 19 1
      js/custom.js
  5. 154 33
      js/functions.js
  6. 236 0
      js/jqColorPicker.min.js
  7. 236 0
      js/jsColor.js
  8. 2 0
      js/jsColorPicker.min.js

+ 7 - 0
api/config/default.php

@@ -14,6 +14,13 @@ return array(
     'headerTextColor' => '',
     'sidebarColor' => '',
     'sidebarTextColor' => '',
+	'accentColor' => '',
+    'accentTextColor' => '',
+	'buttonColor' => '',
+	'buttonTextColor' => '',
+	'buttonHoverColor' => '',
+    'buttonTextHoverColor' => '',
+	'alternateHomepageHeaders' => false,
     'lockScreen' => false,
     'theme'=>'Organizr',
     'style'=>'dark',

+ 72 - 7
api/functions/organizr-functions.php

@@ -13,6 +13,9 @@ function organizrSpecialSettings()
             ),
             'ombi' => array(
                 'enabled' => (qualifyRequest($GLOBALS['homepageOmbiAuth']) && $GLOBALS['homepageOmbiEnabled'] == true && $GLOBALS['ssoOmbi']) ? true : false,
+            ),
+            'options' => array(
+                'alternateHomepageHeaders' => $GLOBALS['alternateHomepageHeaders'],
             )
         )
     );
@@ -502,6 +505,12 @@ function loadAppearance()
     $appearance['sidebarColor'] = $GLOBALS['sidebarColor'];
     $appearance['headerTextColor'] = $GLOBALS['headerTextColor'];
     $appearance['sidebarTextColor'] = $GLOBALS['sidebarTextColor'];
+    $appearance['accentColor'] = $GLOBALS['accentColor'];
+    $appearance['accentTextColor'] = $GLOBALS['accentTextColor'];
+    $appearance['buttonColor'] = $GLOBALS['buttonColor'];
+    $appearance['buttonTextColor'] = $GLOBALS['buttonTextColor'];
+    $appearance['buttonTextHoverColor'] = $GLOBALS['buttonTextHoverColor'];
+    $appearance['buttonHoverColor'] = $GLOBALS['buttonHoverColor'];
     $appearance['loginWallpaper'] = $GLOBALS['loginWallpaper'];
     $appearance['customCss'] = $GLOBALS['customCss'];
     return $appearance;
@@ -538,39 +547,95 @@ function getCustomizeAppearance()
                     'value' => $GLOBALS['loginWallpaper']
                 )
             ),
+            'Options' => array(
+                array(
+                    'type' => 'switch',
+                    'name' => 'alternateHomepageHeaders',
+                    'label' => 'Alternate Homepage Titles',
+                    'value' => $GLOBALS['alternateHomepageHeaders']
+                )
+            ),
             'Colors & Themes' => array(
                 array(
                     'type' => 'input',
                     'name' => 'headerColor',
                     'label' => 'Nav Bar Color',
                     'value' => $GLOBALS['headerColor'],
-                    'class' => 'colorpicker',
-                    'disabled' => true
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['headerColor'].'"'
                 ),
                 array(
                     'type' => 'input',
                     'name' => 'headerTextColor',
                     'label' => 'Nav Bar Text Color',
                     'value' => $GLOBALS['headerTextColor'],
-                    'class' => 'colorpicker',
-                    'disabled' => true
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['headerTextColor'].'"'
                 ),
                 array(
                     'type' => 'input',
                     'name' => 'sidebarColor',
                     'label' => 'Side Bar Color',
                     'value' => $GLOBALS['sidebarColor'],
-                    'class' => 'colorpicker',
-                    'disabled' => true
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['sidebarColor'].'"'
                 ),
                 array(
                     'type' => 'input',
                     'name' => 'sidebarTextColor',
                     'label' => 'Side Bar Text Color',
                     'value' => $GLOBALS['sidebarTextColor'],
-                    'class' => 'colorpicker',
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['sidebarTextColor'].'"'
+                ),
+                array(
+                    'type' => 'input',
+                    'name' => 'accentColor',
+                    'label' => 'Accent Color',
+                    'value' => $GLOBALS['accentColor'],
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['accentColor'].'"'
+                ),
+                array(
+                    'type' => 'input',
+                    'name' => 'accentTextColor',
+                    'label' => 'Accent Text Color',
+                    'value' => $GLOBALS['accentTextColor'],
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['accentTextColor'].'"'
+                ),
+                array(
+                    'type' => 'input',
+                    'name' => 'buttonColor',
+                    'label' => 'Button Color',
+                    'value' => $GLOBALS['buttonColor'],
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['buttonColor'].'"'
+                ),
+                array(
+                    'type' => 'input',
+                    'name' => 'buttonTextColor',
+                    'label' => 'Button Text Color',
+                    'value' => $GLOBALS['buttonTextColor'],
+                    'class' => 'pick-a-color',
+                    'attr' => 'data-original="'.$GLOBALS['buttonTextColor'].'"'
+                ),/*
+                array(
+                    'type' => 'input',
+                    'name' => 'buttonHoverColor',
+                    'label' => 'Button Hover Color',
+                    'value' => $GLOBALS['buttonHoverColor'],
+                    'class' => 'pick-a-color',
                     'disabled' => true
                 ),
+                array(
+                    'type' => 'input',
+                    'name' => 'buttonTextHoverColor',
+                    'label' => 'Button Hover Text Color',
+                    'value' => $GLOBALS['buttonTextHoverColor'],
+                    'class' => 'pick-a-color',
+                    'disabled' => true
+                ),*/
                 array(
                     'type' => 'select',
                     'name' => 'theme',

+ 2 - 0
index.php

@@ -137,6 +137,8 @@
 	<script src="js/jquery.serializeToJSON.js"></script>
 	<script src="js/lazyload.min2.js"></script>
 	<script src="js/clipboard.js"></script>
+	<script src="js/jsColorPicker.min.js"></script>
+	<script src="js/jsColor.js"></script>
 	<script src="js/emulatetab.joelpurra.js"></script>
 	<script src="plugins/bower_components/ace/ace.js"></script>
 	<script src="plugins/bower_components/ace/mode-css.js"></script>

+ 19 - 1
js/custom.js

@@ -953,7 +953,16 @@ $(document).on("click", ".savecustomHTMLoneTextarea", function () {
 $(document).on("click", ".savecustomHTMLtwoTextarea", function () {
     $('.customHTMLtwoTextarea').val(customHTMLtwoEditor.getValue()).trigger('change');
 });
-$(document).on('change asColorPicker::close', '#customize-appearance-form :input', function(e) {
+
+$(document).on('focusout', 'input.pick-a-color', function(e) {
+    var original = $(this).attr('data-original');
+    var newValue = $(this).val();
+    if((original !== newValue) && (newValue !== '#987654') && newValue !== ''){
+        $(this).change();
+        $(this).attr('data-original', newValue);
+    }
+});
+$(document).on('change colorPicker::close', '#customize-appearance-form :input', function(e) {
     $(this).attr('data-changed', true);
     switch ($(this).attr('type')) {
         case 'switch':
@@ -982,6 +991,15 @@ $(document).on('change asColorPicker::close', '#customize-appearance-form :input
     if($(this).hasClass('styleChanger')){
         changeStyle(value);
     }
+    //disable button then renable
+    $('#customize-appearance-form:input').prop('disabled', 'true');
+    setTimeout(
+        function(){
+            $('#customize-appearance-form :input').prop('disabled', null);
+            //input.emulateTab();
+        },
+        2000
+    );
 
 });
 //DELETE IMAGE

+ 154 - 33
js/functions.js

@@ -890,6 +890,14 @@ function buildCustomizeAppearance(){
 				$('.saveCss').removeClass('hidden');
 			}
 		});
+		var colors = jsColorPicker('input.pick-a-color', {
+			customBG: '#222',
+			readOnly: false,
+			init: function(elm, colors) { // colors is a different instance (not connected to colorPicker)
+				elm.style.backgroundColor = elm.value;
+				elm.style.color = colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd';
+			}
+		});
 	}).fail(function(xhr) {
 		console.error("Organizr Function: API Connection Failed");
 	});
@@ -1973,6 +1981,49 @@ function loadAppearance(appearance){
 		    }
 		`;
 	}
+	if(appearance.accentColor !== ''){
+		cssSettings += `
+			.bg-info,
+			.fc-toolbar,
+			.progress-bar-info,
+			.label-info {
+			    background-color: `+appearance.accentColor+` !important;
+			}
+			.panel-blue .panel-heading, .panel-info .panel-heading {
+			    border-color: `+appearance.accentColor+`;
+			}
+
+			.text-info,
+			.btn-link, a {
+			    color: `+appearance.accentColor+`;
+			}
+		`;
+	}
+	if(appearance.accentTextColor !== ''){
+		cssSettings += `
+			.progress-bar,
+			.panel-default .panel-heading,
+			.mailbox-widget .customtab li.active a, .mailbox-widget .customtab li.active, .mailbox-widget .customtab li.active a:focus,
+			.mailbox-widget .customtab li a {
+				color: `+appearance.accentTextColor+`;
+			}
+		`;
+	}
+	if(appearance.buttonColor !== ''){
+		cssSettings += `
+			.btn-info, .btn-info.disabled {
+				background: `+appearance.buttonColor+` !important;
+				border: 1px solid `+appearance.buttonColor+` !important;
+			}
+		`;
+	}
+	if(appearance.buttonTextColor !== ''){
+		cssSettings += `
+			.btn-info, .btn-info.disabled {
+				color: `+appearance.buttonTextColor+` !important;
+			}
+		`;
+	}
 	if(appearance.loginWallpaper !== ''){
 		cssSettings += `
 		    .login-register {
@@ -2417,28 +2468,46 @@ function buildRecent(array, type){
 	var video = (recent) ? (array.content.filter(p => p.type == "video").length > 0 ? true : false) : false;
 	var music = (recent) ? (array.content.filter(p => p.type == "music").length > 0 ? true : false) : false;
 	var dropdown = '';
+	var header = '';
+	var headerAlt = '';
 	dropdown += (recent && movie) ? `<li><a data-filter="recent-movie" server-filter="`+type+`" href="javascript:void(0);">Movies</a></li>` : '';
 	dropdown += (recent && tv) ? `<li><a data-filter="recent-tv" server-filter="`+type+`" href="javascript:void(0);">Shows</a></li>` : '';
 	dropdown += (recent && video) ? `<li><a data-filter="recent-video" server-filter="`+type+`" href="javascript:void(0);">Videos</a></li>` : '';
 	//dropdown += (recent && music) ? `<li><a data-filter="recent-music" server-filter="`+type+`" href="javascript:void(0);">Music</a></li>` : '';
+	var dropdownMenu = `
+	<div class="btn-group pull-right">
+		<button aria-expanded="false" data-toggle="dropdown" class="btn btn-info dropdown-toggle waves-effect waves-light" type="button">
+			<i class="fa fa-filter m-r-5"></i><span class="caret"></span>
+		</button>
+		<ul role="menu" class="dropdown-menu recent-filter">
+			<li><a data-filter="all" server-filter="`+type+`" href="javascript:void(0);">All</a></li>
+			<li class="divider"></li>
+			`+dropdown+`
+		</ul>
+	</div>`;
+	if(activeInfo.settings.homepage.options.alternateHomepageHeaders){
+		var headerAlt = `
+		<div class="col-md-12">
+			<h4 class="pull-left"><span lang="en">Recently Added</span></h4>
+			`+dropdownMenu+`
+			<hr>
+		</div>
+		`;
+	}else{
+		var header = `
+		<div class="panel-heading bg-info p-t-10 p-b-10">
+			<span class="pull-left m-t-5"><img class="lazyload homepageImageTitle" data-src="plugins/images/tabs/`+type+`.png"> &nbsp; <span lang="en">Recently Added</span></span>
+			`+dropdownMenu+`
+			<div class="clearfix"></div>
+		</div>
+		`;
+	}
 	return (recent) ? `
 	<div id="`+type+`Recent" class="row">
+		`+headerAlt+`
         <div class="col-lg-12">
             <div class="panel panel-default">
-                <div class="panel-heading bg-info p-t-10 p-b-10">
-					<span class="pull-left m-t-5"><img class="lazyload homepageImageTitle" data-src="plugins/images/tabs/`+type+`.png"> &nbsp; <span lang="en">Recently Added</span></span>
-					<div class="btn-group pull-right">
-	                    <button aria-expanded="false" data-toggle="dropdown" class="btn btn-info dropdown-toggle waves-effect waves-light" type="button">
-							<i class="fa fa-filter m-r-5"></i><span class="caret"></span>
-						</button>
-	                    <ul role="menu" class="dropdown-menu recent-filter">
-	                        <li><a data-filter="all" server-filter="`+type+`" href="javascript:void(0);">All</a></li>
-							<li class="divider"></li>
-							`+dropdown+`
-	                    </ul>
-	                </div>
-					<div class="clearfix"></div>
-				</div>
+				`+header+`
                 <div class="panel-wrapper p-b-0 collapse in">
 					<div class="`+type+`-recent-hidden hidden"></div>
                     <div class="owl-carousel owl-theme recent-items `+type+`-recent">
@@ -2467,6 +2536,8 @@ function buildPlaylist(array, type){
 	var hidden = '';
 	var count = 0;
 	var items = '';
+	var header = '';
+	var headerAlt = '';
 	if(playlist){
 		$.each(array.content, function(i,v) {
 			v.title = cleanPlaylistTitle(v.title);
@@ -2491,17 +2562,33 @@ function buildPlaylist(array, type){
 		</ul>
 		`;
 	}
+	if(activeInfo.settings.homepage.options.alternateHomepageHeaders){
+		var headerAlt = `
+		<div class="col-md-12">
+			<h4 class="pull-left"><span class="`+type+`-playlistTitle">`+first+`</span></h4>
+			<div class="btn-group pull-right">
+				`+builtDropdown+`
+			</div>
+			<hr>
+		</div>
+		`;
+	}else{
+		var header = `
+		<div class="panel-heading bg-info p-t-10 p-b-10">
+			<span class="pull-left m-t-5"><img class="lazyload homepageImageTitle" data-src="plugins/images/tabs/`+type+`.png"> &nbsp; <span class="`+type+`-playlistTitle">`+first+`</span></span>
+			<div class="btn-group pull-right">
+					`+builtDropdown+`
+			</div>
+			<div class="clearfix"></div>
+		</div>
+		`;
+	}
 	return (playlist) ? `
 	<div id="`+type+`Playlist" class="row">
+		`+headerAlt+`
         <div class="col-lg-12">
             <div class="panel panel-default">
-                <div class="panel-heading bg-info p-t-10 p-b-10">
-					<span class="pull-left m-t-5"><img class="lazyload homepageImageTitle" data-src="plugins/images/tabs/`+type+`.png"> &nbsp; <span class="`+type+`-playlistTitle">`+first+`</span></span>
-					<div class="btn-group pull-right">
-							`+builtDropdown+`
-	                </div>
-					<div class="clearfix"></div>
-				</div>
+                `+header+`
                 <div class="panel-wrapper p-b-0 collapse in">
                     `+items+`
                 </div>
@@ -2513,6 +2600,8 @@ function buildPlaylist(array, type){
 function buildRequest(array){
 	var requests = (typeof array.content !== 'undefined') ? true : false;
 	var dropdown = '';
+	var headerAlt = '';
+	var header = '';
 	var ombiButton = (activeInfo.settings.homepage.ombi.enabled == true) ? `<button href="#new-request" id="newRequestButton" class="btn btn-info waves-effect waves-light inline-popups" data-effect="mfp-zoom-out"><i class="fa fa-plus m-l-5"></i></button>` : '';
 	if(requests){
 		var builtDropdown = `
@@ -2553,17 +2642,33 @@ function buildRequest(array){
 
 		`;
 	}
+	if(activeInfo.settings.homepage.options.alternateHomepageHeaders){
+		var headerAlt = `
+		<div class="col-md-12">
+			<h4 class="pull-left"><span lang="en">Requested Content</span></h4>
+			<div class="btn-group pull-right">
+				`+builtDropdown+`
+			</div>
+			<hr>
+		</div>
+		`;
+	}else{
+		var header = `
+		<div class="panel-heading bg-info p-t-10 p-b-10">
+			<span class="pull-left m-t-5"><img class="lazyload homepageImageTitle" data-src="plugins/images/tabs/ombi.png"> &nbsp; Requested Content</span>
+			<div class="btn-group pull-right">
+					`+builtDropdown+`
+			</div>
+			<div class="clearfix"></div>
+		</div>
+		`;
+	}
 	return (requests) ? `
 	<div id="ombi-requests" class="row">
+		`+headerAlt+`
         <div class="col-lg-12">
             <div class="panel panel-default">
-                <div class="panel-heading bg-info p-t-10 p-b-10">
-					<span class="pull-left m-t-5"><img class="lazyload homepageImageTitle" data-src="plugins/images/tabs/ombi.png"> &nbsp; Requested Content</span>
-					<div class="btn-group pull-right">
-							`+builtDropdown+`
-	                </div>
-					<div class="clearfix"></div>
-				</div>
+				`+header+`
                 <div class="panel-wrapper p-b-0 collapse in">
 				<div class="owl-carousel owl-theme request-items">
 					`+buildRequestItem(array.content)+`
@@ -3029,6 +3134,8 @@ function buildDownloader(array, source){
 	var downloader = (queueItems || historyItems) ? true : false;
 	var state = '';
 	var active = '';
+	var headerAlt = '';
+	var header = '';
 	//console.log(array);
 	//console.log(queueItems);
 	//console.log(historyItems);
@@ -3076,14 +3183,28 @@ function buildDownloader(array, source){
 		`;
 	}
 	menu += '</ul>';
+	if(activeInfo.settings.homepage.options.alternateHomepageHeaders){
+		var headerAlt = `
+		<div class="col-md-12">
+			<h2 class="text-white m-0 pull-left text-uppercase"><img class="lazyload homepageImageTitle `+active+`" data-src="plugins/images/tabs/`+source+`.png">  &nbsp; `+state+`</h2>
+			`+menu+`
+			<hr>
+		</div>
+		`;
+	}else{
+		var header = `
+		<div class="white-box bg-info m-b-0 p-b-0 p-t-10 mailbox-widget">
+			<h2 class="text-white m-0 pull-left text-uppercase"><img class="lazyload homepageImageTitle `+active+`" data-src="plugins/images/tabs/`+source+`.png">  &nbsp; `+state+`</h2>
+			`+menu+`
+			<div class="clearfix"></div>
+		</div>
+		`;
+	}
 	return downloader ? `
 	<div class="row">
+		`+headerAlt+`
 		<div class="col-lg-12">
-	        <div class="white-box bg-info m-b-0 p-b-0 p-t-10 mailbox-widget">
-				<h2 class="text-white m-0 pull-left text-uppercase"><img class="lazyload homepageImageTitle `+active+`" data-src="plugins/images/tabs/`+source+`.png">  &nbsp; `+state+`</h2>
-	            `+menu+`
-				<div class="clearfix"></div>
-	        </div>
+	        `+header+`
 	        <div class="white-box p-0">
 	            <div class="tab-content m-t-0">`+listing+`</div>
 	        </div>

+ 236 - 0
js/jqColorPicker.min.js

@@ -0,0 +1,236 @@
+(function (window) {
+	window.jsColorPicker = function(selectors, config) {
+		var renderCallback = function(colors, mode) {
+				var options = this,
+					input = options.input,
+					patch = options.patch,
+					RGB = colors.RND.rgb,
+					HSL = colors.RND.hsl,
+					AHEX = options.isIE8 ? (colors.alpha < 0.16 ? '0' : '') +
+						(Math.round(colors.alpha * 100)).toString(16).toUpperCase() + colors.HEX : '',
+					RGBInnerText = RGB.r + ', ' + RGB.g + ', ' + RGB.b,
+					RGBAText = 'rgba(' + RGBInnerText + ', ' + colors.alpha + ')',
+					isAlpha = colors.alpha !== 1 && !options.isIE8,
+					colorMode = input.getAttribute('data-colorMode');
+
+				patch.style.cssText =
+					'color:' + (colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd') + ';' + // Black...???
+					'background-color:' + RGBAText + ';' +
+					'filter:' + (options.isIE8 ? 'progid:DXImageTransform.Microsoft.gradient(' + // IE<9
+						'startColorstr=#' + AHEX + ',' + 'endColorstr=#' + AHEX + ')' : '');
+
+				input.value = (colorMode === 'HEX' && !isAlpha ? '#' + (options.isIE8 ? AHEX : colors.HEX) :
+					colorMode === 'rgb' || (colorMode === 'HEX' && isAlpha) ?
+					(!isAlpha ? 'rgb(' + RGBInnerText + ')' : RGBAText) :
+					('hsl' + (isAlpha ? 'a(' : '(') + HSL.h + ', ' + HSL.s + '%, ' + HSL.l + '%' +
+						(isAlpha ? ', ' + colors.alpha : '') + ')')
+				);
+
+				if (options.displayCallback) {
+					options.displayCallback(colors, mode, options);
+				}
+			},
+			extractValue = function(elm) {
+				return elm.value || elm.getAttribute('value') || elm.style.backgroundColor || '#FFFFFF';
+			},
+			actionCallback = function(event, action) {
+				var options = this,
+					colorPicker = colorPickers.current;
+
+				if (action === 'toMemory') {
+					var memos = colorPicker.nodes.memos,
+						backgroundColor = '',
+						opacity = 0,
+						cookieTXT = [];
+
+					for (var n = 0, m = memos.length; n < m; n++) {
+						backgroundColor = memos[n].style.backgroundColor;
+						opacity = memos[n].style.opacity;
+						opacity = Math.round((opacity === '' ? 1 : opacity) * 100) / 100;
+						cookieTXT.push(backgroundColor.
+							replace(/, /g, ',').
+							replace('rgb(', 'rgba(').
+							replace(')', ',' + opacity + ')')
+						);
+					}
+					cookieTXT = '\'' + cookieTXT.join('\',\'') + '\'';
+					ColorPicker.docCookies('colorPickerMemos' + (options.noAlpha ? 'NoAlpha' : ''), cookieTXT);
+				} else if (action === 'resizeApp') {
+					ColorPicker.docCookies('colorPickerSize', colorPicker.color.options.currentSize);
+				} else if (action === 'modeChange') {
+					var mode = colorPicker.color.options.mode;
+
+					ColorPicker.docCookies('colorPickerMode', mode.type + '-' + mode.z);
+				}
+			},
+			createInstance = function(elm, config) {
+				var initConfig = {
+						klass: window.ColorPicker,
+						input: elm,
+						patch: elm,
+						isIE8: !!document.all && !document.addEventListener, // Opera???
+						// *** animationSpeed: 200,
+						// *** draggable: true,
+						margin: {left: -1, top: 2},
+						customBG: '#FFFFFF',
+						// displayCallback: displayCallback,
+						/* --- regular colorPicker options from this point --- */
+						color: extractValue(elm),
+						initStyle: 'display: none',
+						mode: ColorPicker.docCookies('colorPickerMode') || 'hsv-h',
+						// memoryColors: (function(colors, config) {
+						// 	return config.noAlpha ?
+						// 		colors.replace(/\,\d*\.*\d*\)/g, ',1)') : colors;
+						// })($.docCookies('colorPickerMemos'), config || {}),
+						memoryColors: ColorPicker.docCookies('colorPickerMemos' +
+							((config || {}).noAlpha ? 'NoAlpha' : '')),
+						size: ColorPicker.docCookies('colorPickerSize') || 1,
+						renderCallback: renderCallback,
+						actionCallback: actionCallback
+					};
+
+				for (var n in config) {
+					initConfig[n] = config[n]; 
+				}
+				return new initConfig.klass(initConfig);
+			},
+			doEventListeners = function(elm, multiple, off) {
+				var onOff = off ? 'removeEventListener' : 'addEventListener',
+					focusListener = function(e) {
+						var input = this,
+							position = window.ColorPicker.getOrigin(input),
+							index = multiple ? Array.prototype.indexOf.call(elms, this) : 0,
+							colorPicker = colorPickers[index] ||
+								(colorPickers[index] = createInstance(this, config)),
+							options = colorPicker.color.options,
+							colorPickerUI = colorPicker.nodes.colorPicker,
+							appendTo = (options.appendTo || document.body),
+							isStatic = /static/.test(window.getComputedStyle(appendTo).position),
+							atrect = isStatic ? {left: 0, top: 0} : appendTo.getBoundingClientRect(),
+							waitTimer = 0;
+
+						options.color = extractValue(elm); // brings color to default on reset
+						colorPickerUI.style.cssText = 
+							'position: absolute;' + (!colorPickers[index].cssIsReady ? 'display: none;' : '') +
+							'left:' + (position.left + options.margin.left - atrect.left) + 'px;' +
+							'top:' + (position.top + +input.offsetHeight + options.margin.top - atrect.top) + 'px;';
+
+						if (!multiple) {
+							options.input = elm;
+							options.patch = elm; // check again???
+							colorPicker.setColor(extractValue(elm), undefined, undefined, true);
+							colorPicker.saveAsBackground();
+						}
+						colorPickers.current = colorPickers[index];
+						appendTo.appendChild(colorPickerUI);
+						waitTimer = setInterval(function() { // compensating late style on onload in colorPicker
+							if (colorPickers.current.cssIsReady) {
+								waitTimer = clearInterval(waitTimer);
+								colorPickerUI.style.display = 'block';
+							}
+						}, 10);
+					},
+					mousDownListener = function(e) {
+						var colorPicker = colorPickers.current,
+							colorPickerUI = (colorPicker ? colorPicker.nodes.colorPicker : undefined),
+							animationSpeed = colorPicker ? colorPicker.color.options.animationSpeed : 0,
+							isColorPicker = colorPicker && (function(elm) {
+								while (elm) {
+									if ((elm.className || '').indexOf('cp-app') !== -1) return elm;
+									elm = elm.parentNode;
+								}
+								return false;
+							})(e.target),
+							inputIndex = Array.prototype.indexOf.call(elms, e.target);
+
+						if (isColorPicker && Array.prototype.indexOf.call(colorPickers, isColorPicker)) {
+							if (e.target === colorPicker.nodes.exit) {
+								colorPickerUI.style.display = 'none';
+								document.activeElement.blur();
+							} else {
+								// ...
+							}
+						} else if (inputIndex !== -1) {
+							// ...
+						} else if (colorPickerUI) {
+							colorPickerUI.style.display = 'none';
+						}
+					};
+
+				elm[onOff]('focus', focusListener);
+
+				if (!colorPickers.evt || off) {
+					colorPickers.evt = true; // prevent new eventListener for window
+
+					window[onOff]('mousedown', mousDownListener);
+				}
+			},
+			// this is a way to prevent data binding on HTMLElements
+			colorPickers = window.jsColorPicker.colorPickers || [],
+			elms = document.querySelectorAll(selectors),
+			testColors = new window.Colors({customBG: config.customBG, allMixDetails: true});
+
+		window.jsColorPicker.colorPickers = colorPickers;
+
+		for (var n = 0, m = elms.length; n < m; n++) {
+			var elm = elms[n];
+
+			if (config === 'destroy') {
+				doEventListeners(elm, (config && config.multipleInstances), true);
+				if (colorPickers[n]) {
+					colorPickers[n].destroyAll();
+				}
+			} else {
+				var color = extractValue(elm);
+				var value = color.split('(');
+
+				testColors.setColor(color);
+				if (config && config.init) {
+					config.init(elm, testColors.colors);
+				}
+				elm.setAttribute('data-colorMode', value[1] ? value[0].substr(0, 3) : 'HEX');
+				doEventListeners(elm, (config && config.multipleInstances), false);
+				if (config && config.readOnly) {
+					elm.readOnly = true;
+				}
+			}
+		};
+
+		return window.jsColorPicker.colorPickers;
+	};
+
+	window.ColorPicker.docCookies = function(key, val, options) {
+		var encode = encodeURIComponent, decode = decodeURIComponent,
+			cookies, n, tmp, cache = {},
+			days;
+
+		if (val === undefined) { // all about reading cookies
+			cookies = document.cookie.split(/;\s*/) || [];
+			for (n = cookies.length; n--; ) {
+				tmp = cookies[n].split('=');
+				if (tmp[0]) cache[decode(tmp.shift())] = decode(tmp.join('=')); // there might be '='s in the value...
+			}
+
+			if (!key) return cache; // return Json for easy access to all cookies
+			else return cache[key]; // easy access to cookies from here
+		} else { // write/delete cookie
+			options = options || {};
+
+			if (val === '' || options.expires < 0) { // prepare deleteing the cookie
+				options.expires = -1;
+				// options.path = options.domain = options.secure = undefined; // to make shure the cookie gets deleted...
+			}
+
+			if (options.expires !== undefined) { // prepare date if any
+				days = new Date();
+				days.setDate(days.getDate() + options.expires);
+			}
+
+			document.cookie = encode(key) + '=' + encode(val) +
+				(days            ? '; expires=' + days.toUTCString() : '') +
+				(options.path    ? '; path='    + options.path       : '') +
+				(options.domain  ? '; domain='  + options.domain     : '') +
+				(options.secure  ? '; secure'                        : '');
+		}
+	};
+})(this);

+ 236 - 0
js/jsColor.js

@@ -0,0 +1,236 @@
+(function (window) {
+	window.jsColorPicker = function(selectors, config) {
+		var renderCallback = function(colors, mode) {
+				var options = this,
+					input = options.input,
+					patch = options.patch,
+					RGB = colors.RND.rgb,
+					HSL = colors.RND.hsl,
+					AHEX = options.isIE8 ? (colors.alpha < 0.16 ? '0' : '') +
+						(Math.round(colors.alpha * 100)).toString(16).toUpperCase() + colors.HEX : '',
+					RGBInnerText = RGB.r + ', ' + RGB.g + ', ' + RGB.b,
+					RGBAText = 'rgba(' + RGBInnerText + ', ' + colors.alpha + ')',
+					isAlpha = colors.alpha !== 1 && !options.isIE8,
+					colorMode = input.getAttribute('data-colorMode');
+
+				patch.style.cssText =
+					'color:' + (colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd') + ';' + // Black...???
+					'background-color:' + RGBAText + ';' +
+					'filter:' + (options.isIE8 ? 'progid:DXImageTransform.Microsoft.gradient(' + // IE<9
+						'startColorstr=#' + AHEX + ',' + 'endColorstr=#' + AHEX + ')' : '');
+
+				input.value = (colorMode === 'HEX' && !isAlpha ? '#' + (options.isIE8 ? AHEX : colors.HEX) :
+					colorMode === 'rgb' || (colorMode === 'HEX' && isAlpha) ?
+					(!isAlpha ? 'rgb(' + RGBInnerText + ')' : RGBAText) :
+					('hsl' + (isAlpha ? 'a(' : '(') + HSL.h + ', ' + HSL.s + '%, ' + HSL.l + '%' +
+						(isAlpha ? ', ' + colors.alpha : '') + ')')
+				);
+
+				if (options.displayCallback) {
+					options.displayCallback(colors, mode, options);
+				}
+			},
+			extractValue = function(elm) {
+				return elm.value || elm.getAttribute('value') || elm.style.backgroundColor || '#987654';
+			},
+			actionCallback = function(event, action) {
+				var options = this,
+					colorPicker = colorPickers.current;
+
+				if (action === 'toMemory') {
+					var memos = colorPicker.nodes.memos,
+						backgroundColor = '',
+						opacity = 0,
+						cookieTXT = [];
+
+					for (var n = 0, m = memos.length; n < m; n++) {
+						backgroundColor = memos[n].style.backgroundColor;
+						opacity = memos[n].style.opacity;
+						opacity = Math.round((opacity === '' ? 1 : opacity) * 100) / 100;
+						cookieTXT.push(backgroundColor.
+							replace(/, /g, ',').
+							replace('rgb(', 'rgba(').
+							replace(')', ',' + opacity + ')')
+						);
+					}
+					cookieTXT = '\'' + cookieTXT.join('\',\'') + '\'';
+					ColorPicker.docCookies('colorPickerMemos' + (options.noAlpha ? 'NoAlpha' : ''), cookieTXT);
+				} else if (action === 'resizeApp') {
+					ColorPicker.docCookies('colorPickerSize', colorPicker.color.options.currentSize);
+				} else if (action === 'modeChange') {
+					var mode = colorPicker.color.options.mode;
+
+					ColorPicker.docCookies('colorPickerMode', mode.type + '-' + mode.z);
+				}
+			},
+			createInstance = function(elm, config) {
+				var initConfig = {
+						klass: window.ColorPicker,
+						input: elm,
+						patch: elm,
+						isIE8: !!document.all && !document.addEventListener, // Opera???
+						// *** animationSpeed: 200,
+						// *** draggable: true,
+						margin: {left: -1, top: 2},
+						customBG: '#FFFFFF',
+						// displayCallback: displayCallback,
+						/* --- regular colorPicker options from this point --- */
+						color: extractValue(elm),
+						initStyle: 'display: none',
+						mode: ColorPicker.docCookies('colorPickerMode') || 'hsv-h',
+						// memoryColors: (function(colors, config) {
+						// 	return config.noAlpha ?
+						// 		colors.replace(/\,\d*\.*\d*\)/g, ',1)') : colors;
+						// })($.docCookies('colorPickerMemos'), config || {}),
+						memoryColors: ColorPicker.docCookies('colorPickerMemos' +
+							((config || {}).noAlpha ? 'NoAlpha' : '')),
+						size: ColorPicker.docCookies('colorPickerSize') || 1,
+						renderCallback: renderCallback,
+						actionCallback: actionCallback
+					};
+
+				for (var n in config) {
+					initConfig[n] = config[n];
+				}
+				return new initConfig.klass(initConfig);
+			},
+			doEventListeners = function(elm, multiple, off) {
+				var onOff = off ? 'removeEventListener' : 'addEventListener',
+					focusListener = function(e) {
+						var input = this,
+							position = window.ColorPicker.getOrigin(input),
+							index = multiple ? Array.prototype.indexOf.call(elms, this) : 0,
+							colorPicker = colorPickers[index] ||
+								(colorPickers[index] = createInstance(this, config)),
+							options = colorPicker.color.options,
+							colorPickerUI = colorPicker.nodes.colorPicker,
+							appendTo = (options.appendTo || document.body),
+							isStatic = /static/.test(window.getComputedStyle(appendTo).position),
+							atrect = isStatic ? {left: 0, top: 0} : appendTo.getBoundingClientRect(),
+							waitTimer = 0;
+
+						options.color = extractValue(elm); // brings color to default on reset
+						colorPickerUI.style.cssText =
+							'position: absolute;' + (!colorPickers[index].cssIsReady ? 'display: none;' : '') +
+							'left:' + (position.left + options.margin.left - atrect.left) + 'px;' +
+							'top:' + (position.top + +input.offsetHeight + options.margin.top - atrect.top) + 'px;';
+
+						if (!multiple) {
+							options.input = elm;
+							options.patch = elm; // check again???
+							colorPicker.setColor(extractValue(elm), undefined, undefined, true);
+							colorPicker.saveAsBackground();
+						}
+						colorPickers.current = colorPickers[index];
+						appendTo.appendChild(colorPickerUI);
+						waitTimer = setInterval(function() { // compensating late style on onload in colorPicker
+							if (colorPickers.current.cssIsReady) {
+								waitTimer = clearInterval(waitTimer);
+								colorPickerUI.style.display = 'block';
+							}
+						}, 10);
+					},
+					mousDownListener = function(e) {
+						var colorPicker = colorPickers.current,
+							colorPickerUI = (colorPicker ? colorPicker.nodes.colorPicker : undefined),
+							animationSpeed = colorPicker ? colorPicker.color.options.animationSpeed : 0,
+							isColorPicker = colorPicker && (function(elm) {
+								while (elm) {
+									if ((elm.className || '').indexOf('cp-app') !== -1) return elm;
+									elm = elm.parentNode;
+								}
+								return false;
+							})(e.target),
+							inputIndex = Array.prototype.indexOf.call(elms, e.target);
+
+						if (isColorPicker && Array.prototype.indexOf.call(colorPickers, isColorPicker)) {
+							if (e.target === colorPicker.nodes.exit) {
+								colorPickerUI.style.display = 'none';
+								document.activeElement.blur();
+							} else {
+								// ...
+							}
+						} else if (inputIndex !== -1) {
+							// ...
+						} else if (colorPickerUI) {
+							colorPickerUI.style.display = 'none';
+						}
+					};
+
+				elm[onOff]('focus', focusListener);
+
+				if (!colorPickers.evt || off) {
+					colorPickers.evt = true; // prevent new eventListener for window
+
+					window[onOff]('mousedown', mousDownListener);
+				}
+			},
+			// this is a way to prevent data binding on HTMLElements
+			colorPickers = window.jsColorPicker.colorPickers || [],
+			elms = document.querySelectorAll(selectors),
+			testColors = new window.Colors({customBG: config.customBG, allMixDetails: true});
+
+		window.jsColorPicker.colorPickers = colorPickers;
+
+		for (var n = 0, m = elms.length; n < m; n++) {
+			var elm = elms[n];
+
+			if (config === 'destroy') {
+				doEventListeners(elm, (config && config.multipleInstances), true);
+				if (colorPickers[n]) {
+					colorPickers[n].destroyAll();
+				}
+			} else {
+				var color = extractValue(elm);
+				var value = color.split('(');
+
+				testColors.setColor(color);
+				if (config && config.init) {
+					config.init(elm, testColors.colors);
+				}
+				elm.setAttribute('data-colorMode', value[1] ? value[0].substr(0, 3) : 'HEX');
+				doEventListeners(elm, (config && config.multipleInstances), false);
+				if (config && config.readOnly) {
+					elm.readOnly = true;
+				}
+			}
+		};
+
+		return window.jsColorPicker.colorPickers;
+	};
+
+	window.ColorPicker.docCookies = function(key, val, options) {
+		var encode = encodeURIComponent, decode = decodeURIComponent,
+			cookies, n, tmp, cache = {},
+			days;
+
+		if (val === undefined) { // all about reading cookies
+			cookies = document.cookie.split(/;\s*/) || [];
+			for (n = cookies.length; n--; ) {
+				tmp = cookies[n].split('=');
+				if (tmp[0]) cache[decode(tmp.shift())] = decode(tmp.join('=')); // there might be '='s in the value...
+			}
+
+			if (!key) return cache; // return Json for easy access to all cookies
+			else return cache[key]; // easy access to cookies from here
+		} else { // write/delete cookie
+			options = options || {};
+
+			if (val === '' || options.expires < 0) { // prepare deleteing the cookie
+				options.expires = -1;
+				// options.path = options.domain = options.secure = undefined; // to make shure the cookie gets deleted...
+			}
+
+			if (options.expires !== undefined) { // prepare date if any
+				days = new Date();
+				days.setDate(days.getDate() + options.expires);
+			}
+
+			document.cookie = encode(key) + '=' + encode(val) +
+				(days            ? '; expires=' + days.toUTCString() : '') +
+				(options.path    ? '; path='    + options.path       : '') +
+				(options.domain  ? '; domain='  + options.domain     : '') +
+				(options.secure  ? '; secure'                        : '');
+		}
+	};
+})(this);

File diff suppressed because it is too large
+ 2 - 0
js/jsColorPicker.min.js


Some files were not shown because too many files changed in this diff