Rework handling of icons and tinting of external icons
19
README.md
@@ -5,4 +5,21 @@ This is a fork of the original default dokuwiki template.
|
|||||||
|
|
||||||
## Changes from the original template
|
## Changes from the original template
|
||||||
- Default font changed to "Perfect DOS VGA 437 Win"
|
- Default font changed to "Perfect DOS VGA 437 Win"
|
||||||
- Enhanced header search with DokuWiki quicksearch suggestions, keyboard navigation, and disabled browser autofill
|
- Enhanced header search with DokuWiki quicksearch suggestions, keyboard navigation, and disabled browser autofill
|
||||||
|
|
||||||
|
## Icon theming (light/dark)
|
||||||
|
- Header tool icons (user tools and site tools) are rendered as inline SVG.
|
||||||
|
- The pagetools footer is intentionally text-only (no icons).
|
||||||
|
- Icon color is controlled through `@ini_icons` (placeholder `__icons__`) in [replacements] inside `style.ini`.
|
||||||
|
- Hover/active icon color follows `@ini_link` to match link interaction color.
|
||||||
|
|
||||||
|
## Edit toolbar icons
|
||||||
|
- The edit page toolbar (`?do=edit`) is generated by DokuWiki core and uses PNG toolbar images.
|
||||||
|
- This template converts those toolbar `<img>` icons to CSS mask icons at runtime, then applies `@ini_icons`.
|
||||||
|
- Hover/active/focus color follows `@ini_link`.
|
||||||
|
- This keeps DokuWiki core files untouched while still allowing light/dark icon theming.
|
||||||
|
|
||||||
|
### About coloring SVG icons from the outside
|
||||||
|
- Recommended: inline SVG + CSS (`fill`, `stroke`, or `currentColor`).
|
||||||
|
- Limited: external SVG via `<img>` or `background-image` cannot reliably be recolored with plain CSS.
|
||||||
|
- Workarounds for external SVG exist (`mask-image`, CSS `filter`), but they are less maintainable and less precise.
|
||||||
@@ -30,6 +30,27 @@
|
|||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dokuwiki div.toolbar #tool__bar button.toolbutton .toolicon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: @ini_icons;
|
||||||
|
-webkit-mask-image: var(--icon-url);
|
||||||
|
mask-image: var(--icon-url);
|
||||||
|
-webkit-mask-repeat: no-repeat;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
-webkit-mask-position: center;
|
||||||
|
mask-position: center;
|
||||||
|
-webkit-mask-size: contain;
|
||||||
|
mask-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dokuwiki div.toolbar #tool__bar button.toolbutton:hover .toolicon,
|
||||||
|
.dokuwiki div.toolbar #tool__bar button.toolbutton:active .toolicon,
|
||||||
|
.dokuwiki div.toolbar #tool__bar button.toolbutton:focus .toolicon {
|
||||||
|
background-color: @ini_link;
|
||||||
|
}
|
||||||
|
|
||||||
/* picker popups (outside of .dokuwiki) */
|
/* picker popups (outside of .dokuwiki) */
|
||||||
div.picker {
|
div.picker {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
|||||||
@@ -79,7 +79,6 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide SVG icons - we use text-only status bar style */
|
|
||||||
svg {
|
svg {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
height: 1.4em;
|
height: 1.4em;
|
||||||
width: 1.4em;
|
width: 1.4em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
fill: @ini_border;
|
fill: @ini_icons;
|
||||||
margin-right: 0.2em;
|
margin-right: 0.2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 297 B |
|
Before Width: | Height: | Size: 187 B |
|
Before Width: | Height: | Size: 398 B |
|
Before Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 178 B |
@@ -1,5 +0,0 @@
|
|||||||
Icons for: sitetools.png
|
|
||||||
Icon set: Dusseldorf
|
|
||||||
Designer: pc.de
|
|
||||||
License: Creative Commons Attribution License [http://creativecommons.org/licenses/by/3.0/]
|
|
||||||
URL: http://pc.de/icons/#Dusseldorf
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
<?php
|
|
||||||
// phpcs:ignoreFile -- deprecated and will be removed
|
|
||||||
/**
|
|
||||||
* This script generates a sprite from the unprocessed pagetool icons by combining them
|
|
||||||
* and overlaying a color layer for the active state.
|
|
||||||
*
|
|
||||||
* This script requires a current libGD to be available.
|
|
||||||
*
|
|
||||||
* The color for the active state is read from the style.ini's __link__ replacement
|
|
||||||
*
|
|
||||||
* The final sprite is optimized with optipng if available.
|
|
||||||
*
|
|
||||||
* @author Andreas Gohr <andi@splitbrain.org>
|
|
||||||
* @deprecated 2018-06-15 we no longer use PNG based icons
|
|
||||||
* @todo Maybe add some more error checking
|
|
||||||
*/
|
|
||||||
$GAMMA = 0.8;
|
|
||||||
$OPTIPNG = '/usr/bin/optipng';
|
|
||||||
|
|
||||||
if('cli' != PHP_SAPI) die('please run from commandline');
|
|
||||||
|
|
||||||
// load input images
|
|
||||||
$input = glob('pagetools/*.png');
|
|
||||||
sort($input);
|
|
||||||
$cnt = count($input);
|
|
||||||
if(!$cnt){
|
|
||||||
die("No input images found. This script needs to be called from within the image directory!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create destination image
|
|
||||||
$DST = imagecreatetruecolor(30,$cnt*45*2);
|
|
||||||
imagesavealpha($DST, true);
|
|
||||||
$C_trans = imagecolorallocatealpha($DST, 0, 0, 0, 127);
|
|
||||||
imagefill($DST, 0, 0, $C_trans);
|
|
||||||
|
|
||||||
// load highlight color from style.ini
|
|
||||||
$ini = parse_ini_file('../style.ini',true);
|
|
||||||
$COLOR = hex2rgb($ini['replacements']['__link__']);
|
|
||||||
$C_active = imagecolorallocate($DST, $COLOR['r'],$COLOR['g'],$COLOR['b']);
|
|
||||||
|
|
||||||
// add all the icons to the sprite image
|
|
||||||
for($i=0; $i<$cnt; $i++){
|
|
||||||
$base = $i*90;
|
|
||||||
|
|
||||||
$IN = imagecreatefrompng($input[$i]);
|
|
||||||
imagesavealpha($IN, true);
|
|
||||||
imagecolorscale($IN,$GAMMA);
|
|
||||||
imagecopy($DST,$IN, 0,$base, 0,0, 30,30);
|
|
||||||
imagedestroy($IN);
|
|
||||||
|
|
||||||
$IN = imagecreatefrompng($input[$i]);
|
|
||||||
imagesavealpha($IN, true);
|
|
||||||
imagecolorscale($IN,$GAMMA);
|
|
||||||
imagecopy($DST,$IN, 0,$base+45, 0,0, 30,30);
|
|
||||||
imagedestroy($IN);
|
|
||||||
|
|
||||||
imagelayereffect($DST, IMG_EFFECT_OVERLAY);
|
|
||||||
imagefilledrectangle($DST, 0,$base+45, 30,$base+45+30, $C_active);
|
|
||||||
imagelayereffect($DST, IMG_EFFECT_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// output sprite
|
|
||||||
imagepng($DST,'pagetools-sprite.png');
|
|
||||||
imagedestroy($DST);
|
|
||||||
|
|
||||||
// optimize if possible
|
|
||||||
if(is_executable($OPTIPNG)){
|
|
||||||
system("$OPTIPNG -o5 'pagetools-sprite.png'");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a hex color code to an rgb array
|
|
||||||
*/
|
|
||||||
function hex2rgb($hex) {
|
|
||||||
// strip hash
|
|
||||||
$hex = str_replace('#', '', $hex);
|
|
||||||
|
|
||||||
// normalize short codes
|
|
||||||
if(strlen($hex) == 3){
|
|
||||||
$hex = substr($hex,0,1).
|
|
||||||
substr($hex,0,1).
|
|
||||||
substr($hex,1,1).
|
|
||||||
substr($hex,1,1).
|
|
||||||
substr($hex,2,1).
|
|
||||||
substr($hex,2,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calc rgb
|
|
||||||
return ['r' => hexdec(substr($hex, 0, 2)), 'g' => hexdec(substr($hex, 2, 2)), 'b' => hexdec(substr($hex, 4, 2))];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scale (darken/lighten) a given image
|
|
||||||
*
|
|
||||||
* @param resource $img The truetype GD image to work on
|
|
||||||
* @param float $scale Scale the colors by this value ( <1 darkens, >1 lightens)
|
|
||||||
*/
|
|
||||||
function imagecolorscale(&$img, $scale){
|
|
||||||
$w = imagesx($img);
|
|
||||||
$h = imagesy($img);
|
|
||||||
|
|
||||||
imagealphablending($img, false);
|
|
||||||
for($x = 0; $x < $w; $x++){
|
|
||||||
for($y = 0; $y < $h; $y++){
|
|
||||||
$rgba = imagecolorat($img, $x, $y);
|
|
||||||
$a = ($rgba >> 24) & 0xFF;
|
|
||||||
$r = ($rgba >> 16) & 0xFF;
|
|
||||||
$g = ($rgba >> 8) & 0xFF;
|
|
||||||
$b = $rgba & 0xFF;
|
|
||||||
|
|
||||||
$r = max(min(round($r*$scale),255),0);
|
|
||||||
$g = max(min(round($g*$scale),255),0);
|
|
||||||
$b = max(min(round($b*$scale),255),0);
|
|
||||||
|
|
||||||
$color = imagecolorallocatealpha($img, $r, $g, $b, $a);
|
|
||||||
imagesetpixel($img, $x, $y, $color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imagealphablending($img, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 494 B |
|
Before Width: | Height: | Size: 519 B |
|
Before Width: | Height: | Size: 580 B |
|
Before Width: | Height: | Size: 592 B |
|
Before Width: | Height: | Size: 321 B |
|
Before Width: | Height: | Size: 478 B |
|
Before Width: | Height: | Size: 462 B |
|
Before Width: | Height: | Size: 769 B |
|
Before Width: | Height: | Size: 527 B |
|
Before Width: | Height: | Size: 374 B |
|
Before Width: | Height: | Size: 297 B |
|
Before Width: | Height: | Size: 320 B |
|
Before Width: | Height: | Size: 288 B |
@@ -1,4 +0,0 @@
|
|||||||
Icon set: iPhone toolbar icons
|
|
||||||
Designer: TheWorkingGroup.ca
|
|
||||||
License: Creative Commons Attribution-Share Alike License [http://creativecommons.org/licenses/by-sa/3.0/]
|
|
||||||
URL: http://blog.twg.ca/2009/09/free-iphone-toolbar-icons/
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB |
28
script.js
@@ -87,6 +87,34 @@ jQuery(function(){
|
|||||||
this.blur();
|
this.blur();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// make edit toolbar icons themeable by converting img icons to CSS masks
|
||||||
|
(function enhanceEditToolbarIcons() {
|
||||||
|
function toMaskIcons() {
|
||||||
|
jQuery('.dokuwiki #tool__bar button.toolbutton img').each(function () {
|
||||||
|
var $img = jQuery(this);
|
||||||
|
var src = $img.attr('src');
|
||||||
|
|
||||||
|
if (!src) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $icon = jQuery('<span/>', {
|
||||||
|
'class': 'toolicon',
|
||||||
|
'aria-hidden': 'true'
|
||||||
|
});
|
||||||
|
$icon[0].style.setProperty('--icon-url', 'url("' + src.replace(/"/g, '\\"') + '")');
|
||||||
|
$img.replaceWith($icon);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
toMaskIcons();
|
||||||
|
|
||||||
|
var toolbar = document.getElementById('tool__bar');
|
||||||
|
if (toolbar && window.MutationObserver) {
|
||||||
|
new MutationObserver(toMaskIcons).observe(toolbar, {childList: true, subtree: true});
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
||||||
// enhance header search with suggestions and keyboard navigation
|
// enhance header search with suggestions and keyboard navigation
|
||||||
(function enhanceSearch(){
|
(function enhanceSearch(){
|
||||||
var $input = jQuery('#qsearch__in');
|
var $input = jQuery('#qsearch__in');
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ __highlight__ = "#ff9" ; @ini_highlight
|
|||||||
|
|
||||||
; links
|
; links
|
||||||
__link__ = "#2b73b7" ; @ini_link
|
__link__ = "#2b73b7" ; @ini_link
|
||||||
|
__icons__ = "#666" ; @ini_icons
|
||||||
__luxtools_locationlink__ = "#b57d35" ; @ini_luxtools_locationlink
|
__luxtools_locationlink__ = "#b57d35" ; @ini_luxtools_locationlink
|
||||||
|
|
||||||
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ if (!defined('DOKU_INC')) die();
|
|||||||
<?php echo (new \dokuwiki\Menu\MobileMenu())->getDropdown($lang['tools']); ?>
|
<?php echo (new \dokuwiki\Menu\MobileMenu())->getDropdown($lang['tools']); ?>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<?php echo (new \dokuwiki\Menu\SiteMenu())->getListItems('action ', false); ?>
|
<?php echo (new \dokuwiki\Menu\SiteMenu())->getListItems('action '); ?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||