Updated: Internal module "Color Picker" v2.1.3 -> v2.1.4 (#134)

This commit is contained in:
nobody 2020-10-14 06:07:13 +02:00
parent 078a8198d0
commit 09cbad0c75
No known key found for this signature in database
GPG Key ID: 8F6DE3D614FCFD7A
7 changed files with 730 additions and 162 deletions

View File

@ -0,0 +1,129 @@
.color-picker,
.color-picker::before,
.color-picker::after,
.color-picker *,
.color-picker *::before,
.color-picker *::after {
box-sizing: border-box;
}
.color-picker {
position: absolute;
top: 0;
left: 0;
z-index: 9999;
box-shadow: 1px 3px 6px rgba(0, 0, 0, .5);
}
.color-picker > div {
display: flex;
height: 10em;
border: 1px solid #000;
color: #000;
}
.color-picker > div * {
border-color: inherit;
color: inherit;
}
.color-picker i {
font: inherit;
font-size: 12px; /* Measure the color picker control size by measuring the text size */
}
.color-picker\:a,
.color-picker\:h,
.color-picker\:sv {
background-size: 100% 100%;
position: relative;
}
.color-picker\:a,
.color-picker\:h {
width: 1.5em;
border-left: 1px solid;
cursor: ns-resize;
overflow: hidden;
}
.color-picker\:a div,
.color-picker\:h div,
.color-picker\:sv div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.color-picker\:a i,
.color-picker\:h i {
display: block;
height: .5em;
position: absolute;
top: -.25em;
right: 0;
left: 0;
z-index: 2;
}
.color-picker\:a i::before,
.color-picker\:h i::before {
display: block;
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border:.25em solid;
border-top-color: transparent;
border-bottom-color: transparent;
}
.color-picker\:sv {
width: 10em;
cursor: crosshair;
overflow: hidden;
}
.color-picker\:sv i {
display: block;
width: .75em;
height: .75em;
position: absolute;
top: -.375em;
right: -.375em;
z-index: 2;
}
.color-picker\:sv i::before {
display: block;
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 1px solid #fff;
border-radius: 100%;
box-shadow: 0 0 2px #000;
}
.color-picker\:a div {
z-index: 2;
}
.color-picker\:a div + div {
background-image: linear-gradient(45deg, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%, #ddd 100%), linear-gradient(45deg, #ddd 25%, #fff 25%, #fff 75%, #ddd 75%, #ddd 100%);
background-size: .5em .5em;
background-position: 0 0, .25em .25em;
z-index: 1;
}
.color-picker\:h div {
background-image: linear-gradient(to top, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}
.color-picker\:sv div + div {
background-image: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
}
.color-picker\:sv div + div + div {
background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
}
.color-picker\:a,
.color-picker\:h,
.color-picker\:sv {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}

View File

@ -0,0 +1,594 @@
/*!
* ==============================================================
* COLOR PICKER 2.1.4
* ==============================================================
* Author: Taufik Nurrohman <https://github.com/taufik-nurrohman>
* License: MIT
* --------------------------------------------------------------
*/
(function(win, doc, name) {
var html = doc.documentElement,
HEX = 'HEX',
top = 'top',
right = 'right',
left = 'left',
px = 'px',
delay = win.setTimeout,
instances = 'instances',
downEvents = ['touchstart', 'mousedown'],
moveEvents = ['touchmove', 'mousemove'],
resizeEvents = ['orientationchange', 'resize'],
upEvents = ['touchend', 'mouseup'];
// Convert cursor position to RGBA
function P2RGB(a) {
var h = +a[0],
s = +a[1],
v = +a[2],
r, g, b, i, f, p, q, t;
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
i = i || 0;
q = q || 0;
t = t || 0;
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 [toRound(r * 255), toRound(g * 255), toRound(b * 255), isSet(a[3]) ? +a[3] : 1];
}
// Convert RGBA to HSVA
function RGB2HSV(a) {
var r = +a[0] / 255,
g = +a[1] / 255,
b = +a[2] / 255,
max = Math.max(r, g, b),
min = Math.min(r, g, b),
h, s, v = max,
d = max - min,
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 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;
}
return [h, s, v, isSet(a[3]) ? +a[3] : 1];
}
function axixGet(el, e) {
var touches = 'touches',
clientX = 'clientX',
clientY = 'clientY',
x = !!e[touches] ? e[touches][0][clientX] : e[clientX],
y = !!e[touches] ? e[touches][0][clientY] : e[clientY],
offset = offsetGet(el);
return [x - offset[0], y - offset[1]];
}
function closestGet(a, b) {
if (a === b) {
return a;
}
while ((a = a.parentElement) && a !== b);
return a;
}
function offsetGet(el) {
var x, y, rect;
if (el === win) {
x = win.pageXOffset || html.scrollLeft;
y = win.pageYOffset || html.scrollTop;
} else {
rect = el.getBoundingClientRect();
x = rect.left;
y = rect.top;
}
return [x, y];
}
function sizeGet(el) {
return el === win ? [win.innerWidth, win.innerHeight] : [el.offsetWidth, el.offsetHeight];
}
function doPreventDefault(e) {
e && e.preventDefault();
}
function isFunction(x) {
return 'function' === typeof x;
}
function isObject(x) {
return 'object' === typeof x;
}
function isSet(x) {
return 'undefined' !== typeof x && null !== x;
}
function isString(x) {
return 'string' === typeof x;
}
function toEdge(a, b) {
if (a < b[0]) return b[0];
if (a > b[1]) return b[1];
return a;
}
function toInt(a, b) {
return parseInt(a, b || 10);
}
function toNode(a, b, c) {
a = doc.createElement(a);
b && b.appendChild(a);
c && (a.className = c);
return a;
}
function toRound(a) {
return Math.round(a);
}
function toString(a, b) {
return a.toString(b);
}
function eventsLet(to, events, fn) {
for (var i = 0, j = events.length; i < j; ++i) {
to.removeEventListener(events[i], fn, false);
}
}
function eventsSet(to, events, fn) {
for (var i = 0, j = events.length; i < j; ++i) {
to.addEventListener(events[i], fn, false);
}
}
function styleSet(to, prop, value) {
to.style[prop] = value;
}
(function($$) {
$$.version = '2.1.4';
$$.state = {
'class': 'color-picker',
'color': HEX,
'parent': null
};
// Collect all instance(s)
$$[instances] = {};
$$[HEX] = function(x) {
if (isString(x)) {
var count = (x = x.trim()).length;
if ((4 === count || 7 === count) && '#' === x[0]) {
if (/^#([a-f\d]{3}){1,2}$/i.test(x)) {
if (4 === count) {
return [toInt(x[1] + x[1], 16), toInt(x[2] + x[2], 16), toInt(x[3] + x[3], 16), 1];
}
return [toInt(x[1] + x[2], 16), toInt(x[3] + x[4], 16), toInt(x[5] + x[6], 16), 1];
}
} else if ((5 === count || 9 === count) && '#' === x[0]) {
if (/^#([a-f\d]{3,4}){1,2}$/i.test(x)) {
if (5 === count) {
return [toInt(x[1] + x[1], 16), toInt(x[2] + x[2], 16), toInt(x[3] + x[3], 16), toInt(x[4] + x[4], 16) / 255];
}
return [toInt(x[1] + x[2], 16), toInt(x[3] + x[4], 16), toInt(x[5] + x[6], 16), toInt(x[7] + x[8], 16) / 255];
}
}
return [0, 0, 0, 1]; // Default to black
}
return '#' + ('000000' + toString(+x[2] | (+x[1] << 8) | (+x[0] << 16), 16)).slice(-6) + (isSet(x[3]) && x[3] < 1 ? toString(toRound(x[3] * 255) + 0x10000, 16).substr(-2) : "");
};
})(win[name] = function(source, o) {
if (!source) return;
var $ = this,
$$ = win[name],
hooks = {},
state = Object.assign({}, $$.state, isString(o) ? {
'color': o
} : (o || {})),
cn = state['class'],
self = toNode('div', 0, cn);
// Already instantiated, skip!
if (source[name]) {
return $;
}
// Return new instance if `CP` was called without the `new` operator
if (!($ instanceof $$)) {
return new $$(source, o);
}
// Store color picker instance to `CP.instances`
$$[instances][source.id || source.name || Object.keys($$[instances]).length] = $;
// Mark current DOM as active color picker to prevent duplicate instance
source[name] = 1;
$.visible = false;
function value(a) {
var to = $$[isFunction($$[state.color]) ? state.color : HEX],
color;
if (color = source.dataset.color) {
if (isSet(a)) {
return (source.dataset.color = to(color));
}
return to(color);
}
if (color = source.value) {
if (isSet(a)) {
return (source.value = to(color));
}
return to(color);
}
if (color = source.textContent) {
if (isSet(a)) {
return (source.textContent = to(color));
}
return to(color);
}
if (isSet(a)) {
return; // Do nothing
}
return [0, 0, 0, 1]; // Default to black
}
function hookLet(name, fn) {
if (!isSet(name)) {
return (hooks = {}), $;
}
if (isSet(hooks[name])) {
if (isSet(fn)) {
for (var i = 0, j = hooks[name].length; i < j; ++i) {
if (fn === hooks[name][i]) {
hooks[name].splice(i, 1);
}
}
// Clean-up empty hook(s)
if (0 === j) {
delete hooks[name];
}
} else {
delete hooks[name];
}
}
return $;
}
function hookSet(name, fn) {
if (!isSet(hooks[name])) {
hooks[name] = [];
}
if (isSet(fn)) {
hooks[name].push(fn);
}
return $;
}
function hookFire(name, lot) {
if (!isSet(hooks[name])) {
return $;
}
for (var i = 0, j = hooks[name].length; i < j; ++i) {
hooks[name][i].apply($, lot);
}
return $;
}
var doEnter,
doExit,
doFit,
doFitTo,
body = doc.body,
color = value(),
data = RGB2HSV(color),
C = toNode('div', self),
SV = toNode('div', C, cn + ':sv'),
H = toNode('div', C, cn + ':h'),
A = toNode('div', C, cn + ':a'),
SVColor = toNode('div', SV),
SVSaturation = toNode('div', SV),
SVValue = toNode('div', SV),
SVCursor = toNode('i', SV),
HColor = toNode('div', H),
HCursor = toNode('i', H),
AColor = toNode('div', A),
APattern = toNode('div', A),
ACursor = toNode('i', A),
SVStarting = 0,
HStarting = 0,
AStarting = 0,
SVDragging = 0,
HDragging = 0,
ADragging = 0;
function isVisible() {
return self.parentNode;
}
function doClick(e) {
if (hooks.focus) {
hookFire('focus', color);
} else {
var t = e.target,
isSource = source === closestGet(t, source);
if (isSource) {
!isVisible() && doEnter(state.parent);
} else {
doExit();
}
}
}
function doApply(isFirst, to) {
// Refresh value
data = RGB2HSV(color = value());
if (!isFirst) {
(to || state.parent || body).appendChild(self), ($.visible = true);
}
doEnter = function(to) {
return doApply(0, to), hookFire('enter', color), $;
};
doExit = function() {
var exist = isVisible();
if (exist) {
exist.removeChild(self);
$.current = null;
$.visible = false;
}
eventsLet(SV, downEvents, doDownSV);
eventsLet(H, downEvents, doDownH);
eventsLet(A, downEvents, doDownA);
eventsLet(doc, moveEvents, doMove);
eventsLet(doc, upEvents, doStop);
eventsLet(win, resizeEvents, doFitTo);
return hookFire('exit', color), $;
};
doFit = function(to) {
var winSize = sizeGet(win),
htmlSize = sizeGet(html),
scrollBarSizeV = winSize[0] - htmlSize[0], // Vertical scroll bar
scrollBarSizeH = winSize[1] - html.clientHeight, // Horizontal scroll bar
winOffset = offsetGet(win),
sourceOffset = offsetGet(source),
selfSize = sizeGet(self),
selfSizeWidth = selfSize[0],
selfSizeHeight = selfSize[1],
selfOffsetLeft = sourceOffset[0] + winOffset[0],
selfOffsetTop = sourceOffset[1] + winOffset[1] + sizeGet(source)[1]; // Drop!
if (isObject(to)) {
isSet(to[0]) && (selfOffsetLeft = to[0]);
isSet(to[1]) && (selfOffsetTop = to[1]);
} else {
var minX = winOffset[0],
minY = winOffset[1],
maxX = winOffset[0] + winSize[0] - selfSizeWidth - scrollBarSizeV,
maxY = winOffset[1] + winSize[1] - selfSizeHeight - scrollBarSizeH;
selfOffsetLeft = toEdge(selfOffsetLeft, [minX, maxX]) >> 0;
selfOffsetTop = toEdge(selfOffsetTop, [minY, maxY]) >> 0;
}
styleSet(self, left, selfOffsetLeft + px);
styleSet(self, top, selfOffsetTop + px);
return hookFire('fit', color), $;
};
doFitTo = function() {
return doFit();
};
var SVSize = sizeGet(SV),
SVSizeWidth = SVSize[0],
SVSizeHeight = SVSize[1],
SVCursorSize = sizeGet(SVCursor),
SVCursorSizeWidth = SVCursorSize[0],
SVCursorSizeHeight = SVCursorSize[1],
HSizeHeight = sizeGet(H)[1],
HCursorSizeHeight = sizeGet(HCursor)[1],
ASizeHeight = sizeGet(A)[1],
ACursorSizeHeight = sizeGet(ACursor)[1];
if (isFirst) {
eventsSet(source, downEvents, doClick);
delay(function() {
hookFire('change', color);
}, 1);
} else {
eventsSet(SV, downEvents, doDownSV);
eventsSet(H, downEvents, doDownH);
eventsSet(A, downEvents, doDownA);
eventsSet(doc, moveEvents, doMove);
eventsSet(doc, upEvents, doStop);
eventsSet(win, resizeEvents, doFitTo);
doFit();
}
function doMove(e) {
SVDragging && cursorSVSet(e);
HDragging && cursorHSet(e);
ADragging && cursorASet(e);
color = P2RGB(data);
if (SVDragging || HDragging || ADragging) {
hookFire((SVStarting || HStarting || AStarting ? 'start' : 'drag'), color);
hookFire('change', color);
}
SVStarting = HStarting = AStarting = 0;
}
function doStop(e) {
color = P2RGB(data);
var t = e.target,
isSource = source === closestGet(t, source),
isSelf = self === closestGet(t, self);
$.current = null;
if (!isSource && !isSelf) {
if (hooks.blur) {
hookFire('blur', color);
} else {
// Click outside the source or picker element to exit
isVisible() && doExit();
}
} else {
if (isSelf) {
if (SVDragging || HDragging || ADragging) {
hookFire('stop', color);
}
}
}
SVDragging = HDragging = ADragging = 0;
}
function doDownSV(e) {
$.current = SV;
SVStarting = SVDragging = 1;
doMove(e);
doPreventDefault(e);
}
function doDownH(e) {
$.current = H;
HStarting = HDragging = 1;
doMove(e);
doPreventDefault(e);
}
function doDownA(e) {
$.current = A;
AStarting = ADragging = 1;
doMove(e);
doPreventDefault(e);
}
function cursorSet(x) {
isSet(x[1]) && styleSet(SVCursor, right, (SVSizeWidth - (SVCursorSizeWidth / 2) - (SVSizeWidth * +x[1])) + px);
isSet(x[2]) && styleSet(SVCursor, top, (SVSizeHeight - (SVCursorSizeHeight / 2) - (SVSizeHeight * +x[2])) + px);
isSet(x[0]) && styleSet(HCursor, top, (HSizeHeight - (HCursorSizeHeight / 2) - (HSizeHeight * +x[0])) + px);
isSet(x[3]) && styleSet(ACursor, top, (ASizeHeight - (ACursorSizeHeight / 2) - (ASizeHeight * +x[3])) + px);
}
$.get = function() {
return value();
};
$.set = function(r, g, b, a) {
data = RGB2HSV([r, g, b, a]);
return colorSet(), $;
};
function cursorSVSet(e) {
var SVPoint = axixGet(SV, e),
x = toEdge(SVPoint[0], [0, SVSizeWidth]),
y = toEdge(SVPoint[1], [0, SVSizeHeight]);
data[1] = 1 - ((SVSizeWidth - x) / SVSizeWidth);
data[2] = (SVSizeHeight - y) / SVSizeHeight;
colorSet();
}
function cursorHSet(e) {
data[0] = (HSizeHeight - toEdge(axixGet(H, e)[1], [0, HSizeHeight])) / HSizeHeight;
colorSet();
}
function cursorASet(e) {
data[3] = (ASizeHeight - toEdge(axixGet(A, e)[1], [0, ASizeHeight])) / ASizeHeight;
colorSet();
}
function colorSet() {
cursorSet(data);
var a = P2RGB(data),
b = P2RGB([data[0], 1, 1]);
styleSet(SVColor, 'backgroundColor', 'rgb(' + b[0] + ',' + b[1] + ',' + b[2] + ')');
styleSet(AColor, 'backgroundImage', 'linear-gradient(rgb(' + a[0] + ',' + a[1] + ',' + a[2] + '),transparent)');
} colorSet();
} doApply(1);
$.color = function(r, g, b, a) {
return $$[isFunction($$[state.color]) ? state.color : HEX]([r, g, b, a]);
};
$.current = null;
$.enter = doEnter;
$.exit = doExit;
$.fire = hookFire;
$.fit = doFit;
$.hooks = hooks;
$.off = hookLet;
$.on = hookSet;
$.pop = function() {
if (!source[name]) {
return $; // Already ejected
}
delete source[name];
eventsLet(source, downEvents, doClick);
return doExit(), hookFire('pop', color);
};
$.value = function(r, g, b, a) {
return $.set(r, g, b, a), hookFire('change', [r, g, b, a]);
};
$.self = self;
$.source = source;
$.state = state;
});
})(window, document, 'CP');

View File

@ -1,151 +0,0 @@
.color-picker,
.color-picker *,
.color-picker ::after,
.color-picker ::before,
.color-picker::after,
.color-picker::before {
box-sizing: border-box
}
.color-picker {
position: absolute;
top: 0;
left: 0;
z-index: 9999;
box-shadow: 1px 3px 6px rgba(0, 0, 0, .5)
}
.color-picker>div {
display: flex;
height: 10em;
border: 1px solid #000;
color: #000
}
.color-picker>div * {
border-color: inherit;
color: inherit
}
.color-picker i {
font: inherit;
font-size: 12px
}
.color-picker\:a,
.color-picker\:h,
.color-picker\:sv {
background-size: 100% 100%;
position: relative
}
.color-picker\:a,
.color-picker\:h {
width: 1.5em;
border-left: 1px solid;
cursor: ns-resize;
overflow: hidden
}
.color-picker\:a div,
.color-picker\:h div,
.color-picker\:sv div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0
}
.color-picker\:a i,
.color-picker\:h i {
display: block;
height: .5em;
position: absolute;
top: -.25em;
right: 0;
left: 0;
z-index: 2
}
.color-picker\:a i::before,
.color-picker\:h i::before {
display: block;
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: .25em solid;
border-top-color: transparent;
border-bottom-color: transparent
}
.color-picker\:sv {
width: 10em;
cursor: crosshair;
overflow: hidden
}
.color-picker\:sv i {
display: block;
width: .75em;
height: .75em;
position: absolute;
top: -.375em;
right: -.375em;
z-index: 2
}
.color-picker\:sv i::before {
display: block;
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 1px solid #fff;
border-radius: 100%;
box-shadow: 0 0 2px #000
}
.color-picker\:a div {
z-index: 2
}
.color-picker\:a div+div {
background-image: linear-gradient(45deg, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%, #ddd 100%), linear-gradient(45deg, #ddd 25%, #fff 25%, #fff 75%, #ddd 75%, #ddd 100%);
background-size: .5em .5em;
background-position: 0 0, .25em .25em;
z-index: 1
}
.color-picker\:h div {
background-image: linear-gradient(to top, red 0, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red 100%)
}
.color-picker\:sv div+div {
background-image: linear-gradient(to right, #fff, rgba(255, 255, 255, 0))
}
.color-picker\:sv div+div+div {
background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0))
}
.color-picker\:a,
.color-picker\:h,
.color-picker\:sv {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-tap-highlight-color: transparent
}
.color-picker\:a {
display: none;
}

File diff suppressed because one or more lines are too long

View File

@ -255,6 +255,10 @@ body {
margin-top: 0px !important;
}
div[class="color-picker:a"] {
display: none;
}
.color-error {
color: red;
}

View File

@ -4,13 +4,13 @@
<title>LocalCDN Options</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="../../modules/internal/color-picker/color-picker.min.css">
<link rel="stylesheet" type="text/css" href="../../modules/internal/color-picker/color-picker.css">
<link rel="stylesheet" type="text/css" href="options.css">
<link rel="stylesheet" type="text/css" href="../base.css">
</head>
<body>
<script src="../../modules/internal/color-picker/color-picker.min.js"></script>
<script src="../../modules/internal/color-picker/color-picker.js"></script>
<script src="../../core/constants.js"></script>
<script src="../../core/storage-manager.js"></script>

View File

@ -26,6 +26,7 @@
</div>
<ul>
<li>Fixed: Only open release notes in case of new CDNs (<a href="https://codeberg.org/nobody/LocalCDN/issues/132">#132</a>)</li>
<li>Updated: Internal module "Color Picker" v2.1.3 -> v2.1.4 (<a href="https://codeberg.org/nobody/LocalCDN/issues/134">#134</a>)</li>
</ul>
<div id="generator-section">
<div class="topic-label">