diff --git a/Gruntfile.js b/Gruntfile.js index 534493c4b0..545b1235c7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -76,6 +76,22 @@ module.exports = function(grunt) { } } }, + sass: { + colors: { + options: { + style: 'expanded', + sourcemap: true, + noCache: true + }, + files : [{ + expand: true, + cwd: SOURCE_DIR, + dest: BUILD_DIR, + ext: '.css', + src: ['wp-admin/css/color-schemes/*/colors.scss'] + }] + } + }, cssmin: { core: { expand: true, @@ -98,6 +114,15 @@ module.exports = function(grunt) { 'wp-admin/css/*-rtl.css', 'wp-includes/css/*-rtl.css' ] + }, + colors: { + expand: true, + cwd: BUILD_DIR, + dest: BUILD_DIR, + ext: '.min.css', + src: [ + 'wp-admin/css/color-schemes/**/*.css' + ] } }, cssjanus: { @@ -316,6 +341,10 @@ module.exports = function(grunt) { test: { files: ['tests/qunit/**'], tasks: ['qunit'] + }, + colors: { + files: [SOURCE_DIR + 'wp-admin/css/color-schemes/**'], + tasks: ['sass:colors'] } } }); @@ -328,8 +357,10 @@ module.exports = function(grunt) { // RTL task. grunt.registerTask('rtl', ['cssjanus:core']); + grunt.registerTask('colors', ['sass:colors', 'cssmin:colors']); + // Build task. - grunt.registerTask('build', ['clean:all', 'copy:all', 'rtl', 'cssmin:core', 'cssmin:rtl', + grunt.registerTask('build', ['clean:all', 'copy:all', 'rtl', 'colors', 'cssmin:core', 'cssmin:rtl', 'uglify:core', 'uglify:tinymce', 'concat:tinymce', 'compress:tinymce', 'clean:tinymce']); // Testing tasks. diff --git a/package.json b/package.json index d9136c17fd..00dcdcbcb1 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "grunt-contrib-clean": "~0.5.0", "grunt-contrib-copy": "~0.4.1", "grunt-contrib-cssmin": "~0.6.1", + "grunt-contrib-sass": "~0.5.0", "grunt-contrib-qunit": "~0.2.2", "grunt-contrib-uglify": "~0.2.2", "grunt-contrib-watch": "~0.5.1", diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php index b220d33226..8847cda8b9 100644 --- a/src/wp-admin/admin-ajax.php +++ b/src/wp-admin/admin-ajax.php @@ -58,6 +58,7 @@ $core_actions_post = array( 'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment', 'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor', 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs', + 'save-user-color-scheme', ); // Register core Ajax calls. diff --git a/src/wp-admin/css/wp-admin.css b/src/wp-admin/css/wp-admin.css index 218b64cf6a..7781134791 100644 --- a/src/wp-admin/css/wp-admin.css +++ b/src/wp-admin/css/wp-admin.css @@ -5636,12 +5636,6 @@ span.imgedit-scale-warn { width: auto; } -.form-table div.color-option { - display: block; - clear: both; - margin-top: 12px; -} - .form-table input.tog { margin-top: 2px; margin-right: 2px; @@ -5653,21 +5647,6 @@ span.imgedit-scale-warn { margin-bottom: 0; } -.form-table table.color-palette { - vertical-align: bottom; - float: left; - margin: -12px 3px 11px; -} - -.form-table .color-palette td { - border-width: 1px 1px 0; - border-style: solid solid none; - height: 10px; - line-height: 20px; - width: 10px; -} - - .form-table td fieldset label { margin: 0.25em 0 0.5em !important; display: inline-block; @@ -6330,6 +6309,120 @@ h2 .nav-tab { width: 25em; } +.picker-dropdown { + background: #fcfcfc; + border: 1px solid #dedede; + margin-right: 12%; + max-width: 270px; + position: relative; + width: auto; +} + +.picker-dropdown.dropdown-current { + padding: 20px; + margin-bottom: 15px; + cursor: pointer; +} + +.picker-dropdown.dropdown-container { + display: none; + position: absolute; + width: 340px; + border-top: none; + -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); + z-index: 1; +} + +.picker-expanded .picker-dropdown.dropdown-container { + display: block; +} + +.picker-dropdown.dropdown-container:before, +.picker-dropdown.dropdown-container:after { + content: "\0020"; + display: block; + position: absolute; + top: -10px; + left: 150px; + z-index: 2; + width: 0; + height: 0; + overflow: hidden; + border: solid 11px transparent; + border-top: 0; + border-bottom-color: #fefefe; +} + +.picker-dropdown.dropdown-container:before { + top: -11px; + z-index: 1; + border-bottom-color: #dedede; +} + +.picker-dropdown-arrow { + position: absolute; + top: -1px; + right: -42px; + display: block; + width: 40px; + height: 100%; + background: white; + text-align: center; + border: 1px solid #dedede; + border-left-width: 0; + cursor: pointer; +} + +.picker-dropdown-arrow:before { + font: 20px/91px dashicons; + content: '\f140'; +} + +.picker-expanded .picker-dropdown-arrow:before { + content: '\f142'; +} + +.color-option { + display: block; + padding: 20px; + border-top: 1px solid #dedede; +} + +.color-option:hover, +.color-option.selected { + background: #f2f8fa; +} + +.color-palette { + width: 100%; + border-spacing: 0; + border-collapse: collapse; +} +.color-palette td { + height: 20px; + padding: 0; + border: none; +} + +.color-option { + cursor: pointer; +} + +.no-js .dropdown-current { + display: none; +} + +.no-js .dropdown-container { + display: block; + position: static; +} + +.no-js .dropdown-container:before, +.no-js .dropdown-container:after { + display: none; +} + /*------------------------------------------------------------------------------ 19.0 - Tools ------------------------------------------------------------------------------*/ diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index e6c28344b1..f2deaf1df7 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2244,3 +2244,27 @@ function wp_ajax_get_revision_diffs() { } wp_send_json_success( $return ); } + +/** + * Auto-save the selected color scheme for a user's own profile. + * + * @since 3.8.0 + */ +function wp_ajax_save_user_color_scheme() { + global $_wp_admin_css_colors; + + $user_id = intval( $_POST['user_id'] ); + $color_scheme = sanitize_key( $_POST['color_scheme'] ); + + if ( get_current_user_id() !== $user_id ) + wp_send_json_error(); + + if ( ! get_user_by( 'id', $user_id ) ) + wp_send_json_error(); + + if ( ! isset( $_wp_admin_css_colors[ $color_scheme ] ) ) + wp_send_json_error(); + + update_user_option( $user_id, 'admin_color', $color_scheme, true ); + wp_send_json_success(); +} diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php index 1e3edeb788..c3520dd999 100644 --- a/src/wp-admin/includes/misc.php +++ b/src/wp-admin/includes/misc.php @@ -562,29 +562,70 @@ function saveDomDocument($doc, $filename) { * @since 3.0.0 */ function admin_color_scheme_picker() { - global $_wp_admin_css_colors, $user_id; ?> -
- $color_info ): ?> -
/> - - - colors as $html_color ): ?> - - - -
 
+ global $_wp_admin_css_colors, $user_id; + ksort($_wp_admin_css_colors); + + $current_color = get_user_option( 'admin_color', $user_id ); + + if ( empty( $current_color ) || ! isset( $_wp_admin_css_colors[ $current_color ] ) ) + $current_color = 'fresh'; + + $color_info = $_wp_admin_css_colors[ $current_color ]; +?> + +
+ + + + + + +
- -
- -
icon_colors ) ) { + echo '\n"; + } +} +add_action( 'admin_head', 'set_color_scheme_json' ); + function _ipad_meta() { if ( wp_is_mobile() ) { ?> diff --git a/src/wp-admin/js/user-profile.js b/src/wp-admin/js/user-profile.js index d11de9f677..6e5ecc6e9b 100644 --- a/src/wp-admin/js/user-profile.js +++ b/src/wp-admin/js/user-profile.js @@ -73,6 +73,50 @@ }); }); } + + var $colorpicker = $( '#color-picker' ), + $stylesheet = $( '#colors-css' ), + user_id = $( 'input#user_id' ).val(), + current_user_id = $( 'input[name="checkuser_id"]' ).val(); + + // dropdown toggle + $colorpicker.on( 'click', '.dropdown-current', function() { + $colorpicker.toggleClass( 'picker-expanded' ); + }); + + $colorpicker.on( 'click', '.color-option', function() { + + var color_scheme = $( this ).children( 'input[name="admin_color"]' ).val(); + + // update selected + $( this ).siblings( '.selected' ).removeClass( 'selected' ) + $( this ).addClass( 'selected' ); + $( this ).find( 'input' ).prop( 'checked', true ); + + // update current + $colorpicker.find( '.dropdown-current label' ).html( $( this ).children( 'label' ).html() ); + $colorpicker.find( '.dropdown-current table' ).html( $( this ).children( 'table' ).html() ); + $colorpicker.toggleClass( 'picker-expanded' ); + + // preview/save color scheme + if ( user_id == current_user_id ) { + + // repaint icons + $stylesheet.attr( 'href', $( this ).children( '.css_url' ).val() ); + svgPainter.setColors( $.parseJSON( $( this ).children( '.icon_colors' ).val() ) ); + svgPainter.paint(); + + // update user option + $.post( ajaxurl, { + action: 'save-user-color-scheme', + color_scheme: color_scheme, + user_id: user_id + }); + + } + + }); + }); })(jQuery); diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 0c2fed624f..e09a817690 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -2085,14 +2085,20 @@ function paginate_links( $args = '' ) { * @param string $name The name of the theme. * @param string $url The url of the css file containing the colour scheme. * @param array $colors Optional An array of CSS color definitions which are used to give the user a feel for the theme. + * @param array $icons Optional An array of CSS color definitions used to color any SVG icons */ -function wp_admin_css_color($key, $name, $url, $colors = array()) { +function wp_admin_css_color( $key, $name, $url, $colors = array(), $icons = array() ) { global $_wp_admin_css_colors; if ( !isset($_wp_admin_css_colors) ) $_wp_admin_css_colors = array(); - $_wp_admin_css_colors[$key] = (object) array('name' => $name, 'url' => $url, 'colors' => $colors); + $_wp_admin_css_colors[$key] = (object) array( + 'name' => $name, + 'url' => $url, + 'colors' => $colors, + 'icon_colors' => $icons, + ); } /** @@ -2101,8 +2107,33 @@ function wp_admin_css_color($key, $name, $url, $colors = array()) { * @since 3.0.0 */ function register_admin_color_schemes() { - wp_admin_css_color( 'fresh', _x( 'Default', 'admin color scheme' ), admin_url( 'css/colors-fresh.min.css' ), - array( '#222', '#333', '#0074a2', '#2ea2cc' ) ); + $suffix = SCRIPT_DEBUG ? '' : '.min'; + + wp_admin_css_color( 'fresh', _x( 'Default', 'admin color scheme' ), + admin_url( "css/colors-fresh$suffix.css" ), + array( '#222', '#333', '#0074a2', '#2ea2cc' ) + ); + + // Other color schemes are not available when running out of src + if ( ! strpos( $GLOBALS['wp_version'], '-src' ) ) { + wp_admin_css_color( 'light', _x( 'Light', 'admin color scheme' ), + admin_url( "css/color-schemes/light/colors$suffix.css" ), + array( '#e5e5e5', '#999', '#d64e07', '#04a4cc' ), + array( 'base' => '#999', 'focus' => '#ccc', 'current' => '#ccc' ) + ); + + wp_admin_css_color( 'blue', _x( 'Blue', 'admin color scheme' ), + admin_url( "css/color-schemes/blue/colors$suffix.css" ), + array( '#096484', '#4796b3', '#52accc', '#74B6CE' ), + array( 'base' => '#e5f8ff', 'focus' => '#fff', 'current' => '#fff' ) + ); + + wp_admin_css_color( 'midnight', _x( 'Midnight', 'admin color scheme' ), + admin_url( "css/color-schemes/midnight/colors$suffix.css" ), + array( '#25282b', '#363b3f', '#69a8bb', '#e14d43' ), + array( 'base' => '#f1f2f3', 'focus' => '#fff', 'current' => '#fff' ) + ); + } } /**