@qtoggle/qui 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +2 -0
- package/.eslintrc.json +492 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- package/.github/ISSUE_TEMPLATE/improvement_proposal.md +20 -0
- package/.github/workflows/main.yml +74 -0
- package/.pre-commit-config.yaml +8 -0
- package/LICENSE.txt +177 -0
- package/README.md +4 -0
- package/font/dejavusans-bold.woff +0 -0
- package/font/dejavusans-bolditalic.woff +0 -0
- package/font/dejavusans-italic.woff +0 -0
- package/font/dejavusans-regular.woff +0 -0
- package/img/qui-icons.svg +1937 -0
- package/js/base/base.js +47 -0
- package/js/base/condition-variable.js +92 -0
- package/js/base/errors.js +36 -0
- package/js/base/i18n.js +20 -0
- package/js/base/mixwith.js +135 -0
- package/js/base/require-js-compat.js +78 -0
- package/js/base/signal.js +91 -0
- package/js/base/singleton.js +66 -0
- package/js/base/timer.js +126 -0
- package/js/config.js +184 -0
- package/js/forms/common-fields/check-field.js +42 -0
- package/js/forms/common-fields/choice-buttons-field.js +30 -0
- package/js/forms/common-fields/color-combo-field.js +37 -0
- package/js/forms/common-fields/combo-field.js +108 -0
- package/js/forms/common-fields/common-fields.js +23 -0
- package/js/forms/common-fields/composite-field.js +132 -0
- package/js/forms/common-fields/custom-html-field.js +51 -0
- package/js/forms/common-fields/email-field.js +30 -0
- package/js/forms/common-fields/file-picker-field.js +46 -0
- package/js/forms/common-fields/jquery-ui-field.js +111 -0
- package/js/forms/common-fields/labels-field.js +69 -0
- package/js/forms/common-fields/numeric-field.js +39 -0
- package/js/forms/common-fields/password-field.js +28 -0
- package/js/forms/common-fields/phone-field.js +26 -0
- package/js/forms/common-fields/progress-disk-field.js +69 -0
- package/js/forms/common-fields/push-button-field.js +138 -0
- package/js/forms/common-fields/slider-field.js +51 -0
- package/js/forms/common-fields/text-area-field.js +34 -0
- package/js/forms/common-fields/text-field.js +89 -0
- package/js/forms/common-fields/up-down-field.js +85 -0
- package/js/forms/common-forms/common-forms.js +16 -0
- package/js/forms/common-forms/options-form.js +77 -0
- package/js/forms/common-forms/page-form.js +115 -0
- package/js/forms/form-button.js +202 -0
- package/js/forms/form-field.js +1183 -0
- package/js/forms/form.js +1181 -0
- package/js/forms/forms.js +68 -0
- package/js/global-glass.js +100 -0
- package/js/icons/default-stock.js +173 -0
- package/js/icons/icon.js +64 -0
- package/js/icons/icons.js +16 -0
- package/js/icons/multi-state-sprites-icon.js +362 -0
- package/js/icons/stock-icon.js +219 -0
- package/js/icons/stock.js +98 -0
- package/js/icons/stocks.js +57 -0
- package/js/index.js +232 -0
- package/js/lib/jquery.longpress.js +79 -0
- package/js/lib/jquery.module.js +4 -0
- package/js/lib/logger.module.js +4 -0
- package/js/lib/pep.module.js +4 -0
- package/js/lists/common-items/common-items.js +5 -0
- package/js/lists/common-items/icon-label-list-item.js +86 -0
- package/js/lists/common-lists/common-lists.js +5 -0
- package/js/lists/common-lists/page-list.js +53 -0
- package/js/lists/list-item.js +147 -0
- package/js/lists/list.js +636 -0
- package/js/lists/lists.js +26 -0
- package/js/main-ui/main-ui.js +64 -0
- package/js/main-ui/menu-bar.js +144 -0
- package/js/main-ui/options-bar.js +181 -0
- package/js/main-ui/status.js +185 -0
- package/js/main-ui/top-bar.js +59 -0
- package/js/messages/common-message-forms/common-message-forms.js +7 -0
- package/js/messages/common-message-forms/confirm-message-form.js +81 -0
- package/js/messages/common-message-forms/simple-message-form.js +67 -0
- package/js/messages/common-message-forms/sticky-simple-message-form.js +27 -0
- package/js/messages/message-form.js +107 -0
- package/js/messages/messages.js +21 -0
- package/js/messages/sticky-modal-page.js +98 -0
- package/js/messages/sticky-modal-progress-message.js +27 -0
- package/js/messages/toast.js +164 -0
- package/js/navigation.js +654 -0
- package/js/pages/breadcrumbs.js +124 -0
- package/js/pages/common-pages/common-pages.js +6 -0
- package/js/pages/common-pages/modal-progress-page.js +83 -0
- package/js/pages/common-pages/structured-page.js +46 -0
- package/js/pages/page.js +1018 -0
- package/js/pages/pages-context.js +154 -0
- package/js/pages/pages.js +252 -0
- package/js/pwa.js +337 -0
- package/js/sections/section.js +612 -0
- package/js/sections/sections.js +300 -0
- package/js/tables/common-cells/common-cells.js +7 -0
- package/js/tables/common-cells/icon-label-table-cell.js +68 -0
- package/js/tables/common-cells/push-button-table-cell.js +133 -0
- package/js/tables/common-cells/simple-table-cell.js +37 -0
- package/js/tables/common-tables/common-tables.js +5 -0
- package/js/tables/common-tables/page-table.js +55 -0
- package/js/tables/table-cell.js +198 -0
- package/js/tables/table-row.js +126 -0
- package/js/tables/table.js +492 -0
- package/js/tables/tables.js +36 -0
- package/js/theme.js +304 -0
- package/js/utils/ajax.js +126 -0
- package/js/utils/array.js +194 -0
- package/js/utils/colors.js +445 -0
- package/js/utils/cookies.js +65 -0
- package/js/utils/crypto.js +439 -0
- package/js/utils/css.js +234 -0
- package/js/utils/date.js +300 -0
- package/js/utils/files.js +27 -0
- package/js/utils/gestures.js +165 -0
- package/js/utils/html.js +76 -0
- package/js/utils/misc.js +81 -0
- package/js/utils/object.js +324 -0
- package/js/utils/promise.js +49 -0
- package/js/utils/string.js +192 -0
- package/js/utils/url.js +187 -0
- package/js/utils/utils.js +3 -0
- package/js/utils/visibility-manager.js +211 -0
- package/js/views/common-views/common-views.js +7 -0
- package/js/views/common-views/icon-label-view.js +210 -0
- package/js/views/common-views/progress-view.js +89 -0
- package/js/views/common-views/structured-view.js +368 -0
- package/js/views/view.js +467 -0
- package/js/views/views.js +3 -0
- package/js/widgets/base-widget.js +23 -0
- package/js/widgets/common-widgets/check-button.js +109 -0
- package/js/widgets/common-widgets/choice-buttons.js +322 -0
- package/js/widgets/common-widgets/color-combo.js +104 -0
- package/js/widgets/common-widgets/combo.js +645 -0
- package/js/widgets/common-widgets/common-widgets.js +17 -0
- package/js/widgets/common-widgets/email-input.js +7 -0
- package/js/widgets/common-widgets/file-picker.js +133 -0
- package/js/widgets/common-widgets/labels.js +132 -0
- package/js/widgets/common-widgets/numeric-input.js +49 -0
- package/js/widgets/common-widgets/password-input.js +91 -0
- package/js/widgets/common-widgets/phone-input.js +7 -0
- package/js/widgets/common-widgets/progress-disk.js +174 -0
- package/js/widgets/common-widgets/push-button.js +155 -0
- package/js/widgets/common-widgets/slider.js +455 -0
- package/js/widgets/common-widgets/text-area.js +52 -0
- package/js/widgets/common-widgets/text-input.js +174 -0
- package/js/widgets/common-widgets/up-down.js +351 -0
- package/js/widgets/widgets.js +57 -0
- package/js/window.js +557 -0
- package/jsdoc.conf.json +20 -0
- package/less/base.less +123 -0
- package/less/forms/common-fields.less +101 -0
- package/less/forms/common-forms.less +5 -0
- package/less/forms/form-button.less +21 -0
- package/less/forms/form-field.less +266 -0
- package/less/forms/form.less +131 -0
- package/less/global-glass.less +64 -0
- package/less/icon-label-view.less +82 -0
- package/less/icons.less +144 -0
- package/less/lists.less +105 -0
- package/less/main-ui.less +328 -0
- package/less/messages.less +189 -0
- package/less/no-effects.less +24 -0
- package/less/pages/breadcrumbs.less +98 -0
- package/less/pages/common-pages.less +36 -0
- package/less/pages/page.less +70 -0
- package/less/progress-view.less +51 -0
- package/less/stock-icons.less +43 -0
- package/less/structured-view.less +245 -0
- package/less/tables.less +84 -0
- package/less/theme-dark.less +133 -0
- package/less/theme-light.less +132 -0
- package/less/theme.less +419 -0
- package/less/visibility-manager.less +11 -0
- package/less/widgets/check-button.less +96 -0
- package/less/widgets/choice-buttons.less +160 -0
- package/less/widgets/color-combo.less +33 -0
- package/less/widgets/combo.less +230 -0
- package/less/widgets/common-buttons.less +120 -0
- package/less/widgets/common.less +24 -0
- package/less/widgets/input.less +258 -0
- package/less/widgets/labels.less +81 -0
- package/less/widgets/progress-disk.less +70 -0
- package/less/widgets/slider.less +199 -0
- package/less/widgets/updown.less +115 -0
- package/less/widgets/various.less +36 -0
- package/package.json +47 -0
- package/pyproject.toml +45 -0
- package/qui/__init__.py +110 -0
- package/qui/constants.py +1 -0
- package/qui/exceptions.py +2 -0
- package/qui/j2template.py +71 -0
- package/qui/settings.py +60 -0
- package/qui/templates/manifest.json +25 -0
- package/qui/templates/qui.html +126 -0
- package/qui/templates/service-worker.js +188 -0
- package/qui/web/__init__.py +0 -0
- package/qui/web/tornado.py +220 -0
- package/scripts/postinstall.sh +10 -0
- package/webpack/webpack-adjust-css-urls-loader.js +36 -0
- package/webpack/webpack-common.js +384 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deals with color format conversions and color adjustments.
|
|
3
|
+
*
|
|
4
|
+
* Contains code taken from https://github.com/antimatter15/rgb-lab/
|
|
5
|
+
* @namespace qui.utils.colors
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* eslint-disable no-multi-spaces */
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
let cachedColorsRGBAByName = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Convert a tuple of (*hue*, *saturation*, *value*) components into (*red*, *green*, *blue*) equivalent.
|
|
16
|
+
*
|
|
17
|
+
* *red*, *green* and *blue* range from `0` to `255`. *hue* ranges from `0` to `359`, while *saturation* and *value*
|
|
18
|
+
* range from `0` to `1`.
|
|
19
|
+
*
|
|
20
|
+
* @alias qui.utils.colors.hsv2rgb
|
|
21
|
+
* @param {Number[]} hsv a 3 elements array representing the *hue*, *saturation* and *value* components
|
|
22
|
+
* @returns {Number[]} a 3 elements array representing the *red*, *green* and *blue* components
|
|
23
|
+
*/
|
|
24
|
+
export function hsv2rgb(hsv) {
|
|
25
|
+
let h = hsv[0], s = hsv[1], v = hsv[2]
|
|
26
|
+
let hi = Math.floor(h / 60.0) % 6
|
|
27
|
+
let f = (h / 60.0) - Math.floor(h / 60.0)
|
|
28
|
+
let p = v * (1.0 - s)
|
|
29
|
+
let q = v * (1.0 - (f * s))
|
|
30
|
+
let t = v * (1.0 - ((1.0 - f) * s))
|
|
31
|
+
|
|
32
|
+
v *= 255
|
|
33
|
+
t *= 255
|
|
34
|
+
p *= 255
|
|
35
|
+
q *= 255
|
|
36
|
+
|
|
37
|
+
let rgb = [
|
|
38
|
+
[v, t, p],
|
|
39
|
+
[q, v, p],
|
|
40
|
+
[p, v, t],
|
|
41
|
+
[p, q, v],
|
|
42
|
+
[t, p, v],
|
|
43
|
+
[v, p, q]
|
|
44
|
+
][hi]
|
|
45
|
+
|
|
46
|
+
return [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2])]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Convert a tuple of (*red*, *green*, *blue*) components into (*hue*, *saturation*, *value*) equivalent.
|
|
51
|
+
*
|
|
52
|
+
* *red*, *green* and *blue* range from `0` to `255`. *hue* ranges from `0` to `359`, while *saturation* and *value*
|
|
53
|
+
* range from `0` to `1`.
|
|
54
|
+
*
|
|
55
|
+
* @alias qui.utils.colors.rgb2hsv
|
|
56
|
+
* @param {Number[]} rgb a 3 elements array representing the *red*, *green* and *blue* components
|
|
57
|
+
* @returns {Number[]} a 3 elements array representing the *hue*, *saturation* and *value* components
|
|
58
|
+
*/
|
|
59
|
+
export function rgb2hsv(rgb) {
|
|
60
|
+
let r = rgb[0] / 255
|
|
61
|
+
let g = rgb[1] / 255
|
|
62
|
+
let b = rgb[2] / 255
|
|
63
|
+
|
|
64
|
+
let min = Math.min(r, g, b)
|
|
65
|
+
let max = Math.max(r, g, b)
|
|
66
|
+
let delta = max - min
|
|
67
|
+
|
|
68
|
+
let h = 0
|
|
69
|
+
let s = 0
|
|
70
|
+
let v = max
|
|
71
|
+
|
|
72
|
+
if (delta !== 0) {
|
|
73
|
+
s = delta / max
|
|
74
|
+
let dr = (((max - r) / 6) + (delta / 2)) / delta
|
|
75
|
+
let dg = (((max - g) / 6) + (delta / 2)) / delta
|
|
76
|
+
let db = (((max - b) / 6) + (delta / 2)) / delta
|
|
77
|
+
|
|
78
|
+
if (r === max) {
|
|
79
|
+
h = db - dg
|
|
80
|
+
}
|
|
81
|
+
else if (g === max) {
|
|
82
|
+
h = (1 / 3) + dr - db
|
|
83
|
+
}
|
|
84
|
+
else if (b === max) {
|
|
85
|
+
h = (2 / 3) + dg - dr
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (h < 0) {
|
|
89
|
+
h += 1
|
|
90
|
+
}
|
|
91
|
+
if (h > 1) {
|
|
92
|
+
h -= 1
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
h = Math.round(h * 360)
|
|
97
|
+
|
|
98
|
+
return [h, s, v]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Convert a color string into (*red*, *green*, *blue*, *alpha*) equivalent.
|
|
103
|
+
*
|
|
104
|
+
* *red*, *green* and *blue* range from `0` to `255`, while *alpha* ranges from `0` to `1`. Accepted string color
|
|
105
|
+
* formats are `rgb(r, g, b)`, `rgba(r, g, b, a)`, `#rrggbb` and an HTML color name.
|
|
106
|
+
*
|
|
107
|
+
* @alias qui.utils.colors.str2rgba
|
|
108
|
+
* @param {String} strColor
|
|
109
|
+
* @returns {Number[]} a 4 elements array representing the *red*, *green*, *blue* and *alpha* components
|
|
110
|
+
*/
|
|
111
|
+
export function str2rgba(strColor) {
|
|
112
|
+
if (!strColor) {
|
|
113
|
+
return [0, 0, 0, 1] /* Defaults to black */
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let r = 0, g = 0, b = 0, a = 1
|
|
117
|
+
let start, stop, parts
|
|
118
|
+
|
|
119
|
+
if (strColor.startsWith('#')) {
|
|
120
|
+
if (strColor.length === 4) {
|
|
121
|
+
r = strColor.substr(1, 1)
|
|
122
|
+
g = strColor.substr(2, 1)
|
|
123
|
+
b = strColor.substr(3, 1)
|
|
124
|
+
|
|
125
|
+
r = parseInt(r + r, 16)
|
|
126
|
+
g = parseInt(g + g, 16)
|
|
127
|
+
b = parseInt(b + b, 16)
|
|
128
|
+
}
|
|
129
|
+
else if (strColor.length === 7) {
|
|
130
|
+
r = parseInt(strColor.substr(1, 2), 16)
|
|
131
|
+
g = parseInt(strColor.substr(3, 2), 16)
|
|
132
|
+
b = parseInt(strColor.substr(5, 2), 16)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else if (strColor.startsWith('rgba')) {
|
|
136
|
+
start = strColor.indexOf('(')
|
|
137
|
+
stop = strColor.indexOf(')')
|
|
138
|
+
|
|
139
|
+
if (start !== -1 && stop !== -1) {
|
|
140
|
+
strColor = strColor.substring(start + 1, stop)
|
|
141
|
+
parts = strColor.split(',')
|
|
142
|
+
if (parts.length === 4) {
|
|
143
|
+
r = parseInt(parts[0].trim())
|
|
144
|
+
g = parseInt(parts[1].trim())
|
|
145
|
+
b = parseInt(parts[2].trim())
|
|
146
|
+
a = parseFloat(parts[3].trim())
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (strColor.startsWith('rgb')) {
|
|
151
|
+
start = strColor.indexOf('(')
|
|
152
|
+
stop = strColor.indexOf(')')
|
|
153
|
+
|
|
154
|
+
if (start !== -1 && stop !== -1) {
|
|
155
|
+
strColor = strColor.substring(start + 1, stop)
|
|
156
|
+
parts = strColor.split(',')
|
|
157
|
+
if (parts.length === 3) {
|
|
158
|
+
r = parseInt(parts[0].trim())
|
|
159
|
+
g = parseInt(parts[1].trim())
|
|
160
|
+
b = parseInt(parts[2].trim())
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else { /* A color name */
|
|
165
|
+
let colorRGBA = cachedColorsRGBAByName[strColor]
|
|
166
|
+
if (colorRGBA) {
|
|
167
|
+
return colorRGBA
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let div = document.createElement('div')
|
|
171
|
+
div.style.display = 'none'
|
|
172
|
+
div.style.color = strColor
|
|
173
|
+
document.body.appendChild(div)
|
|
174
|
+
|
|
175
|
+
let style = window.getComputedStyle(div)
|
|
176
|
+
let result = str2rgba(style.color)
|
|
177
|
+
|
|
178
|
+
document.body.removeChild(div)
|
|
179
|
+
|
|
180
|
+
cachedColorsRGBAByName[strColor] = result
|
|
181
|
+
return result
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return [r, g, b, a]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Convert a tuple of (*red*, *green*, *blue*, *alpha*) components into color string equivalent.
|
|
189
|
+
*
|
|
190
|
+
* *red*, *green* and *blue* range from `0` to `255`, while *alpha* ranges from `0` to `1`. Returned string color format
|
|
191
|
+
* is `rgba(r, g, b, a)` or `#rrggbb`, depending on the presence of the alpha factor.
|
|
192
|
+
*
|
|
193
|
+
* @alias qui.utils.colors.rgba2str
|
|
194
|
+
* @param {Number[]} rgba a 4 elements array representing the *red*, *green*, *blue* and *alpha* components,
|
|
195
|
+
* respectively
|
|
196
|
+
* @returns {String}
|
|
197
|
+
*/
|
|
198
|
+
export function rgba2str(rgba) {
|
|
199
|
+
function byte2hex(value) {
|
|
200
|
+
value = parseInt(value).toString(16)
|
|
201
|
+
if (value.length < 2) {
|
|
202
|
+
value = `0${value}`
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return value
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (rgba.length === 3 || (rgba.length === 4 && rgba[3] === 1)) {
|
|
209
|
+
return `#${byte2hex(rgba[0])}${byte2hex(rgba[1])}${byte2hex(rgba[2])}`
|
|
210
|
+
}
|
|
211
|
+
else { /* Assuming the length is 4 */
|
|
212
|
+
return `rgba(${rgba[0]}, ${rgba[1]}, ${rgba[2]}, ${rgba[3]})`
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Convert a tuple of (*lightness*, *a*, *b*) components into (*red*, *green*, *blue*) equivalent. The *lightness*, *a*
|
|
218
|
+
* and *b* components are defined by the CIELAB color space.
|
|
219
|
+
*
|
|
220
|
+
* *red*, *green* and *blue* range from `0` to `255`. *lightness* ranges from `0` to `100`, while *a* and *b* range from
|
|
221
|
+
* `-100` to `100`.
|
|
222
|
+
*
|
|
223
|
+
* @alias qui.utils.colors.lab2rgb
|
|
224
|
+
* @param {Number[]} lab a 3 elements array representing the *lightness*, *a* and *b* components
|
|
225
|
+
* @returns {Number[]} a 3 elements array representing the *red*, *green* and *blue* components
|
|
226
|
+
*/
|
|
227
|
+
export function lab2rgb(lab) {
|
|
228
|
+
let y = (lab[0] + 16) / 116
|
|
229
|
+
let x = lab[1] / 500 + y
|
|
230
|
+
let z = y - lab[2] / 200
|
|
231
|
+
let r, g, b
|
|
232
|
+
|
|
233
|
+
x = 0.95047 * ((x * x * x > 0.008856) ? x * x * x : (x - 16 / 116) / 7.787)
|
|
234
|
+
y = 1.00000 * ((y * y * y > 0.008856) ? y * y * y : (y - 16 / 116) / 7.787)
|
|
235
|
+
z = 1.08883 * ((z * z * z > 0.008856) ? z * z * z : (z - 16 / 116) / 7.787)
|
|
236
|
+
|
|
237
|
+
r = x * 3.2406 + y * -1.5372 + z * -0.4986
|
|
238
|
+
g = x * -0.9689 + y * 1.8758 + z * 0.0415
|
|
239
|
+
b = x * 0.0557 + y * -0.2040 + z * 1.0570
|
|
240
|
+
|
|
241
|
+
r = (r > 0.0031308) ? (1.055 * Math.pow(r, 1 / 2.4) - 0.055) : 12.92 * r
|
|
242
|
+
g = (g > 0.0031308) ? (1.055 * Math.pow(g, 1 / 2.4) - 0.055) : 12.92 * g
|
|
243
|
+
b = (b > 0.0031308) ? (1.055 * Math.pow(b, 1 / 2.4) - 0.055) : 12.92 * b
|
|
244
|
+
|
|
245
|
+
return [
|
|
246
|
+
Math.max(0, Math.min(1, r)) * 255,
|
|
247
|
+
Math.max(0, Math.min(1, g)) * 255,
|
|
248
|
+
Math.max(0, Math.min(1, b)) * 255
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Convert a tuple of (*red*, *green*, *blue*) components into (*lightness*, *a*, *b*) equivalent. The *lightness*, *a*
|
|
254
|
+
* and *b* components are defined by the CIELAB color space.
|
|
255
|
+
*
|
|
256
|
+
* *red*, *green* and *blue* range from `0` to `255`. *lightness* ranges from `0` to `100`, while *a* and *b* range from
|
|
257
|
+
* `-100` to `100`.
|
|
258
|
+
*
|
|
259
|
+
* @alias qui.utils.colors.rgb2lab
|
|
260
|
+
* @param {Number[]} rgb a 3 elements array representing the *red*, *green* and *blue* components
|
|
261
|
+
* @returns {Number[]} lab a 3 elements array representing the *lightness*, *a* and *b* components
|
|
262
|
+
*/
|
|
263
|
+
export function rgb2lab(rgb) {
|
|
264
|
+
let r = rgb[0] / 255
|
|
265
|
+
let g = rgb[1] / 255
|
|
266
|
+
let b = rgb[2] / 255
|
|
267
|
+
let x, y, z
|
|
268
|
+
|
|
269
|
+
r = (r > 0.04045) ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92
|
|
270
|
+
g = (g > 0.04045) ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92
|
|
271
|
+
b = (b > 0.04045) ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92
|
|
272
|
+
|
|
273
|
+
x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047
|
|
274
|
+
y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000
|
|
275
|
+
z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883
|
|
276
|
+
|
|
277
|
+
x = (x > 0.008856) ? Math.pow(x, 1 / 3) : (7.787 * x) + 16 / 116
|
|
278
|
+
y = (y > 0.008856) ? Math.pow(y, 1 / 3) : (7.787 * y) + 16 / 116
|
|
279
|
+
z = (z > 0.008856) ? Math.pow(z, 1 / 3) : (7.787 * z) + 16 / 116
|
|
280
|
+
|
|
281
|
+
return [(116 * y) - 16, 500 * (x - y), 200 * (y - z)]
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Compute the luminance of a color, as defined by https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef.
|
|
286
|
+
*
|
|
287
|
+
* *red*, *green* and *blue* range from `0` to `255`. *luminance* ranges from `0` to `1`.
|
|
288
|
+
*
|
|
289
|
+
* @alias qui.utils.colors.luminance
|
|
290
|
+
* @param {Number[]} rgb a 3 elements array representing the *red*, *green* and *blue* components
|
|
291
|
+
* @returns {Number}
|
|
292
|
+
*/
|
|
293
|
+
export function luminance(rgb) {
|
|
294
|
+
let a = rgb.map(function (v) {
|
|
295
|
+
v /= 255
|
|
296
|
+
|
|
297
|
+
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Compute the contrast ratio between two colors, as defined by
|
|
305
|
+
* https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef.
|
|
306
|
+
*
|
|
307
|
+
* *red*, *green* and *blue* range from `0` to `255`. *contrast* ranges from `1` to `21`.
|
|
308
|
+
*
|
|
309
|
+
* @alias qui.utils.colors.contrast
|
|
310
|
+
* @param {Number[]} rgb1 a 3 elements array representing the *red*, *green* and *blue* components of the first color
|
|
311
|
+
* @param {Number[]} rgb2 a 3 elements array representing the *red*, *green* and *blue* components of the second color
|
|
312
|
+
* @returns {Number}
|
|
313
|
+
*/
|
|
314
|
+
export function contrast(rgb1, rgb2) {
|
|
315
|
+
let c = (luminance(rgb1) + 0.05) / (luminance(rgb2) + 0.05)
|
|
316
|
+
if (c < 1) {
|
|
317
|
+
c = 1 / c
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return c
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Compute the distance between two colors, as defined by the *deltaE* CIE94 specification.
|
|
325
|
+
*
|
|
326
|
+
* *lightness* ranges from `0` to `100`, while *a* and *b* range from `-100` to `100`. *deltaE* ranges from `0` to
|
|
327
|
+
* `255`.
|
|
328
|
+
*
|
|
329
|
+
* @alias qui.utils.colors.deltaE
|
|
330
|
+
* @param {Number[]} lab1 a 3 elements array representing the *lightness*, *a* and *b* components of the first color
|
|
331
|
+
* @param {Number[]} lab2 a 3 elements array representing the *lightness*, *a* and *b* components of the second color
|
|
332
|
+
* @returns {Number}
|
|
333
|
+
*/
|
|
334
|
+
export function deltaE(lab1, lab2) {
|
|
335
|
+
/* CIE94 implementation */
|
|
336
|
+
let deltaL = lab1[0] - lab2[0]
|
|
337
|
+
let deltaA = lab1[1] - lab2[1]
|
|
338
|
+
let deltaB = lab1[2] - lab2[2]
|
|
339
|
+
let c1 = Math.sqrt(lab1[1] * lab1[1] + lab1[2] * lab1[2])
|
|
340
|
+
let c2 = Math.sqrt(lab2[1] * lab2[1] + lab2[2] * lab2[2])
|
|
341
|
+
let deltaC = c1 - c2
|
|
342
|
+
let deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC
|
|
343
|
+
deltaH = deltaH < 0 ? 0 : Math.sqrt(deltaH)
|
|
344
|
+
let sc = 1.0 + 0.045 * c1
|
|
345
|
+
let sh = 1.0 + 0.015 * c1
|
|
346
|
+
let deltaLklsl = deltaL / (1.0)
|
|
347
|
+
let deltaCkcsc = deltaC / (sc)
|
|
348
|
+
let deltaHkhsh = deltaH / (sh)
|
|
349
|
+
let i = deltaLklsl * deltaLklsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh
|
|
350
|
+
|
|
351
|
+
return i < 0 ? 0 : Math.min(Math.sqrt(i), 255)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Return a darker variant of a given color.
|
|
356
|
+
*
|
|
357
|
+
* Accepted string color formats are `rgb(r, g, b)`, `rgba(r, g, b, a)`, `#rrggbb` and an HTML color name.
|
|
358
|
+
*
|
|
359
|
+
* @alias qui.utils.colors.darker
|
|
360
|
+
* @param {String} strColor
|
|
361
|
+
* @param {Number} amount the fraction used to alter the value component (from `0` to `1`)
|
|
362
|
+
* @returns {String}
|
|
363
|
+
*/
|
|
364
|
+
export function darker(strColor, amount) {
|
|
365
|
+
let rgba = str2rgba(strColor)
|
|
366
|
+
let alpha = rgba[3]
|
|
367
|
+
let hsv = rgb2hsv(rgba.slice(0, 3))
|
|
368
|
+
hsv[2] /= amount
|
|
369
|
+
|
|
370
|
+
rgba = hsv2rgb(hsv)
|
|
371
|
+
rgba.push(alpha)
|
|
372
|
+
|
|
373
|
+
return rgba2str(rgba)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Return a lighter variant of a given color.
|
|
378
|
+
*
|
|
379
|
+
* Accepted string color formats are `rgb(r, g, b)`, `rgba(r, g, b, a)`, `#rrggbb` and an HTML color name.
|
|
380
|
+
*
|
|
381
|
+
* @alias qui.utils.colors.lighter
|
|
382
|
+
* @param {String} strColor
|
|
383
|
+
* @param {Number} amount the fraction used to alter the value component (from `0` to `1`)
|
|
384
|
+
* @returns {String}
|
|
385
|
+
*/
|
|
386
|
+
export function lighter(strColor, amount) {
|
|
387
|
+
return darker(strColor, 1 / amount)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Alter the alpha factor of a color.
|
|
392
|
+
*
|
|
393
|
+
* Accepted string color formats are `rgb(r, g, b)`, `rgba(r, g, b, a)`, `#rrggbb` and an HTML color name.
|
|
394
|
+
*
|
|
395
|
+
* @alias qui.utils.colors.alpha
|
|
396
|
+
* @param {String} strColor
|
|
397
|
+
* @param {Number} factor the alpha factor (from `0` to `1`)
|
|
398
|
+
* @returns {String}
|
|
399
|
+
*/
|
|
400
|
+
export function alpha(strColor, factor) {
|
|
401
|
+
let rgba = str2rgba(strColor)
|
|
402
|
+
rgba[3] = factor
|
|
403
|
+
|
|
404
|
+
return rgba2str(rgba)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Mix two colors.
|
|
409
|
+
*
|
|
410
|
+
* Accepted string color formats are `rgb(r, g, b)`, `rgba(r, g, b, a)`, `#rrggbb` and an HTML color name.
|
|
411
|
+
*
|
|
412
|
+
* @alias qui.utils.colors.mix
|
|
413
|
+
* @param {String} strColor1
|
|
414
|
+
* @param {String} strColor2
|
|
415
|
+
* @param {Number} factor the ratio by which the two input colors contribute to the output color; `0` results in 100% of
|
|
416
|
+
* `strColor1` and `1` results in 100% of `strColor2`
|
|
417
|
+
* @returns {String}
|
|
418
|
+
*/
|
|
419
|
+
export function mix(strColor1, strColor2, factor) {
|
|
420
|
+
let rgba1 = str2rgba(strColor1)
|
|
421
|
+
let rgba2 = str2rgba(strColor2)
|
|
422
|
+
|
|
423
|
+
let r = rgba1[0] * (1 - factor) + rgba2[0] * factor
|
|
424
|
+
let g = rgba1[1] * (1 - factor) + rgba2[1] * factor
|
|
425
|
+
let b = rgba1[2] * (1 - factor) + rgba2[2] * factor
|
|
426
|
+
let a = rgba1[3] * (1 - factor) + rgba2[3] * factor
|
|
427
|
+
|
|
428
|
+
return rgba2str([r, g, b, a])
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Normalize a color by converting it to the most appropriate string format.
|
|
433
|
+
*
|
|
434
|
+
* Accepted string color formats are `rgb(r, g, b)`, `rgba(r, g, b, a)`, `#rrggbb` and an HTML color name.
|
|
435
|
+
*
|
|
436
|
+
* Colors with alpha factor are represented as `rgba(r, g, b, a)`, while those without alpha factor are represented as
|
|
437
|
+
* `#rrggbb`.
|
|
438
|
+
*
|
|
439
|
+
* @alias qui.utils.colors.normalize
|
|
440
|
+
* @param {String} strColor
|
|
441
|
+
* @returns {String}
|
|
442
|
+
*/
|
|
443
|
+
export function normalize(strColor) {
|
|
444
|
+
return rgba2str(str2rgba(strColor))
|
|
445
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @namespace qui.utils.cookies
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Return the value of a cookie.
|
|
7
|
+
* @alias qui.utils.cookies.get
|
|
8
|
+
* @param {String} name cookie name
|
|
9
|
+
* @param {*} def default value to return if cookie not found
|
|
10
|
+
* @returns {?String}
|
|
11
|
+
*/
|
|
12
|
+
export function get(name, def = null) {
|
|
13
|
+
let cookie = document.cookie.substring(0)
|
|
14
|
+
|
|
15
|
+
if (cookie.length <= 0) {
|
|
16
|
+
return def
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let start = cookie.indexOf(`${name}=`)
|
|
20
|
+
if (start === -1) {
|
|
21
|
+
return def
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
start = start + name.length + 1
|
|
25
|
+
let end = cookie.indexOf(';', start)
|
|
26
|
+
if (end === -1) {
|
|
27
|
+
end = cookie.length
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return cookie.substring(start, end)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Set the value of a cookie, optionally indicating a validity period.
|
|
35
|
+
* @alias qui.utils.cookies.set
|
|
36
|
+
* @param {String} name cookie name
|
|
37
|
+
* @param {String} value cookie value
|
|
38
|
+
* @param {Number} [validDays] number of days of validity; defaults to `null`, in which case cookie never expires
|
|
39
|
+
*/
|
|
40
|
+
export function set(name, value, validDays = null) {
|
|
41
|
+
let date, expires
|
|
42
|
+
if (validDays) {
|
|
43
|
+
date = new Date()
|
|
44
|
+
date.setTime(date.getTime() + (validDays * 24 * 60 * 60 * 1000))
|
|
45
|
+
expires = `expires=${date.toUTCString()}`
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
expires = ''
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
document.cookie = `${name}=${value}; ${expires}; path=/`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Clear a cookie.
|
|
56
|
+
* @alias qui.utils.cookies.clear
|
|
57
|
+
* @param {String} name cookie name
|
|
58
|
+
*/
|
|
59
|
+
export function clear(name) {
|
|
60
|
+
let date = new Date()
|
|
61
|
+
date.setTime(date.getTime() + (-1 * 24 * 60 * 60 * 1000))
|
|
62
|
+
let expires = `expires=${date.toUTCString()}`
|
|
63
|
+
|
|
64
|
+
document.cookie = `${name}=; ${expires}; path=/`
|
|
65
|
+
}
|