first import
67
sites/all/modules/panels/panels_ipe/css/panels_ipe-rtl.css
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
div.panels-ipe-handlebar-wrapper ul {
|
||||
float: right;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li {
|
||||
margin: 0 0 0 .5em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.panels-ipe-draghandle span.panels-ipe-draghandle-icon {
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.panels-ipe-placeholder {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.panels-ipe-newblock {
|
||||
left: 30px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li a span,
|
||||
div.panels-ipe-newblock a span {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.panels-ipe-newblock a.style {
|
||||
margin-left: .5em;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-region {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** ============================================================================
|
||||
* Controller form markup
|
||||
*/
|
||||
|
||||
.ipe-throbber {
|
||||
right: 49%;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
div.panels-ipe-control .form-submit {
|
||||
padding: 0 34px 2px 0.8em;
|
||||
}
|
||||
|
||||
input#panels-ipe-save,
|
||||
input#panels-ipe-cancel {
|
||||
background-position: 86% 0;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a.panels-ipe-startedit {
|
||||
padding-right: 34px;
|
||||
padding-left: 10px;
|
||||
background-position: 93% 9px;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a.panels-ipe-change-layout {
|
||||
padding-right: 34px;
|
||||
padding-left: 10px;
|
||||
background-position: 93% 9px;
|
||||
}
|
559
sites/all/modules/panels/panels_ipe/css/panels_ipe.css
Normal file
@@ -0,0 +1,559 @@
|
||||
body.panels-ipe {
|
||||
margin-bottom: 60px !important;
|
||||
}
|
||||
|
||||
/* Hide the IPE toolbar on print output. */
|
||||
@media print {
|
||||
#panels-ipe-control-container {
|
||||
display: none !important;
|
||||
}
|
||||
body.panels-ipe {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide the control container when the overlay is open. */
|
||||
html.overlay-open #panels-ipe-control-container {
|
||||
display: none !important;
|
||||
}
|
||||
html.overlay-open body.panels-ipe {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper {
|
||||
border-bottom: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.panels-ipe-editing div.panels-ipe-portlet-wrapper {
|
||||
margin-top: 1em;
|
||||
border: 1px solid #CCC;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Hide empty panes when not editing them. */
|
||||
.panels-ipe-empty-pane {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-empty-pane {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.panels-ipe-editing div.panels-ipe-portlet-wrapper:hover {
|
||||
border: 1px dashed #CCC;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-sort-container {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-sort-container .ui-sortable-helper {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.panels-ipe-editing div.panel-pane div.admin-links {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-sort-container .ui-sortable-placeholder {
|
||||
border: 2px dashed #999;
|
||||
background-color: #FFFF99;
|
||||
margin: 1em 0;
|
||||
-moz-border-radius: 0;
|
||||
-khtml-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper ul {
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li {
|
||||
background: none;
|
||||
list-style-type: none;
|
||||
list-style-image: none;
|
||||
margin: 0 .5em 0 0;
|
||||
padding: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.panels-ipe-draghandle,
|
||||
div.panels-ipe-nodraghandle {
|
||||
background: #E9E9E9;
|
||||
background-image: linear-gradient(bottom, #D5D5D5 0%, #FCFCFC 100%);
|
||||
background-image: -o-linear-gradient(bottom, #D5D5D5 0%, #FCFCFC 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #D5D5D5 0%, #FCFCFC 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #D5D5D5 0%, #FCFCFC 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #D5D5D5 0%, #FCFCFC 100%);
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #D5D5D5),
|
||||
color-stop(1, #FCFCFC)
|
||||
);
|
||||
|
||||
padding: 8px 7px;
|
||||
}
|
||||
|
||||
div.panels-ipe-draghandle span.panels-ipe-draghandle-icon {
|
||||
display: block;
|
||||
float: right;
|
||||
cursor: move;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
padding: 0 !important; /* override button defaults */
|
||||
}
|
||||
|
||||
span.panels-ipe-draghandle-icon-inner {
|
||||
display: block;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
background: url(../images/icon-draggable.png) no-repeat 3px 3px;
|
||||
}
|
||||
|
||||
div.panels-ipe-placeholder {
|
||||
border: 2px dashed #999;
|
||||
padding: .5em;
|
||||
position: relative;
|
||||
margin-top: .5em;
|
||||
background-color: #ECFAFF;
|
||||
color: #999;
|
||||
font: 15px/1.3em "Open Sans", "Lucida Grande", Tahoma, Verdana, sans-serif;
|
||||
text-transform: none;
|
||||
letter-spacing: 0;
|
||||
text-align: left;
|
||||
word-spacing: 0;
|
||||
}
|
||||
|
||||
div.panels-ipe-placeholder h3 {
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
width: 75px; /* In order to prevent the region title from running into the button, set a width. Initital width only--this will be changed by jQuery */
|
||||
margin: 1.154em 0;
|
||||
}
|
||||
|
||||
/* Hide editor-state-on elements initially */
|
||||
.panels-ipe-on {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-on {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Show editor-state-off elements initially */
|
||||
.panels-ipe-off {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.panels-ipe-newblock {
|
||||
-webkit-box-shadow: 0px 0 5px 5px #ECFAFF;
|
||||
-moz-box-shadow: 0px 0 5px 5px #ECFAFF;
|
||||
box-shadow: 0px 0 5px 5px #ECFAFF;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
margin-top: -18px; /* some initial guesses to help center the add button
|
||||
panels_ipe.js will evaluate the width and get this pixel-perfect */
|
||||
margin-left: -30px;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
div.panels-ipe-newblock li {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li a,
|
||||
div.panels-ipe-dragtitle span,
|
||||
div.panels-ipe-newblock a,
|
||||
span.panels-ipe-draghandle-icon {
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
padding: 0 8px 1px;
|
||||
font: bold 12px/32px 'Open Sans', 'Lucida Sans', 'Lucida Grande', verdana sans-serif;
|
||||
text-decoration: none;
|
||||
height: 33px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
-moz-border-radius: 3px;
|
||||
-khtml-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
|
||||
background: #FAFAFA;
|
||||
background-image: linear-gradient(bottom, #E9EAEC 0%, #FAFAFA 100%);
|
||||
background-image: -o-linear-gradient(bottom, #E9EAEC 0%, #FAFAFA 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #E9EAEC 0%, #FAFAFA 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #E9EAEC 0%, #FAFAFA 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #E9EAEC 0%, #FAFAFA 100%);
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #E9EAEC),
|
||||
color-stop(1, #FAFAFA)
|
||||
);
|
||||
|
||||
-webkit-box-shadow: 0px 3px 3px 0px #d2d2d2;
|
||||
-moz-box-shadow: 0px 3px 3px 0px #d2d2d2;
|
||||
box-shadow: 0px 3px 3px 0px #d2d2d2;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li a span,
|
||||
div.panels-ipe-newblock a span {
|
||||
display: block;
|
||||
height: 32px;
|
||||
width: 18px;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
text-align: left;
|
||||
text-indent: -9999em;
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li.edit a span {
|
||||
background-image: url(../images/icon-settings.png);
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li.style a span,
|
||||
div.panels-ipe-newblock a.style span {
|
||||
background-image: url(../images/icon-style.png);
|
||||
}
|
||||
|
||||
div.panels-ipe-newblock a.style {
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
div.panels-ipe-newblock a.add span {
|
||||
background-image: url(../images/icon-add.png);
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li.delete a span {
|
||||
background-image: url(../images/icon-delete.png);
|
||||
}
|
||||
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li a:hover,
|
||||
div.panels-ipe-dragtitle span:hover,
|
||||
div.panels-ipe-newblock a:hover,
|
||||
span.panels-ipe-draghandle-icon:hover {
|
||||
background: #E6E6E6;
|
||||
background-image: linear-gradient(bottom, #C5C5C5 0%, #FAFAFA 100%);
|
||||
background-image: -o-linear-gradient(bottom, #C5C5C5 0%, #FAFAFA 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #C5C5C5 0%, #FAFAFA 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #C5C5C5 0%, #FAFAFA 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #C5C5C5 0%, #FAFAFA 100%);
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #C5C5C5),
|
||||
color-stop(1, #FAFAFA)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-handlebar-wrapper li a:active,
|
||||
div.panels-ipe-dragtitle span:active,
|
||||
div.panels-ipe-newblock a:active,
|
||||
span.panels-ipe-draghandle-icon:active {
|
||||
outline: none;
|
||||
background-image: linear-gradient(bottom, #FFFFFF 0%, #E9EAEC 100%);
|
||||
background-image: -o-linear-gradient(bottom, #FFFFFF 0%, #E9EAEC 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #FFFFFF 0%, #E9EAEC 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #FFFFFF 0%, #E9EAEC 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #FFFFFF 0%, #E9EAEC 100%);
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #FFFFFF),
|
||||
color-stop(1, #E9EAEC)
|
||||
);
|
||||
|
||||
-webkit-box-shadow: 0px 0px 0px 0px #fff;
|
||||
-moz-box-shadow: 0px 0px 0px 0px #fff;
|
||||
box-shadow: 0px 0px 0px 0px #fff;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-portlet-content {
|
||||
margin: 10px 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panels-ipe-editing .panels-ipe-region {
|
||||
border: transparent dotted 1px;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
div.panels-ipe-draghandle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ui-sortable-placeholder {
|
||||
margin: 1em;
|
||||
border: 1px dotted black;
|
||||
visibility: visible !important;
|
||||
height: 50px !important;
|
||||
}
|
||||
.ui-sortable-placeholder * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/** ============================================================================
|
||||
* Controller form markup
|
||||
*/
|
||||
|
||||
div#panels-ipe-control-container {
|
||||
z-index: 99999;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
background-color: #000;
|
||||
padding: 0.5em 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
-moz-box-shadow: 0 3px 20px #000;
|
||||
-webkit-box-shadow: 0 3px 20px #000;
|
||||
box-shadow: 0 3px 20px #000;
|
||||
}
|
||||
|
||||
.ipe-throbber {
|
||||
background-color: #232323;
|
||||
background-image: url("../images/loading-small.gif");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
-moz-border-radius: 7px;
|
||||
-webkit-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
height: 24px;
|
||||
opacity: .9;
|
||||
padding: 4px;
|
||||
width: 24px;
|
||||
/* Can't do center:50% middle: 50%, so approximate it for a typical window size. */
|
||||
left: 49%;
|
||||
position: fixed;
|
||||
top: 48.5%;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/* Hide the drupal system throbber image */
|
||||
.ipe-throbber .throbber {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container,
|
||||
div.panels-ipe-control .form-submit {
|
||||
cursor: pointer;
|
||||
background: #666666;
|
||||
background-image: linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: -o-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #383838),
|
||||
color-stop(1, #666666)
|
||||
);
|
||||
border: 0;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
color: #CCC;
|
||||
display: inline-block;
|
||||
font: bold 12px/33px "Open Sans", "Lucida Grande", Tahoma, Verdana, sans-serif;
|
||||
height: 33px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
div.panels-ipe-control .form-submit {
|
||||
padding: 0 0.8em 2px 34px;
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-save, div.panels-ipe-control input.panels-ipe-cancel,
|
||||
div.panels-ipe-control input.panels-ipe-save:hover, div.panels-ipe-control input.panels-ipe-cancel:hover,
|
||||
div.panels-ipe-control input.panels-ipe-save:active, div.panels-ipe-control input.panels-ipe-cancel:active {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a {
|
||||
height: 33px;
|
||||
padding: 0 0.8em;
|
||||
display: inline-block;
|
||||
color: #CCC;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-save {
|
||||
background-image: url(../images/icon-save.png);
|
||||
background-image: url(../images/icon-save.png), linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-save.png), -o-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-save.png), -moz-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-save.png), -webkit-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-save.png), -ms-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
|
||||
background-image: url(../images/icon-save.png), -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #383838),
|
||||
color-stop(1, #666666)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-cancel {
|
||||
background-image: url(../images/icon-close.png);
|
||||
background-image: url(../images/icon-close.png), linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-close.png), -o-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-close.png), -moz-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-close.png), -webkit-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
background-image: url(../images/icon-close.png), -ms-linear-gradient(bottom, #383838 0%, #666666 100%);
|
||||
|
||||
background-image: url(../images/icon-close.png), -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #383838),
|
||||
color-stop(1, #666666)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container:hover,
|
||||
div.panels-ipe-control .form-submit:hover {
|
||||
background: #999999;
|
||||
background-image: linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: -o-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #3D3D3D),
|
||||
color-stop(1, #999999)
|
||||
);
|
||||
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a:hover {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-cancel:hover {
|
||||
background-image: url(../images/icon-close.png), linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-close.png), -o-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-close.png), -moz-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-close.png), -webkit-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-close.png), -ms-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
|
||||
background-image: url(../images/icon-close.png), -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #3D3D3D),
|
||||
color-stop(1, #999999)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-save:hover {
|
||||
background-image: url(../images/icon-save.png), linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-save.png), -o-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-save.png), -moz-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-save.png), -webkit-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
background-image: url(../images/icon-save.png), -ms-linear-gradient(bottom, #3D3D3D 0%, #999999 100%);
|
||||
|
||||
background-image: url(../images/icon-save.png), -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #3D3D3D),
|
||||
color-stop(1, #999999)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container:active,
|
||||
div.panels-ipe-control .form-submit:active {
|
||||
background: #333;
|
||||
background-image: linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: -o-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: -moz-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: -webkit-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #616161),
|
||||
color-stop(1, #333333)
|
||||
);
|
||||
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a:active {
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-cancel:active {
|
||||
background-image: url(../images/icon-close.png), linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-close.png), -o-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-close.png), -moz-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-close.png), -webkit-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-close.png), -ms-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
|
||||
background-image: url(../images/icon-close.png), -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #616161),
|
||||
color-stop(1, #333333)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-control input.panels-ipe-save:active {
|
||||
background-image: url(../images/icon-save.png), linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-save.png), -o-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-save.png), -moz-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-save.png), -webkit-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
background-image: url(../images/icon-save.png), -ms-linear-gradient(bottom, #616161 0%, #333333 100%);
|
||||
|
||||
background-image: url(../images/icon-save.png), -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0, #616161),
|
||||
color-stop(1, #333333)
|
||||
);
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a.panels-ipe-startedit {
|
||||
padding-left: 34px;
|
||||
background: url(../images/icon-configure.png) no-repeat 10px 9px;
|
||||
}
|
||||
|
||||
div.panels-ipe-pseudobutton-container a.panels-ipe-change-layout {
|
||||
padding-left: 34px;
|
||||
background: url(../images/icon-change-layout.png) no-repeat 10px 9px;
|
||||
}
|
||||
|
||||
div.panels-ipe-button-container {
|
||||
margin: 0.3em 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
form#panels-ipe-edit-control-form {
|
||||
text-align: center;
|
||||
}
|
BIN
sites/all/modules/panels/panels_ipe/images/dragger.png
Normal file
After Width: | Height: | Size: 946 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-add.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 319 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-close.png
Normal file
After Width: | Height: | Size: 285 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-configure.png
Normal file
After Width: | Height: | Size: 546 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-delete.png
Normal file
After Width: | Height: | Size: 658 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-draggable.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
sites/all/modules/panels/panels_ipe/images/icon-save.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-settings.png
Normal file
After Width: | Height: | Size: 567 B |
BIN
sites/all/modules/panels/panels_ipe/images/icon-style.png
Normal file
After Width: | Height: | Size: 488 B |
BIN
sites/all/modules/panels/panels_ipe/images/loading-small.gif
Normal file
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Bulk export of panels_layouts objects generated by Bulk export module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_default_panels_renderer_pipeline().
|
||||
*/
|
||||
function panels_ipe_default_panels_renderer_pipeline() {
|
||||
$pipelines = array();
|
||||
|
||||
$pipeline = new stdClass;
|
||||
$pipeline->disabled = FALSE; /* Edit this to true to make a default pipeline disabled initially */
|
||||
$pipeline->api_version = 1;
|
||||
$pipeline->name = 'ipe';
|
||||
$pipeline->admin_title = t('In-Place Editor');
|
||||
$pipeline->admin_description = t('Allows privileged users to update and rearrange the content while viewing this panel.');
|
||||
$pipeline->weight = 0;
|
||||
$pipeline->settings = array(
|
||||
'renderers' => array(
|
||||
0 => array(
|
||||
'access' => array(
|
||||
'plugins' => array(
|
||||
0 => array(
|
||||
'name' => 'perm',
|
||||
'settings' => array(
|
||||
'perm' => 'use panels in place editing',
|
||||
),
|
||||
'context' => 'logged-in-user',
|
||||
),
|
||||
),
|
||||
'logic' => 'and',
|
||||
),
|
||||
'renderer' => 'ipe',
|
||||
'options' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
$pipelines[$pipeline->name] = $pipeline;
|
||||
|
||||
return $pipelines;
|
||||
}
|
455
sites/all/modules/panels/panels_ipe/js/panels_ipe.js
Normal file
@@ -0,0 +1,455 @@
|
||||
|
||||
// Ensure the $ alias is owned by jQuery.
|
||||
(function($) {
|
||||
|
||||
// randomly lock a pane.
|
||||
// @debug only
|
||||
Drupal.settings.Panels = Drupal.settings.Panels || {};
|
||||
Drupal.settings.Panels.RegionLock = {
|
||||
10: { 'top': false, 'left': true, 'middle': true }
|
||||
}
|
||||
|
||||
Drupal.PanelsIPE = {
|
||||
editors: {},
|
||||
bindClickDelete: function(context) {
|
||||
$('a.pane-delete:not(.pane-delete-processed)', context)
|
||||
.addClass('pane-delete-processed')
|
||||
.click(function() {
|
||||
if (confirm(Drupal.t('Remove this pane?'))) {
|
||||
$(this).parents('div.panels-ipe-portlet-wrapper').fadeOut('medium', function() {
|
||||
var $sortable = $(this).closest('.ui-sortable');
|
||||
$(this).empty().remove();
|
||||
$sortable.trigger('sortremove');
|
||||
});
|
||||
$(this).parents('div.panels-ipe-display-container').addClass('changed');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Drupal.behaviors.PanelsIPE = {
|
||||
attach: function(context) {
|
||||
for (var i in Drupal.settings.PanelsIPECacheKeys) {
|
||||
var key = Drupal.settings.PanelsIPECacheKeys[i];
|
||||
$('div#panels-ipe-display-' + key + ':not(.panels-ipe-processed)')
|
||||
.addClass('panels-ipe-processed')
|
||||
.each(function() {
|
||||
// If we're replacing an old IPE, clean it up a little.
|
||||
if (Drupal.PanelsIPE.editors[key]) {
|
||||
Drupal.PanelsIPE.editors[key].editing = false;
|
||||
}
|
||||
Drupal.PanelsIPE.editors[key] = new DrupalPanelsIPE(key);
|
||||
Drupal.PanelsIPE.editors[key].showContainer();
|
||||
});
|
||||
}
|
||||
$('.panels-ipe-hide-bar').once('panels-ipe-hide-bar-processed').click(function() {
|
||||
Drupal.PanelsIPE.editors[key].hideContainer();
|
||||
});
|
||||
Drupal.PanelsIPE.bindClickDelete(context);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Base object (class) definition for the Panels In-Place Editor.
|
||||
*
|
||||
* A new instance of this object is instanciated for every unique IPE on a given
|
||||
* page.
|
||||
*
|
||||
* Note that this form is provisional, and we hope to replace it with a more
|
||||
* flexible, loosely-coupled model that utilizes separate controllers for the
|
||||
* discrete IPE elements. This will result in greater IPE flexibility.
|
||||
*/
|
||||
function DrupalPanelsIPE(cache_key, cfg) {
|
||||
cfg = cfg || {};
|
||||
var ipe = this;
|
||||
this.key = cache_key;
|
||||
this.lockPath = null;
|
||||
this.state = {};
|
||||
this.container = $('#panels-ipe-control-container');
|
||||
this.control = $('div#panels-ipe-control-' + cache_key);
|
||||
this.initButton = $('div.panels-ipe-startedit', this.control);
|
||||
this.cfg = cfg;
|
||||
this.changed = false;
|
||||
this.sortableOptions = $.extend({
|
||||
opacity: 0.75, // opacity of sortable while sorting
|
||||
items: 'div.panels-ipe-portlet-wrapper',
|
||||
handle: 'div.panels-ipe-draghandle',
|
||||
cancel: '.panels-ipe-nodrag',
|
||||
dropOnEmpty: true
|
||||
}, cfg.sortableOptions || {});
|
||||
|
||||
this.regions = [];
|
||||
this.sortables = {};
|
||||
|
||||
$(document).bind('CToolsDetachBehaviors', function() {
|
||||
// If the IPE is off and the container is not visible, then we need
|
||||
// to reshow the container on modal close.
|
||||
if (!$('.panels-ipe-form-container', ipe.control).html() && !ipe.container.is(':visible')) {
|
||||
ipe.showContainer();
|
||||
ipe.cancelLock();
|
||||
}
|
||||
|
||||
// If the IPE is on and we've hidden the bar for a modal, we need to
|
||||
// re-display it.
|
||||
if (ipe.topParent && ipe.topParent.hasClass('panels-ipe-editing') && ipe.container.is(':not(visible)')) {
|
||||
ipe.showContainer();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// If a user navigates away from a locked IPE, cancel the lock in the background.
|
||||
$(window).bind('beforeunload', function() {
|
||||
if (!ipe.editing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ipe.topParent && ipe.topParent.hasClass('changed')) {
|
||||
ipe.changed = true;
|
||||
}
|
||||
|
||||
if (ipe.changed) {
|
||||
return Drupal.t('This will discard all unsaved changes. Are you sure?');
|
||||
}
|
||||
});
|
||||
|
||||
// If a user navigates away from a locked IPE, cancel the lock in the background.
|
||||
$(window).bind('unload', function() {
|
||||
ipe.cancelLock(true);
|
||||
});
|
||||
|
||||
/**
|
||||
* If something caused us to abort what we were doing, send a background
|
||||
* cancel lock request to the server so that we do not leave stale locks
|
||||
* hanging around.
|
||||
*/
|
||||
this.cancelLock = function(sync) {
|
||||
// If there's a lockpath and an ajax available, inform server to clear lock.
|
||||
// We borrow the ajax options from the customize this page link.
|
||||
if (ipe.lockPath && Drupal.ajax['panels-ipe-customize-page']) {
|
||||
var ajaxOptions = {
|
||||
type: 'POST',
|
||||
url: ipe.lockPath
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
ajaxOptions.async = false;
|
||||
}
|
||||
|
||||
// Make sure we don't somehow get another one:
|
||||
ipe.lockPath = null;
|
||||
|
||||
// Send the request. This is synchronous to prevent being cancelled.
|
||||
$.ajax(ajaxOptions);
|
||||
}
|
||||
}
|
||||
|
||||
this.activateSortable = function(event, ui) {
|
||||
if (!Drupal.settings.Panels || !Drupal.settings.Panels.RegionLock) {
|
||||
// don't bother if there are no region locks in play.
|
||||
return;
|
||||
}
|
||||
|
||||
var region = event.data.region;
|
||||
var paneId = ui.item.attr('id').replace('panels-ipe-paneid-', '');
|
||||
|
||||
var disabledRegions = false;
|
||||
|
||||
// Determined if this pane is locked out of this region.
|
||||
if (!Drupal.settings.Panels.RegionLock[paneId] || Drupal.settings.Panels.RegionLock[paneId][region]) {
|
||||
ipe.sortables[region].sortable('enable');
|
||||
ipe.sortables[region].sortable('refresh');
|
||||
}
|
||||
else {
|
||||
disabledRegions = true;
|
||||
ipe.sortables[region].sortable('disable');
|
||||
ipe.sortables[region].sortable('refresh');
|
||||
}
|
||||
|
||||
// If we disabled regions, we need to
|
||||
if (disabledRegions) {
|
||||
$(event.srcElement).bind('dragstop', function(event, ui) {
|
||||
// Go through
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// When dragging is stopped, we need to ensure all sortable regions are enabled.
|
||||
this.enableRegions = function(event, ui) {
|
||||
for (var i in ipe.regions) {
|
||||
ipe.sortables[ipe.regions[i]].sortable('enable');
|
||||
ipe.sortables[ipe.regions[i]].sortable('refresh');
|
||||
}
|
||||
}
|
||||
|
||||
this.initSorting = function() {
|
||||
var $region = $(this).parents('.panels-ipe-region');
|
||||
var region = $region.attr('id').replace('panels-ipe-regionid-', '');
|
||||
ipe.sortables[region] = $(this).sortable(ipe.sortableOptions);
|
||||
ipe.regions.push(region);
|
||||
$(this).bind('sortactivate', {region: region}, ipe.activateSortable);
|
||||
};
|
||||
|
||||
this.initEditing = function(formdata) {
|
||||
ipe.editing = true;
|
||||
ipe.topParent = $('div#panels-ipe-display-' + cache_key);
|
||||
ipe.backup = this.topParent.clone();
|
||||
|
||||
// See http://jqueryui.com/demos/sortable/ for details on the configuration
|
||||
// parameters used here.
|
||||
ipe.changed = false;
|
||||
|
||||
$('div.panels-ipe-sort-container', ipe.topParent).each(ipe.initSorting);
|
||||
|
||||
// Since the connectWith option only does a one-way hookup, iterate over
|
||||
// all sortable regions to connect them with one another.
|
||||
$('div.panels-ipe-sort-container', ipe.topParent)
|
||||
.sortable('option', 'connectWith', ['div.panels-ipe-sort-container']);
|
||||
|
||||
$('div.panels-ipe-sort-container', ipe.topParent).bind('sortupdate', function() {
|
||||
ipe.changed = true;
|
||||
});
|
||||
|
||||
$('div.panels-ipe-sort-container', ipe.topParent).bind('sortstop', this.enableRegions);
|
||||
|
||||
$('.panels-ipe-form-container', ipe.control).append(formdata);
|
||||
|
||||
$('input:submit:not(.ajax-processed)', ipe.control).addClass('ajax-processed').each(function() {
|
||||
var element_settings = {};
|
||||
|
||||
element_settings.url = $(this.form).attr('action');
|
||||
element_settings.setClick = true;
|
||||
element_settings.event = 'click';
|
||||
element_settings.progress = { 'type': 'throbber' };
|
||||
element_settings.ipe_cache_key = cache_key;
|
||||
|
||||
var base = $(this).attr('id');
|
||||
Drupal.ajax[ipe.base] = new Drupal.ajax(base, this, element_settings);
|
||||
});
|
||||
|
||||
// Perform visual effects in a particular sequence.
|
||||
// .show() + .hide() cannot have speeds associated with them, otherwise
|
||||
// it clears out inline styles.
|
||||
$('.panels-ipe-on').show();
|
||||
ipe.showForm();
|
||||
ipe.topParent.addClass('panels-ipe-editing');
|
||||
|
||||
};
|
||||
|
||||
this.hideContainer = function() {
|
||||
ipe.container.slideUp('fast');
|
||||
};
|
||||
|
||||
this.showContainer = function() {
|
||||
ipe.container.slideDown('normal');
|
||||
};
|
||||
|
||||
this.showButtons = function() {
|
||||
$('.panels-ipe-form-container').hide();
|
||||
$('.panels-ipe-button-container').show();
|
||||
ipe.showContainer();
|
||||
};
|
||||
|
||||
this.showForm = function() {
|
||||
$('.panels-ipe-button-container').hide();
|
||||
$('.panels-ipe-form-container').show();
|
||||
ipe.showContainer();
|
||||
};
|
||||
|
||||
this.endEditing = function() {
|
||||
ipe.editing = false;
|
||||
ipe.lockPath = null;
|
||||
$('.panels-ipe-form-container').empty();
|
||||
// Re-show all the IPE non-editing meta-elements
|
||||
$('div.panels-ipe-off').show('fast');
|
||||
|
||||
ipe.showButtons();
|
||||
// Re-hide all the IPE meta-elements
|
||||
$('div.panels-ipe-on').hide();
|
||||
|
||||
$('.panels-ipe-editing').removeClass('panels-ipe-editing');
|
||||
$('div.panels-ipe-sort-container', ipe.topParent).sortable("destroy");
|
||||
};
|
||||
|
||||
this.saveEditing = function() {
|
||||
$('div.panels-ipe-region', ipe.topParent).each(function() {
|
||||
var val = '';
|
||||
var region = $(this).attr('id').split('panels-ipe-regionid-')[1];
|
||||
$(this).find('div.panels-ipe-portlet-wrapper').each(function() {
|
||||
var id = $(this).attr('id').split('panels-ipe-paneid-')[1];
|
||||
if (id) {
|
||||
if (val) {
|
||||
val += ',';
|
||||
}
|
||||
val += id;
|
||||
}
|
||||
});
|
||||
$('input[name="panel[pane][' + region + ']"]', ipe.control).val(val);
|
||||
});
|
||||
}
|
||||
|
||||
this.cancelIPE = function() {
|
||||
ipe.hideContainer();
|
||||
ipe.topParent.fadeOut('medium', function() {
|
||||
ipe.topParent.replaceWith(ipe.backup.clone());
|
||||
ipe.topParent = $('div#panels-ipe-display-' + ipe.key);
|
||||
|
||||
// Processing of these things got lost in the cloning, but the classes remained behind.
|
||||
// @todo this isn't ideal but I can't seem to figure out how to keep an unprocessed backup
|
||||
// that will later get processed.
|
||||
$('.ctools-use-modal-processed', ipe.topParent).removeClass('ctools-use-modal-processed');
|
||||
$('.pane-delete-processed', ipe.topParent).removeClass('pane-delete-processed');
|
||||
ipe.topParent.fadeIn('medium');
|
||||
Drupal.attachBehaviors();
|
||||
});
|
||||
};
|
||||
|
||||
this.cancelEditing = function() {
|
||||
if (ipe.topParent.hasClass('changed')) {
|
||||
ipe.changed = true;
|
||||
}
|
||||
|
||||
if (!ipe.changed || confirm(Drupal.t('This will discard all unsaved changes. Are you sure?'))) {
|
||||
this.cancelIPE();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Cancel the submission.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
this.createSortContainers = function() {
|
||||
$('div.panels-ipe-region', this.topParent).each(function() {
|
||||
$('div.panels-ipe-portlet-marker', this).parent()
|
||||
.wrapInner('<div class="panels-ipe-sort-container" />');
|
||||
|
||||
// Move our gadgets outside of the sort container so that sortables
|
||||
// cannot be placed after them.
|
||||
$('div.panels-ipe-portlet-static', this).each(function() {
|
||||
$(this).prependTo($(this).parent().parent());
|
||||
});
|
||||
|
||||
// Also remove the last panel separator.
|
||||
$('div.panel-separator', this).filter(':last').remove();
|
||||
});
|
||||
}
|
||||
|
||||
this.createSortContainers();
|
||||
|
||||
};
|
||||
|
||||
$(function() {
|
||||
Drupal.ajax.prototype.commands.initIPE = function(ajax, data, status) {
|
||||
if (Drupal.PanelsIPE.editors[data.key]) {
|
||||
Drupal.PanelsIPE.editors[data.key].initEditing(data.data);
|
||||
Drupal.PanelsIPE.editors[data.key].lockPath = data.lockPath;
|
||||
}
|
||||
Drupal.attachBehaviors();
|
||||
|
||||
};
|
||||
|
||||
Drupal.ajax.prototype.commands.IPEsetLockState = function(ajax, data, status) {
|
||||
if (Drupal.PanelsIPE.editors[data.key]) {
|
||||
Drupal.PanelsIPE.editors[data.key].lockPath = data.lockPath;
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.ajax.prototype.commands.addNewPane = function(ajax, data, status) {
|
||||
if (Drupal.PanelsIPE.editors[data.key]) {
|
||||
Drupal.PanelsIPE.editors[data.key].changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.ajax.prototype.commands.cancelIPE = function(ajax, data, status) {
|
||||
if (Drupal.PanelsIPE.editors[data.key]) {
|
||||
Drupal.PanelsIPE.editors[data.key].cancelIPE();
|
||||
Drupal.PanelsIPE.editors[data.key].endEditing();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.ajax.prototype.commands.unlockIPE = function(ajax, data, status) {
|
||||
if (confirm(data.message)) {
|
||||
var ajaxOptions = ajax.options;
|
||||
ajaxOptions.url = data.break_path;
|
||||
$.ajax(ajaxOptions);
|
||||
}
|
||||
else {
|
||||
Drupal.PanelsIPE.editors[data.key].endEditing();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.ajax.prototype.commands.endIPE = function(ajax, data, status) {
|
||||
if (Drupal.PanelsIPE.editors[data.key]) {
|
||||
Drupal.PanelsIPE.editors[data.key].endEditing();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the eventResponse on ajax.js so we can add a little extra
|
||||
* behavior.
|
||||
*/
|
||||
Drupal.ajax.prototype.ipeReplacedEventResponse = Drupal.ajax.prototype.eventResponse;
|
||||
Drupal.ajax.prototype.eventResponse = function (element, event) {
|
||||
if (element.ipeCancelThis) {
|
||||
element.ipeCancelThis = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($(this.element).attr('id') == 'panels-ipe-cancel') {
|
||||
if (!Drupal.PanelsIPE.editors[this.element_settings.ipe_cache_key].cancelEditing()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var retval = this.ipeReplacedEventResponse(element, event);
|
||||
if (this.ajaxing && this.element_settings.ipe_cache_key) {
|
||||
// Move the throbber so that it appears outside our container.
|
||||
if (this.progress.element) {
|
||||
$(this.progress.element).addClass('ipe-throbber').appendTo($('body'));
|
||||
}
|
||||
Drupal.PanelsIPE.editors[this.element_settings.ipe_cache_key].hideContainer();
|
||||
}
|
||||
// @TODO $('#panels-ipe-throbber-backdrop').remove();
|
||||
return retval;
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the eventResponse on ajax.js so we can add a little extra
|
||||
* behavior.
|
||||
*/
|
||||
Drupal.ajax.prototype.ipeReplacedError = Drupal.ajax.prototype.error;
|
||||
Drupal.ajax.prototype.error = function (response, uri) {
|
||||
var retval = this.ipeReplacedError(response, uri);
|
||||
if (this.element_settings.ipe_cache_key) {
|
||||
Drupal.PanelsIPE.editors[this.element_settings.ipe_cache_key].showContainer();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.ajax.prototype.ipeReplacedBeforeSerialize = Drupal.ajax.prototype.beforeSerialize;
|
||||
Drupal.ajax.prototype.beforeSerialize = function (element_settings, options) {
|
||||
if ($(this.element).hasClass('panels-ipe-save')) {
|
||||
Drupal.PanelsIPE.editors[this.element_settings.ipe_cache_key].saveEditing();
|
||||
};
|
||||
return this.ipeReplacedBeforeSerialize(element_settings, options);
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Apply margin to bottom of the page.
|
||||
*
|
||||
* Note that directly applying marginBottom does not work in IE. To prevent
|
||||
* flickering/jumping page content with client-side caching, this is a regular
|
||||
* Drupal behavior.
|
||||
*
|
||||
* @see admin_menu.js via https://drupal.org/project/admin_menu
|
||||
*/
|
||||
Drupal.behaviors.panelsIpeMarginBottom = {
|
||||
attach: function () {
|
||||
$('body:not(.panels-ipe)').addClass('panels-ipe');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
14
sites/all/modules/panels/panels_ipe/panels_ipe.info
Normal file
@@ -0,0 +1,14 @@
|
||||
name = Panels In-Place Editor
|
||||
description = Provide a UI for managing some Panels directly on the frontend, instead of having to use the backend.
|
||||
package = "Panels"
|
||||
dependencies[] = panels
|
||||
core = 7.x
|
||||
configure = admin/structure/panels
|
||||
files[] = panels_ipe.module
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-03-02
|
||||
version = "7.x-3.3+39-dev"
|
||||
core = "7.x"
|
||||
project = "panels"
|
||||
datestamp = "1362187383"
|
||||
|
266
sites/all/modules/panels/panels_ipe/panels_ipe.module
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implementation of hook_ctools_plugin_directory().
|
||||
*/
|
||||
function panels_ipe_ctools_plugin_directory($module, $plugin) {
|
||||
if ($module == 'panels' && $plugin == 'display_renderers') {
|
||||
return 'plugins/' . $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_ctools_plugin_api().
|
||||
*
|
||||
* Inform CTools about version information for various plugins implemented by
|
||||
* Panels.
|
||||
*
|
||||
* @param string $owner
|
||||
* The system name of the module owning the API about which information is
|
||||
* being requested.
|
||||
* @param string $api
|
||||
* The name of the API about which information is being requested.
|
||||
*/
|
||||
function panels_ipe_ctools_plugin_api($owner, $api) {
|
||||
if ($owner == 'panels' && $api == 'pipelines') {
|
||||
return array(
|
||||
'version' => 1,
|
||||
'path' => drupal_get_path('module', 'panels_ipe') . '/includes',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_theme().
|
||||
*/
|
||||
function panels_ipe_theme() {
|
||||
return array(
|
||||
'panels_ipe_pane_wrapper' => array(
|
||||
'variables' => array('output' => NULL, 'pane' => NULL, 'display' => NULL, 'renderer' => NULL),
|
||||
),
|
||||
'panels_ipe_region_wrapper' => array(
|
||||
'variables' => array('output' => NULL, 'region_id' => NULL, 'display' => NULL, 'controls' => NULL, 'renderer' => NULL),
|
||||
),
|
||||
'panels_ipe_add_pane_button' => array(
|
||||
'variables' => array('region_id' => NULL, 'display' => NULL, 'renderer' => NULL),
|
||||
),
|
||||
'panels_ipe_placeholder_pane' => array(
|
||||
'variables' => array('region_id' => NULL, 'region_title' => NULL),
|
||||
),
|
||||
'panels_ipe_dnd_form_container' => array(
|
||||
'variables' => array('link' => NULL, 'cache_key' => NULL, 'display' => NULL),
|
||||
),
|
||||
'panels_ipe_toolbar' => array(
|
||||
'variables' => array('buttons' => NULL),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme the 'placeholder' pane, which is shown on an active IPE when no panes
|
||||
* live in that region.
|
||||
*
|
||||
* @param string $region_id
|
||||
* @param string $region_title
|
||||
*/
|
||||
function theme_panels_ipe_placeholder_pane($vars) {
|
||||
$region_id = $vars['region_id'];
|
||||
$region_title = $vars['region_title'];
|
||||
|
||||
$output = '<div class="panels-ipe-placeholder-content">';
|
||||
$output .= "<h3>$region_title</h3>";
|
||||
$output .= '</div>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
function template_preprocess_panels_ipe_pane_wrapper(&$vars) {
|
||||
$pane = $vars['pane'];
|
||||
$display = $vars['display'];
|
||||
$renderer = $vars['renderer'];
|
||||
|
||||
$content_type = ctools_get_content_type($pane->type);
|
||||
$subtype = ctools_content_get_subtype($content_type, $pane->subtype);
|
||||
$vars['links'] = array();
|
||||
|
||||
if (ctools_content_editable($content_type, $subtype, $pane->configuration)) {
|
||||
$vars['links']['edit'] = array(
|
||||
'title' => isset($content_type['edit text']) ? '<span>' . $content_type['edit text'] . '</span>' : '<span>' . t('Settings') . '</span>',
|
||||
'href' => $renderer->get_url('edit-pane', $pane->pid),
|
||||
'html' => TRUE,
|
||||
'attributes' => array(
|
||||
'class' => array('ctools-use-modal', 'panels-ipe-hide-bar'),
|
||||
'title' => isset($content_type['edit text']) ? $content_type['edit text'] : t('Settings'),
|
||||
// 'id' => "pane-edit-panel-pane-$pane->pid",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Add option to configure style in IPE
|
||||
if (user_access('administer panels styles')) {
|
||||
$vars['links']['style'] = array(
|
||||
'title' => '<span>' . t('Style') . '</span>',
|
||||
'href' => $renderer->get_url('style-type', 'pane', $pane->pid),
|
||||
'html' => TRUE,
|
||||
'attributes' => array(
|
||||
'class' => array('ctools-use-modal', 'panels-ipe-hide-bar'),
|
||||
'title' => t('Style'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Deleting is managed entirely in the js; this is just an attachment point
|
||||
// for it
|
||||
$vars['links']['delete'] = array(
|
||||
'title' => '<span>' . t('Delete') . '</span>',
|
||||
'href' => '#',
|
||||
'html' => TRUE,
|
||||
'attributes' => array(
|
||||
'class' => 'pane-delete',
|
||||
'id' => "pane-delete-panel-pane-$pane->pid",
|
||||
'title' => t('Delete'),
|
||||
),
|
||||
);
|
||||
|
||||
$context = array(
|
||||
'pane' => $pane,
|
||||
'display' => $display,
|
||||
'renderer' => $renderer
|
||||
);
|
||||
drupal_alter('panels_ipe_pane_links', $vars['links'], $context);
|
||||
|
||||
}
|
||||
|
||||
function theme_panels_ipe_pane_wrapper($vars) {
|
||||
$output = $vars['output'];
|
||||
$pane = $vars['pane'];
|
||||
|
||||
$attributes = array(
|
||||
'class' => 'panels-ipe-linkbar',
|
||||
);
|
||||
|
||||
$links = theme('links', array('links' => $vars['links'], 'attributes' => $attributes));
|
||||
|
||||
if (!empty($pane->locks['type']) && $pane->locks['type'] == 'immovable') {
|
||||
$links = '<div class="panels-ipe-dragbar panels-ipe-nodraghandle clearfix">' . $links . '</div>';
|
||||
}
|
||||
else {
|
||||
$links = '<div class="panels-ipe-dragbar panels-ipe-draghandle clearfix">' . $links . '<span class="panels-ipe-draghandle-icon"><span class="panels-ipe-draghandle-icon-inner"></span></span></div>';
|
||||
}
|
||||
|
||||
$handlebar = '<div class="panels-ipe-handlebar-wrapper panels-ipe-on">' . $links . '</div>';
|
||||
|
||||
return $handlebar . $output;
|
||||
}
|
||||
|
||||
function theme_panels_ipe_region_wrapper($vars) {
|
||||
return $vars['controls'] . $vars['output'];
|
||||
}
|
||||
|
||||
function template_preprocess_panels_ipe_add_pane_button(&$vars) {
|
||||
$region_id = $vars['region_id'];
|
||||
$display = $vars['display'];
|
||||
$renderer = $vars['renderer'];
|
||||
$vars['links'] = '';
|
||||
|
||||
// Add option to configure style in IPE
|
||||
if (user_access('administer panels styles')) {
|
||||
$vars['links']['style'] = array(
|
||||
'title' => '<span>' . t('Region style') . '</span>',
|
||||
'href' => $renderer->get_url('style-type', 'region', $region_id),
|
||||
'html' => TRUE,
|
||||
'attributes' => array(
|
||||
'class' => array('ctools-use-modal', 'panels-ipe-hide-bar', 'style'),
|
||||
'title' => t('Region style'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Add option to add items in the IPE
|
||||
$vars['links']['add-pane'] = array(
|
||||
'title' => '<span>' . t('Add new pane') . '</span>',
|
||||
'href' => $renderer->get_url('select-content', $region_id),
|
||||
'attributes' => array(
|
||||
'class' => array('ctools-use-modal', 'add', 'panels-ipe-hide-bar'),
|
||||
'title' => t('Add new pane'),
|
||||
),
|
||||
'html' => TRUE,
|
||||
);
|
||||
|
||||
$context = array(
|
||||
'region_id' => $region_id,
|
||||
'display' => $display,
|
||||
'renderer' => $renderer,
|
||||
);
|
||||
drupal_alter('panels_ipe_region_links', $vars['links'], $context);
|
||||
|
||||
}
|
||||
|
||||
function theme_panels_ipe_add_pane_button($vars) {
|
||||
$attributes = array(
|
||||
'class' => array('panels-ipe-linkbar', 'inline'),
|
||||
);
|
||||
|
||||
$links = theme('links', array('links' => $vars['links'], 'attributes' => $attributes));
|
||||
|
||||
return '<div class="panels-ipe-newblock panels-ipe-on">' . $links . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function panels_ipe_get_cache_key($key = NULL) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a button to the IPE toolbar.
|
||||
*/
|
||||
function panels_ipe_toolbar_add_button($cache_key, $id, $button) {
|
||||
$buttons = &drupal_static('panels_ipe_toolbar_buttons', array());
|
||||
$buttons[$cache_key][$id] = $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_footer()
|
||||
*
|
||||
* Adds the IPE control container.
|
||||
*
|
||||
* @param unknown_type $main
|
||||
*/
|
||||
function panels_ipe_page_alter(&$page) {
|
||||
$buttons = &drupal_static('panels_ipe_toolbar_buttons', array());
|
||||
if (empty($buttons)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$output = theme('panels_ipe_toolbar', array('buttons' => $buttons));
|
||||
|
||||
$page['page_bottom']['panels_ipe'] = array(
|
||||
'#markup' => $output,
|
||||
);
|
||||
}
|
||||
|
||||
function theme_panels_ipe_toolbar($vars) {
|
||||
$buttons = $vars['buttons'];
|
||||
|
||||
$output = "<div id='panels-ipe-control-container' class='clearfix'>";
|
||||
foreach ($buttons as $key => $ipe_buttons) {
|
||||
$output .= "<div id='panels-ipe-control-$key' class='panels-ipe-control'>";
|
||||
|
||||
// Controls in this container will appear when the IPE is not on.
|
||||
$output .= '<div class="panels-ipe-button-container clearfix">';
|
||||
foreach ($ipe_buttons as $button) {
|
||||
$output .= is_string($button) ? $button : drupal_render($button);
|
||||
}
|
||||
$output .= '</div>';
|
||||
|
||||
// Controls in this container will appear when the IPE is on. It is usually
|
||||
// filled via AJAX.
|
||||
$output .= '<div class="panels-ipe-form-container clearfix"></div>';
|
||||
$output .= '</div>';
|
||||
}
|
||||
|
||||
$output .= "</div>";
|
||||
|
||||
return $output;
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
$plugin = array(
|
||||
'renderer' => 'panels_renderer_ipe',
|
||||
);
|
@@ -0,0 +1,462 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Renderer class for all In-Place Editor (IPE) behavior.
|
||||
*/
|
||||
class panels_renderer_ipe extends panels_renderer_editor {
|
||||
// The IPE operates in normal render mode, not admin mode.
|
||||
var $admin = FALSE;
|
||||
|
||||
function render() {
|
||||
$output = parent::render();
|
||||
return "<div id='panels-ipe-display-{$this->clean_key}' class='panels-ipe-display-container'>$output</div>";
|
||||
}
|
||||
|
||||
function add_meta() {
|
||||
ctools_include('display-edit', 'panels');
|
||||
ctools_include('content');
|
||||
|
||||
if (empty($this->display->cache_key)) {
|
||||
$this->cache = panels_edit_cache_get_default($this->display);
|
||||
}
|
||||
// @todo we may need an else to load the cache, but I am not sure we
|
||||
// actually need to load it if we already have our cache key, and doing
|
||||
// so is a waste of resources.
|
||||
|
||||
ctools_include('cleanstring');
|
||||
$this->clean_key = ctools_cleanstring($this->display->cache_key);
|
||||
$button = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Customize this page'),
|
||||
'#href' => $this->get_url('save_form'),
|
||||
'#id' => 'panels-ipe-customize-page',
|
||||
'#attributes' => array(
|
||||
'class' => array('panels-ipe-startedit', 'panels-ipe-pseudobutton'),
|
||||
),
|
||||
'#ajax' => array(
|
||||
'progress' => 'throbber',
|
||||
'ipe_cache_key' => $this->clean_key,
|
||||
),
|
||||
'#prefix' => '<div class="panels-ipe-pseudobutton-container">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
|
||||
panels_ipe_toolbar_add_button($this->clean_key, 'panels-ipe-startedit', $button);
|
||||
|
||||
// @todo this actually should be an IPE setting instead.
|
||||
if (user_access('change layouts in place editing')) {
|
||||
$button = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Change layout'),
|
||||
'#href' => $this->get_url('change_layout'),
|
||||
'#attributes' => array(
|
||||
'class' => array('panels-ipe-change-layout', 'panels-ipe-pseudobutton', 'ctools-modal-layout'),
|
||||
),
|
||||
'#ajax' => array(
|
||||
'progress' => 'throbber',
|
||||
'ipe_cache_key' => $this->clean_key,
|
||||
),
|
||||
|
||||
'#prefix' => '<div class="panels-ipe-pseudobutton-container">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
|
||||
panels_ipe_toolbar_add_button($this->clean_key, 'panels-ipe-change-layout', $button);
|
||||
}
|
||||
|
||||
ctools_include('ajax');
|
||||
ctools_include('modal');
|
||||
ctools_modal_add_js();
|
||||
|
||||
ctools_add_css('panels_dnd', 'panels');
|
||||
ctools_add_css('panels_admin', 'panels');
|
||||
ctools_add_js('panels_ipe', 'panels_ipe');
|
||||
ctools_add_css('panels_ipe', 'panels_ipe');
|
||||
|
||||
drupal_add_js(array('PanelsIPECacheKeys' => array($this->clean_key)), 'setting');
|
||||
|
||||
drupal_add_library('system', 'ui.draggable');
|
||||
drupal_add_library('system', 'ui.droppable');
|
||||
drupal_add_library('system', 'ui.sortable');
|
||||
|
||||
parent::add_meta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override & call the parent, then pass output through to the dnd wrapper
|
||||
* theme function.
|
||||
*
|
||||
* @param $pane
|
||||
*/
|
||||
function render_pane(&$pane) {
|
||||
$output = parent::render_pane($pane);
|
||||
if (empty($output)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there are region locks, add them.
|
||||
if (!empty($pane->locks['type']) && $pane->locks['type'] == 'regions') {
|
||||
static $key = NULL;
|
||||
$javascript = &drupal_static('drupal_add_js', array());
|
||||
|
||||
// drupal_add_js breaks as we add these, but we can't just lump them
|
||||
// together because panes can be rendered independently. So game the system:
|
||||
if (empty($key)) {
|
||||
$settings['Panels']['RegionLock'][$pane->pid] = $pane->locks['regions'];
|
||||
drupal_add_js($settings, 'setting');
|
||||
|
||||
// These are just added via [] so we have to grab the last one
|
||||
// and reference it.
|
||||
$keys = array_keys($javascript['settings']['data']);
|
||||
$key = end($keys);
|
||||
}
|
||||
else {
|
||||
$javascript['settings']['data'][$key]['Panels']['RegionLock'][$pane->pid] = $pane->locks['regions'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (empty($pane->IPE_empty)) {
|
||||
// Add an inner layer wrapper to the pane content before placing it into
|
||||
// draggable portlet
|
||||
$output = "<div class=\"panels-ipe-portlet-content\">$output</div>";
|
||||
}
|
||||
else {
|
||||
$output = "<div class=\"panels-ipe-portlet-content panels-ipe-empty-pane\">$output</div>";
|
||||
}
|
||||
// Hand it off to the plugin/theme for placing draggers/buttons
|
||||
$output = theme('panels_ipe_pane_wrapper', array('output' => $output, 'pane' => $pane, 'display' => $this->display, 'renderer' => $this));
|
||||
|
||||
if (!empty($pane->locks['type']) && $pane->locks['type'] == 'immovable') {
|
||||
return "<div id=\"panels-ipe-paneid-{$pane->pid}\" class=\"panels-ipe-nodrag panels-ipe-portlet-wrapper panels-ipe-portlet-marker\">" . $output . "</div>";
|
||||
}
|
||||
|
||||
return "<div id=\"panels-ipe-paneid-{$pane->pid}\" class=\"panels-ipe-portlet-wrapper panels-ipe-portlet-marker\">" . $output . "</div>";
|
||||
}
|
||||
|
||||
function prepare_panes($panes) {
|
||||
// Set to admin mode just for this to ensure all panes are represented.
|
||||
$this->admin = TRUE;
|
||||
$panes = parent::prepare_panes($panes);
|
||||
$this->admin = FALSE;
|
||||
}
|
||||
|
||||
function render_pane_content(&$pane) {
|
||||
if (!empty($pane->shown) && panels_pane_access($pane, $this->display)) {
|
||||
$content = parent::render_pane_content($pane);
|
||||
}
|
||||
// Ensure that empty panes have some content.
|
||||
if (empty($content) || empty($content->content)) {
|
||||
if (empty($content)) {
|
||||
$content = new stdClass();
|
||||
}
|
||||
|
||||
// Get the administrative title.
|
||||
$content_type = ctools_get_content_type($pane->type);
|
||||
$title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context);
|
||||
|
||||
$content->content = t('Placeholder for empty or inaccessible "@title"', array('@title' => html_entity_decode($title, ENT_QUOTES)));
|
||||
// Add these to prevent notices.
|
||||
$content->type = 'panels_ipe';
|
||||
$content->subtype = 'panels_ipe';
|
||||
$pane->IPE_empty = TRUE;
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an 'empty' pane placeholder above all the normal panes.
|
||||
*
|
||||
* @param $region_id
|
||||
* @param $panes
|
||||
*/
|
||||
function render_region($region_id, $panes) {
|
||||
// Generate this region's 'empty' placeholder pane from the IPE plugin.
|
||||
$empty_ph = theme('panels_ipe_placeholder_pane', array('region_id' => $region_id, 'region_title' => $this->plugins['layout']['regions'][$region_id]));
|
||||
|
||||
// Wrap the placeholder in some guaranteed markup.
|
||||
$control = '<div class="panels-ipe-placeholder panels-ipe-on panels-ipe-portlet-marker panels-ipe-portlet-static">' . $empty_ph . theme('panels_ipe_add_pane_button', array('region_id' => $region_id, 'display' => $this->display, 'renderer' => $this)) . "</div>";
|
||||
|
||||
$output = parent::render_region($region_id, $panes);
|
||||
$output = theme('panels_ipe_region_wrapper', array('output' => $output, 'region_id' => $region_id, 'display' => $this->display, 'controls' => $control, 'renderer' => $this));
|
||||
$classes = 'panels-ipe-region';
|
||||
|
||||
return "<div id='panels-ipe-regionid-$region_id' class='panels-ipe-region'>$output</div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a generic lock test.
|
||||
*/
|
||||
function ipe_test_lock($url, $break) {
|
||||
if (!empty($this->cache->locked)) {
|
||||
if ($break != 'break') {
|
||||
$account = user_load($this->cache->locked->uid);
|
||||
$name = format_username($account);
|
||||
$lock_age = format_interval(time() - $this->cache->locked->updated);
|
||||
|
||||
$message = t("This panel is being edited by user !user, and is therefore locked from editing by others. This lock is !age old.\n\nClick OK to break this lock and discard any changes made by !user.", array('!user' => $name, '!age' => $lock_age));
|
||||
|
||||
$this->commands[] = array(
|
||||
'command' => 'unlockIPE',
|
||||
'message' => $message,
|
||||
'break_path' => url($this->get_url($url, 'break')),
|
||||
'key' => $this->clean_key,
|
||||
);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Break the lock.
|
||||
panels_edit_cache_break_lock($this->cache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback to unlock the IPE.
|
||||
*
|
||||
* This is called whenever something server side determines that editing
|
||||
* has stopped and cleans up no longer needed locks.
|
||||
*
|
||||
* It has no visible return value as this is considered a background task
|
||||
* and the client side has already given all indications that things are
|
||||
* now in a 'normal' state.
|
||||
*/
|
||||
function ajax_unlock_ipe() {
|
||||
panels_edit_cache_clear($this->cache);
|
||||
$this->commands[] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX entry point to create the controller form for an IPE.
|
||||
*/
|
||||
function ajax_save_form($break = NULL) {
|
||||
if ($this->ipe_test_lock('save-form', $break)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the $_POST['ajax_html_ids'] values to preserve
|
||||
// proper IDs on form elements when they are rebuilt
|
||||
// by the Panels IPE without refreshing the page
|
||||
$_POST['ajax_html_ids'] = array();
|
||||
|
||||
$form_state = array(
|
||||
'renderer' => $this,
|
||||
'display' => &$this->display,
|
||||
'content_types' => $this->cache->content_types,
|
||||
'rerender' => FALSE,
|
||||
'no_redirect' => TRUE,
|
||||
// Panels needs this to make sure that the layout gets callbacks
|
||||
'layout' => $this->plugins['layout'],
|
||||
);
|
||||
|
||||
$output = drupal_build_form('panels_ipe_edit_control_form', $form_state);
|
||||
if (empty($form_state['executed'])) {
|
||||
// At this point, we want to save the cache to ensure that we have a lock.
|
||||
$this->cache->ipe_locked = TRUE;
|
||||
panels_edit_cache_set($this->cache);
|
||||
$this->commands[] = array(
|
||||
'command' => 'initIPE',
|
||||
'key' => $this->clean_key,
|
||||
'data' => drupal_render($output),
|
||||
'lockPath' => url($this->get_url('unlock_ipe')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see if we have a lock that was broken. If so we need to
|
||||
// inform the user and abort.
|
||||
if (empty($this->cache->ipe_locked)) {
|
||||
$this->commands[] = ajax_command_alert(t('A lock you had has been externally broken, and all your changes have been reverted.'));
|
||||
$this->commands[] = array(
|
||||
'command' => 'cancelIPE',
|
||||
'key' => $this->clean_key,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise it was submitted.
|
||||
if (!empty($form_state['clicked_button']['#save-display'])) {
|
||||
// Saved. Save the cache.
|
||||
panels_edit_cache_save($this->cache);
|
||||
// A rerender should fix IDs on added panes as well as ensure style changes are
|
||||
// rendered.
|
||||
$this->meta_location = 'inline';
|
||||
$this->commands[] = ajax_command_replace("#panels-ipe-display-{$this->clean_key}", panels_render_display($this->display, $this));
|
||||
}
|
||||
else {
|
||||
// Cancelled. Clear the cache.
|
||||
panels_edit_cache_clear($this->cache);
|
||||
}
|
||||
|
||||
$this->commands[] = array(
|
||||
'command' => 'endIPE',
|
||||
'key' => $this->clean_key,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX entry point to create the controller form for an IPE.
|
||||
*/
|
||||
function ajax_change_layout($break = NULL) {
|
||||
if ($this->ipe_test_lock('change_layout', $break)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point, we want to save the cache to ensure that we have a lock.
|
||||
$this->cache->ipe_locked = TRUE;
|
||||
panels_edit_cache_set($this->cache);
|
||||
|
||||
ctools_include('plugins', 'panels');
|
||||
ctools_include('common', 'panels');
|
||||
|
||||
// @todo figure out a solution for this, it's critical
|
||||
if (isset($this->display->allowed_layouts)) {
|
||||
$layouts = $this->display->allowed_layouts;
|
||||
}
|
||||
else {
|
||||
$layouts = panels_common_get_allowed_layouts('panels_page');
|
||||
}
|
||||
|
||||
// Filter out builders
|
||||
$layouts = array_filter($layouts, '_panels_builder_filter');
|
||||
|
||||
// Define the current layout
|
||||
$current_layout = $this->plugins['layout']['name'];
|
||||
|
||||
$output = panels_common_print_layout_links($layouts, $this->get_url('set_layout'), array('attributes' => array('class' => array('use-ajax'))), $current_layout);
|
||||
|
||||
$this->commands[] = ctools_modal_command_display(t('Change layout'), $output);
|
||||
$this->commands[] = array(
|
||||
'command' => 'IPEsetLockState',
|
||||
'key' => $this->clean_key,
|
||||
'lockPath' => url($this->get_url('unlock_ipe')),
|
||||
);
|
||||
}
|
||||
|
||||
function ajax_set_layout($layout) {
|
||||
ctools_include('context');
|
||||
ctools_include('display-layout', 'panels');
|
||||
$form_state = array(
|
||||
'layout' => $layout,
|
||||
'display' => $this->display,
|
||||
'finish' => t('Save'),
|
||||
'no_redirect' => TRUE,
|
||||
);
|
||||
|
||||
// Reset the $_POST['ajax_html_ids'] values to preserve
|
||||
// proper IDs on form elements when they are rebuilt
|
||||
// by the Panels IPE without refreshing the page
|
||||
$_POST['ajax_html_ids'] = array();
|
||||
|
||||
$output = drupal_build_form('panels_change_layout', $form_state);
|
||||
$output = drupal_render($output);
|
||||
if (!empty($form_state['executed'])) {
|
||||
if (isset($form_state['back'])) {
|
||||
return $this->ajax_change_layout();
|
||||
}
|
||||
|
||||
if (!empty($form_state['clicked_button']['#save-display'])) {
|
||||
// Saved. Save the cache.
|
||||
panels_edit_cache_save($this->cache);
|
||||
$this->display->skip_cache;
|
||||
|
||||
// Since the layout changed, we have to update these things in the
|
||||
// renderer in order to get the right settings.
|
||||
$layout = panels_get_layout($this->display->layout);
|
||||
$this->plugins['layout'] = $layout;
|
||||
if (!isset($layout['regions'])) {
|
||||
$this->plugins['layout']['regions'] = panels_get_regions($layout, $this->display);
|
||||
}
|
||||
|
||||
$this->meta_location = 'inline';
|
||||
|
||||
$this->commands[] = ajax_command_replace("#panels-ipe-display-{$this->clean_key}", panels_render_display($this->display, $this));
|
||||
$this->commands[] = ctools_modal_command_dismiss();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->commands[] = ctools_modal_command_display(t('Change layout'), $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a command array to redraw a pane.
|
||||
*/
|
||||
function command_update_pane($pid) {
|
||||
if (is_object($pid)) {
|
||||
$pane = $pid;
|
||||
}
|
||||
else {
|
||||
$pane = $this->display->content[$pid];
|
||||
}
|
||||
|
||||
$this->commands[] = ajax_command_replace("#panels-ipe-paneid-$pane->pid", $this->render_pane($pane));
|
||||
$this->commands[] = ajax_command_changed("#panels-ipe-display-{$this->clean_key}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a command array to add a new pane.
|
||||
*/
|
||||
function command_add_pane($pid) {
|
||||
if (is_object($pid)) {
|
||||
$pane = $pid;
|
||||
}
|
||||
else {
|
||||
$pane = $this->display->content[$pid];
|
||||
}
|
||||
|
||||
$this->commands[] = ajax_command_prepend("#panels-ipe-regionid-{$pane->panel} div.panels-ipe-sort-container", $this->render_pane($pane));
|
||||
$this->commands[] = ajax_command_changed("#panels-ipe-display-{$this->clean_key}");
|
||||
$this->commands[] = array(
|
||||
'command' => 'addNewPane',
|
||||
'key' => $this->clean_key,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FAPI callback to create the Save/Cancel form for the IPE.
|
||||
*/
|
||||
function panels_ipe_edit_control_form($form, &$form_state) {
|
||||
$display = &$form_state['display'];
|
||||
// @todo -- this should be unnecessary as we ensure cache_key is set in add_meta()
|
||||
// $display->cache_key = isset($display->cache_key) ? $display->cache_key : $display->did;
|
||||
|
||||
// Annoyingly, theme doesn't have access to form_state so we have to do this.
|
||||
$form['#display'] = $display;
|
||||
|
||||
$layout = panels_get_layout($display->layout);
|
||||
$layout_panels = panels_get_regions($layout, $display);
|
||||
|
||||
$form['panel'] = array('#tree' => TRUE);
|
||||
$form['panel']['pane'] = array('#tree' => TRUE);
|
||||
|
||||
foreach ($layout_panels as $panel_id => $title) {
|
||||
// Make sure we at least have an empty array for all possible locations.
|
||||
if (!isset($display->panels[$panel_id])) {
|
||||
$display->panels[$panel_id] = array();
|
||||
}
|
||||
|
||||
$form['panel']['pane'][$panel_id] = array(
|
||||
// Use 'hidden' instead of 'value' so the js can access it.
|
||||
'#type' => 'hidden',
|
||||
'#default_value' => implode(',', (array) $display->panels[$panel_id]),
|
||||
);
|
||||
}
|
||||
|
||||
$form['buttons']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
'#id' => 'panels-ipe-save',
|
||||
'#attributes' => array('class' => array('panels-ipe-save')),
|
||||
'#submit' => array('panels_edit_display_form_submit'),
|
||||
'#save-display' => TRUE,
|
||||
);
|
||||
$form['buttons']['cancel'] = array(
|
||||
'#type' => 'submit',
|
||||
'#id' => 'panels-ipe-cancel',
|
||||
'#attributes' => array('class' => array('panels-ipe-cancel')),
|
||||
'#value' => t('Cancel'),
|
||||
);
|
||||
return $form;
|
||||
}
|