Last active
September 12, 2016 18:32
-
-
Save JanCK/be468cf07ef8dd105f438ec3c3059d50 to your computer and use it in GitHub Desktop.
syncview getkirby plugin / field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Append to your config.php | |
*/ | |
c::set('routes', array( | |
// SYNCVIEW Route for JSON POST request calls helper to check target url for last modification | |
array( | |
'pattern' => 'syncview', | |
'action' => function() { | |
// check if a request happend | |
if(kirby()->request()->ajax()) | |
{ | |
// check if timestamp is integer / set url | |
if( v::integer( kirby()->request()->data()['timestamp'] ) ) | |
{ | |
$t = kirby()->request()->data()['timestamp']; | |
$url = kirby()->request()->data()['route']; | |
} | |
// validate url | |
if( isset($t) && isset($url) && !filter_var($url, FILTER_VALIDATE_URL) === false) | |
{ | |
return response::json( Helpers::pageHasChanged( $url , $t) ); | |
} | |
} | |
// error response | |
return response::json( array('error'=>'404') ); | |
},'method' => 'POST' | |
) | |
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if(!defined('KIRBY')) exit; | |
/* | |
Place the syncview field within your blueprint to use the splitview for specific panel forms only. | |
*/ | |
?> | |
title: Test | |
fields: | |
syncview: | |
help: Use shortcuts to toggle live preview (expand = alt + left arrow / collapse = alt + right arrow / close = escape) | |
type: syncview | |
width: 1 | |
title: | |
label: Title | |
type: text | |
text: | |
label: Text | |
type: textarea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Place in fields/syncview/assets/css and remove fields.syncview.assets.css. frome file name | |
*/ | |
body.hasSyncView .section form > *, | |
body.hasSyncView #syncview-wrapper | |
{ | |
-webkit-user-select: none; /* Chrome all / Safari all */ | |
-moz-user-select: none; /* Firefox all */ | |
-ms-user-select: none; /* IE 10+ */ | |
user-select: none; | |
} | |
body.hasSyncView .syncview{ | |
position: relative; | |
float:right; | |
width: 50%; | |
} | |
body.hasSyncView .syncview * { | |
box-sizing: border-box; | |
} | |
body.hasSyncView .mainbar { | |
left: 50%; | |
width: calc(50% + 15px); | |
right: none; | |
} | |
body.hasSyncView .mainbar .section{ | |
left: 0; | |
} | |
body.hasSyncView .fieldset.buttons.buttons-centered{ | |
position: relative; | |
left: 0 !important; | |
width: auto; | |
max-width: inherit !important; | |
} | |
body.hasSyncView #syncview{ | |
float:right; | |
position: relative; | |
top: 0; | |
width: calc(100% - 20px); | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
z-index: 0; | |
} | |
body.hasSyncView .mainbar, | |
body.hasSyncView #syncview iframe{ | |
overflow:auto; | |
} | |
body.hasSyncView .mainbar.syncview-noscroll, | |
body.hasSyncView #syncview.syncview-noscroll iframe{ | |
overflow:hidden !important; | |
} | |
body.hasSyncView.syncview-fullsize, | |
body.hasSyncView.syncview-half, | |
body.hasSyncView.syncview-hidden, | |
body.hasSyncView #syncview-wrapper, | |
body.hasSyncView .mainbar{ | |
-webkit-transition: all 0.2s linear; | |
-moz-transition: all 0.2s linear; | |
-ms-transition: all 0.2s linear; | |
-o-transition: all 0.2s linear; | |
transition: all 0.2s linear; | |
} | |
body.hasSyncView.syncview-dragging #syncview-wrapper, | |
body.hasSyncView.syncview-dragging .mainbar { | |
-webkit-transition: none; | |
-moz-transition: none; | |
-ms-transition: none; | |
-o-transition: none; | |
transition: none; | |
} | |
body.hasSyncView.syncview-fullsize #syncview-wrapper{ | |
width: 100vw !important; | |
} | |
body.hasSyncView.syncview-hidden #syncview-wrapper{ | |
width: 0px !important; | |
display:none; | |
} | |
body.hasSyncView.syncview-fullsize .mainbar{ | |
width: 100%; | |
} | |
body.hasSyncView.syncview-half #syncview-wrapper{ | |
width: 50vw !important; | |
} | |
body.hasSyncView.syncview-half .mainbar{ | |
width: 100%; | |
} | |
body.hasSyncView.syncview-hidden .mainbar{ | |
width: 100%; | |
} | |
@media screen and (min-width: 820px) { | |
body.hasSyncView.syncview-fullsize .mainbar{ | |
width: calc(33.33vw + 15px) !important; | |
} | |
body.hasSyncView.syncview-half #syncview-wrapper{ | |
width: 33.33vw !important; | |
} | |
body.hasSyncView.syncview-half .mainbar{ | |
width: calc(33.33vw + 40px) !important; | |
} | |
body.hasSyncView.syncview-hidden .mainbar{ | |
width: calc(66.66vw) !important; | |
} | |
body.hasSyncView #syncview-wrapper{ | |
top: 48px; | |
} | |
body.hasSyncView .mainbar { | |
left: 33vw; | |
min-width: calc(33vw + 15px) !important; | |
width: calc(33vw + 15px); | |
right: none; | |
} | |
} | |
body.hasSyncView #syncview-wrapper{ | |
position: fixed; | |
right: 0; | |
top: 0; | |
bottom: 0; | |
z-index: 999 !important; | |
background: #FFF; | |
resize: both; | |
overflow: auto; | |
margin: 0; | |
padding: 0; | |
border:none; | |
width: 33%; | |
max-width:100% !important; | |
} | |
body.hasSyncView #syncview-handler{ | |
border:none; | |
z-index: 1; | |
position: relative; | |
left: 0; | |
top: 0; | |
float:left; | |
width: 20px; | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
background-color: #444; | |
-webkit-transition: background-color 0.2s ease-in-out; | |
-moz-transition: background-color 0.2s ease-in-out; | |
-ms-transition: background-color 0.2s ease-in-out; | |
-o-transition: background-color 0.2s ease-in-out; | |
transition: background-color 0.2s ease-in-out; | |
} | |
body.hasSyncView #syncview-handler:hover{ | |
cursor: ew-resize; | |
background-color: #888; | |
-webkit-transition: background-color 0.2s ease-in-out; | |
-moz-transition: background-color 0.2s ease-in-out; | |
-ms-transition: background-color 0.2s ease-in-out; | |
-o-transition: background-color 0.2s ease-in-out; | |
transition: background-color 0.2s ease-in-out; | |
} | |
body.hasSyncView #syncview-handler:after{ | |
content:""; | |
position: absolute; | |
background: transparent; | |
left: 0; | |
top: 0; | |
bottom: 0; | |
width:100px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Place in fields/syncview/assets/js and remove fields.syncview.assets.js. frome file name | |
*/ | |
(function() | |
{ | |
jQuery(document).ready(function(event) | |
{ | |
var alt = false; // alt shortcut | |
var classes = ['syncview-hidden','syncview-half','syncview-fullsize']; // breakpoint classes defined in style.css | |
var position = 0; // breakpoint pointer | |
var len = classes.length - 1; // number of breakpoints | |
var polled = true; // longpolling active | |
function init() | |
{ | |
// inject within scope of mainbar | |
jQuery('.mainbar').append(jQuery('.syncview')); | |
if(jQuery('#syncview').length <= 0) jQuery('body').removeClass('hasSyncView'); | |
else jQuery('body').addClass('hasSyncView'); | |
// resize handle behavior | |
jQuery('#syncview-handler').on('mousedown',function(e) | |
{ | |
var w; // position x | |
jQuery('body').removeClass('syncview-half').removeClass('syncview-hidden').removeClass('syncview-fullsize').addClass('syncview-dragging'); | |
jQuery('body').on( 'mousemove' , | |
function( e2 ) | |
{ | |
if(!jQuery('.hasSyncView').length < 0) return false; | |
w = window.innerWidth - e2.pageX + 10; | |
jQuery('#syncview-wrapper').width( w ); | |
if( window.innerWidth > 820 ) | |
jQuery('.mainbar').width( window.innerWidth - w - window.innerWidth * 0.3 - 20 ); | |
else | |
jQuery('.mainbar').width( window.innerWidth - 40 ); | |
} | |
); | |
jQuery('body').on('mouseup', | |
function() | |
{ | |
if(!jQuery('.hasSyncView').length < 0) return false; | |
jQuery(this).off('mousemove'); | |
jQuery(this).removeClass('syncview-dragging'); | |
} | |
); | |
}); | |
// enable scrolling in iframe | |
jQuery('#syncview').on('mouseover', | |
function( event ) | |
{ | |
if(!jQuery('.hasSyncView').length < 0) return false; | |
jQuery('#syncview').removeClass('syncview-noscroll'); | |
jQuery('.mainbar').addClass('syncview-noscroll'); | |
} | |
); | |
jQuery('#syncview').on('mouseout', | |
function( event ) | |
{ | |
if(!jQuery('.hasSyncView').length < 0) return false; | |
jQuery('#syncview').addClass('syncview-noscroll'); | |
jQuery('.mainbar').removeClass('syncview-noscroll'); | |
} | |
); | |
// long polling refresh: timestamp from static helper class compares Unix last modified stamp with json submitted looped | |
var timestamp = 0; | |
var server = 'http://127.0.0.1/___projekte___/getkirby/kirby-2.2.3/'; | |
var route = jQuery('#syncview').attr('src'); | |
var longPoll = function() | |
{ | |
var data = new Object(); | |
data.timestamp = timestamp; | |
data.route = route + '?time=' + new Date().getTime(); | |
jQuery.ajax({ | |
url: server + 'syncview/', | |
dataType: 'json', | |
type: 'post', | |
data: data, | |
contentType: 'application/x-www-form-urlencoded', | |
success: function( res, textStatus, jQxhr ) | |
{ | |
if(!jQuery('body').hasClass('hasSyncView')) | |
return false; | |
console.log(res) | |
// replace last timestamp | |
timestamp = res.timestamp; | |
if(res.changed === true) | |
{ | |
// refresh iframe | |
jQuery('#syncview').attr('src', route); | |
} | |
setTimeout(function() | |
{ | |
longPoll(data.route); | |
}, 1000); | |
}, | |
error: function( jqXhr, textStatus, errorThrown ){ | |
console.log( jqXhr, textStatus, errorThrown ); | |
} | |
}); | |
} | |
longPoll(); | |
} | |
// shortcuts | |
jQuery(window).keydown( | |
// start alt | |
function(event) | |
{ | |
if(!jQuery('.hasSyncView').length < 0 ) return false; | |
if( event.keyCode == 18 ){ | |
alt = true; | |
} | |
if(jQuery(event.target).is('input') || jQuery(event.target).is('textarea')) | |
alt = false; | |
} | |
); | |
jQuery(window).keyup( | |
function(event) | |
{ | |
if(jQuery('#syncview').length <= 0 || !jQuery('.hasSyncView').length < 0 ) return false; | |
switch( event.keyCode ){ | |
// alt + arrow Left | |
case 37: | |
if(alt == true && position >= 0 && position < len) | |
{ | |
position++; | |
} | |
break; | |
// alt + arrow right | |
case 39: | |
if(alt == true && position > 0 && position <= len) | |
{ | |
position--; | |
} | |
break; | |
// escape | |
case 27: | |
position = 0; | |
break; | |
// dissolve alt | |
case 18: | |
alt = false; | |
} | |
jQuery('body').removeClass('syncview-fullsize').removeClass('syncview-half').removeClass('syncview-hidden').addClass(classes[position]); | |
} | |
); | |
// dom observation to kill layout in abscense of field syncview | |
if( jQuery(event.target).find('#syncview').length == 1 ) | |
{ | |
jQuery('body').addClass('hasSyncView'); | |
} | |
// unregistrate dom elements to toggle events | |
jQuery('body').on('DOMNodeRemoved', function(event) | |
{ | |
if(polled == true) return false; | |
if( jQuery(event.target).find('.syncview').length == 1 ) | |
{ | |
polled = true; | |
if(jQuery('body').hasClass('hasSyncView')) | |
{ | |
jQuery('body').removeClass('hasSyncView'); | |
} | |
} | |
}); | |
// registrate dom elements to toggle events | |
jQuery('body').on('DOMNodeInserted', function(event) | |
{ | |
if(polled == false) return false; | |
if( jQuery(event.target).find('.syncview').length == 1 ) | |
{ | |
polled = false; | |
if(!jQuery('body').hasClass('hasSyncView')) | |
{ | |
jQuery('body').addClass('hasSyncView'); | |
init(); | |
} | |
} | |
}); | |
init(); | |
}); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Place in fields/syncview and remove fields.syncview. frome file name | |
*/ | |
class SyncviewField extends BaseField { | |
static public $assets = array( | |
'js' => array( | |
'script.js' | |
), | |
'css' => array( | |
'style.css' | |
) | |
); | |
public function icon() { | |
if(empty($this->icon)) { | |
return null; | |
} else if($this->readonly()) { | |
$this->icon = 'refresh'; | |
} | |
return 'icon fa fa-' . $this->icon; | |
} | |
public function result() { | |
return null; | |
} | |
public function content() | |
{ | |
$wrapper = new Brick('div'); | |
$wrapper->addClass('syncview'); | |
$wrapper->html(tpl::load(__DIR__ . DS . 'template.php', array('page' => $this->page()))); | |
return $wrapper; | |
} | |
public function element() { | |
$element = parent::element(); | |
return $element; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Place in fields/syncview and remove fields.syncview frome file name | |
*/ | |
?> | |
<div id="syncview-wrapper"> | |
<iframe id="syncview" height="100%" width="100%" src="<?php echo $page->url(); ?>" seamless="seamless" | |
frameborder="0" marginheight="0" marginwidth="0" noresize="noresize"> | |
</iframe> | |
<div id="syncview-handler"></div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Place in plugins and remove plugins. frome file name | |
*/ | |
class Helpers { | |
// Syncview | |
public static function pageHasChanged($path, $timestamp) | |
{ | |
// make url a uri path | |
$modified = str_replace( url::index(),'',$path); | |
foreach ( site()->languages() as $lang ){ | |
// clear path from language codes | |
$modified = str_replace( '/'.$lang->code().'/' , '/' , $modified); | |
} | |
// get last mod from folder | |
/*$p = site()->find( strtok( $modified , '?' ) )->root(); | |
$modified = file_exists($p) ? filemtime( $p ) : '';*/ | |
$modified = site()->find( strtok( $modified , '?' ) )->modified(); | |
// append bool to avoid doubled timestamp comparision so JS success handler passes new timestamp and uses bool to take action | |
$is = ($modified > $timestamp) ? TRUE : FALSE; | |
return array('timestamp' => $modified , 'changed' => $is); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment