From a589d9d757be413e6b10708f2af765e607e8bae2 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Tue, 11 Mar 2014 04:13:16 +0000 Subject: [PATCH] Add header image uploads with cropping to the customizer. props mcsf, ehg, gcorne. see #21785. Built from https://develop.svn.wordpress.org/trunk@27497 git-svn-id: http://core.svn.wordpress.org/trunk@27339 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/css/customize-controls-rtl.css | 161 +++++++++ wp-admin/css/customize-controls-rtl.min.css | 2 +- wp-admin/css/customize-controls.css | 161 +++++++++ wp-admin/css/customize-controls.min.css | 2 +- wp-admin/custom-header.php | 275 +++++++++++--- wp-admin/js/customize-controls.js | 244 +++++++++++-- wp-admin/js/customize-controls.min.js | 2 +- wp-includes/class-wp-customize-control.php | 375 +++++++++++++++----- wp-includes/css/media-views-rtl.css | 13 + wp-includes/css/media-views-rtl.min.css | 2 +- wp-includes/css/media-views.css | 13 + wp-includes/css/media-views.min.css | 2 +- wp-includes/js/customize-models.js | 249 +++++++++++++ wp-includes/js/customize-models.min.js | 1 + wp-includes/js/customize-views.js | 232 ++++++++++++ wp-includes/js/customize-views.min.js | 1 + wp-includes/js/media-views.js | 150 ++++++++ wp-includes/js/media-views.min.js | 6 +- wp-includes/media.php | 17 + wp-includes/script-loader.php | 4 +- 20 files changed, 1737 insertions(+), 175 deletions(-) create mode 100644 wp-includes/js/customize-models.js create mode 100644 wp-includes/js/customize-models.min.js create mode 100644 wp-includes/js/customize-views.js create mode 100644 wp-includes/js/customize-views.min.js diff --git a/wp-admin/css/customize-controls-rtl.css b/wp-admin/css/customize-controls-rtl.css index 76fdc003a8..a8452ffe14 100644 --- a/wp-admin/css/customize-controls-rtl.css +++ b/wp-admin/css/customize-controls-rtl.css @@ -455,6 +455,167 @@ body { -webkit-overflow-scrolling: touch; } +/** Header control **/ + +#customize-control-header_image .current { + margin-bottom: 8px; +} + +#customize-control-header_image .uploaded { + margin-bottom: 18px; +} + +/* Header control: current image container */ + +#customize-control-header_image .current .container { + overflow: hidden; + border-radius: 2px; +} + +#customize-control-header_image .placeholder { + width: 100%; + position: relative; + background: #262626; + text-align: center; + cursor: default; +} + +#customize-control-header_image .inner { + display: none; + position: absolute; + width: 100%; + height: 18px; + margin-top: -9px; + top: 50%; + color: #eee; +} + +/* Header control: overlay "close" button */ + +#customize-control-header_image .header-view { + position: relative; +} + +#customize-control-header_image .uploaded .header-view .close { + font-size: 2em; + color: grey; + position: absolute; + visibility: hidden; + top: 10px; + left: 10px; + z-index: 1; + width: 20px; + height: 20px; + cursor: pointer; +} + +#customize-control-header_image .uploaded .header-view .close:hover { + color: black; + text-shadow: + -1px -1px 0 #fff, + 1px -1px 0 #fff, + -1px 1px 0 #fff, + 1px 1px 0 #fff; +} + +#customize-control-header_image .header-view:hover .close { + visibility: visible; +} + +/* Header control: randomiz(s)er */ + +#customize-control-header_image .random.placeholder { + cursor: pointer; + border-radius: 2px; + height: 40px; +} + +#customize-control-header_image .random .inner { + display: block; +} + +#customize-control-header_image .dice { + font-size: 16px; + vertical-align: -1px; +} + +#customize-control-header_image .placeholder:hover .dice { + -webkit-animation: dice-color-change 3s infinite; + -moz-animation: dice-color-change 3s infinite; + -ms-animation: dice-color-change 3s infinite; + animation: dice-color-change 3s infinite; +} + +@-webkit-keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +@-moz-keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +@-ms-keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +@keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +/* Header control: actions and choices */ + +#customize-control-header_image .actions { + margin-bottom: 32px; +} + +#customize-control-header_image .choice { + position: relative; + display: block; + margin-bottom: 9px; +} + +#customize-control-header_image .choice.random:before { + position: absolute; + content: attr(data-label); + right: 0; + top: 0; +} + +#customize-control-header_image .uploaded div:last-child > .choice { + margin-bottom: 0; +} + +#customize-control-header_image .choices hr { + visibility: hidden; +} + +#customize-control-header_image img { + width: 100%; + border-radius: 2px; +} + +#customize-control-header_image .remove { + float: right; + margin-left: 3px; +} + +#customize-control-header_image .new { + float: left; +} + + /** Handle cheaters. */ body.cheatin { min-width: 0; diff --git a/wp-admin/css/customize-controls-rtl.min.css b/wp-admin/css/customize-controls-rtl.min.css index 56bd37ef00..229d0ffe14 100644 --- a/wp-admin/css/customize-controls-rtl.min.css +++ b/wp-admin/css/customize-controls-rtl.min.css @@ -1 +1 @@ -body{overflow:hidden}#customize-controls a{text-decoration:none}#customize-controls h3{font-size:14px}#customize-controls .submit{text-align:center}#customize-controls .description{color:#666}#customize-header-actions .button-primary{float:left;margin-top:9px}#customize-header-actions .spinner{margin-top:16px;margin-left:4px}.saving #customize-header-actions .spinner{display:block}#customize-info{border:0;border-top:1px solid #ddd}#customize-info .accordion-section-title{background-color:#fff;color:#666;border-right:0;border-left:0;border-bottom:1px solid #eee}#customize-info .accordion-section-title:focus,#customize-info .accordion-section-title:focus:after,#customize-info .accordion-section-title:hover,#customize-info .accordion-section-title:hover:after,#customize-info.open .accordion-section-title,#customize-info.open .accordion-section-title:after{color:#555}#customize-info.open .accordion-section-title{border-color:transparent}#customize-info .preview-notice{font-size:13px;line-height:24px}#customize-info .theme-name{font-size:20px;font-weight:200;line-height:24px;display:block}#customize-info .theme-screenshot{width:258px}#customize-info .theme-description{margin-top:1em;color:#666;line-height:20px}#customize-theme-controls{-webkit-box-shadow:0 1px 1px -1px rgba(0,0,0,.1);box-shadow:0 1px 1px -1px rgba(0,0,0,.1)}#customize-theme-controls .control-section{border:0}#customize-theme-controls .accordion-section-title{color:#555;background-color:#fff;border-bottom:1px solid #eee}#customize-theme-controls .accordion-section-content{color:#555;background:#fff}#customize-theme-controls .control-section .accordion-section-title:focus,#customize-theme-controls .control-section .accordion-section-title:hover,#customize-theme-controls .control-section.open .accordion-section-title,#customize-theme-controls .control-section:hover .accordion-section-title{color:#555;background:#f5f5f5}.js .control-section .accordion-section-title:focus,.js .control-section .accordion-section-title:hover,.js .control-section.open .accordion-section-title,.js .control-section:hover .accordion-section-title{background:#f5f5f5}#customize-theme-controls .control-section .accordion-section-title:focus::after,#customize-theme-controls .control-section .accordion-section-title:hover::after,#customize-theme-controls .control-section.open .accordion-section-title::after,#customize-theme-controls .control-section:hover .accordion-section-title::after{color:#555}#customize-theme-controls .control-section.open{border-bottom:1px solid #eee}#customize-theme-controls .control-section.open .accordion-section-title{border-bottom-color:#eee!important}#customize-theme-controls .control-section:last-of-type .accordion-section-title,#customize-theme-controls .control-section:last-of-type.open{border-bottom-color:#ddd}#customize-theme-controls .accordion-section-content,#customize-theme-controls>ul{margin:0}.customize-control{width:100%;float:right;clear:both;margin-bottom:8px}.customize-control input[type=checkbox],.customize-control input[type=radio],.customize-control input[type=text],.customize-control select{line-height:28px}.customize-control input[type=text]{width:98%;line-height:18px;margin:0}.customize-control select{min-width:50%;max-width:100%;height:28px;line-height:28px}.customize-control-title{display:block;font-size:14px;line-height:24px;font-weight:600;margin-bottom:5px}.customize-control-checkbox label,.customize-control-color .color-picker,.customize-control-upload div{line-height:28px}.customize-control-checkbox input{margin-left:5px}.customize-control-radio{padding:5px 0 10px}.customize-control-radio .customize-control-title{margin-bottom:0;line-height:22px}.customize-control-radio label{line-height:32px}.customize-control-radio input{margin-left:5px}#customize-preview iframe{width:100%;height:100%}.wp-full-overlay-sidebar{background:#eee;border-left:1px solid #ddd}.collapse-sidebar{background-color:transparent!important;border:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-border-radius:!important 0;border-radius:!important 0}.collapse-sidebar:active,.collapse-sidebar:active .collapse-sidebar-arrow:before,.collapse-sidebar:active .collapse-sidebar-label{text-shadow:none}.collapsed .collapse-sidebar-arrow:before{color:#888}.accordion-section .dropdown{float:right;display:block;position:relative;cursor:pointer}.accordion-section .dropdown-content{overflow:hidden;float:right;min-width:30px;height:16px;line-height:16px;margin-left:16px;padding:4px 5px;border:2px solid #eee;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.customize-control .dropdown-arrow{position:absolute;top:0;bottom:0;left:0;width:20px;background:#eee}.customize-control .dropdown-arrow:after{content:"\f140";font:400 20px/1 dashicons;speak:none;display:block;padding:0;text-indent:0;text-align:center;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#333}.customize-control .dropdown-status{color:#333;background:#eee;display:none;max-width:112px}.customize-control-color .color-picker-hex{display:none}.customize-control-color.open .color-picker-hex{display:block}.customize-control-color .dropdown{margin-left:5px;margin-bottom:5px}.customize-control-color .dropdown .dropdown-content{background-color:#555;border:1px solid rgba(0,0,0,.15)}.customize-control-color .dropdown:hover .dropdown-content{border-color:rgba(0,0,0,.25)}.customize-control-image .actions,.customize-control-image .library{display:none;float:right;width:100%}.customize-control-image.open .actions,.customize-control-image.open .library{display:block}.accordion-section .customize-control-image .dropdown-content{height:auto;min-height:24px;min-width:40px;padding:0}.accordion-section .customize-control-image .dropdown-status{padding:4px 5px}.accordion-section .customize-control-image .preview-thumbnail img{display:block;width:100%;max-width:122px;max-height:98px;margin:0 auto}.accordion-section .customize-control-image .actions{text-align:left}.accordion-section .customize-control-image .library ul{border-bottom:1px solid #ddd;float:right;width:100%;margin:10px 0 0}.accordion-section .customize-control-image .library li{color:#ccc;float:right;padding:3px 15px;margin:0;border:1px solid transparent}.accordion-section .customize-control-image .library li.library-selected{margin-bottom:-1px;padding-bottom:4px;color:#666;border-color:#ddd;border-bottom-color:#fff}.accordion-section .customize-control-image .library .thumbnail{display:block;width:100%}.accordion-section .customize-control-image .library .thumbnail img{display:block;max-width:90%;max-height:80px;margin:5px auto;padding:2px;background:#666}.accordion-section .customize-control-image .library .thumbnail:hover img{background-color:#2ea2cc}.accordion-section .customize-control-image .library-content{display:none;width:100%;float:right;padding:10px 0}.accordion-section .customize-control-image .library-content.library-selected{display:block}.accordion-section .customize-control-image .upload-fallback,.accordion-section .customize-control-upload .upload-fallback{display:none}.accordion-section .customize-control-image .upload-dropzone,.accordion-section .customize-control-upload .upload-dropzone{display:none;padding:15px 10px;border:3px dashed #dfdfdf;margin:5px auto;text-align:center;position:relative;cursor:default}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop{display:block;-webkit-transition:border-color .1s;transition:border-color .1s}.accordion-section .customize-control-image .library ul li,.accordion-section .customize-control-upload .library ul li{cursor:pointer}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop.drag-over,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop.drag-over{border-color:#83b4d8}.ios #customize-preview,.ios .wp-full-overlay{position:relative}.ios #customize-controls .wp-full-overlay-sidebar-content{-webkit-overflow-scrolling:touch}body.cheatin{min-width:0;background:#f9f9f9;padding:50px}body.cheatin p{max-width:700px;margin:0 auto;padding:2em;font-size:14px;background:#555;border:1px solid #dfdfdf;-webkit-border-radius:3px;border-radius:3px} \ No newline at end of file +body{overflow:hidden}#customize-controls a{text-decoration:none}#customize-controls h3{font-size:14px}#customize-controls .submit{text-align:center}#customize-controls .description{color:#666}#customize-header-actions .button-primary{float:left;margin-top:9px}#customize-header-actions .spinner{margin-top:16px;margin-left:4px}.saving #customize-header-actions .spinner{display:block}#customize-info{border:0;border-top:1px solid #ddd}#customize-info .accordion-section-title{background-color:#fff;color:#666;border-right:0;border-left:0;border-bottom:1px solid #eee}#customize-info .accordion-section-title:focus,#customize-info .accordion-section-title:focus:after,#customize-info .accordion-section-title:hover,#customize-info .accordion-section-title:hover:after,#customize-info.open .accordion-section-title,#customize-info.open .accordion-section-title:after{color:#555}#customize-info.open .accordion-section-title{border-color:transparent}#customize-info .preview-notice{font-size:13px;line-height:24px}#customize-info .theme-name{font-size:20px;font-weight:200;line-height:24px;display:block}#customize-info .theme-screenshot{width:258px}#customize-info .theme-description{margin-top:1em;color:#666;line-height:20px}#customize-theme-controls{-webkit-box-shadow:0 1px 1px -1px rgba(0,0,0,.1);box-shadow:0 1px 1px -1px rgba(0,0,0,.1)}#customize-theme-controls .control-section{border:0}#customize-theme-controls .accordion-section-title{color:#555;background-color:#fff;border-bottom:1px solid #eee}#customize-theme-controls .accordion-section-content{color:#555;background:#fff}#customize-theme-controls .control-section .accordion-section-title:focus,#customize-theme-controls .control-section .accordion-section-title:hover,#customize-theme-controls .control-section.open .accordion-section-title,#customize-theme-controls .control-section:hover .accordion-section-title{color:#555;background:#f5f5f5}.js .control-section .accordion-section-title:focus,.js .control-section .accordion-section-title:hover,.js .control-section.open .accordion-section-title,.js .control-section:hover .accordion-section-title{background:#f5f5f5}#customize-theme-controls .control-section .accordion-section-title:focus::after,#customize-theme-controls .control-section .accordion-section-title:hover::after,#customize-theme-controls .control-section.open .accordion-section-title::after,#customize-theme-controls .control-section:hover .accordion-section-title::after{color:#555}#customize-theme-controls .control-section.open{border-bottom:1px solid #eee}#customize-theme-controls .control-section.open .accordion-section-title{border-bottom-color:#eee!important}#customize-theme-controls .control-section:last-of-type .accordion-section-title,#customize-theme-controls .control-section:last-of-type.open{border-bottom-color:#ddd}#customize-theme-controls .accordion-section-content,#customize-theme-controls>ul{margin:0}.customize-control{width:100%;float:right;clear:both;margin-bottom:8px}.customize-control input[type=checkbox],.customize-control input[type=radio],.customize-control input[type=text],.customize-control select{line-height:28px}.customize-control input[type=text]{width:98%;line-height:18px;margin:0}.customize-control select{min-width:50%;max-width:100%;height:28px;line-height:28px}.customize-control-title{display:block;font-size:14px;line-height:24px;font-weight:600;margin-bottom:5px}.customize-control-checkbox label,.customize-control-color .color-picker,.customize-control-upload div{line-height:28px}.customize-control-checkbox input{margin-left:5px}.customize-control-radio{padding:5px 0 10px}.customize-control-radio .customize-control-title{margin-bottom:0;line-height:22px}.customize-control-radio label{line-height:32px}.customize-control-radio input{margin-left:5px}#customize-preview iframe{width:100%;height:100%}.wp-full-overlay-sidebar{background:#eee;border-left:1px solid #ddd}.collapse-sidebar{background-color:transparent!important;border:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-border-radius:!important 0;border-radius:!important 0}.collapse-sidebar:active,.collapse-sidebar:active .collapse-sidebar-arrow:before,.collapse-sidebar:active .collapse-sidebar-label{text-shadow:none}.collapsed .collapse-sidebar-arrow:before{color:#888}.accordion-section .dropdown{float:right;display:block;position:relative;cursor:pointer}.accordion-section .dropdown-content{overflow:hidden;float:right;min-width:30px;height:16px;line-height:16px;margin-left:16px;padding:4px 5px;border:2px solid #eee;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.customize-control .dropdown-arrow{position:absolute;top:0;bottom:0;left:0;width:20px;background:#eee}.customize-control .dropdown-arrow:after{content:"\f140";font:400 20px/1 dashicons;speak:none;display:block;padding:0;text-indent:0;text-align:center;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#333}.customize-control .dropdown-status{color:#333;background:#eee;display:none;max-width:112px}.customize-control-color .color-picker-hex{display:none}.customize-control-color.open .color-picker-hex{display:block}.customize-control-color .dropdown{margin-left:5px;margin-bottom:5px}.customize-control-color .dropdown .dropdown-content{background-color:#555;border:1px solid rgba(0,0,0,.15)}.customize-control-color .dropdown:hover .dropdown-content{border-color:rgba(0,0,0,.25)}.customize-control-image .actions,.customize-control-image .library{display:none;float:right;width:100%}.customize-control-image.open .actions,.customize-control-image.open .library{display:block}.accordion-section .customize-control-image .dropdown-content{height:auto;min-height:24px;min-width:40px;padding:0}.accordion-section .customize-control-image .dropdown-status{padding:4px 5px}.accordion-section .customize-control-image .preview-thumbnail img{display:block;width:100%;max-width:122px;max-height:98px;margin:0 auto}.accordion-section .customize-control-image .actions{text-align:left}.accordion-section .customize-control-image .library ul{border-bottom:1px solid #ddd;float:right;width:100%;margin:10px 0 0}.accordion-section .customize-control-image .library li{color:#ccc;float:right;padding:3px 15px;margin:0;border:1px solid transparent}.accordion-section .customize-control-image .library li.library-selected{margin-bottom:-1px;padding-bottom:4px;color:#666;border-color:#ddd;border-bottom-color:#fff}.accordion-section .customize-control-image .library .thumbnail{display:block;width:100%}.accordion-section .customize-control-image .library .thumbnail img{display:block;max-width:90%;max-height:80px;margin:5px auto;padding:2px;background:#666}.accordion-section .customize-control-image .library .thumbnail:hover img{background-color:#2ea2cc}.accordion-section .customize-control-image .library-content{display:none;width:100%;float:right;padding:10px 0}.accordion-section .customize-control-image .library-content.library-selected{display:block}.accordion-section .customize-control-image .upload-fallback,.accordion-section .customize-control-upload .upload-fallback{display:none}.accordion-section .customize-control-image .upload-dropzone,.accordion-section .customize-control-upload .upload-dropzone{display:none;padding:15px 10px;border:3px dashed #dfdfdf;margin:5px auto;text-align:center;position:relative;cursor:default}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop{display:block;-webkit-transition:border-color .1s;transition:border-color .1s}.accordion-section .customize-control-image .library ul li,.accordion-section .customize-control-upload .library ul li{cursor:pointer}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop.drag-over,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop.drag-over{border-color:#83b4d8}.ios #customize-preview,.ios .wp-full-overlay{position:relative}.ios #customize-controls .wp-full-overlay-sidebar-content{-webkit-overflow-scrolling:touch}#customize-control-header_image .current{margin-bottom:8px}#customize-control-header_image .uploaded{margin-bottom:18px}#customize-control-header_image .current .container{overflow:hidden;border-radius:2px}#customize-control-header_image .placeholder{width:100%;position:relative;background:#262626;text-align:center;cursor:default}#customize-control-header_image .inner{display:none;position:absolute;width:100%;height:18px;margin-top:-9px;top:50%;color:#eee}#customize-control-header_image .header-view{position:relative}#customize-control-header_image .uploaded .header-view .close{font-size:2em;color:grey;position:absolute;visibility:hidden;top:10px;left:10px;z-index:1;width:20px;height:20px;cursor:pointer}#customize-control-header_image .uploaded .header-view .close:hover{color:#000;text-shadow:-1px -1px 0 #fff,1px -1px 0 #fff,-1px 1px 0 #fff,1px 1px 0 #fff}#customize-control-header_image .header-view:hover .close{visibility:visible}#customize-control-header_image .random.placeholder{cursor:pointer;border-radius:2px;height:40px}#customize-control-header_image .random .inner{display:block}#customize-control-header_image .dice{font-size:16px;vertical-align:-1px}#customize-control-header_image .placeholder:hover .dice{-webkit-animation:dice-color-change 3s infinite;-moz-animation:dice-color-change 3s infinite;-ms-animation:dice-color-change 3s infinite;animation:dice-color-change 3s infinite}@-webkit-keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}@-moz-keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}@-ms-keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}@keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}#customize-control-header_image .actions{margin-bottom:32px}#customize-control-header_image .choice{position:relative;display:block;margin-bottom:9px}#customize-control-header_image .choice.random:before{position:absolute;content:attr(data-label);right:0;top:0}#customize-control-header_image .uploaded div:last-child>.choice{margin-bottom:0}#customize-control-header_image .choices hr{visibility:hidden}#customize-control-header_image img{width:100%;border-radius:2px}#customize-control-header_image .remove{float:right;margin-left:3px}#customize-control-header_image .new{float:left}body.cheatin{min-width:0;background:#f9f9f9;padding:50px}body.cheatin p{max-width:700px;margin:0 auto;padding:2em;font-size:14px;background:#555;border:1px solid #dfdfdf;-webkit-border-radius:3px;border-radius:3px} \ No newline at end of file diff --git a/wp-admin/css/customize-controls.css b/wp-admin/css/customize-controls.css index c76a6e5fa3..448f1b5593 100644 --- a/wp-admin/css/customize-controls.css +++ b/wp-admin/css/customize-controls.css @@ -455,6 +455,167 @@ body { -webkit-overflow-scrolling: touch; } +/** Header control **/ + +#customize-control-header_image .current { + margin-bottom: 8px; +} + +#customize-control-header_image .uploaded { + margin-bottom: 18px; +} + +/* Header control: current image container */ + +#customize-control-header_image .current .container { + overflow: hidden; + border-radius: 2px; +} + +#customize-control-header_image .placeholder { + width: 100%; + position: relative; + background: #262626; + text-align: center; + cursor: default; +} + +#customize-control-header_image .inner { + display: none; + position: absolute; + width: 100%; + height: 18px; + margin-top: -9px; + top: 50%; + color: #eee; +} + +/* Header control: overlay "close" button */ + +#customize-control-header_image .header-view { + position: relative; +} + +#customize-control-header_image .uploaded .header-view .close { + font-size: 2em; + color: grey; + position: absolute; + visibility: hidden; + top: 10px; + right: 10px; + z-index: 1; + width: 20px; + height: 20px; + cursor: pointer; +} + +#customize-control-header_image .uploaded .header-view .close:hover { + color: black; + text-shadow: + -1px -1px 0 #fff, + 1px -1px 0 #fff, + -1px 1px 0 #fff, + 1px 1px 0 #fff; +} + +#customize-control-header_image .header-view:hover .close { + visibility: visible; +} + +/* Header control: randomiz(s)er */ + +#customize-control-header_image .random.placeholder { + cursor: pointer; + border-radius: 2px; + height: 40px; +} + +#customize-control-header_image .random .inner { + display: block; +} + +#customize-control-header_image .dice { + font-size: 16px; + vertical-align: -1px; +} + +#customize-control-header_image .placeholder:hover .dice { + -webkit-animation: dice-color-change 3s infinite; + -moz-animation: dice-color-change 3s infinite; + -ms-animation: dice-color-change 3s infinite; + animation: dice-color-change 3s infinite; +} + +@-webkit-keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +@-moz-keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +@-ms-keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +@keyframes dice-color-change { + 0% { color: #d4b146; } + 50% { color: #ef54b0; } + 75% { color: #7190d3; } + 100% { color: #d4b146; } +} + +/* Header control: actions and choices */ + +#customize-control-header_image .actions { + margin-bottom: 32px; +} + +#customize-control-header_image .choice { + position: relative; + display: block; + margin-bottom: 9px; +} + +#customize-control-header_image .choice.random:before { + position: absolute; + content: attr(data-label); + left: 0; + top: 0; +} + +#customize-control-header_image .uploaded div:last-child > .choice { + margin-bottom: 0; +} + +#customize-control-header_image .choices hr { + visibility: hidden; +} + +#customize-control-header_image img { + width: 100%; + border-radius: 2px; +} + +#customize-control-header_image .remove { + float: left; + margin-right: 3px; +} + +#customize-control-header_image .new { + float: right; +} + + /** Handle cheaters. */ body.cheatin { min-width: 0; diff --git a/wp-admin/css/customize-controls.min.css b/wp-admin/css/customize-controls.min.css index d60d73cb73..3c7e41cd5b 100644 --- a/wp-admin/css/customize-controls.min.css +++ b/wp-admin/css/customize-controls.min.css @@ -1 +1 @@ -body{overflow:hidden}#customize-controls a{text-decoration:none}#customize-controls h3{font-size:14px}#customize-controls .submit{text-align:center}#customize-controls .description{color:#666}#customize-header-actions .button-primary{float:right;margin-top:9px}#customize-header-actions .spinner{margin-top:16px;margin-right:4px}.saving #customize-header-actions .spinner{display:block}#customize-info{border:0;border-top:1px solid #ddd}#customize-info .accordion-section-title{background-color:#fff;color:#666;border-left:0;border-right:0;border-bottom:1px solid #eee}#customize-info .accordion-section-title:focus,#customize-info .accordion-section-title:focus:after,#customize-info .accordion-section-title:hover,#customize-info .accordion-section-title:hover:after,#customize-info.open .accordion-section-title,#customize-info.open .accordion-section-title:after{color:#555}#customize-info.open .accordion-section-title{border-color:transparent}#customize-info .preview-notice{font-size:13px;line-height:24px}#customize-info .theme-name{font-size:20px;font-weight:200;line-height:24px;display:block}#customize-info .theme-screenshot{width:258px}#customize-info .theme-description{margin-top:1em;color:#666;line-height:20px}#customize-theme-controls{-webkit-box-shadow:0 1px 1px -1px rgba(0,0,0,.1);box-shadow:0 1px 1px -1px rgba(0,0,0,.1)}#customize-theme-controls .control-section{border:0}#customize-theme-controls .accordion-section-title{color:#555;background-color:#fff;border-bottom:1px solid #eee}#customize-theme-controls .accordion-section-content{color:#555;background:#fff}#customize-theme-controls .control-section .accordion-section-title:focus,#customize-theme-controls .control-section .accordion-section-title:hover,#customize-theme-controls .control-section.open .accordion-section-title,#customize-theme-controls .control-section:hover .accordion-section-title{color:#555;background:#f5f5f5}.js .control-section .accordion-section-title:focus,.js .control-section .accordion-section-title:hover,.js .control-section.open .accordion-section-title,.js .control-section:hover .accordion-section-title{background:#f5f5f5}#customize-theme-controls .control-section .accordion-section-title:focus::after,#customize-theme-controls .control-section .accordion-section-title:hover::after,#customize-theme-controls .control-section.open .accordion-section-title::after,#customize-theme-controls .control-section:hover .accordion-section-title::after{color:#555}#customize-theme-controls .control-section.open{border-bottom:1px solid #eee}#customize-theme-controls .control-section.open .accordion-section-title{border-bottom-color:#eee!important}#customize-theme-controls .control-section:last-of-type .accordion-section-title,#customize-theme-controls .control-section:last-of-type.open{border-bottom-color:#ddd}#customize-theme-controls .accordion-section-content,#customize-theme-controls>ul{margin:0}.customize-control{width:100%;float:left;clear:both;margin-bottom:8px}.customize-control input[type=checkbox],.customize-control input[type=radio],.customize-control input[type=text],.customize-control select{line-height:28px}.customize-control input[type=text]{width:98%;line-height:18px;margin:0}.customize-control select{min-width:50%;max-width:100%;height:28px;line-height:28px}.customize-control-title{display:block;font-size:14px;line-height:24px;font-weight:600;margin-bottom:5px}.customize-control-checkbox label,.customize-control-color .color-picker,.customize-control-upload div{line-height:28px}.customize-control-checkbox input{margin-right:5px}.customize-control-radio{padding:5px 0 10px}.customize-control-radio .customize-control-title{margin-bottom:0;line-height:22px}.customize-control-radio label{line-height:32px}.customize-control-radio input{margin-right:5px}#customize-preview iframe{width:100%;height:100%}.wp-full-overlay-sidebar{background:#eee;border-right:1px solid #ddd}.collapse-sidebar{background-color:transparent!important;border:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-border-radius:0!important;border-radius:0!important}.collapse-sidebar:active,.collapse-sidebar:active .collapse-sidebar-arrow:before,.collapse-sidebar:active .collapse-sidebar-label{text-shadow:none}.collapsed .collapse-sidebar-arrow:before{color:#888}.accordion-section .dropdown{float:left;display:block;position:relative;cursor:pointer}.accordion-section .dropdown-content{overflow:hidden;float:left;min-width:30px;height:16px;line-height:16px;margin-right:16px;padding:4px 5px;border:2px solid #eee;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.customize-control .dropdown-arrow{position:absolute;top:0;bottom:0;right:0;width:20px;background:#eee}.customize-control .dropdown-arrow:after{content:"\f140";font:400 20px/1 dashicons;speak:none;display:block;padding:0;text-indent:0;text-align:center;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#333}.customize-control .dropdown-status{color:#333;background:#eee;display:none;max-width:112px}.customize-control-color .color-picker-hex{display:none}.customize-control-color.open .color-picker-hex{display:block}.customize-control-color .dropdown{margin-right:5px;margin-bottom:5px}.customize-control-color .dropdown .dropdown-content{background-color:#555;border:1px solid rgba(0,0,0,.15)}.customize-control-color .dropdown:hover .dropdown-content{border-color:rgba(0,0,0,.25)}.customize-control-image .actions,.customize-control-image .library{display:none;float:left;width:100%}.customize-control-image.open .actions,.customize-control-image.open .library{display:block}.accordion-section .customize-control-image .dropdown-content{height:auto;min-height:24px;min-width:40px;padding:0}.accordion-section .customize-control-image .dropdown-status{padding:4px 5px}.accordion-section .customize-control-image .preview-thumbnail img{display:block;width:100%;max-width:122px;max-height:98px;margin:0 auto}.accordion-section .customize-control-image .actions{text-align:right}.accordion-section .customize-control-image .library ul{border-bottom:1px solid #ddd;float:left;width:100%;margin:10px 0 0}.accordion-section .customize-control-image .library li{color:#ccc;float:left;padding:3px 15px;margin:0;border:1px solid transparent}.accordion-section .customize-control-image .library li.library-selected{margin-bottom:-1px;padding-bottom:4px;color:#666;border-color:#ddd;border-bottom-color:#fff}.accordion-section .customize-control-image .library .thumbnail{display:block;width:100%}.accordion-section .customize-control-image .library .thumbnail img{display:block;max-width:90%;max-height:80px;margin:5px auto;padding:2px;background:#666}.accordion-section .customize-control-image .library .thumbnail:hover img{background-color:#2ea2cc}.accordion-section .customize-control-image .library-content{display:none;width:100%;float:left;padding:10px 0}.accordion-section .customize-control-image .library-content.library-selected{display:block}.accordion-section .customize-control-image .upload-fallback,.accordion-section .customize-control-upload .upload-fallback{display:none}.accordion-section .customize-control-image .upload-dropzone,.accordion-section .customize-control-upload .upload-dropzone{display:none;padding:15px 10px;border:3px dashed #dfdfdf;margin:5px auto;text-align:center;position:relative;cursor:default}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop{display:block;-webkit-transition:border-color .1s;transition:border-color .1s}.accordion-section .customize-control-image .library ul li,.accordion-section .customize-control-upload .library ul li{cursor:pointer}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop.drag-over,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop.drag-over{border-color:#83b4d8}.ios #customize-preview,.ios .wp-full-overlay{position:relative}.ios #customize-controls .wp-full-overlay-sidebar-content{-webkit-overflow-scrolling:touch}body.cheatin{min-width:0;background:#f9f9f9;padding:50px}body.cheatin p{max-width:700px;margin:0 auto;padding:2em;font-size:14px;background:#555;border:1px solid #dfdfdf;-webkit-border-radius:3px;border-radius:3px} \ No newline at end of file +body{overflow:hidden}#customize-controls a{text-decoration:none}#customize-controls h3{font-size:14px}#customize-controls .submit{text-align:center}#customize-controls .description{color:#666}#customize-header-actions .button-primary{float:right;margin-top:9px}#customize-header-actions .spinner{margin-top:16px;margin-right:4px}.saving #customize-header-actions .spinner{display:block}#customize-info{border:0;border-top:1px solid #ddd}#customize-info .accordion-section-title{background-color:#fff;color:#666;border-left:0;border-right:0;border-bottom:1px solid #eee}#customize-info .accordion-section-title:focus,#customize-info .accordion-section-title:focus:after,#customize-info .accordion-section-title:hover,#customize-info .accordion-section-title:hover:after,#customize-info.open .accordion-section-title,#customize-info.open .accordion-section-title:after{color:#555}#customize-info.open .accordion-section-title{border-color:transparent}#customize-info .preview-notice{font-size:13px;line-height:24px}#customize-info .theme-name{font-size:20px;font-weight:200;line-height:24px;display:block}#customize-info .theme-screenshot{width:258px}#customize-info .theme-description{margin-top:1em;color:#666;line-height:20px}#customize-theme-controls{-webkit-box-shadow:0 1px 1px -1px rgba(0,0,0,.1);box-shadow:0 1px 1px -1px rgba(0,0,0,.1)}#customize-theme-controls .control-section{border:0}#customize-theme-controls .accordion-section-title{color:#555;background-color:#fff;border-bottom:1px solid #eee}#customize-theme-controls .accordion-section-content{color:#555;background:#fff}#customize-theme-controls .control-section .accordion-section-title:focus,#customize-theme-controls .control-section .accordion-section-title:hover,#customize-theme-controls .control-section.open .accordion-section-title,#customize-theme-controls .control-section:hover .accordion-section-title{color:#555;background:#f5f5f5}.js .control-section .accordion-section-title:focus,.js .control-section .accordion-section-title:hover,.js .control-section.open .accordion-section-title,.js .control-section:hover .accordion-section-title{background:#f5f5f5}#customize-theme-controls .control-section .accordion-section-title:focus::after,#customize-theme-controls .control-section .accordion-section-title:hover::after,#customize-theme-controls .control-section.open .accordion-section-title::after,#customize-theme-controls .control-section:hover .accordion-section-title::after{color:#555}#customize-theme-controls .control-section.open{border-bottom:1px solid #eee}#customize-theme-controls .control-section.open .accordion-section-title{border-bottom-color:#eee!important}#customize-theme-controls .control-section:last-of-type .accordion-section-title,#customize-theme-controls .control-section:last-of-type.open{border-bottom-color:#ddd}#customize-theme-controls .accordion-section-content,#customize-theme-controls>ul{margin:0}.customize-control{width:100%;float:left;clear:both;margin-bottom:8px}.customize-control input[type=checkbox],.customize-control input[type=radio],.customize-control input[type=text],.customize-control select{line-height:28px}.customize-control input[type=text]{width:98%;line-height:18px;margin:0}.customize-control select{min-width:50%;max-width:100%;height:28px;line-height:28px}.customize-control-title{display:block;font-size:14px;line-height:24px;font-weight:600;margin-bottom:5px}.customize-control-checkbox label,.customize-control-color .color-picker,.customize-control-upload div{line-height:28px}.customize-control-checkbox input{margin-right:5px}.customize-control-radio{padding:5px 0 10px}.customize-control-radio .customize-control-title{margin-bottom:0;line-height:22px}.customize-control-radio label{line-height:32px}.customize-control-radio input{margin-right:5px}#customize-preview iframe{width:100%;height:100%}.wp-full-overlay-sidebar{background:#eee;border-right:1px solid #ddd}.collapse-sidebar{background-color:transparent!important;border:0!important;-webkit-box-shadow:none!important;box-shadow:none!important;-webkit-border-radius:0!important;border-radius:0!important}.collapse-sidebar:active,.collapse-sidebar:active .collapse-sidebar-arrow:before,.collapse-sidebar:active .collapse-sidebar-label{text-shadow:none}.collapsed .collapse-sidebar-arrow:before{color:#888}.accordion-section .dropdown{float:left;display:block;position:relative;cursor:pointer}.accordion-section .dropdown-content{overflow:hidden;float:left;min-width:30px;height:16px;line-height:16px;margin-right:16px;padding:4px 5px;border:2px solid #eee;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.customize-control .dropdown-arrow{position:absolute;top:0;bottom:0;right:0;width:20px;background:#eee}.customize-control .dropdown-arrow:after{content:"\f140";font:400 20px/1 dashicons;speak:none;display:block;padding:0;text-indent:0;text-align:center;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#333}.customize-control .dropdown-status{color:#333;background:#eee;display:none;max-width:112px}.customize-control-color .color-picker-hex{display:none}.customize-control-color.open .color-picker-hex{display:block}.customize-control-color .dropdown{margin-right:5px;margin-bottom:5px}.customize-control-color .dropdown .dropdown-content{background-color:#555;border:1px solid rgba(0,0,0,.15)}.customize-control-color .dropdown:hover .dropdown-content{border-color:rgba(0,0,0,.25)}.customize-control-image .actions,.customize-control-image .library{display:none;float:left;width:100%}.customize-control-image.open .actions,.customize-control-image.open .library{display:block}.accordion-section .customize-control-image .dropdown-content{height:auto;min-height:24px;min-width:40px;padding:0}.accordion-section .customize-control-image .dropdown-status{padding:4px 5px}.accordion-section .customize-control-image .preview-thumbnail img{display:block;width:100%;max-width:122px;max-height:98px;margin:0 auto}.accordion-section .customize-control-image .actions{text-align:right}.accordion-section .customize-control-image .library ul{border-bottom:1px solid #ddd;float:left;width:100%;margin:10px 0 0}.accordion-section .customize-control-image .library li{color:#ccc;float:left;padding:3px 15px;margin:0;border:1px solid transparent}.accordion-section .customize-control-image .library li.library-selected{margin-bottom:-1px;padding-bottom:4px;color:#666;border-color:#ddd;border-bottom-color:#fff}.accordion-section .customize-control-image .library .thumbnail{display:block;width:100%}.accordion-section .customize-control-image .library .thumbnail img{display:block;max-width:90%;max-height:80px;margin:5px auto;padding:2px;background:#666}.accordion-section .customize-control-image .library .thumbnail:hover img{background-color:#2ea2cc}.accordion-section .customize-control-image .library-content{display:none;width:100%;float:left;padding:10px 0}.accordion-section .customize-control-image .library-content.library-selected{display:block}.accordion-section .customize-control-image .upload-fallback,.accordion-section .customize-control-upload .upload-fallback{display:none}.accordion-section .customize-control-image .upload-dropzone,.accordion-section .customize-control-upload .upload-dropzone{display:none;padding:15px 10px;border:3px dashed #dfdfdf;margin:5px auto;text-align:center;position:relative;cursor:default}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop{display:block;-webkit-transition:border-color .1s;transition:border-color .1s}.accordion-section .customize-control-image .library ul li,.accordion-section .customize-control-upload .library ul li{cursor:pointer}.accordion-section .customize-control-image .upload-dropzone.supports-drag-drop.drag-over,.accordion-section .customize-control-upload .upload-dropzone.supports-drag-drop.drag-over{border-color:#83b4d8}.ios #customize-preview,.ios .wp-full-overlay{position:relative}.ios #customize-controls .wp-full-overlay-sidebar-content{-webkit-overflow-scrolling:touch}#customize-control-header_image .current{margin-bottom:8px}#customize-control-header_image .uploaded{margin-bottom:18px}#customize-control-header_image .current .container{overflow:hidden;border-radius:2px}#customize-control-header_image .placeholder{width:100%;position:relative;background:#262626;text-align:center;cursor:default}#customize-control-header_image .inner{display:none;position:absolute;width:100%;height:18px;margin-top:-9px;top:50%;color:#eee}#customize-control-header_image .header-view{position:relative}#customize-control-header_image .uploaded .header-view .close{font-size:2em;color:grey;position:absolute;visibility:hidden;top:10px;right:10px;z-index:1;width:20px;height:20px;cursor:pointer}#customize-control-header_image .uploaded .header-view .close:hover{color:#000;text-shadow:-1px -1px 0 #fff,1px -1px 0 #fff,-1px 1px 0 #fff,1px 1px 0 #fff}#customize-control-header_image .header-view:hover .close{visibility:visible}#customize-control-header_image .random.placeholder{cursor:pointer;border-radius:2px;height:40px}#customize-control-header_image .random .inner{display:block}#customize-control-header_image .dice{font-size:16px;vertical-align:-1px}#customize-control-header_image .placeholder:hover .dice{-webkit-animation:dice-color-change 3s infinite;-moz-animation:dice-color-change 3s infinite;-ms-animation:dice-color-change 3s infinite;animation:dice-color-change 3s infinite}@-webkit-keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}@-moz-keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}@-ms-keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}@keyframes dice-color-change{0%{color:#d4b146}50%{color:#ef54b0}75%{color:#7190d3}100%{color:#d4b146}}#customize-control-header_image .actions{margin-bottom:32px}#customize-control-header_image .choice{position:relative;display:block;margin-bottom:9px}#customize-control-header_image .choice.random:before{position:absolute;content:attr(data-label);left:0;top:0}#customize-control-header_image .uploaded div:last-child>.choice{margin-bottom:0}#customize-control-header_image .choices hr{visibility:hidden}#customize-control-header_image img{width:100%;border-radius:2px}#customize-control-header_image .remove{float:left;margin-right:3px}#customize-control-header_image .new{float:right}body.cheatin{min-width:0;background:#f9f9f9;padding:50px}body.cheatin p{max-width:700px;margin:0 auto;padding:2em;font-size:14px;background:#555;border:1px solid #dfdfdf;-webkit-border-radius:3px;border-radius:3px} \ No newline at end of file diff --git a/wp-admin/custom-header.php b/wp-admin/custom-header.php index 1a3db1a4a5..07c5dd8101 100644 --- a/wp-admin/custom-header.php +++ b/wp-admin/custom-header.php @@ -43,7 +43,7 @@ class Custom_Image_Header { var $default_headers = array(); /** - * Holds custom headers uploaded by the user + * Holds custom headers uploaded by the user. * * @var array * @since 3.2.0 @@ -73,6 +73,11 @@ class Custom_Image_Header { $this->admin_image_div_callback = $admin_image_div_callback; add_action( 'admin_menu', array( $this, 'init' ) ); + + add_action( 'customize_save_after', array( $this, 'customize_set_last_used' ) ); + add_action( 'wp_ajax_custom-header-crop', array( $this, 'ajax_header_crop' ) ); + add_action( 'wp_ajax_custom-header-add', array( $this, 'ajax_header_add' ) ); + add_action( 'wp_ajax_custom-header-remove', array( $this, 'ajax_header_remove' ) ); } /** @@ -93,6 +98,7 @@ class Custom_Image_Header { add_action("admin_head-$page", array($this, 'js'), 50); if ( $this->admin_header_callback ) add_action("admin_head-$page", $this->admin_header_callback, 51); + } /** @@ -819,32 +825,15 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> $attachment_id = absint( $_POST['attachment_id'] ); $original = get_attached_file($attachment_id); - - $max_width = 0; - // For flex, limit size of image displayed to 1500px unless theme says otherwise - if ( current_theme_supports( 'custom-header', 'flex-width' ) ) - $max_width = 1500; - - if ( current_theme_supports( 'custom-header', 'max-width' ) ) - $max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) ); - $max_width = max( $max_width, get_theme_support( 'custom-header', 'width' ) ); - - if ( ( current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) || $_POST['width'] > $max_width ) - $dst_height = absint( $_POST['height'] * ( $max_width / $_POST['width'] ) ); - elseif ( current_theme_supports( 'custom-header', 'flex-height' ) && current_theme_supports( 'custom-header', 'flex-width' ) ) - $dst_height = absint( $_POST['height'] ); - else - $dst_height = get_theme_support( 'custom-header', 'height' ); - - if ( ( current_theme_supports( 'custom-header', 'flex-width' ) && ! current_theme_supports( 'custom-header', 'flex-height' ) ) || $_POST['width'] > $max_width ) - $dst_width = absint( $_POST['width'] * ( $max_width / $_POST['width'] ) ); - elseif ( current_theme_supports( 'custom-header', 'flex-width' ) && current_theme_supports( 'custom-header', 'flex-height' ) ) - $dst_width = absint( $_POST['width'] ); - else - $dst_width = get_theme_support( 'custom-header', 'width' ); + $dimensions = $this->get_header_dimensions( array( + 'height' => $_POST['height'], + 'width' => $_POST['width'], + ) ); + $height = $dimensions['dst_height']; + $width = $dimensions['dst_width']; if ( empty( $_POST['skip-cropping'] ) ) - $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $dst_width, $dst_height ); + $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $width, $height ); elseif ( ! empty( $_POST['create-new-attachment'] ) ) $cropped = _copy_image_file( $attachment_id ); else @@ -856,31 +845,15 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> /** This filter is documented in wp-admin/custom-header.php */ $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication - $parent = get_post($attachment_id); - $parent_url = $parent->guid; - $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url ); + $object = $this->create_attachment_object( $cropped, $attachment_id ); - $size = @getimagesize( $cropped ); - $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; - - // Construct the object array - $object = array( - 'ID' => $attachment_id, - 'post_title' => basename($cropped), - 'post_content' => $url, - 'post_mime_type' => $image_type, - 'guid' => $url, - 'context' => 'custom-header' - ); if ( ! empty( $_POST['create-new-attachment'] ) ) unset( $object['ID'] ); // Update the attachment - $attachment_id = wp_insert_attachment( $object, $cropped ); - wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $cropped ) ); + $attachment_id = $this->insert_attachment( $object, $cropped ); - $width = $dst_width; - $height = $dst_height; + $url = $object['guid']; $this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) ); // cleanup @@ -1041,4 +1014,218 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> set_theme_mod( 'header_image', $default ); set_theme_mod( 'header_image_data', (object) $default_data ); } + + /** + * Calculate width and height based on what the currently selected theme supports. + * + * @return array dst_height and dst_width of header image. + */ + final public function get_header_dimensions( $dimensions ) { + $max_width = 0; + $width = absint( $dimensions['width'] ); + $height = absint( $dimensions['height'] ); + $theme_height = get_theme_support( 'custom-header', 'height' ); + $theme_width = get_theme_support( 'custom-header', 'width' ); + $has_flex_width = current_theme_supports( 'custom-header', 'flex-width' ); + $has_flex_height = current_theme_supports( 'custom-header', 'flex-height' ); + $has_max_width = current_theme_supports( 'custom-header', 'max-width' ) ; + $dst = array( 'dst_height' => null, 'dst_height' => null ); + + // For flex, limit size of image displayed to 1500px unless theme says otherwise + if ( $has_flex_width ) { + $max_width = 1500; + } + + if ( $has_max_width ) { + $max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) ); + } + $max_width = max( $max_width, $theme_width ); + + if ( $has_flex_height && ( ! $has_flex_width || $width > $max_width ) ) { + $dst['dst_height'] = absint( $height * ( $max_width / $width ) ); + } + elseif ( $has_flex_height && $has_flex_width ) { + $dst['dst_height'] = $height; + } + else { + $dst['dst_height'] = $theme_height; + } + + if ( $has_flex_width && ( ! $has_flex_height || $width > $max_width ) ) { + $dst['dst_width'] = absint( $width * ( $max_width / $width ) ); + } + elseif ( $has_flex_width && $has_flex_height ) { + $dst['dst_width'] = $width; + } + else { + $dst['dst_width'] = $theme_width; + } + + return $dst; + } + + /** + * Create an attachment 'object'. + * + * @param string $cropped Cropped image URL. + * @param int $parent_attachment_id Attachment ID of parent image. + * + * @return array Attachment object. + */ + final public function create_attachment_object( $cropped, $parent_attachment_id ) { + $parent = get_post( $parent_attachment_id ); + $parent_url = $parent->guid; + $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url ); + + $size = @getimagesize( $cropped ); + $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; + + $object = array( + 'ID' => $parent_attachment_id, + 'post_title' => basename($cropped), + 'post_content' => $url, + 'post_mime_type' => $image_type, + 'guid' => $url, + 'context' => 'custom-header' + ); + + return $object; + } + + /** + * Insert an attachment & its metadata. + * + * @param array $object Attachment object. + * @param string $cropped Cropped image URL. + * + * @return int Attachment ID. + */ + final public function insert_attachment( $object, $cropped ) { + $attachment_id = wp_insert_attachment( $object, $cropped ); + $metadata = wp_generate_attachment_metadata( $attachment_id, $cropped ); + /** + * Allows us to insert custom meta data for an attachment. + * + */ + $metadata = apply_filters( 'wp_header_image_attachment_metadata', $metadata ); + wp_update_attachment_metadata( $attachment_id, $metadata ); + return $attachment_id; + } + + /** + * Gets attachment uploaded by Media Manager, crops it, then saves it as a + * new object. Returns JSON-encoded object details. + */ + function ajax_header_crop() { + check_ajax_referer( 'image_editor-' . $_POST['id'], 'nonce' ); + + if ( ! current_user_can( 'edit_theme_options' ) ) { + wp_send_json_error(); + } + + if ( ! current_theme_supports( 'custom-header', 'uploads' ) ) { + wp_send_json_error(); + } + + $crop_details = $_POST['cropDetails']; + + $dimensions = $this->get_header_dimensions( array( + 'height' => $crop_details['height'], + 'width' => $crop_details['width'], + ) ); + + $attachment_id = absint( $_POST['id'] ); + + $cropped = wp_crop_image( + $attachment_id, + (int) $crop_details['x1'], + (int) $crop_details['y1'], + (int) $crop_details['width'], + (int) $crop_details['height'], + (int) $dimensions['dst_width'], + (int) $dimensions['dst_height'] + ); + + if ( ! $cropped || is_wp_error( $cropped ) ) { + wp_send_json_error( array( 'message' => __( 'Image could not be processed. Please go back and try again.' ) ) ); + } + + $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication + + $object = $this->create_attachment_object( $cropped, $attachment_id ); + + unset( $object['ID'] ); + + $new_attachment_id = $this->insert_attachment( $object, $cropped ); + + $object['attachment_id'] = $new_attachment_id; + $object['width'] = $dimensions['dst_width']; + $object['height'] = $dimensions['dst_height']; + + wp_send_json_success( $object ); + } + + /** + * Given an attachment ID for a header image, updates its "last used" + * timestamp to now. + * + * Triggered when the user tries adds a new header image from the + * Media Manager, even if s/he doesn't save that change. + */ + function ajax_header_add() { + check_ajax_referer( 'header-add', 'nonce' ); + + if ( ! current_user_can( 'edit_theme_options' ) ) { + wp_send_json_error(); + } + + $attachment_id = absint( $_POST['attachment_id'] ); + if ( $attachment_id < 1 ) { + wp_send_json_error(); + } + + $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); + update_post_meta( $attachment_id, $key, time() ); + update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() ); + + wp_send_json_success(); + } + + /** + * Given an attachment ID for a header image, unsets it as a user-uploaded + * header image for the current theme. + * + * Triggered when the user clicks the overlay "X" button next to each image + * choice in the Customizer's Header tool. + */ + function ajax_header_remove() { + check_ajax_referer( 'header-remove', 'nonce' ); + + if ( ! current_user_can( 'edit_theme_options' ) ) { + wp_send_json_error(); + } + + $attachment_id = absint( $_POST['attachment_id'] ); + if ( $attachment_id < 1 ) { + wp_send_json_error(); + } + + $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); + delete_post_meta( $attachment_id, $key ); + delete_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() ); + + wp_send_json_success(); + } + + function customize_set_last_used( $wp_customize ) { + $data = $wp_customize->get_setting( 'header_image_data' )->post_value(); + + if ( ! isset( $data['attachment_id'] ) ) { + return; + } + + $attachment_id = $data['attachment_id']; + $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); + update_post_meta( $attachment_id, $key, time() ); + } } diff --git a/wp-admin/js/customize-controls.js b/wp-admin/js/customize-controls.js index 3a05ad437f..3bd7b414a1 100644 --- a/wp-admin/js/customize-controls.js +++ b/wp-admin/js/customize-controls.js @@ -1,3 +1,4 @@ +/* globals _wpCustomizeHeader, _wpMediaViewsL10n */ (function( exports, $ ){ var api = wp.customize; @@ -306,6 +307,217 @@ } }); + api.HeaderControl = api.Control.extend({ + ready: function() { + this.btnRemove = $('.actions .remove'); + this.btnNew = $('.actions .new'); + + _.bindAll(this, 'openMedia', 'removeImage'); + + this.btnNew.on( 'click', this.openMedia ); + this.btnRemove.on( 'click', this.removeImage ); + + api.HeaderTool.currentHeader = new api.HeaderTool.ImageModel(); + + new api.HeaderTool.CurrentView({ + model: api.HeaderTool.currentHeader, + el: '.current .container' + }); + + new api.HeaderTool.ChoiceListView({ + collection: api.HeaderTool.UploadsList = new api.HeaderTool.ChoiceList(), + el: '.choices .uploaded .list' + }); + + new api.HeaderTool.ChoiceListView({ + collection: api.HeaderTool.DefaultsList = new api.HeaderTool.DefaultsList(), + el: '.choices .default .list' + }); + + api.HeaderTool.combinedList = api.HeaderTool.CombinedList = new api.HeaderTool.CombinedList([ + api.HeaderTool.UploadsList, + api.HeaderTool.DefaultsList + ]); + }, + + /** + * Returns a set of options, computed from the attached image data and + * theme-specific data, to be fed to the imgAreaSelect plugin in + * wp.media.view.Cropper. + * + * @param {wp.media.model.Attachment} attachment + * @param {wp.media.controller.Cropper} controller + * @returns {Object} Options + */ + calculateImageSelectOptions: function(attachment, controller) { + var xInit = parseInt(_wpCustomizeHeader.data.width, 10), + yInit = parseInt(_wpCustomizeHeader.data.height, 10), + flexWidth = !! parseInt(_wpCustomizeHeader.data['flex-width'], 10), + flexHeight = !! parseInt(_wpCustomizeHeader.data['flex-height'], 10), + ratio, xImg, yImg, realHeight, realWidth, + imgSelectOptions; + + realWidth = attachment.get('width'); + realHeight = attachment.get('height'); + + this.headerImage = new api.HeaderTool.ImageModel(); + this.headerImage.set({ + themeWidth: xInit, + themeHeight: yInit, + themeFlexWidth: flexWidth, + themeFlexHeight: flexHeight, + imageWidth: realWidth, + imageHeight: realHeight + }); + + controller.set( 'canSkipCrop', ! this.headerImage.shouldBeCropped() ); + + ratio = xInit / yInit; + xImg = realWidth; + yImg = realHeight; + + if ( xImg / yImg > ratio ) { + yInit = yImg; + xInit = yInit * ratio; + } else { + xInit = xImg; + yInit = xInit / ratio; + } + + imgSelectOptions = { + handles: true, + keys: true, + instance: true, + persistent: true, + parent: this.$el, + imageWidth: realWidth, + imageHeight: realHeight, + x1: 0, + y1: 0, + x2: xInit, + y2: yInit + }; + + if (flexHeight === false && flexWidth === false) { + imgSelectOptions.aspectRatio = xInit + ':' + yInit; + } + if (flexHeight === false ) { + imgSelectOptions.maxHeight = yInit; + } + if (flexWidth === false ) { + imgSelectOptions.maxWidth = xInit; + } + + return imgSelectOptions; + }, + + /** + * Sets up and opens the Media Manager in order to select an image. + * Depending on both the size of the image and the properties of the + * current theme, a cropping step after selection may be required or + * skippable. + * + * @param {event} event + */ + openMedia: function(event) { + var title, suggestedWidth, suggestedHeight, + l10n = _wpMediaViewsL10n; + + event.preventDefault(); + + suggestedWidth = l10n.suggestedWidth.replace('%d', _wpCustomizeHeader.data.width); + suggestedHeight = l10n.suggestedHeight.replace('%d', _wpCustomizeHeader.data.height); + + /* '' + suggestedWidth + ' ' + suggestedHeight + '' */ + + this.frame = wp.media({ + title: l10n.chooseImage, + library: { + type: 'image' + }, + button: { + text: l10n.selectAndCrop, + close: false + }, + multiple: false, + imgSelectOptions: this.calculateImageSelectOptions + }); + + this.frame.states.add([new wp.media.controller.Cropper()]); + + this.frame.on('select', this.onSelect, this); + this.frame.on('cropped', this.onCropped, this); + this.frame.on('skippedcrop', this.onSkippedCrop, this); + + this.frame.open(); + }, + + onSelect: function() { + this.frame.setState('cropper'); + }, + onCropped: function(croppedImage) { + var url = croppedImage.post_content, + attachmentId = croppedImage.attachment_id, + w = croppedImage.width, + h = croppedImage.height; + this.setImageFromURL(url, attachmentId, w, h); + }, + onSkippedCrop: function(selection) { + var url = selection.get('url'), + w = selection.get('width'), + h = selection.get('height'); + this.setImageFromURL(url, selection.id, w, h); + }, + + /** + * Creates a new wp.customize.HeaderTool.ImageModel from provided + * header image data and inserts it into the user-uploaded headers + * collection. + * + * @param {String} url + * @param {Number} attachmentId + * @param {Number} width + * @param {Number} height + */ + setImageFromURL: function(url, attachmentId, width, height) { + var choice, data = {}; + + data.url = url; + data.thumbnail_url = url; + + if (attachmentId) { + data.attachment_id = attachmentId; + } + + if (width) { + data.width = width; + } + + if (height) { + data.height = height; + } + + choice = new api.HeaderTool.ImageModel({ + header: data, + choice: url.split('/').pop() + }); + api.HeaderTool.UploadsList.add(choice); + api.HeaderTool.currentHeader.set(choice.toJSON()); + choice.save(); + choice.importImage(); + }, + + /** + * Triggers the necessary events to deselect an image which was set as + * the currently selected one. + */ + removeImage: function() { + api.HeaderTool.currentHeader.trigger('hide'); + api.HeaderTool.CombinedList.trigger('control:removeImage'); + } + + }); + // Change objects contained within the main customize object to Settings. api.defaultConstructor = api.Setting; @@ -686,7 +898,8 @@ api.controlConstructor = { color: api.ColorControl, upload: api.UploadControl, - image: api.ImageControl + image: api.ImageControl, + header: api.HeaderControl }; $( function() { @@ -961,35 +1174,6 @@ }); }); - // Handle header image data - api.control( 'header_image', function( control ) { - control.setting.bind( function( to ) { - if ( to === control.params.removed ) - control.settings.data.set( false ); - }); - - control.library.on( 'click', 'a', function() { - control.settings.data.set( $(this).data('customizeHeaderImageData') ); - }); - - control.uploader.success = function( attachment ) { - var data; - - api.ImageControl.prototype.success.call( control, attachment ); - - data = { - attachment_id: attachment.get('id'), - url: attachment.get('url'), - thumbnail_url: attachment.get('url'), - height: attachment.get('height'), - width: attachment.get('width') - }; - - attachment.element.data( 'customizeHeaderImageData', data ); - control.settings.data.set( data ); - }; - }); - api.trigger( 'ready' ); // Make sure left column gets focus diff --git a/wp-admin/js/customize-controls.min.js b/wp-admin/js/customize-controls.min.js index 1a03b0cf62..c76844678f 100644 --- a/wp-admin/js/customize-controls.min.js +++ b/wp-admin/js/customize-controls.min.js @@ -1 +1 @@ -!function(a,b){var c=wp.customize;c.Setting=c.Value.extend({initialize:function(a,b,d){c.Value.prototype.initialize.call(this,b,d),this.id=a,this.transport=this.transport||"refresh",this.bind(this.preview)},preview:function(){switch(this.transport){case"refresh":return this.previewer.refresh();case"postMessage":return this.previewer.send("setting",[this.id,this()])}}}),c.Control=c.Class.extend({initialize:function(a,d){var e,f,g,h=this;this.params={},b.extend(this,d||{}),this.id=a,this.selector="#customize-control-"+a.replace(/\]/g,"").replace(/\[/g,"-"),this.container=b(this.selector),g=b.map(this.params.settings,function(a){return a}),c.apply(c,g.concat(function(){var a;h.settings={};for(a in h.params.settings)h.settings[a]=c(h.params.settings[a]);h.setting=h.settings["default"]||null,h.ready()})),h.elements=[],e=this.container.find("[data-customize-setting-link]"),f={},e.each(function(){var a,d=b(this);if(d.is(":radio")){if(a=d.prop("name"),f[a])return;f[a]=!0,d=e.filter('[name="'+a+'"]')}c(d.data("customizeSettingLink"),function(a){var b=new c.Element(d);h.elements.push(b),b.sync(a),b.set(a())})})},ready:function(){},dropdownInit:function(){var a=this,b=this.container.find(".dropdown-status"),c=this.params,d=!1,e=function(a){"string"==typeof a&&c.statuses&&c.statuses[a]?b.html(c.statuses[a]).show():b.hide()};this.container.on("click keydown",".dropdown",function(b){("keydown"!==b.type||13===b.which)&&(b.preventDefault(),d||a.container.toggleClass("open"),a.container.hasClass("open")&&a.container.parent().parent().find("li.library-selected").focus(),d=!0,setTimeout(function(){d=!1},400))}),this.setting.bind(e),e(this.setting())}}),c.ColorControl=c.Control.extend({ready:function(){var a=this,b=this.container.find(".color-picker-hex");b.val(a.setting()).wpColorPicker({change:function(){a.setting.set(b.wpColorPicker("color"))},clear:function(){a.setting.set(!1)}})}}),c.UploadControl=c.Control.extend({ready:function(){var a=this;this.params.removed=this.params.removed||"",this.success=b.proxy(this.success,this),this.uploader=b.extend({container:this.container,browser:this.container.find(".upload"),dropzone:this.container.find(".upload-dropzone"),success:this.success,plupload:{},params:{}},this.uploader||{}),a.params.extensions&&(a.uploader.plupload.filters=[{title:c.l10n.allowedFiles,extensions:a.params.extensions}]),a.params.context&&(a.uploader.params["post_data[context]"]=this.params.context),c.settings.theme.stylesheet&&(a.uploader.params["post_data[theme]"]=c.settings.theme.stylesheet),this.uploader=new wp.Uploader(this.uploader),this.remover=this.container.find(".remove"),this.remover.on("click keydown",function(b){("keydown"!==b.type||13===b.which)&&(a.setting.set(a.params.removed),b.preventDefault())}),this.removerVisibility=b.proxy(this.removerVisibility,this),this.setting.bind(this.removerVisibility),this.removerVisibility(this.setting.get())},success:function(a){this.setting.set(a.get("url"))},removerVisibility:function(a){this.remover.toggle(a!=this.params.removed)}}),c.ImageControl=c.UploadControl.extend({ready:function(){var a,d=this;this.uploader={init:function(){var a,b;this.supports.dragdrop||(a=d.container.find(".upload-fallback"),b=a.children().detach(),this.browser.detach().empty().append(b),a.append(this.browser).show())}},c.UploadControl.prototype.ready.call(this),this.thumbnail=this.container.find(".preview-thumbnail img"),this.thumbnailSrc=b.proxy(this.thumbnailSrc,this),this.setting.bind(this.thumbnailSrc),this.library=this.container.find(".library"),this.tabs={},a=this.library.find(".library-content"),this.library.children("ul").children("li").each(function(){var c=b(this),e=c.data("customizeTab"),f=a.filter('[data-customize-tab="'+e+'"]');d.tabs[e]={both:c.add(f),link:c,panel:f}}),this.library.children("ul").on("click keydown","li",function(a){if("keydown"!==a.type||13===a.which){var c=b(this).data("customizeTab"),e=d.tabs[c];a.preventDefault(),e.link.hasClass("library-selected")||(d.selected.both.removeClass("library-selected"),d.selected=e,d.selected.both.addClass("library-selected"))}}),this.library.on("click keydown","a",function(a){if("keydown"!==a.type||13===a.which){var c=b(this).data("customizeImageValue");c&&(d.setting.set(c),a.preventDefault())}}),this.tabs.uploaded&&(this.tabs.uploaded.target=this.library.find(".uploaded-target"),this.tabs.uploaded.panel.find(".thumbnail").length||this.tabs.uploaded.both.addClass("hidden")),a.each(function(){var a=d.tabs[b(this).data("customizeTab")];return a.link.hasClass("hidden")?void 0:(d.selected=a,a.both.addClass("library-selected"),!1)}),this.dropdownInit()},success:function(a){c.UploadControl.prototype.success.call(this,a),this.tabs.uploaded&&this.tabs.uploaded.target.length&&(this.tabs.uploaded.both.removeClass("hidden"),a.element=b('').data("customizeImageValue",a.get("url")).append('').appendTo(this.tabs.uploaded.target))},thumbnailSrc:function(a){/^(https?:)?\/\//.test(a)?this.thumbnail.prop("src",a).show():this.thumbnail.hide()}}),c.defaultConstructor=c.Setting,c.control=new c.Values({defaultConstructor:c.Control}),c.PreviewFrame=c.Messenger.extend({sensitivity:2e3,initialize:function(a,d){var e=b.Deferred();e.promise(this),this.container=a.container,this.signature=a.signature,b.extend(a,{channel:c.PreviewFrame.uuid()}),c.Messenger.prototype.initialize.call(this,a,d),this.add("previewUrl",a.previewUrl),this.query=b.extend(a.query||{},{customize_messenger_channel:this.channel()}),this.run(e)},run:function(a){var c=this,d=!1,e=!1;this._ready&&this.unbind("ready",this._ready),this._ready=function(){e=!0,d&&a.resolveWith(c)},this.bind("ready",this._ready),this.request=b.ajax(this.previewUrl(),{type:"POST",data:this.query,xhrFields:{withCredentials:!0}}),this.request.fail(function(){a.rejectWith(c,["request failure"])}),this.request.done(function(f){var g,h=c.request.getResponseHeader("Location"),i=c.signature;return h&&h!=c.previewUrl()?void a.rejectWith(c,["redirect",h]):"0"===f?void c.login(a):"-1"===f?void a.rejectWith(c,["cheatin"]):(g=f.lastIndexOf(i),-1===g||g")?void a.rejectWith(c,["unsigned"]):(f=f.slice(0,g)+f.slice(g+i.length),c.iframe=b("