diff --git a/adminer/designs.php b/adminer/designs.php index 11f603f0..81c213ed 100644 --- a/adminer/designs.php +++ b/adminer/designs.php @@ -3,8 +3,13 @@ function adminer_object() { include_once "../plugins/plugin.php"; include_once "../plugins/designs.php"; $designs = array(); - foreach (glob("../designs/*", GLOB_ONLYDIR) as $filename) { - $designs["$filename/adminer.css"] = basename($filename); + foreach (glob("../designs/*", GLOB_ONLYDIR) as $dirname) { + foreach (array("", "-dark") as $mode) { + $filename = "$dirname/adminer$mode.css"; + if (file_exists($filename)) { + $designs[$filename] = basename($dirname); + } + } } return new AdminerPlugin(array( new AdminerDesigns($designs), diff --git a/adminer/file.inc.php b/adminer/file.inc.php index 760e874e..7254f625 100644 --- a/adminer/file.inc.php +++ b/adminer/file.inc.php @@ -11,7 +11,7 @@ if ($_GET["file"] == "favicon.ico") { echo lzw_decompress(compile_file('../adminer/static/default.css;../externals/jush/jush.css', 'minify_css')); } elseif ($_GET["file"] == "dark.css") { header("Content-Type: text/css; charset=utf-8"); - echo lzw_decompress(compile_file('../adminer/static/dark.css', 'minify_css')); + echo lzw_decompress(compile_file('../adminer/static/dark.css;../externals/jush/jush-dark.css', 'minify_css')); } elseif ($_GET["file"] == "functions.js") { header("Content-Type: text/javascript; charset=utf-8"); echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js')); diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php index d0696b9d..55448c50 100644 --- a/adminer/include/adminer.inc.php +++ b/adminer/include/adminer.inc.php @@ -94,12 +94,12 @@ class Adminer { } /** Print HTML code inside - * @return bool true to link favicon.ico and adminer.css if exists + * @param bool dark CSS: false to disable, true to force, null to base on user preferences + * @return bool true to link favicon.ico */ - function head() { - ?> - -\n"; + echo ($dark !== false ? "\n" : ""); return true; } @@ -108,9 +108,11 @@ class Adminer { */ function css() { $return = array(); - $filename = "adminer.css"; - if (file_exists($filename)) { - $return[] = "$filename?v=" . crc32(file_get_contents($filename)); + foreach (array("", "-dark") as $mode) { + $filename = "adminer$mode.css"; + if (file_exists($filename)) { + $return[] = "$filename?v=" . crc32(file_get_contents($filename)); + } } return $return; } diff --git a/adminer/include/design.inc.php b/adminer/include/design.inc.php index 077972fd..2b9a72db 100644 --- a/adminer/include/design.inc.php +++ b/adminer/include/design.inc.php @@ -31,17 +31,19 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") { css(); - if ($css) { - foreach ($css as $val) { - echo "\n"; - } - } else { + $dark = ($css == array_filter($css, function ($filename) { + return preg_match('~-dark~', $filename); + })); + if ($dark) { // we need to load this before user styles echo "\n"; } + foreach ($css as $val) { + echo "\n"; + } echo script_src("../adminer/static/functions.js"); echo script_src("static/editing.js"); ?> -head()) { ?> +head($css ? $dark : null)) { ?> diff --git a/adminer/static/dark.css b/adminer/static/dark.css index 445339a5..8261461a 100644 --- a/adminer/static/dark.css +++ b/adminer/static/dark.css @@ -13,7 +13,7 @@ thead th a { color: #a8b05f; } fieldset { border-color: #16548a; } code { background: #11385a; } tbody tr:hover td, tbody tr:hover th { background: #133553; } -pre.jush { background: #a7c3dc; } +pre.jush { background: #11385a; } input.default { box-shadow: 1px 1px 1px #888; } input.required, input.maxlength { box-shadow: 1px 1px 1px red; } .version { color: #888; } diff --git a/changes.txt b/changes.txt index 4a509093..25923003 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,7 @@ Adminer dev: +CSS: Dark mode syntax highlighting SQL textarea: Open help on Ctrl+click +Designs named adminer-dark.css use dark syntax highlighting Adminer 5.0.5 (released 2025-03-13): MySQL: Display converting function for binary, bit or geometry fields diff --git a/compile.php b/compile.php index 5ecb29b3..1edfd169 100755 --- a/compile.php +++ b/compile.php @@ -329,7 +329,7 @@ if ($driver) { //! strip doc_link() definition } if ($project == "editor") { - $file = preg_replace('~;.\.\/externals/jush/jush\.css~', '', $file); + $file = preg_replace('~;.\.\/externals/jush/jush(-dark)?\.css~', '', $file); $file = preg_replace('~compile_file\(\'\.\./(externals/jush/modules/jush\.js|adminer/static/[^.]+\.gif)[^)]+\)~', "''", $file); } $file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file); @@ -343,7 +343,7 @@ if ($_SESSION["lang"]) { } $file = str_replace('echo script_src("static/editing.js");' . "\n", "", $file); // merged into functions.js $file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|" \. JUSH \. ")\.js"\);~', '', $file); // merged into jush.js -$file = str_replace('' . "\n", "", $file); // merged into default.css +$file = preg_replace('~echo .*/jush(-dark)?.css\'>.*~', '', $file); // merged into default.css or dark.css $file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files $replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . $VERSION . '"'; $file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '', $file); diff --git a/designs/bilal-dark/adminer.css b/designs/bilal-dark/adminer.css deleted file mode 100644 index 2c429bf1..00000000 --- a/designs/bilal-dark/adminer.css +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Dark Theme for Adminer by 'Muhammad Bilal Yameen' [github.com/bilal-yameen/dark-theme-for-adminer] - */ -html,body,header,footer,aside,menu,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;outline:0;border:none;background:transparent;font-size:10pt;font-weight:normal} -ol,ul{list-style:none} -blockquote,q{quotes:none} -blockquote:before,blockquote:after,q:before,q:after{content:none} -:focus{outline:0} -ins{text-decoration:none} -del{text-decoration:line-through} -table{border-collapse:collapse;border-spacing:0} -aside,menu{display:block} -input[type='submit'],input[type='checkbox'],input[type='radio'],input[type='file'],select,label{cursor:pointer} -input[disabled=""]{opacity:.5;cursor:not-allowed;color:#666 !important;border-color:#aaa !important} -input[type='text']{-webkit-user-modify:read-write-plaintext-only} -@font-face{font-family:'entypo';src:url('../fonts/entypo.eot');src:url('../fonts/entypo.eot?#iefix') format('embedded-opentype'),url('../fonts/entypo.woff') format('woff'),url('../fonts/entypo.ttf') format('truetype'),url('../fonts/entypo.svg#entypo') format('svg');font-weight:normal;font-style:normal} -html{overflow-y:scroll;-webkit-text-size-adjust:none} -body{font-family:"Helvetica Neue",Helvetica,Verdana,Arial,sans-serif;background:#22252a;color:#a5a8ad;width:100%} -a,a:visited{padding:4px 0;color:#0c83d9;transition:color .1s ease 0s,background-color .1s ease 0s} -a:link:hover,a:visited:hover{color:#0063a9;text-decoration:none} -a sup{padding:0 5px} -#logins a,#tables a,#tables span{background:none} -.active:before{font-weight:normal} -label{padding:3px 10px} -input::-webkit-input-placeholder{color:#999} -input::-moz-placeholder{color:#999} -input:-ms-input-placeholder{color:#999} -input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea,pre[contenteditable="true"],select{padding:4px 5px !important;border:1px solid #ccc !important;border-radius:2px;font-size:10pt;background:#202225;color:#a5a8ad;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} -input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea{-webkit-appearance:none} -input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],select{height:28px} -input[type="submit"]{display:inline-block;padding:7px 15px;border:1px solid #0c83d9;border-radius:2px;background:#0c83d9;color:#fff;text-align:center;text-decoration:none;font-size:10pt;transition:background-color .1s ease 0s;-webkit-appearance:none} -input[type="submit"]:hover{background:#0063a9;border-color:#0063a9} -input[type="submit"][disabled=""]:hover{background:#22252a} -input[type="submit"].default{box-shadow:none} -input[type="image"]{border:4px solid #22252a;outline:1px solid #0a83d9;-moz-outline-radius:2px;margin-right:5px} -input[type="image"]:last-child{margin-right:0} -input[type="image"]:hover{border-color:#282b2f} -input[type="checkbox"],input[type="radio"]{margin:7px 5px 7px 0} -fieldset{margin:5px 5px 10px 0;padding:5px 10px;border:1px solid rgba(255,255,255,0.1);border-radius:2px;background:#282b2f;min-height:55px} -fieldset input[type="submit"]{padding:3px 10px;border-color:#0c83d9;background:#22252a;color:#0c83d9} -fieldset input[type="submit"]:hover{background:#0c82d4;color:#fff} -fieldset input[type="submit"].default{border-color:#0c83d9;background:#0c83d9;color:#22252a} -fieldset input[type="submit"].default:hover{background:#0063a9;border-color:#0063a9} -fieldset a{padding:6px 8px} -fieldset+table,table+fieldset{margin-top:10px} -fieldset legend a{position:relative;padding:4px 0 50px} -fieldset>div>div,fieldset>div>p,fieldset>div>a,fieldset>div>code,fieldset>div>input,fieldset>div>select,fieldset>a{position:relative} -legend{margin-bottom:3px} -legend:before,legend:after{content:"ย "} -p input,p select,p label,fieldset input,fieldset select{margin:0 5px 5px 0} -.js fieldset>.hidden{display:block;margin-top:5px;text-align:center} -.js fieldset>.hidden *{display:none !important} -.js fieldset>.hidden:before{content:"โถ";font-family:"entypo",sans-serif;font-size:40pt;line-height:0;vertical-align:middle;color:#e2e2e2} -#fieldset-select.hidden:before{content:"โš"} -#fieldset-search.hidden:before{content:"๐Ÿ”"} -#fieldset-sort.hidden:before{content:"โท"} -#fieldset-export.hidden:before{content:"๐Ÿ“ค"} -#fieldset-import.hidden:before{content:"๐Ÿ“ฅ"} -#fieldset-history.hidden:before{content:"๎ €"} -#fieldset-history br{display:block;margin-bottom:20px} -#fieldset-history.hidden br{display:none} -#fieldset-partition.hidden:before{content:"๎œฃ"} -.size{width:8ex} -.sqlarea{width:100% !important;height:350px} -@media only screen and (max-width:768px){ - input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea,pre[contenteditable="true"],select{font-size:12pt;vertical-align:-1px} - input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],select{height:32px} - fieldset input[type="submit"]{padding:6px 15px} - .sqlarea{height:250px} -} -@media only screen and (max-width:360px){ - input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea,pre[contenteditable="true"],select{width:100%} - input[type="submit"],fieldset input[type="submit"]{padding-left:10px;padding-right:10px} -} -#lang{position:fixed;right:0;top:0;left:auto;border:none;padding:0 0 0 10px;width:190px;height:40px;line-height:30px;font-size:0;z-index:101;background:#282b2f} -#lang select{padding:2px 3px;margin:6px 0;width:100px} -.logout{position:fixed;right:10px;margin:0;z-index:101;overflow:hidden} -.logout input[type="submit"]{border:none;margin:0;padding:0 10px;height:40px;background:transparent;color:#0c83d9} -.logout input[type="submit"]:hover{background:transparent;color:#0063a9} -@media only screen and (max-width:768px){ - #lang{position:static;left:0;top:0;width:auto;border-top:1px solid rgba(255,255,255,0.1);background:#282b2f} - #lang select{margin:4px 10px 0 10px} - .logout{position:relative;float:right;margin-top:-40px} -} -@media only screen and (max-width:360px){ - #lang select{margin-left:0} -} -#content{position:relative;margin:0 0 0 261px;padding:41px 20px 80px 20px} -#content:before{position:fixed;left:0;top:0;content:"";display:block;width:100%;height:40px;background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1)} -#content .links+p{color:#999} -#breadcrumb{position:fixed;left:261px;top:0;right:0;margin:0;padding:0 0 0 20px;border-right:205px solid #282b2f;background:#282b2f;height:40px;line-height:40px;z-index:100;overflow:hidden;text-overflow:ellipsis} -#breadcrumb a{display:inline-block;padding:0;height:40px;line-height:40px} -h2{margin:20px 0;font-size:20pt;color:#a5a8ad} -h3{margin:30px 0 10px 0;font-size:16pt} -p{margin:10px 0} -code{display:block;padding:10px;margin:5px 0;border-left:7px solid #58595a;border-radius:2px;background:#2d3135;overflow:auto} -td code,th code,fieldset code:first-child{display:inline;margin:0;padding:0;background:none;border:none} -pre code{margin:0} -fieldset code+i{display:none} -.time{margin-left:10px;float:right;font-size:8pt;color:#bbb} -.error,.message{margin:20px 0;padding:10px;border-left:7px solid #cec} -.error{color:#900;border-color:#ecc} -.message pre{margin:15px 0 5px 0} -.message p{margin:0 0 5px 0} -pre+.message,pre+.error{margin-top:0} -#help{z-index:200;border:1px solid rgba(255,255,255,0.1);border-radius:2px;background:#282b2f;padding:5px 7px} -.icon{background-color:#0c83d9} -.icon:hover{background-color:#0063a9} -@media only screen and (max-width:768px){ - #content{margin-left:0} - #breadcrumb{left:0;padding-left:50px;border-right-width:0} -} -@media only screen and (max-width:360px){ - #content{padding:41px 10px 20px} - h2{margin:15px 0;font-size:16pt} -} -h1{height:40px;white-space:nowrap;overflow:hidden} -h1 #h1{display:inline-block;padding:0;background:url("../images/logo.png?3") 10px center no-repeat;background-size:120px;text-indent:-100px;width:135px;height:40px} -.version,#version{position:relative;top:-7px;vertical-align:bottom;font-size:8pt;font-style:italic;color:#bbb} -#version{padding:5px;color:#0c83d9} -#version:hover{color:#0063a9} -#menu{position:fixed;left:0;top:0;bottom:0;width:260px;margin:0;padding:0;border-right:1px solid rgba(255,255,255,0.1);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;background:#22252a;z-index:100} -#menu p{padding:10px;border-bottom:none} -#menu .links{background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1);padding:0 10px 7px 10px} -#menu .message{background:transparent;border:none;border-bottom:1px solid rgba(255,255,255,0.1);color:#bbb} -#filter-field{margin:0;width:100%} -.menu-list{border-bottom:1px solid rgba(255,255,255,0.1) !important;padding:0 !important;margin-bottom:25px !important } -.menu-link{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis} -.menu-link.active{background:#282b2f;color:#0c83d9} -.menu-link.active:hover{background:#1b1f25} -p#dbs{border-top:1px solid rgba(255,255,255,0.1);background:#282b2f;color:#282b2f;font-size:0} -p#dbs span{font-size:0} -p#dbs select{margin:0;width:100%} -#tables{border-bottom:1px solid rgba(255,255,255,0.1) !important;padding:0 !important;margin-bottom:25px !important } -#tables li{position:relative} -#tables li:hover{background:#282b2f} -#tables a strong{font-weight:bold} -#tables a.structure{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis;padding-right:0} -#tables a.structure.active{background:#282b2f;color:#0c83d9} -#tables a.structure.active:hover{background:#1b1f25} -#tables a.select{position:absolute;right:0;top:0;display:block;padding:2px 7px;height:20px;line-height:20px;color:#999;overflow:hidden;width:16px} -#tables a.select:before{content:"๐Ÿ“„ย ย ";font-family:entypo,sans-serif;font-size:24pt;line-height:0;vertical-align:-3px} -#tables li:first-of-type a{padding-top:7px} -#tables li:last-child a{padding-bottom:7px} -#tables a.active+a{background:#282b2f;color:#0c83d9;font-weight:bold} -#tables a.active+a:hover{background:#1b1f25} -#tables a.active:hover+a{background:#1b1f25} -#tables a:hover+a.active{background:#1b1f25} -#tables br{display:none} -#tables.simple a{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis} -#tables.simple a.active{background:#282b2f;color:#0c83d9} -#tables.simple a.active:hover{background:#1b1f25} -#logins{border-bottom:1px solid rgba(255,255,255,0.1) !important;padding:0 !important;margin-bottom:25px !important ;border-top:1px solid rgba(255,255,255,0.1)} -#logins a{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis} -#logins a.active{background:#282b2f;color:#0c83d9} -#logins a.active:hover{background:#1b1f25} -#logins a:hover{background:#282b2f} -#logins a:first-of-type{padding-top:7px} -#logins a:last-of-type{padding-bottom:7px} -#logins br{display:none} -@media only screen and (max-width:768px){ - h1:before{float:left;position:relative;left:4px;top:4px;width:30px;height:30px;content:"โ˜ฐ";font-family:"entypo",sans-serif;font-size:32pt;line-height:30px;border:1px solid #0c83d9;border-radius:2px;text-align:center;vertical-align:middle;background:#22252a;cursor:pointer} - h1 #h1{margin-left:10px} - #menu{width:40px;height:40px;bottom:auto;border:none;overflow:hidden;background:transparent} - #menu form,#menu p{display:none} - #menu.open{width:260px;height:auto;max-width:100%;max-height:100%;border-right:1px solid rgba(255,255,255,0.1);border-bottom:5px solid rgba(255,255,255,0.1);background:#22252a;box-shadow:2px 2px 10px rgba(0,0,0,0.03);z-index:200;overflow-y:auto} - #menu.open form,#menu.open p{display:block} -} -@media only screen and (max-width:270px){ - #menu.open{border-right:none} -} -@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (-o-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){ - h1 #h1{background-image:url("../images/logo-hres.png?3");background-size:120px} -} -a[href*="&sql="]:before{content:"โœŽ";padding:0 5px;font-family:entypo,sans-serif;font-size:24pt;line-height:10pt;vertical-align:-3px} -.links{line-height:22px} -.links a:before{content:"โดย ";font-family:entypo,sans-serif;font-size:24pt;line-height:10pt;vertical-align:-3px} -.links a[href*="&sql="]:before{content:"๎œท";margin-left:-4px;margin-right:3px} -.links a[href*="&import="]:before{content:"๐Ÿ“ฅย "} -.links a[href*="&dump="]:before{content:"๐Ÿ“คย "} -.links a[href*="&create="]:before,.links a[href*="&db="][href*="&database="]:before,.links a[href*="&indexes="]:before{content:"โœŽย "} -.links a[href$="&create="]:before,.links a[href$="&database="]:before,.links a[href$="&indexes="]:before{content:"โž•ย "} -.links a[href*="&schema="]:before{content:"๐Ÿ•ชย "} -.links a[href*="&privileges="]:before{content:"๐Ÿ‘ฅย "} -.links a[href*="&view="]:before{content:"๎œŠย "} -.links a[href*="&procedure="]:before,.links a[href*="&function="]:before{content:"๎€ƒย "} -.links a[href*="&event="]:before{content:"๐Ÿ”ย "} -.links a[href*="&edit="]:before{content:"โŠ•ย "} -.links a[href*="&table="]:before{content:"โš™ย "} -.links a[href*="&select="]:before{content:"๐Ÿ“„ย "} -.links a[href*="&processlist="]:before{content:"๎€…ย "} -.links a[href*="&status="]:before{content:"๐Ÿ“ฟย "} -.links a[href*="&variables="]:before{content:"๎œ”ย "} -.links a[href*="&user="]:before{content:"๎œ€ย "} -.links a[href*="&foreign="]:before,.links a[href*="&trigger="]:before{content:"โž•ย "} -table{border:1px solid rgba(255,255,255,0.1);margin:20px 0 10px 0} -table label.block{padding:0} -tr{border-bottom:1px dotted rgba(255,255,255,0.1)} -th,td{padding:4px 10px} -th[style="text-align: right;"] input[type="checkbox"],td[align="right"] input[type="checkbox"],th[style="text-align: right;"] input[type="radio"],td[align="right"] input[type="radio"]{margin-right:0;margin-left:5px} -thead td,thead th,.odds tbody tr:nth-child(2n),tbody tr:hover td,tbody tr:hover th,.js .checkable .checked td,.js .checkable .checked th{background:transparent} -thead tr{background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1)} -thead td,thead th{padding:7px 10px;background:transparent;text-align:left} -tbody th,tbody td{vertical-align:top} -tbody td[align="right"]{text-align:right} -tbody td[align="right"] label.block{text-align:right} -tbody th span{padding-top:4px} -table.checkable .checked{background:#282b2f} -table.checkable input[type="checkbox"],table.checkable input[type="radio"]{margin:2px 5px 2px 0} -table.checkable>thead a{padding:7px 0} -table.checkable>thead input[type="checkbox"],table.checkable>thead input[type="radio"]{margin:2px 5px 2px 0} -table.checkable>tbody>tr:hover{background:#282b2f} -table.checkable>tbody>tr.checked:hover{background:#1b1f25} -.scrollable{display:table-cell;padding-right:20px} -.loadmore{margin:0;padding:10px 0} -.footer{position:relative;padding:0} -.footer>div{padding:0} -.footer>p{position:fixed;left:261px;right:0;bottom:0;margin:0;padding:0 10px;border:none;border-top:1px solid rgba(255,255,255,0.1);background:#282b2f;z-index:102;font-weight:bold} -.footer>p a,.footer>p label{display:inline-block;margin:0;padding:0 10px;height:40px;line-height:40px} -.footer+div{line-height:36px} -.footer+div a{padding:10px 0} -.js .column{background:#22252a;padding:0;margin:-36px 0 0 -62px;border:1px solid #3e4144;border-radius:2px;z-index:10} -.js .column a{display:inline-block;padding:0;width:30px;height:30px;overflow:hidden;vertical-align:middle} -.js .column a:before{display:inline-block;width:30px;height:30px;line-height:30px;font-family:entypo,sans-serif;font-size:24pt;text-align:center;vertical-align:-3px} -.js .column a:hover:before{background:#282b2f} -.js .column a[href*='&select=']:before{content:"โฌ‡"} -.js .column a[href='#fieldset-search']:before{content:"๐Ÿ”"} -@media only screen and (max-width:768px){ - .footer>p{position:static;margin:-10px 0 10px 0;border-top:none;border-left:1px solid rgba(255,255,255,0.1);border-right:1px solid rgba(255,255,255,0.1);border-bottom:1px solid rgba(255,255,255,0.1)} - .scrollable{display:block;margin:0 -20px;padding:0 20px;overflow-x:scroll} -} -a.jush-custom:hover,a.jush-help:hover{color:inherit;text-decoration:underline} -.json{border-color:#58595a;border-left:7px solid #58595a;background:#282b2f;margin:5px 0 3px 0} -.json tr{border-bottom:1px solid #58595a} -.json tr:last-child{border-bottom:none} -.json th{border-right:1px solid #58595a;vertical-align:top} -.json code{padding:4px 10px} -.json+textarea{margin-top:6px} -a.json-icon{background:transparent;text-indent:0} -a.json-icon:hover{background:transparent} -a.json-icon:before{display:inline-block;width:20px;height:18px;line-height:18px;font-family:entypo,sans-serif;font-size:24pt;vertical-align:-3px;content:"โ–ธ"} -a.json-icon.json-up{background:transparent;text-indent:0} -a.json-icon.json-up:before{content:"โ–พ"} -a.json-link{padding-left:0} -a.json-link:before{width:10px} -a.json-link span{color:inherit} -.footer{border-image: linear-gradient(rgb(34 37 42 / 22%),#22252a) 100% 0;} -.footer > div{background: #22252a;} -.jush a {color: #1383d9;} -a.jush-custom:hover, a.jush-help:hover{color:#fff;} -.jush {color: #a5a8ad;} -.error {background: #ff00001a;color: #d8bfbf;} -.message {color: #cceecc;background: #0075001c;} -::-webkit-scrollbar {width: 10px;height: 10px;} -::-webkit-scrollbar-track {background: #3e3e3e;} -::-webkit-scrollbar-thumb {background: #888;} -::-webkit-scrollbar-thumb:hover {background: #555;} -input[type=checkbox] {display:inline-block;padding-left:25px;height:20px;outline:0;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgd2lkdGg9IjIwcHQiCiAgIGhlaWdodD0iNDBwdCIKICAgdmlld0JveD0iMCAwIDIwIDQwIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmcyIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4LjUgcjEwMDQwIgogICBzb2RpcG9kaTpkb2NuYW1lPSJjaGVjay5zdmciPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTE5Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzMTciIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMTciCiAgICAgaWQ9Im5hbWVkdmlldzE1IgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp6b29tPSIxNiIKICAgICBpbmtzY2FwZTpjeD0iNDMuNzAyNjQ2IgogICAgIGlua3NjYXBlOmN5PSIzMS45NTE3ODMiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjE5MTIiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMiIgLz4KICA8ZwogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDAiCiAgICAgaWQ9ImczMDY4IgogICAgIHRyYW5zZm9ybT0ic2NhbGUoMC44LDAuOCkiPgogICAgPHBhdGgKICAgICAgIGlkPSJwYXRoMzA1OCIKICAgICAgIGQ9Ik0gMTksNSBWIDE5IEggNSBWIDUgSCAxOSBNIDE5LDMgSCA1IEMgMy45LDMgMywzLjkgMyw1IHYgMTQgYyAwLDEuMSAwLjksMiAyLDIgaCAxNCBjIDEuMSwwIDIsLTAuOSAyLC0yIFYgNSBDIDIxLDMuOSAyMC4xLDMgMTksMyB6IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBpZD0icGF0aDMwNjAiCiAgICAgICBkPSJNIDAsMCBIIDI0IFYgMjQgSCAwIHoiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6bm9uZSIgLz4KICA8L2c+CiAgPGcKICAgICBzdHlsZT0iZmlsbDojMDAwMDAwIgogICAgIGlkPSJnMzA4NCIKICAgICB0cmFuc2Zvcm09Im1hdHJpeCgwLjgsMCwwLDAuOCwwLDIwKSI+CiAgICA8cGF0aAogICAgICAgaWQ9InBhdGgzMDc0IgogICAgICAgZD0iTSAwLDAgSCAyNCBWIDI0IEggMCB6IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOm5vbmUiIC8+CiAgICA8cGF0aAogICAgICAgaWQ9InBhdGgzMDc2IgogICAgICAgZD0iTSAxOSwzIEggNSBDIDMuODksMyAzLDMuOSAzLDUgdiAxNCBjIDAsMS4xIDAuODksMiAyLDIgaCAxNCBjIDEuMTEsMCAyLC0wLjkgMiwtMiBWIDUgQyAyMSwzLjkgMjAuMTEsMyAxOSwzIHogTSAxMCwxNyA1LDEyIDYuNDEsMTAuNTkgMTAsMTQuMTcgMTcuNTksNi41OCAxOSw4IDEwLDE3IHoiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg==);background-position:00;background-size:20px;background-repeat:no-repeat;vertical-align:middle;font-size:20px;line-height:20px;cursor:pointer;-webkit-appearance:none;-webkit-user-select:none;user-select:none;filter:invert();} -input[type=checkbox]:checked {background-position:0-20px;} diff --git a/designs/dracula/adminer.css b/designs/dracula/adminer-dark.css similarity index 100% rename from designs/dracula/adminer.css rename to designs/dracula/adminer-dark.css diff --git a/designs/galkaev/adminer.css b/designs/galkaev/adminer-dark.css similarity index 100% rename from designs/galkaev/adminer.css rename to designs/galkaev/adminer-dark.css diff --git a/designs/mancave/adminer.css b/designs/mancave/adminer-dark.css similarity index 100% rename from designs/mancave/adminer.css rename to designs/mancave/adminer-dark.css diff --git a/designs/readme.txt b/designs/readme.txt index 72135883..c9a3046b 100644 --- a/designs/readme.txt +++ b/designs/readme.txt @@ -1 +1,3 @@ Copy adminer.css alongside Adminer PHP script to use an alternative design. + +If the design supports dark mode then it should be named adminer-dark.css. diff --git a/designs/rmsoft_blue-dark/adminer.css b/designs/rmsoft_blue-dark/adminer-dark.css similarity index 100% rename from designs/rmsoft_blue-dark/adminer.css rename to designs/rmsoft_blue-dark/adminer-dark.css diff --git a/editor/include/adminer.inc.php b/editor/include/adminer.inc.php index a4df17e3..0516eacc 100644 --- a/editor/include/adminer.inc.php +++ b/editor/include/adminer.inc.php @@ -59,15 +59,17 @@ class Adminer { return csp(); } - function head() { + function head($dark = null) { return true; } function css() { $return = array(); - $filename = "adminer.css"; - if (file_exists($filename)) { - $return[] = $filename; + foreach (array("", "-dark") as $mode) { + $filename = "adminer$mode.css"; + if (file_exists($filename)) { + $return[] = "$filename?v=" . crc32(file_get_contents($filename)); + } } return $return; } diff --git a/externals/jush b/externals/jush index ab07b683..e73bdd5d 160000 --- a/externals/jush +++ b/externals/jush @@ -1 +1 @@ -Subproject commit ab07b68315dd6177869079b5888396bc8efb1571 +Subproject commit e73bdd5d805632151dedc203eed7f3efb3417edd diff --git a/plugins/adminer.js.php b/plugins/adminer.js.php index 7b7a427d..a89ccae5 100644 --- a/plugins/adminer.js.php +++ b/plugins/adminer.js.php @@ -11,7 +11,7 @@ class AdminerDotJs { const FILENAME = "adminer.js"; - function head() { + function head($dark = null) { if (file_exists(self::FILENAME)) { echo Adminer\script_src(self::FILENAME . "?v=" . crc32(file_get_contents(self::FILENAME))), "\n"; } diff --git a/plugins/edit-calendar.php b/plugins/edit-calendar.php index d6a052d2..09cd88cb 100644 --- a/plugins/edit-calendar.php +++ b/plugins/edit-calendar.php @@ -27,7 +27,7 @@ class AdminerEditCalendar { $this->langPath = $langPath; } - function head() { + function head($dark = null) { echo $this->prepend; if ($this->langPath) { $lang = Adminer\get_lang(); diff --git a/plugins/plugin.php b/plugins/plugin.php index b2e4aa51..84dcbe4c 100644 --- a/plugins/plugin.php +++ b/plugins/plugin.php @@ -162,7 +162,7 @@ class AdminerPlugin extends Adminer\Adminer { return $this->applyPlugin(__FUNCTION__, $args); } - function head() { + function head($dark = null) { $args = func_get_args(); return $this->applyPlugin(__FUNCTION__, $args); } diff --git a/plugins/tinymce.php b/plugins/tinymce.php index 2bb109f8..5695b9a2 100644 --- a/plugins/tinymce.php +++ b/plugins/tinymce.php @@ -17,7 +17,7 @@ class AdminerTinymce { $this->path = $path; } - function head() { + function head($dark = null) { $lang = Adminer\get_lang(); $lang = ($lang == "zh" ? "zh-cn" : ($lang == "zh-tw" ? "zh" : $lang)); if (!file_exists(dirname($this->path) . "/langs/$lang.js")) { diff --git a/plugins/version-noverify.php b/plugins/version-noverify.php index 36d13dd9..3d83384a 100644 --- a/plugins/version-noverify.php +++ b/plugins/version-noverify.php @@ -8,7 +8,7 @@ */ class AdminerVersionNoverify { - function head() { + function head($dark = null) { echo Adminer\script("verifyVersion = function () {};"); } } diff --git a/plugins/wymeditor.php b/plugins/wymeditor.php index 146e7593..c8095275 100644 --- a/plugins/wymeditor.php +++ b/plugins/wymeditor.php @@ -19,7 +19,7 @@ class AdminerWymeditor { $this->options = $options; } - function head() { + function head($dark = null) { foreach ($this->scripts as $script) { echo Adminer\script_src($script); }