Use links for CMS preview states to allow open in new tab

Important to allow users to send around preview links,
open draft versions in new tabs, or find out which URL to
use to preview on mobile phones and other devices which
can't load the CMS preview panel directly.

Removed CSS animations since they complicated the component too much.

Removed input/label setup since its not contained in a form,
so has no relevance as far as server-side state goes.

This does mean there's no longer an indication that only one
state can be active at a given time (which the radio buttons communicated),
but that's no different from e.g. the CMS menu.

Not an API change since the Entwine JS and PHP interfaces stay the same.

Conflicts:
	admin/css/screen.css
This commit is contained in:
Ingo Schommer 2014-11-10 10:31:53 +13:00
parent 9cbd6f8023
commit 659634557d
4 changed files with 62 additions and 155 deletions

View File

@ -281,60 +281,21 @@ input.radio { margin-left: 0; }
/*************************************************************** /***************************************************************
* On/Off Switch. * On/Off Switch.
* Supports switching between up to 5 values (used for Draft/Published)
* Example html set-up: * Example html set-up:
* <fieldset class="switch-states size_2"> * <fieldset class="switch-states">
* <div class="switch"> * <div class="switch">
* <input id="Draft" class="first" name="view" type="radio" checked> * <a href="my-page/?stage=Draft" class="first active"><span>Draft</span></a>
* <label for="Draft">Draft</label> * <a href="my-page/?stage=Live" class="last"><span>Live</span></a>
* <input id="Published" class="last" name="view" type="radio">
* <label for="Published">Published</label>
* <span class="slide-button"></span>
* </div> * </div>
* </fieldset> * </fieldset>
****************************************************************/ ****************************************************************/
fieldset.switch-states { padding: 0 20px 0 0; margin-right: 5px; /* .switch-states { padding: 0 20px 0 0; margin-right: 5px; }
Produce css for up to 5 states. .switch-states .switch { -moz-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1); -webkit-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1); box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1); -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; background: #dee0e3; display: block; height: 25px; margin-top: 3px; width: 100%; z-index: 5; }
.switch-states .switch a { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); color: #858585; color: rgba(31, 31, 31, 0.5); cursor: pointer; float: left; font-weight: bold; height: 100%; line-height: 25px; z-index: 2; }
Note: with a little adjustment the switch can take more than 5 items, .switch-states .switch a:hover { color: #6c6c6c; color: rgba(31, 31, 31, 0.7); }
but a dropdown would probably be more appropriate .switch-states .switch a span { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; display: inline-block; padding: 0 10px; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); color: #858585; color: rgba(31, 31, 31, 0.5); }
*/ } .switch-states .switch a.active { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzJiOWMzMiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzY0YWIzNiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='); background-size: 100%; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #2b9c32), color-stop(100%, #64ab36)); background-image: -moz-linear-gradient(#2b9c32, #64ab36); background-image: -webkit-linear-gradient(#2b9c32, #64ab36); background-image: linear-gradient(#2b9c32, #64ab36); -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; -moz-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); -webkit-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); background-color: #2b9c32; }
fieldset.switch-states .switch { -webkit-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1); -moz-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1); box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1); -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; -webkit-animation: bugfix infinite 1s; background: #dee0e3; display: block; height: 25px; margin-top: 3px; padding: 0 10px; position: relative; width: 100%; z-index: 5; } .switch-states .switch a.active span { color: #fff; text-shadow: 0 -1px 0 #287099; }
fieldset.switch-states .switch label { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); color: #858585; color: rgba(31, 31, 31, 0.5); cursor: pointer; float: left; font-weight: bold; height: 100%; line-height: 25px; position: relative; z-index: 2; /* Make text unselectable in browsers that support that */ -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
fieldset.switch-states .switch label:hover { color: #6c6c6c; color: rgba(31, 31, 31, 0.7); }
fieldset.switch-states .switch label span { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; display: inline-block; padding: 0 10px; }
fieldset.switch-states .switch input { opacity: 0; filter: alpha(opacity=0); visibility: none; position: absolute; }
fieldset.switch-states .switch input:checked + label { -moz-transition: all 0.3s ease-out 0s; -webkit-transition: all 0.3s ease-out 0s; -o-transition: all 0.3s ease-out 0s; transition: all 0.3s ease-out 0s; color: #fff; text-shadow: 0 -1px 0 #287099; }
fieldset.switch-states .switch .slide-button { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzJiOWMzMiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzY0YWIzNiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='); background-size: 100%; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #2b9c32), color-stop(100%, #64ab36)); background-image: -webkit-linear-gradient(#2b9c32, #64ab36); background-image: -moz-linear-gradient(#2b9c32, #64ab36); background-image: -o-linear-gradient(#2b9c32, #64ab36); background-image: linear-gradient(#2b9c32, #64ab36); -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); -moz-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -moz-transition: all 0.3s ease-out 0s; -webkit-transition: all 0.3s ease-out 0s; -o-transition: all 0.3s ease-out 0s; transition: all 0.3s ease-out 0s; background-color: #2b9c32; display: block; height: 100%; left: 0; padding: 0; position: absolute; top: 0; z-index: 1; }
fieldset.switch-states.size_1 label, fieldset.switch-states.size_1 .slide-button { width: 100%; }
fieldset.switch-states.size_1 label span { padding-right: 0; }
fieldset.switch-states.size_1 input:checked:nth-of-type(2) ~ .slide-button { left: 100%; }
fieldset.switch-states.size_1 input:checked:nth-of-type(3) ~ .slide-button { left: 200%; }
fieldset.switch-states.size_1 input:checked:nth-of-type(4) ~ .slide-button { left: 300%; }
fieldset.switch-states.size_1 input:checked:nth-of-type(5) ~ .slide-button { left: 400%; }
fieldset.switch-states.size_2 label, fieldset.switch-states.size_2 .slide-button { width: 50%; }
fieldset.switch-states.size_2 input:checked:nth-of-type(2) ~ .slide-button { left: 50%; }
fieldset.switch-states.size_2 input:checked:nth-of-type(3) ~ .slide-button { left: 100%; }
fieldset.switch-states.size_2 input:checked:nth-of-type(4) ~ .slide-button { left: 150%; }
fieldset.switch-states.size_2 input:checked:nth-of-type(5) ~ .slide-button { left: 200%; }
fieldset.switch-states.size_3 label, fieldset.switch-states.size_3 .slide-button { width: 33.33333%; }
fieldset.switch-states.size_3 input:checked:nth-of-type(2) ~ .slide-button { left: 33.33333%; }
fieldset.switch-states.size_3 input:checked:nth-of-type(3) ~ .slide-button { left: 66.66667%; }
fieldset.switch-states.size_3 input:checked:nth-of-type(4) ~ .slide-button { left: 100%; }
fieldset.switch-states.size_3 input:checked:nth-of-type(5) ~ .slide-button { left: 133.33333%; }
fieldset.switch-states.size_4 label, fieldset.switch-states.size_4 .slide-button { width: 25%; }
fieldset.switch-states.size_4 input:checked:nth-of-type(2) ~ .slide-button { left: 25%; }
fieldset.switch-states.size_4 input:checked:nth-of-type(3) ~ .slide-button { left: 50%; }
fieldset.switch-states.size_4 input:checked:nth-of-type(4) ~ .slide-button { left: 75%; }
fieldset.switch-states.size_4 input:checked:nth-of-type(5) ~ .slide-button { left: 100%; }
fieldset.switch-states.size_5 label, fieldset.switch-states.size_5 .slide-button { width: 20%; }
fieldset.switch-states.size_5 input:checked:nth-of-type(2) ~ .slide-button { left: 20%; }
fieldset.switch-states.size_5 input:checked:nth-of-type(3) ~ .slide-button { left: 40%; }
fieldset.switch-states.size_5 input:checked:nth-of-type(4) ~ .slide-button { left: 60%; }
fieldset.switch-states.size_5 input:checked:nth-of-type(5) ~ .slide-button { left: 80%; }
@-webkit-keyframes bugfix { from { position: relative; }
to { position: relative; } }
/** /**
* This file defines most styles of the CMS: Colors, fonts, backgrounds, * This file defines most styles of the CMS: Colors, fonts, backgrounds,

View File

@ -373,8 +373,8 @@
if(stateLink.length) { if(stateLink.length) {
return { return {
name: name, name: name,
url: stateLink.attr('data-link'), url: stateLink.attr('href'),
active: stateLink.is(':radio') ? stateLink.is(':checked') : stateLink.is(':selected') active: stateLink.hasClass('active')
}; };
} else { } else {
return null; return null;
@ -532,7 +532,7 @@
* Change the appearance of the state selector. * Change the appearance of the state selector.
*/ */
changeVisibleState: function(state) { changeVisibleState: function(state) {
this.find('input[data-name="'+state+'"]').prop('checked', true); this.find('[data-name="'+state+'"]').addClass('active').siblings().removeClass('active');
} }
}); });
@ -540,17 +540,19 @@
/** /**
* Reacts to the user changing the state of the preview. * Reacts to the user changing the state of the preview.
*/ */
onclick: function(e) { onclick: function(e) {
//Add and remove classes to make switch work ok in old IE
this.parent().find('.active').removeClass('active');
this.next('label').addClass('active');
var targetStateName = $(this).attr('data-name'); var targetStateName = $(this).attr('data-name');
//Add and remove classes to make switch work ok in old IE
this.addClass('active').siblings().removeClass('active');
// Reload preview with the selected state. // Reload preview with the selected state.
$('.cms-preview').changeState(targetStateName); $('.cms-preview').changeState(targetStateName);
e.preventDefault();
} }
}); });
/** /**
* "Preview mode" functions * "Preview mode" functions
* ------------------------------------------------------------------- * -------------------------------------------------------------------

View File

@ -687,36 +687,29 @@ input.radio {
/*************************************************************** /***************************************************************
* On/Off Switch. * On/Off Switch.
* Supports switching between up to 5 values (used for Draft/Published)
* Example html set-up: * Example html set-up:
* <fieldset class="switch-states size_2"> * <fieldset class="switch-states">
* <div class="switch"> * <div class="switch">
* <input id="Draft" class="first" name="view" type="radio" checked> * <a href="my-page/?stage=Draft" class="first active"><span>Draft</span></a>
* <label for="Draft">Draft</label> * <a href="my-page/?stage=Live" class="last"><span>Live</span></a>
* <input id="Published" class="last" name="view" type="radio">
* <label for="Published">Published</label>
* <span class="slide-button"></span>
* </div> * </div>
* </fieldset> * </fieldset>
****************************************************************/ ****************************************************************/
fieldset.switch-states{ .switch-states{
padding:0 20px 0 0; padding:0 20px 0 0;
margin-right: 5px; margin-right: 5px;
.switch{ .switch{
@include box-shadow(inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1)); @include box-shadow(inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.1));
@include border-radius(3px); @include border-radius(3px);
-webkit-animation: bugfix infinite 1s; //Bugfix for older Webkit, including mobile Webkit.
background:lighten(#2d3035,69%); background:lighten(#2d3035,69%);
display: block; display: block;
height: 25px; height: 25px;
margin-top:3px; margin-top:3px;
padding:0 10px;
position: relative;
width:100%; width:100%;
z-index:5; z-index:5;
label{ a {
@include hide-text-overflow; @include hide-text-overflow;
@include text-shadow(0 1px 0 rgba(255,255,255,0.5)); @include text-shadow(0 1px 0 rgba(255,255,255,0.5));
color:lighten($color-text-dark,40%); color:lighten($color-text-dark,40%);
@ -725,88 +718,39 @@ fieldset.switch-states{
float:left; float:left;
font-weight:bold; font-weight:bold;
height: 100%; height: 100%;
line-height: 25px; line-height: 25px;
position:relative; z-index:2;
z-index:2;
/* Make text unselectable in browsers that support that */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&:hover{ &:hover{
color:lighten($color-text-dark, 30%); color:lighten($color-text-dark, 30%);
color:rgba($color-text-dark,0.7); color:rgba($color-text-dark,0.7);
} }
span{
span {
@include box-sizing('border-box'); @include box-sizing('border-box');
@include hide-text-overflow; @include hide-text-overflow;
display:inline-block; display:inline-block;
padding:0 10px; padding:0 10px;
@include text-shadow(0 1px 0 rgba(255,255,255,0.5));
color:lighten($color-text-dark,40%);
color:rgba($color-text-dark,0.5);
} }
}
input {
opacity: 0;
filter: alpha(opacity = 0);
visibility:none;
position: absolute;
&:checked + label {
@include transition(all 0.3s ease-out 0s);
color: #fff;
text-shadow: 0 -1px 0 darken($color-menu-button,10%);
}
}
.slide-button{
@include background-image(linear-gradient(
#2b9c32,
#64ab36
));
@include border-radius(3px);
@include box-shadow(inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2));
@include text-shadow(0 1px 0 rgba(255,255,255,0.5));
@include transition(all 0.3s ease-out 0s);
background-color: #2b9c32;
display:block;
height: 100%;
left:0;
padding: 0;
position: absolute;
top: 0;
z-index: 1;
}
}
/* &.active {
Produce css for up to 5 states. @include background-image(linear-gradient(
#2b9c32,
#64ab36
));
@include border-radius(3px);
@include box-shadow(inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2));
@include text-shadow(0 1px 0 rgba(255,255,255,0.5));
background-color: #2b9c32;
Note: with a little adjustment the switch can take more than 5 items, span {
but a dropdown would probably be more appropriate color: #fff;
*/ text-shadow: 0 -1px 0 darken($color-menu-button,10%);
@for $i from 1 through 5 {
&.size_#{$i} {
label, .slide-button {
width: 100% / $i;
}
@if $i == 1{
label span{
padding-right:0; //even up the padding for a single item
} }
} }
input:checked:nth-of-type(2) ~ .slide-button { }
left: 100% / $i; }
} }
input:checked:nth-of-type(3) ~ .slide-button {
left: (100% / $i) * 2;
}
input:checked:nth-of-type(4) ~ .slide-button {
left: (100% / $i) * 3;
}
input:checked:nth-of-type(5) ~ .slide-button {
left: (100% / $i) * 4;
}
}
}
}
//old web-kit browser fix
@-webkit-keyframes bugfix { from { position: relative; } to { position: relative; } }

