Skip to content

Commit 0b2a679

Browse files
committed
Theming: Generate colorized radio buttons dynamically
1 parent b694c01 commit 0b2a679

5 files changed

Lines changed: 51 additions & 56 deletions

File tree

apps/theming/js/settings-admin.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ function calculateLuminance(rgb) {
4646
return (0.299*r + 0.587*g + 0.114*b)/255;
4747
}
4848

49+
function generateRadioButton(color) {
50+
var radioButton = '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">' +
51+
'<path d="M8 1a7 7 0 0 0-7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0-7-7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6zm0 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z" fill="' + color + '"/></svg>';
52+
return btoa(radioButton);
53+
}
54+
4955
function preview(setting, value) {
5056
if (setting === 'color') {
5157
var headerClass = document.getElementById('header');
@@ -74,15 +80,12 @@ function preview(setting, value) {
7480

7581
$('#previewStyles').html(
7682
'#header .icon-caret { background-image: url(\'' + OC.getRootPath() + '/core/img/actions/' + icon + '.svg\') }' +
77-
'html:not(.ie):not(.edge) input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' +
83+
'input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' +
7884
'background-image:url(\'' + OC.getRootPath() + '/core/img/actions/checkmark-white.svg\');' +
7985
'background-color: ' + elementColor + '; background-position: center center; background-size:contain;' +
8086
'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;}' +
81-
'html:not(.ie):not(.edge) input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' +
82-
'-webkit-mask-image: url(\'' + OC.getRootPath() + '/core/img/actions/radio-checked-white.svg\');' +
83-
'-webkit-mask-repeat: no-repeat;' +
84-
'background-color: ' + elementColor+ ';' +
85-
'background-image: none; }'
87+
'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' +
88+
'background-image: url(\'data:image/svg+xml;base64,' + generateRadioButton(elementColor) + '\'); }'
8689
);
8790
}
8891
if (setting === 'logoMime') {

apps/theming/lib/controller/themingcontroller.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -220,23 +220,17 @@ public function getStylesheet() {
220220
'#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
221221
$color
222222
);
223-
$responseCss .= sprintf('html:not(.ie):not(.edge) input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
223+
$responseCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
224224
'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
225225
'background-color: %s; background-position: center center; background-size:contain;' .
226226
'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
227227
"}\n",
228228
\OC::$WEBROOT,
229229
$elementColor
230230
);
231-
$responseCss .= sprintf('html:not(.ie):not(.edge) input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
232-
'-webkit-mask-image: url(\'%s/core/img/actions/radio-checked-white.svg\');' .
233-
'-webkit-mask-repeat: no-repeat;' .
234-
'background-color: %s;' .
235-
'background-image: none; '.
236-
"}\n",
237-
\OC::$WEBROOT,
238-
$elementColor
239-
);
231+
$responseCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
232+
'background-image: url(\'data:image/svg+xml;base64,'.Util::generateRadioButton($elementColor).'\');' .
233+
"}\n";
240234
}
241235
$logo = $this->config->getAppValue($this->appName, 'logoMime');
242236
if($logo !== '') {

apps/theming/lib/util.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,14 @@ public static function calculateLuminance($color) {
7171
return (0.299 * $r + 0.587 * $g + 0.114 * $b)/255;
7272
}
7373

74+
/**
75+
* @param $color
76+
* @return string base64 encoded radio button svg
77+
*/
78+
public static function generateRadioButton($color) {
79+
$radioButtonIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">' .
80+
'<path d="M8 1a7 7 0 0 0-7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0-7-7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6zm0 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z" fill="'.$color.'"/></svg>';
81+
return base64_encode($radioButtonIcon);
82+
}
83+
7484
}

apps/theming/tests/lib/UtilTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,15 @@ public function testElementColorOnBrightBackground() {
7575
$elementColor = Util::elementColor('#ffffff');
7676
$this->assertEquals('#555555', $elementColor);
7777
}
78+
79+
public function testGenerateRadioButtonWhite() {
80+
$button = Util::generateRadioButton('#ffffff');
81+
$expected = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZD0iTTggMWE3IDcgMCAwIDAtNyA3IDcgNyAwIDAgMCA3IDcgNyA3IDAgMCAwIDctNyA3IDcgMCAwIDAtNy03em0wIDFhNiA2IDAgMCAxIDYgNiA2IDYgMCAwIDEtNiA2IDYgNiAwIDAgMS02LTYgNiA2IDAgMCAxIDYtNnptMCAyYTQgNCAwIDEgMCAwIDggNCA0IDAgMCAwIDAtOHoiIGZpbGw9IiNmZmZmZmYiLz48L3N2Zz4=';
82+
$this->assertEquals($expected, $button);
83+
}
84+
public function testGenerateRadioButtonBlack() {
85+
$button = Util::generateRadioButton('#000000');
86+
$expected = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZD0iTTggMWE3IDcgMCAwIDAtNyA3IDcgNyAwIDAgMCA3IDcgNyA3IDAgMCAwIDctNyA3IDcgMCAwIDAtNy03em0wIDFhNiA2IDAgMCAxIDYgNiA2IDYgMCAwIDEtNiA2IDYgNiAwIDAgMS02LTYgNiA2IDAgMCAxIDYtNnptMCAyYTQgNCAwIDEgMCAwIDggNCA0IDAgMCAwIDAtOHoiIGZpbGw9IiMwMDAwMDAiLz48L3N2Zz4=';
87+
$this->assertEquals($expected, $button);
88+
}
7889
}

apps/theming/tests/lib/controller/ThemingControllerTest.php

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
use OCA\Theming\Controller\ThemingController;
2828
use OCA\Theming\Template;
29+
use OCA\Theming\Util;
2930
use OCP\AppFramework\Http;
3031
use OCP\AppFramework\Http\DataResponse;
3132
use OCP\Files\IRootFolder;
@@ -329,23 +330,17 @@ public function testGetStylesheetWithOnlyColor() {
329330

330331
$elementColor = '#000';
331332
$expectedCss = '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #000}' . "\n";
332-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
333+
$expectedCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
333334
'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
334335
'background-color: %s; background-position: center center; background-size:contain;' .
335336
'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
336337
"}\n",
337338
\OC::$WEBROOT,
338339
$elementColor
339340
);
340-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
341-
'-webkit-mask-image: url(\'%s/core/img/actions/radio-checked-white.svg\');' .
342-
'-webkit-mask-repeat: no-repeat;' .
343-
'background-color: %s;' .
344-
'background-image: none; '.
345-
"}\n",
346-
\OC::$WEBROOT,
347-
$elementColor
348-
);
341+
$expectedCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
342+
'background-image: url(\'data:image/svg+xml;base64,'.Util::generateRadioButton($elementColor).'\');' .
343+
"}\n";
349344
$expected = new Http\DataDownloadResponse($expectedCss, 'style', 'text/css');
350345
$expected->cacheFor(3600);
351346
@$this->assertEquals($expected, $this->themingController->getStylesheet());
@@ -374,23 +369,17 @@ public function testGetStylesheetWithOnlyColorInvert() {
374369
->willReturn('');
375370
$elementColor = '#555555';
376371
$expectedCss = '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #fff}' . "\n";
377-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
372+
$expectedCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
378373
'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
379374
'background-color: %s; background-position: center center; background-size:contain;' .
380375
'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
381376
"}\n",
382377
\OC::$WEBROOT,
383378
$elementColor
384379
);
385-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
386-
'-webkit-mask-image: url(\'%s/core/img/actions/radio-checked-white.svg\');' .
387-
'-webkit-mask-repeat: no-repeat;' .
388-
'background-color: %s;' .
389-
'background-image: none; '.
390-
"}\n",
391-
\OC::$WEBROOT,
392-
$elementColor
393-
);
380+
$expectedCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
381+
'background-image: url(\'data:image/svg+xml;base64,'.Util::generateRadioButton($elementColor).'\');' .
382+
"}\n";
394383
$expectedCss .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n" .
395384
'#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n" .
396385
'.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n" .
@@ -486,23 +475,17 @@ public function testGetStylesheetWithAllCombined() {
486475

487476
$elementColor = '#000';
488477
$expectedCss = '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #000}' . "\n";
489-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
478+
$expectedCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
490479
'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
491480
'background-color: %s; background-position: center center; background-size:contain;' .
492481
'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
493482
"}\n",
494483
\OC::$WEBROOT,
495484
$elementColor
496485
);
497-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
498-
'-webkit-mask-image: url(\'%s/core/img/actions/radio-checked-white.svg\');' .
499-
'-webkit-mask-repeat: no-repeat;' .
500-
'background-color: %s;' .
501-
'background-image: none; '.
502-
"}\n",
503-
\OC::$WEBROOT,
504-
$elementColor
505-
);
486+
$expectedCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
487+
'background-image: url(\'data:image/svg+xml;base64,'.Util::generateRadioButton($elementColor).'\');' .
488+
"}\n";
506489
$expectedCss .= '#header .logo {' .
507490
'background-image: url(\'./logo?v=0\')' .
508491
'}' . "\n" .
@@ -540,23 +523,17 @@ public function testGetStylesheetWithAllCombinedInverted() {
540523

541524
$elementColor = '#555555';
542525
$expectedCss = '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #fff}' . "\n";
543-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
526+
$expectedCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
544527
'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
545528
'background-color: %s; background-position: center center; background-size:contain;' .
546529
'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
547530
"}\n",
548531
\OC::$WEBROOT,
549532
$elementColor
550533
);
551-
$expectedCss .= sprintf('html:not(.ie):not(.edge) input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
552-
'-webkit-mask-image: url(\'%s/core/img/actions/radio-checked-white.svg\');' .
553-
'-webkit-mask-repeat: no-repeat;' .
554-
'background-color: %s;' .
555-
'background-image: none; '.
556-
"}\n",
557-
\OC::$WEBROOT,
558-
$elementColor
559-
);
534+
$expectedCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
535+
'background-image: url(\'data:image/svg+xml;base64,'.Util::generateRadioButton($elementColor).'\');' .
536+
"}\n";
560537
$expectedCss .= '#header .logo {' .
561538
'background-image: url(\'./logo?v=0\')' .
562539
'}' . "\n" .

0 commit comments

Comments
 (0)