View File

@ -21,15 +21,15 @@
<% if $Items %> <% if $Items %>
<% if $Items.Count < 5 %> <% if $Items.Count < 5 %>
<fieldset id="preview-states" class="cms-preview-states switch-states size_{$Items.Count}"> <div id="preview-states" class="cms-preview-states switch-states size_{$Items.Count}">
<div class="switch"> <div class="switch">
<% loop $Items %> <% loop $Items %>
<input id="$Title" data-name="$Name" class="state-name $FirstLast" data-link="$Link" name="view" type="radio" <% if $isActive %>checked<% end_if %>> <a href="$Link" id="$Title" data-name="$Name" class="state-name $FirstLast<% if $isActive %> active<% end_if %>">
<label for="$Title"<% if $isActive %> class="active"<% end_if %>><span>$Title</span></label> <span>$Title</span>
</a>
<% end_loop %> <% end_loop %>
<span class="slide-button"></span>
</div> </div>
</fieldset> </div>
<% else %> <% else %>
<span id="preview-state-dropdown" class="cms-preview-states field dropdown"> <span id="preview-state-dropdown" class="cms-preview-states field dropdown">
<select title="<% _t('SilverStripeNavigator.PreviewState', 'Preview State') %>" id="preview-states" class="preview-state dropdown nolabel" autocomplete="off" name="preview-state"> <select title="<% _t('SilverStripeNavigator.PreviewState', 'Preview State') %>" id="preview-states" class="preview-state dropdown nolabel" autocomplete="off" name="preview-state">