Commit da7820e9 authored by nextime's avatar nextime

* Themable support

 * add dmblack theme and make default
 * better webapp management
 * fixed orientation on ff mobile
 * better manage of snapper panels
 * fix minor bugs in the web gui
 * styled scrollbars
parent d64227e0
ALTER TABLE `users` ADD `gui_theme` VARCHAR( 255 ) NOT NULL DEFAULT 'dmblack', ADD INDEX ( `gui_theme` ) ;
......@@ -9,7 +9,7 @@ if(intval($button['status2'])>0) {
$badgetext=$button['text2_on'];
}
?>
<div class="devlist-item">
<div class="devlist-item devlist-item-theme-<?=$_DOMOTIKA['gui_theme']?>">
<div class="devlist-row">
<div class="devlist-leftpart">
<h4 class="devlist-name"><?=$button['button_name']?></h4>
......
......@@ -23,7 +23,7 @@ if(floatval($button['status'])==floatval($button['minval']))
$pbcoln="progress-bar-";
$perc=(floatval($button['status'])-floatval($button['minval']))*100/(floatval($button['maxval'])-floatval($button['minval']))
?>
<div class="devlist-item">
<div class="devlist-item devlist-item-theme-<?=$_DOMOTIKA['gui_theme']?>">
<div class="devlist-row">
<div class="devlist-leftpart">
<h4 class="devlist-name"><?=$button['button_name']?></h4>
......
......@@ -18,7 +18,7 @@ if(intval($button['status'])>0) {
$button_text=$button['text_on'];
}
?>
<div class="devlist-item">
<div class="devlist-item devlist-item-theme-<?=$_DOMOTIKA['gui_theme']?>">
<div class="devlist-row">
<div class="devlist-leftpart">
<h4 class="devlist-name"><?=$button['button_name']?></h4>
......
......@@ -12,7 +12,7 @@ $button_switchar=array(
);
?>
<?//print_r($button['inputs']);?>
<div class="devlist-item">
<div class="devlist-item devlist-item-theme-<?=$_DOMOTIKA['gui_theme']?>">
<div class="devlist-row">
<div class="devlist-leftpart">
<h4 class="devlist-name"><?=$button['button_name']?></h4>
......
......@@ -23,7 +23,7 @@ if($ampere>0 && $ampere<8) {
}
?>
<div class="devlist-item">
<div class="devlist-item devlist-item-theme-<?=$_DOMOTIKA['gui_theme']?>">
<div class="devlist-row">
<div class="devlist-leftpart">
<h4 class="devlist-name"><?=$button['button_name']?></h4>
......
......@@ -162,6 +162,9 @@
height: 100%;
bottom: 50px;
}
.theme-dmblack {
background-color: #000;
}
.container {
padding-top: 100px;
......@@ -332,6 +335,11 @@ input::-webkit-input-speech-button {
display:table;
}
.devlist-item-theme-dmblack{
background-color: rgb(24,24,24);
border: 0px;
}
.devlist-row {
display:table-row;
margin-top: 0px;
......@@ -447,6 +455,52 @@ input::-webkit-input-speech-button {
.flowplayer { background-image: url(/resources/img/logo_unixmedia.png)}
.flowplayer .fp-duration { display:none; }
.panel-theme-dmblack {
background-color: #000;
border: 0px;
}
.panel-head-theme-dmblack {
background-color: #2a2ac0;
border-bottom: 0px;
margin: 0px;
}
body.theme-dmblack {
color: #fff;
}
@media (min-width: 640px) {
body {
scrollbar-base-color: #C0C0C0;
scrollbar-base-color: #C0C0C0;
scrollbar-3dlight-color: #C0C0C0;
scrollbar-highlight-color: #C0C0C0;
scrollbar-track-color: #EBEBEB;
scrollbar-arrow-color: black;
scrollbar-shadow-color: #C0C0C0;
scrollbar-dark-shadow-color: #C0C0C0;
}
::-webkit-scrollbar { width: 10px; height: 3px;}
::-webkit-scrollbar-button { background-color: #666; }
::-webkit-scrollbar-track { background-color: #999;}
::-webkit-scrollbar-track-piece { background-color: #ffffff;}
::-webkit-scrollbar-thumb { height: 50px; background-color: #666; border-radius: 3px;}
::-webkit-scrollbar-corner { background-color: #999;}
::-webkit-resizer { background-color: #666;}
::-moz-scrollbar { width: 10px;}
::-moz-scrollbar-track { -moz-box-shadow: inset 0 0 6px #fff); background:#000;}
::-moz-scrollbar-thumb { border-radius: 10px; -moz-box-shadow: inset 0 0 6px #fff; background:#7A252B;}
};
@media (max-width: 640px) {
.navbar-title {
text-align: left;
......
......@@ -12,6 +12,7 @@ var updateUser = function(r) {
$("#lang").val(r.data.language);
$("#webspeech").val(r.data.webspeech);
$("#speechlang").val(r.data.speechlang);
$("#gui_theme").val(r.data.gui_theme);
if(r.data.tts==1)
$('#tts-switch').bootstrapSwitch('setState', true); //$("#tts").attr('checked', true);
else
......@@ -36,7 +37,10 @@ $("#userform").on("submit", function(event) {
$.ajax({url: "/rest/v1.2/users/me/json", type:"PUT", data: $(this).serialize(),
success: function(res) {
popupFader('success', 'SUCCESS:','Utente aggiornato correttamente...');
playTTS('Utente aggiornato correttamente');
var a = playTTS('Utente aggiornato correttamente');
a.addEventListener("ended", function(){
$.get("/rest/v1.2/users/refreshme/json", function(){location.reload();});
});
},
error: function(res) {
msg=$.parseJSON(res.responseText).data;
......
......@@ -36,6 +36,10 @@ $dmcolors=array(
include_once("common_includes.php");
@include_once("config.php");
include_once("translations.php");
//print_r($_DOMOTIKA);
$lang=$_DOMOTIKA['language'];
$tr = new Translations($lang);
$img = new Translations("icons");
......
......@@ -8,7 +8,7 @@
<?=$PAGE_BUFFER['head']?>
<?=$PAGE_ADDHEAD?>
</head>
<body>
<body class="theme-<?=$_DOMOTIKA['gui_theme']?>">
<?=$PAGE_BUFFER['alerts']?>
<?=$PAGE_BUFFER['navbar']?>
<div class="drawers">
......@@ -17,8 +17,8 @@
<?=$PAGE_BUFFER['right_drawer']?>
<?=$PAGE_ADDRIGHT?>
</div> <!-- drawers -->
<div id="content" class="primarycontainer scrollable">
<div class="container">
<div id="content" class="primarycontainer scrollable theme-<?=$_DOMOTIKA['gui_theme']?>">
<div class="container theme-<?=$_DOMOTIKA['gui_theme']?>">
<?=$PAGE_BUFFER['content']?>
</div> <!-- container -->
</div> <!-- primarycontainer -->
......
<? @include_once("../includes/common.php");?>
//document.documentElement.requestFullscreen();
//window.screen.mozLockOrientation('portrait');
var windowWidth = window.screen.width < window.outerWidth ?
window.screen.width : window.outerWidth;
var mobile = windowWidth < 500;
var ttsEnabled=<?=$_DOMOTIKA['tts']?>;
var slideEnabled=<?=$_DOMOTIKA['slide']?>;
......@@ -12,6 +17,70 @@
//})
var audioTagSupport = !!(document.createElement('audio').canPlayType);
/*
function DoFullScreen() {
if (!document.fullscreenElement && // alternative standard method
!document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { // current working methods
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.msRequestFullscreen) {
document.documentElement.msRequestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
}
*/
if(mobile)
{
if(window.navigator.userAgent.match(/firefox/i) && window.navigator.userAgent.match(/mobile/i))
{
var installbutton = $("#installbutton");
var port="";
if(document.location.port)
var port=":"+document.location.port;
var manifest_url = document.location.protocol+"//"+document.location.host+port+"<?=str_replace("/js/domotika.js","",$BASEGUIPATH)?>/manifest.webapp";
function installFFApp(ev) {
ev.preventDefault();
var myapp = navigator.mozApps.install(manifest_url);
myapp.onsuccess = function(data) {
$("#install_ff").hide()
console.log(this);
alert('Web Application installed.');
};
myapp.onerror = function() {
console.log('Install failed, error: ' + this.error.name);
alert('Install failed, error: ' + this.error.name);
};
};
var installCheck = navigator.mozApps.checkInstalled(manifest_url);
installCheck.onsuccess = function() {
if(installCheck.result) {
$("#install_ff").hide();
} else {
$("#install_ff").show();
installbutton.on('click', installFFApp);
};
};
}
if(jQuery.isFunction(window.screen.lockOrientation))
window.screen.lockOrientation('portrait');
else if(jQuery.isFunction(window.screen.mozLockOrientation))
window.screen.mozLockOrientation('portrait');
else if(jQuery.isFunction(window.screen.msLockOrientation))
window.screen.msLockOrientation('portrait');
else if(jQuery.isFunction(window.screen.webkitLockOrientation))
window.screen.webkitLockOrientation('portrait');
}
function tmpPopover(el, cont, placement, timeout)
{
......@@ -36,11 +105,20 @@
if (!audioTagSupport) return false;
if (text=='') return false;
if (ttsEnabled!=1 && force===false) return false;
if($("playTTS_audio").length)
{
var audio = $("playTTS_audio");
}
else
{
var audio = document.createElement('audio');
audio.setAttribute('id' , 'playTTS_audio');
}
// XXX BUG: webkit based browsers seems to not work with https:// in <audio>, so, we fix this to http
audio.setAttribute('src', 'http://translate.google.com/translate_tts?tl='+lang+'&q=' + encodeURIComponent(text));
audio.load();
audio.play();
return audio;
}
function speechResult(data) {
......@@ -141,12 +219,25 @@
<? } ?>
<? if($left || $right) { ?>
snapper.on('animating',
function(e) {
function calcSnapSize()
{
if($(window).width()>768)
mval=Math.min(Math.ceil((75/100)*$(window).width()), 800);
var mval=Math.min(Math.ceil((75/100)*$(window).width()), 800);
else
mval=Math.max(Math.ceil((75/100)*$(window).width()), 266);
var mval=Math.max(Math.ceil((75/100)*$(window).width()), 266);
return mval
}
$(document).ready(function() {
mval = calcSnapSize();
$(".left-drawer").css("width", mval);
$(".right-drawer").css("width", mval)
});
snapper.on('animating',
function(e) {
var mval = calcSnapSize();
<? if($left) { ?>
if(snapper.state().info.opening=='left' && snapper.state().state!='left' && $(".left-drawer").css("width")!=mval+"px")
{
......
......@@ -4,7 +4,7 @@
<h1>Settings</h1>
<ul class="nav nav-tabs">
<li <? if($GUISUBSECTION=="") {?>class="active"<?}?>><a href="<?=$BASEGUIPATH.'/'.$GUISECTION?>">User options</a></li>
<li <? if($GUISUBSECTION=="gui") {?>class="active"<?}?>><a href="<?=$BASEGUIPATH.'/'.$GUISECTION?>/gui">GUI options</a></li>
<!-- <li <? if($GUISUBSECTION=="gui") {?>class="active"<?}?>><a href="<?=$BASEGUIPATH.'/'.$GUISECTION?>/gui">GUI options</a></li> -->
</ul>
<? if($GUISUBSECTION=="") {?>
<div class="formcontainer">
......@@ -91,6 +91,15 @@
</select>
</div>
</div>
<div class="form-group">
<label for="gui_theme" class="col-lg-2 control-label">GUI Theme:</label>
<div class="col-lg-3">
<select name="gui_theme" id="gui_theme" class="form-control">
<option value="dmblack">DM Black</option>
<option value="dmwhite">DM White</option>
</select>
</div>
</div>
<div class="form-group">
<label for="mobilehome" class="col-lg-2 control-label"></label>
<div class="col-lg-3">
......@@ -99,7 +108,7 @@
</div>
</form>
<div>
<?} elseif($GUISUBSECTION=="gui") { // $GUISUBSECTIONOPT?>
<?}/* elseif($GUISUBSECTION=="gui") { // $GUISUBSECTIONOPT?>
<ul class="nav nav-pills nav-stacked">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Profile</a></li>
......@@ -122,7 +131,7 @@
</form>
</div>
<?} else {
<?} */ else {
header("Location: $BASEGUIPATH/settings");
exit(0);
}?>
......@@ -5,11 +5,11 @@ if($panel && is_array($panel)) {
$visible="";
if($panel['panel_visible']!="all") $visible=$panel['panel_visible'];
?>
<div class="panel panel-default col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height: auto">
<div class="panel panel-default panel-theme-<?=$_DOMOTIKA['gui_theme']?> col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height: auto">
<?
if($panel['panel_title']!="") {
?>
<div class="panel-heading"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<div class="panel-heading panel-head-theme-<?=$_DOMOTIKA['gui_theme']?>"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<?
}
......
......@@ -5,11 +5,11 @@ if($panel && is_array($panel)) {
$visible="";
if($panel['panel_visible']!="all") $visible=$panel['panel_visible'];
?>
<div class="panel panel-default col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height: <?=$panel['panel_height']?>">
<div class="panel panel-default panel-theme-<?=$_DOMOTIKA['gui_theme']?> col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height: <?=$panel['panel_height']?>">
<?
if($panel['panel_title']!="") {
?>
<div class="panel-heading"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<div class="panel-heading panel-head-theme-<?=$_DOMOTIKA['gui_theme']?>"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<?
}
......
......@@ -10,11 +10,11 @@ if($panel && is_array($panel)) {
$visible.=" hidden-xs hidden-sm";
}
?>
<div class="panel col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height:<?=$panel['panel_height'];?>;">
<div class="panel panel-theme-<?=$_DOMOTIKA['gui_theme']?> col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height:<?=$panel['panel_height'];?>;">
<?
if($panel['panel_title']!="") {
?>
<div class="panel-heading"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<div class="panel-heading panel-head-theme-<?=$_DOMOTIKA['gui_theme']?>"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<?
}
......@@ -36,7 +36,7 @@ if($panel && is_array($panel)) {
?>
<div class="domotika-panel<?=$dmfull;?>" <?=$dmheight;?>>
<div class="home-panel" <?=$dmheight;?>>
<div class="list-group">
<div class="list-group theme-<?=$_DOMOTIKA['gui_theme']?>">
<?
foreach($buttonar as $button) {
if(file_exists($FSPATH."/buttons/".$button['devtype'].".php"))
......
......@@ -5,11 +5,11 @@ if($panel && is_array($panel)) {
$visible="";
if($panel['panel_visible']!="all") $visible=$panel['panel_visible'];
?>
<div class="panel panel-default col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height: auto">
<div class="panel panel-default panel-theme-<?=$_DOMOTIKA['gui_theme']?> col-lg-<?=$panel['panel_cols']?> panel-media-low <?=$visible?>" style="height: auto">
<?
if($panel['panel_title']!="") {
?>
<div class="panel-heading"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<div class="panel-heading panel-head-theme-<?=$_DOMOTIKA['gui_theme']?>"><h2 class="panel-title"><?=$panel['panel_title']?></h2></div>
<?
}
......
......@@ -3,8 +3,13 @@
$webspeech="";
if($_DOMOTIKA['webspeech']=='touch')
$webspeech='x-webkit-speech="x-webkit-speech"';
$themeclass="";
if($_DOMOTIKA['gui_theme']=='dmblack')
$themeclass="navbar-inverse";
?>
<div class="navbar navbar-fixed-bottom">
<div class="navbar <?=$themeclass?> navbar-fixed-bottom">
<a class="navbar-brand" href="http://www.unixmedia.it" target=_blank>Domotika</a>
<p class="navbar-text hidden-sm"><a href="http://www.unixmedia.it" class="navbar-link" target=_blank>by Unixmedia</a></p>
<button id="speechbutton" type="button" class="btn btn-default navbar-btn pull-right speechbutton"></button>
......@@ -19,10 +24,10 @@ if($_DOMOTIKA['webspeech']=='touch')
</button>
<a class="btn btn-default navbar-btn pull-right homebutton" href="<?=$BASEGUIPATH;?>"></a>
<div id="notifypanel" class="panel notifypanel">
<div class="panel-heading"><h4>Notifications<i class="glyphicon glyphicon-remove pull-right" id="notify-removeall"></i></h4></div>
<div id="notifypanel" class="panel panel-theme-<?=$_DOMOTIKA['gui_theme']?> notifypanel">
<div class="panel-heading panel-head-theme-<?=$_DOMOTIKA['gui_theme']?>"><h4>Notifications<i class="glyphicon glyphicon-remove pull-right" id="notify-removeall"></i></h4></div>
<div class="notifylist">
<div id="notifications" class="list-group" data-snap-ignore="true">
<div id="notifications" class="list-group theme-<?=$_DOMOTIKA['gui_theme']?>" data-snap-ignore="true">
</div>
</div>
</div>
......
......@@ -21,6 +21,7 @@
<link href="/resources/full-glyphicons/css/glyphicons.css" rel="stylesheet" media="screen">
<link href="/resources/bootstrap-switch/static/stylesheets/bootstrap-switch.css" rel="stylesheet" media="screen">
<link href="<?=$BASEGUIPATH;?>/css/style.css" rel="stylesheet" media="screen" />
<? } else { ?>
<link href="<?=$BASEGUIPATH;?>/css/combined.min.css" rel="stylesheet" media="screen" />
<? } ?>
......@@ -13,8 +13,13 @@ function isActive($name)
}
return;
}
$themeclass="";
if($_DOMOTIKA['gui_theme']=='dmblack')
$themeclass="navbar-inverse";
?>
<div id="topbar" class="navbar navbar-fixed-top">
<div id="topbar" class="navbar <?=$themeclass?> navbar-fixed-top">
<? if($left) { ?>
<button id="open-left" type="button" class="navbar-open navbar-openleft">
<i class="glyphicon glyphicon-indent-left"></i>
......@@ -39,6 +44,7 @@ function isActive($name)
<li><a href="<?=$BASEGUIPATH?>"/>Domotika GUI</a></li>
<? } ?>
<li><a href="/admin/">admin gui</a></li>
<li id="install_ff" style="display:none"><a id="installbutton">install as webapp</a></li>
<li><a href="/__LOGOUT__/">Logout</a></li>
</ul>
</li>
......
/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
* Licensed under the MIT License (LICENSE.txt).
*
* Version: 3.1.9
*
* Requires: jQuery 1.2.2+
*/
(function (factory) {
if ( typeof define === 'function' && define.amd ) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS style for Browserify
module.exports = factory;
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
slice = Array.prototype.slice,
nullLowestDeltaTimeout, lowestDelta;
if ( $.event.fixHooks ) {
for ( var i = toFix.length; i; ) {
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
}
}
var special = $.event.special.mousewheel = {
version: '3.1.9',
setup: function() {
if ( this.addEventListener ) {
for ( var i = toBind.length; i; ) {
this.addEventListener( toBind[--i], handler, false );
}
} else {
this.onmousewheel = handler;
}
// Store the line height and page height for this particular element
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
},
teardown: function() {
if ( this.removeEventListener ) {
for ( var i = toBind.length; i; ) {
this.removeEventListener( toBind[--i], handler, false );
}
} else {
this.onmousewheel = null;
}
},
getLineHeight: function(elem) {
return parseInt($(elem)['offsetParent' in $.fn ? 'offsetParent' : 'parent']().css('fontSize'), 10);
},
getPageHeight: function(elem) {
return $(elem).height();
},
settings: {
adjustOldDeltas: true
}
};
$.fn.extend({
mousewheel: function(fn) {
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
},
unmousewheel: function(fn) {
return this.unbind('mousewheel', fn);
}
});
function handler(event) {
var orgEvent = event || window.event,
args = slice.call(arguments, 1),
delta = 0,
deltaX = 0,
deltaY = 0,
absDelta = 0;
event = $.event.fix(orgEvent);
event.type = 'mousewheel';
// Old school scrollwheel delta
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaX = deltaY * -1;
deltaY = 0;
}
// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
delta = deltaY === 0 ? deltaX : deltaY;
// New school wheel delta (wheel event)
if ( 'deltaY' in orgEvent ) {
deltaY = orgEvent.deltaY * -1;
delta = deltaY;
}
if ( 'deltaX' in orgEvent ) {
deltaX = orgEvent.deltaX;
if ( deltaY === 0 ) { delta = deltaX * -1; }
}
// No change actually happened, no reason to go any further
if ( deltaY === 0 && deltaX === 0 ) { return; }
// Need to convert lines and pages to pixels if we aren't already in pixels
// There are three delta modes:
// * deltaMode 0 is by pixels, nothing to do
// * deltaMode 1 is by lines
// * deltaMode 2 is by pages
if ( orgEvent.deltaMode === 1 ) {
var lineHeight = $.data(this, 'mousewheel-line-height');
delta *= lineHeight;
deltaY *= lineHeight;
deltaX *= lineHeight;
} else if ( orgEvent.deltaMode === 2 ) {
var pageHeight = $.data(this, 'mousewheel-page-height');
delta *= pageHeight;
deltaY *= pageHeight;
deltaX *= pageHeight;
}
// Store lowest absolute delta to normalize the delta values
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
if ( !lowestDelta || absDelta < lowestDelta ) {
lowestDelta = absDelta;
// Adjust older deltas if necessary
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
lowestDelta /= 40;
}
}
// Adjust older deltas if necessary
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
// Divide all the things by 40!
delta /= 40;
deltaX /= 40;
deltaY /= 40;
}
// Get a whole, normalized value for the deltas
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
// Add information to the event object
event.deltaX = deltaX;
event.deltaY = deltaY;
event.deltaFactor = lowestDelta;
// Go ahead and set deltaMode to 0 since we converted to pixels
// Although this is a little odd since we overwrite the deltaX/Y
// properties with normalized deltas.
event.deltaMode = 0;
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
// Clearout lowestDelta after sometime to better
// handle multiple device types that give different
// a different lowestDelta
// Ex: trackpad = 3 and mouse wheel = 120
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
return ($.event.dispatch || $.event.handle).apply(this, args);
}
function nullLowestDelta() {
lowestDelta = null;
}
function shouldAdjustOldDeltas(orgEvent, absDelta) {
// If this is an older event and the delta is divisable by 120,
// then we are assuming that the browser is treating this as an
// older mouse wheel event and that we should divide the deltas
// by 40 to try and get a more usable deltaFactor.
// Side note, this actually impacts the reported scroll distance
// in older browsers and can cause scrolling to be slower than native.
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
}
}));
/**
* @author trixta
* @version 1.2
*/
(function($){
var mwheelI = {
pos: [-260, -260]
},
minDif = 3,
doc = document,
root = doc.documentElement,
body = doc.body,
longDelay, shortDelay
;
function unsetPos(){
if(this === mwheelI.elem){
mwheelI.pos = [-260, -260];
mwheelI.elem = false;
minDif = 3;
}
}
$.event.special.mwheelIntent = {
setup: function(){
var jElm = $(this).bind('mousewheel', $.event.special.mwheelIntent.handler);
if( this !== doc && this !== root && this !== body ){
jElm.bind('mouseleave', unsetPos);
}
jElm = null;
return true;
},
teardown: function(){
$(this)
.unbind('mousewheel', $.event.special.mwheelIntent.handler)
.unbind('mouseleave', unsetPos)
;
return true;
},
handler: function(e, d){
var pos = [e.clientX, e.clientY];
if( this === mwheelI.elem || Math.abs(mwheelI.pos[0] - pos[0]) > minDif || Math.abs(mwheelI.pos[1] - pos[1]) > minDif ){
mwheelI.elem = this;
mwheelI.pos = pos;
minDif = 250;
clearTimeout(shortDelay);
shortDelay = setTimeout(function(){
minDif = 10;
}, 200);
clearTimeout(longDelay);
longDelay = setTimeout(function(){
minDif = 3;
}, 1500);
e = $.extend({}, e, {type: 'mwheelIntent'});
return ($.event.dispatch || $.event.handle).apply(this, arguments);
}
}
};
$.fn.extend({
mwheelIntent: function(fn) {
return fn ? this.bind("mwheelIntent", fn) : this.trigger("mwheelIntent");
},
unmwheelIntent: function(fn) {
return this.unbind("mwheelIntent", fn);
}
});
$(function(){
body = doc.body;
//assume that document is always scrollable, doesn't hurt if not
$(doc).bind('mwheelIntent.mwheelIntentDefault', $.noop);
});
})(jQuery);
/*
* CSS Styles that are needed by jScrollPane for it to operate correctly.
*
* Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane
* may not operate correctly without them.
*/
.jspContainer
{
overflow: hidden;
position: relative;
}
.jspPane
{
position: absolute;
}
.jspVerticalBar
{
position: absolute;
top: 0;
right: 0;
width: 16px;
height: 100%;
background: red;
}
.jspHorizontalBar
{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 16px;
background: red;
}
.jspCap
{
display: none;
}
.jspHorizontalBar .jspCap
{
float: left;
}
.jspTrack
{
background: #dde;
position: relative;
}
.jspDrag
{
background: #bbd;
position: relative;
top: 0;
left: 0;
cursor: pointer;
}
.jspHorizontalBar .jspTrack,
.jspHorizontalBar .jspDrag
{
float: left;
height: 100%;
}
.jspArrow
{
background: #50506d;
text-indent: -20000px;
display: block;
cursor: pointer;
padding: 0;
margin: 0;
}
.jspArrow.jspDisabled
{
cursor: default;
background: #80808d;
}
.jspVerticalBar .jspArrow
{
height: 16px;
}
.jspHorizontalBar .jspArrow
{
width: 16px;
float: left;
height: 100%;
}
.jspVerticalBar .jspArrow:focus
{
outline: none;
}
.jspCorner
{
background: #eeeef4;
float: left;
height: 100%;
}
/* Yuk! CSS Hack for IE6 3 pixel bug :( */
* html .jspCorner
{
margin: 0 -3px 0 0;
}
\ No newline at end of file
/*!
* jScrollPane - v2.0.19 - 2013-11-16
* http://jscrollpane.kelvinluck.com/
*
* Copyright (c) 2013 Kelvin Luck
* Dual licensed under the MIT or GPL licenses.
*/
// Script: jScrollPane - cross browser customisable scrollbars
//
// *Version: 2.0.19, Last updated: 2013-11-16*
//
// Project Home - http://jscrollpane.kelvinluck.com/
// GitHub - http://github.com/vitch/jScrollPane
// Source - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.js
// (Minified) - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.min.js
//
// About: License
//
// Copyright (c) 2013 Kelvin Luck
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
// http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
//
// About: Examples
//
// All examples and demos are available through the jScrollPane example site at:
// http://jscrollpane.kelvinluck.com/
//
// About: Support and Testing
//
// This plugin is tested on the browsers below and has been found to work reliably on them. If you run
// into a problem on one of the supported browsers then please visit the support section on the jScrollPane
// website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also
// welcome to fork the project on GitHub if you can contribute a fix for a given issue.
//
// jQuery Versions - tested in 1.4.2+ - reported to work in 1.3.x
// Browsers Tested - Firefox 3.6.8, Safari 5, Opera 10.6, Chrome 5.0, IE 6, 7, 8
//
// About: Release History
//
// 2.0.19 - (2013-11-16) Changes for more reliable scroll amount with latest mousewheel plugin (thanks @brandonaaron)
// 2.0.18 - (2013-10-23) Fix for issue with gutters and scrollToElement (thanks @Dubiy)
// 2.0.17 - (2013-08-17) Working correctly when box-sizing is set to border-box (thanks @pieht)
// 2.0.16 - (2013-07-30) Resetting left position when scroll is removed. Fixes #189
// 2.0.15 - (2013-07-29) Fixed issue with scrollToElement where the destX and destY are undefined.
// 2.0.14 - (2013-05-01) Updated to most recent mouse wheel plugin (see #106) and related changes for sensible scroll speed
// 2.0.13 - (2013-05-01) Switched to semver compatible version name
// 2.0.0beta12 - (2012-09-27) fix for jQuery 1.8+
// 2.0.0beta11 - (2012-05-14)
// 2.0.0beta10 - (2011-04-17) cleaner required size calculation, improved keyboard support, stickToBottom/Left, other small fixes
// 2.0.0beta9 - (2011-01-31) new API methods, bug fixes and correct keyboard support for FF/OSX
// 2.0.0beta8 - (2011-01-29) touchscreen support, improved keyboard support
// 2.0.0beta7 - (2011-01-23) scroll speed consistent (thanks Aivo Paas)
// 2.0.0beta6 - (2010-12-07) scrollToElement horizontal support
// 2.0.0beta5 - (2010-10-18) jQuery 1.4.3 support, various bug fixes
// 2.0.0beta4 - (2010-09-17) clickOnTrack support, bug fixes
// 2.0.0beta3 - (2010-08-27) Horizontal mousewheel, mwheelIntent, keyboard support, bug fixes
// 2.0.0beta2 - (2010-08-21) Bug fixes
// 2.0.0beta1 - (2010-08-17) Rewrite to follow modern best practices and enable horizontal scrolling, initially hidden
// elements and dynamically sized elements.
// 1.x - (2006-12-31 - 2010-07-31) Initial version, hosted at googlecode, deprecated
(function($,window,undefined){
$.fn.jScrollPane = function(settings)
{
// JScrollPane "class" - public methods are available through $('selector').data('jsp')
function JScrollPane(elem, s)
{
var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth,
wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false,
originalElement = elem.clone(false, false).empty(),
mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp';
if (elem.css('box-sizing') === 'border-box') {
originalPadding = 0;
originalPaddingTotalWidth = 0;
} else {
originalPadding = elem.css('paddingTop') + ' ' +
elem.css('paddingRight') + ' ' +
elem.css('paddingBottom') + ' ' +
elem.css('paddingLeft');
originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) +
(parseInt(elem.css('paddingRight'), 10) || 0);
}
function initialise(s)
{
var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
hasContainingSpaceChanged, originalScrollTop, originalScrollLeft,
maintainAtBottom = false, maintainAtRight = false;
settings = s;
if (pane === undefined) {
originalScrollTop = elem.scrollTop();
originalScrollLeft = elem.scrollLeft();
elem.css(
{
overflow: 'hidden',
padding: 0
}
);
// TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
// come back to it later and check once it is unhidden...
paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
paneHeight = elem.innerHeight();
elem.width(paneWidth);
pane = $('<div class="jspPane" />').css('padding', originalPadding).append(elem.children());
container = $('<div class="jspContainer" />')
.css({
'width': paneWidth + 'px',
'height': paneHeight + 'px'
}
).append(pane).appendTo(elem);
/*
// Move any margins from the first and last children up to the container so they can still
// collapse with neighbouring elements as they would before jScrollPane
firstChild = pane.find(':first-child');
lastChild = pane.find(':last-child');
elem.css(
{
'margin-top': firstChild.css('margin-top'),
'margin-bottom': lastChild.css('margin-bottom')
}
);
firstChild.css('margin-top', 0);
lastChild.css('margin-bottom', 0);
*/
} else {
elem.css('width', '');
maintainAtBottom = settings.stickToBottom && isCloseToBottom();
maintainAtRight = settings.stickToRight && isCloseToRight();
hasContainingSpaceChanged = elem.innerWidth() + originalPaddingTotalWidth != paneWidth || elem.outerHeight() != paneHeight;
if (hasContainingSpaceChanged) {
paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
paneHeight = elem.innerHeight();
container.css({
width: paneWidth + 'px',
height: paneHeight + 'px'
});
}
// If nothing changed since last check...
if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
elem.width(paneWidth);
return;
}
previousContentWidth = contentWidth;
pane.css('width', '');
elem.width(paneWidth);
container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
}
pane.css('overflow', 'auto');
if (s.contentWidth) {
contentWidth = s.contentWidth;
} else {
contentWidth = pane[0].scrollWidth;
}
contentHeight = pane[0].scrollHeight;
pane.css('overflow', '');
percentInViewH = contentWidth / paneWidth;
percentInViewV = contentHeight / paneHeight;
isScrollableV = percentInViewV > 1;
isScrollableH = percentInViewH > 1;
//console.log(paneWidth, paneHeight, contentWidth, contentHeight, percentInViewH, percentInViewV, isScrollableH, isScrollableV);
if (!(isScrollableH || isScrollableV)) {
elem.removeClass('jspScrollable');
pane.css({
top: 0,
left: 0,
width: container.width() - originalPaddingTotalWidth
});
removeMousewheel();
removeFocusHandler();
removeKeyboardNav();
removeClickOnTrack();
} else {
elem.addClass('jspScrollable');
isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
if (isMaintainingPositon) {
lastContentX = contentPositionX();
lastContentY = contentPositionY();
}
initialiseVerticalScroll();
initialiseHorizontalScroll();
resizeScrollbars();
if (isMaintainingPositon) {
scrollToX(maintainAtRight ? (contentWidth - paneWidth ) : lastContentX, false);
scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false);
}
initFocusHandler();
initMousewheel();
initTouch();
if (settings.enableKeyboardNavigation) {
initKeyboardNav();
}
if (settings.clickOnTrack) {
initClickOnTrack();
}
observeHash();
if (settings.hijackInternalLinks) {
hijackInternalLinks();
}
}
if (settings.autoReinitialise && !reinitialiseInterval) {
reinitialiseInterval = setInterval(
function()
{
initialise(settings);
},
settings.autoReinitialiseDelay
);
} else if (!settings.autoReinitialise && reinitialiseInterval) {
clearInterval(reinitialiseInterval);
}
originalScrollTop && elem.scrollTop(0) && scrollToY(originalScrollTop, false);
originalScrollLeft && elem.scrollLeft(0) && scrollToX(originalScrollLeft, false);
elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
}
function initialiseVerticalScroll()
{
if (isScrollableV) {
container.append(
$('<div class="jspVerticalBar" />').append(
$('<div class="jspCap jspCapTop" />'),
$('<div class="jspTrack" />').append(
$('<div class="jspDrag" />').append(
$('<div class="jspDragTop" />'),
$('<div class="jspDragBottom" />')
)
),
$('<div class="jspCap jspCapBottom" />')
)
);
verticalBar = container.find('>.jspVerticalBar');
verticalTrack = verticalBar.find('>.jspTrack');
verticalDrag = verticalTrack.find('>.jspDrag');
if (settings.showArrows) {
arrowUp = $('<a class="jspArrow jspArrowUp" />').bind(
'mousedown.jsp', getArrowScroll(0, -1)
).bind('click.jsp', nil);
arrowDown = $('<a class="jspArrow jspArrowDown" />').bind(
'mousedown.jsp', getArrowScroll(0, 1)
).bind('click.jsp', nil);
if (settings.arrowScrollOnHover) {
arrowUp.bind('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
arrowDown.bind('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
}
appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
}
verticalTrackHeight = paneHeight;
container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
function()
{
verticalTrackHeight -= $(this).outerHeight();
}
);
verticalDrag.hover(
function()
{
verticalDrag.addClass('jspHover');
},
function()
{
verticalDrag.removeClass('jspHover');
}
).bind(
'mousedown.jsp',
function(e)
{
// Stop IE from allowing text selection
$('html').bind('dragstart.jsp selectstart.jsp', nil);
verticalDrag.addClass('jspActive');
var startY = e.pageY - verticalDrag.position().top;
$('html').bind(
'mousemove.jsp',
function(e)
{
positionDragY(e.pageY - startY, false);
}
).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
return false;
}
);
sizeVerticalScrollbar();
}
}
function sizeVerticalScrollbar()
{
verticalTrack.height(verticalTrackHeight + 'px');
verticalDragPosition = 0;
scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
// Make the pane thinner to allow for the vertical scrollbar
pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
// Add margin to the left of the pane if scrollbars are on that side (to position
// the scrollbar on the left or right set it's left or right property in CSS)
try {
if (verticalBar.position().left === 0) {
pane.css('margin-left', scrollbarWidth + 'px');
}
} catch (err) {
}
}
function initialiseHorizontalScroll()
{
if (isScrollableH) {
container.append(
$('<div class="jspHorizontalBar" />').append(
$('<div class="jspCap jspCapLeft" />'),
$('<div class="jspTrack" />').append(
$('<div class="jspDrag" />').append(
$('<div class="jspDragLeft" />'),
$('<div class="jspDragRight" />')
)
),
$('<div class="jspCap jspCapRight" />')
)
);
horizontalBar = container.find('>.jspHorizontalBar');
horizontalTrack = horizontalBar.find('>.jspTrack');
horizontalDrag = horizontalTrack.find('>.jspDrag');
if (settings.showArrows) {
arrowLeft = $('<a class="jspArrow jspArrowLeft" />').bind(
'mousedown.jsp', getArrowScroll(-1, 0)
).bind('click.jsp', nil);
arrowRight = $('<a class="jspArrow jspArrowRight" />').bind(
'mousedown.jsp', getArrowScroll(1, 0)
).bind('click.jsp', nil);
if (settings.arrowScrollOnHover) {
arrowLeft.bind('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
arrowRight.bind('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
}
appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
}
horizontalDrag.hover(
function()
{
horizontalDrag.addClass('jspHover');
},
function()
{
horizontalDrag.removeClass('jspHover');
}
).bind(
'mousedown.jsp',
function(e)
{
// Stop IE from allowing text selection
$('html').bind('dragstart.jsp selectstart.jsp', nil);
horizontalDrag.addClass('jspActive');
var startX = e.pageX - horizontalDrag.position().left;
$('html').bind(
'mousemove.jsp',
function(e)
{
positionDragX(e.pageX - startX, false);
}
).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
return false;
}
);
horizontalTrackWidth = container.innerWidth();
sizeHorizontalScrollbar();
}
}
function sizeHorizontalScrollbar()
{
container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
function()
{
horizontalTrackWidth -= $(this).outerWidth();
}
);
horizontalTrack.width(horizontalTrackWidth + 'px');
horizontalDragPosition = 0;
}
function resizeScrollbars()
{
if (isScrollableH && isScrollableV) {
var horizontalTrackHeight = horizontalTrack.outerHeight(),
verticalTrackWidth = verticalTrack.outerWidth();
verticalTrackHeight -= horizontalTrackHeight;
$(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
function()
{
horizontalTrackWidth += $(this).outerWidth();
}
);
horizontalTrackWidth -= verticalTrackWidth;
paneHeight -= verticalTrackWidth;
paneWidth -= horizontalTrackHeight;
horizontalTrack.parent().append(
$('<div class="jspCorner" />').css('width', horizontalTrackHeight + 'px')
);
sizeVerticalScrollbar();
sizeHorizontalScrollbar();
}
// reflow content
if (isScrollableH) {
pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
}
contentHeight = pane.outerHeight();
percentInViewV = contentHeight / paneHeight;
if (isScrollableH) {
horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth);
if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
horizontalDragWidth = settings.horizontalDragMaxWidth;
} else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
horizontalDragWidth = settings.horizontalDragMinWidth;
}
horizontalDrag.width(horizontalDragWidth + 'px');
dragMaxX = horizontalTrackWidth - horizontalDragWidth;
_positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
}
if (isScrollableV) {
verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight);
if (verticalDragHeight > settings.verticalDragMaxHeight) {
verticalDragHeight = settings.verticalDragMaxHeight;
} else if (verticalDragHeight < settings.verticalDragMinHeight) {
verticalDragHeight = settings.verticalDragMinHeight;
}
verticalDrag.height(verticalDragHeight + 'px');
dragMaxY = verticalTrackHeight - verticalDragHeight;
_positionDragY(verticalDragPosition); // To update the state for the arrow buttons
}
}
function appendArrows(ele, p, a1, a2)
{
var p1 = "before", p2 = "after", aTemp;
// Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
// at the top or the bottom of the bar?
if (p == "os") {
p = /Mac/.test(navigator.platform) ? "after" : "split";
}
if (p == p1) {
p2 = p;
} else if (p == p2) {
p1 = p;
aTemp = a1;
a1 = a2;
a2 = aTemp;
}
ele[p1](a1)[p2](a2);
}
function getArrowScroll(dirX, dirY, ele)
{
return function()
{
arrowScroll(dirX, dirY, this, ele);
this.blur();
return false;
};
}
function arrowScroll(dirX, dirY, arrow, ele)
{
arrow = $(arrow).addClass('jspActive');
var eve,
scrollTimeout,
isFirst = true,
doScroll = function()
{
if (dirX !== 0) {
jsp.scrollByX(dirX * settings.arrowButtonSpeed);
}
if (dirY !== 0) {
jsp.scrollByY(dirY * settings.arrowButtonSpeed);
}
scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
isFirst = false;
};
doScroll();
eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
ele = ele || $('html');
ele.bind(
eve,
function()
{
arrow.removeClass('jspActive');
scrollTimeout && clearTimeout(scrollTimeout);
scrollTimeout = null;
ele.unbind(eve);
}
);
}
function initClickOnTrack()
{
removeClickOnTrack();
if (isScrollableV) {
verticalTrack.bind(
'mousedown.jsp',
function(e)
{
if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
var clickedTrack = $(this),
offset = clickedTrack.offset(),
direction = e.pageY - offset.top - verticalDragPosition,
scrollTimeout,
isFirst = true,
doScroll = function()
{
var offset = clickedTrack.offset(),
pos = e.pageY - offset.top - verticalDragHeight / 2,
contentDragY = paneHeight * settings.scrollPagePercent,
dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
if (direction < 0) {
if (verticalDragPosition - dragY > pos) {
jsp.scrollByY(-contentDragY);
} else {
positionDragY(pos);
}
} else if (direction > 0) {
if (verticalDragPosition + dragY < pos) {
jsp.scrollByY(contentDragY);
} else {
positionDragY(pos);
}
} else {
cancelClick();
return;
}
scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
isFirst = false;
},
cancelClick = function()
{
scrollTimeout && clearTimeout(scrollTimeout);
scrollTimeout = null;
$(document).unbind('mouseup.jsp', cancelClick);
};
doScroll();
$(document).bind('mouseup.jsp', cancelClick);
return false;
}
}
);
}
if (isScrollableH) {
horizontalTrack.bind(
'mousedown.jsp',
function(e)
{
if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
var clickedTrack = $(this),
offset = clickedTrack.offset(),
direction = e.pageX - offset.left - horizontalDragPosition,
scrollTimeout,
isFirst = true,
doScroll = function()
{
var offset = clickedTrack.offset(),
pos = e.pageX - offset.left - horizontalDragWidth / 2,
contentDragX = paneWidth * settings.scrollPagePercent,
dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
if (direction < 0) {
if (horizontalDragPosition - dragX > pos) {
jsp.scrollByX(-contentDragX);
} else {
positionDragX(pos);
}
} else if (direction > 0) {
if (horizontalDragPosition + dragX < pos) {
jsp.scrollByX(contentDragX);
} else {
positionDragX(pos);
}
} else {
cancelClick();
return;
}
scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
isFirst = false;
},
cancelClick = function()
{
scrollTimeout && clearTimeout(scrollTimeout);
scrollTimeout = null;
$(document).unbind('mouseup.jsp', cancelClick);
};
doScroll();
$(document).bind('mouseup.jsp', cancelClick);
return false;
}
}
);
}
}
function removeClickOnTrack()
{
if (horizontalTrack) {
horizontalTrack.unbind('mousedown.jsp');
}
if (verticalTrack) {
verticalTrack.unbind('mousedown.jsp');
}
}
function cancelDrag()
{
$('html').unbind('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');
if (verticalDrag) {
verticalDrag.removeClass('jspActive');
}
if (horizontalDrag) {
horizontalDrag.removeClass('jspActive');
}
}
function positionDragY(destY, animate)
{
if (!isScrollableV) {
return;
}
if (destY < 0) {
destY = 0;
} else if (destY > dragMaxY) {
destY = dragMaxY;
}
// can't just check if(animate) because false is a valid value that could be passed in...
if (animate === undefined) {
animate = settings.animateScroll;
}
if (animate) {
jsp.animate(verticalDrag, 'top', destY, _positionDragY);
} else {
verticalDrag.css('top', destY);
_positionDragY(destY);
}
}
function _positionDragY(destY)
{
if (destY === undefined) {
destY = verticalDrag.position().top;
}
container.scrollTop(0);
verticalDragPosition = destY;
var isAtTop = verticalDragPosition === 0,
isAtBottom = verticalDragPosition == dragMaxY,
percentScrolled = destY/ dragMaxY,
destTop = -percentScrolled * (contentHeight - paneHeight);
if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
wasAtTop = isAtTop;
wasAtBottom = isAtBottom;
elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
}
updateVerticalArrows(isAtTop, isAtBottom);
pane.css('top', destTop);
elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
}
function positionDragX(destX, animate)
{
if (!isScrollableH) {
return;
}
if (destX < 0) {
destX = 0;
} else if (destX > dragMaxX) {
destX = dragMaxX;
}
if (animate === undefined) {
animate = settings.animateScroll;
}
if (animate) {
jsp.animate(horizontalDrag, 'left', destX, _positionDragX);
} else {
horizontalDrag.css('left', destX);
_positionDragX(destX);
}
}
function _positionDragX(destX)
{
if (destX === undefined) {
destX = horizontalDrag.position().left;
}
container.scrollTop(0);
horizontalDragPosition = destX;
var isAtLeft = horizontalDragPosition === 0,
isAtRight = horizontalDragPosition == dragMaxX,
percentScrolled = destX / dragMaxX,
destLeft = -percentScrolled * (contentWidth - paneWidth);
if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
wasAtLeft = isAtLeft;
wasAtRight = isAtRight;
elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
}
updateHorizontalArrows(isAtLeft, isAtRight);
pane.css('left', destLeft);
elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
}
function updateVerticalArrows(isAtTop, isAtBottom)
{
if (settings.showArrows) {
arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
}
}
function updateHorizontalArrows(isAtLeft, isAtRight)
{
if (settings.showArrows) {
arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
}
}
function scrollToY(destY, animate)
{
var percentScrolled = destY / (contentHeight - paneHeight);
positionDragY(percentScrolled * dragMaxY, animate);
}
function scrollToX(destX, animate)
{
var percentScrolled = destX / (contentWidth - paneWidth);
positionDragX(percentScrolled * dragMaxX, animate);
}
function scrollToElement(ele, stickToTop, animate)
{
var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX;
// Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
// errors from the lookup...
try {
e = $(ele);
} catch (err) {
return;
}
eleHeight = e.outerHeight();
eleWidth= e.outerWidth();
container.scrollTop(0);
container.scrollLeft(0);
// loop through parents adding the offset top of any elements that are relatively positioned between
// the focused element and the jspPane so we can get the true distance from the top
// of the focused element to the top of the scrollpane...
while (!e.is('.jspPane')) {
eleTop += e.position().top;
eleLeft += e.position().left;
e = e.offsetParent();
if (/^body|html$/i.test(e[0].nodeName)) {
// we ended up too high in the document structure. Quit!
return;
}
}
viewportTop = contentPositionY();
maxVisibleEleTop = viewportTop + paneHeight;
if (eleTop < viewportTop || stickToTop) { // element is above viewport
destY = eleTop - settings.horizontalGutter;
} else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
destY = eleTop - paneHeight + eleHeight + settings.horizontalGutter;
}
if (!isNaN(destY)) {
scrollToY(destY, animate);
}
viewportLeft = contentPositionX();
maxVisibleEleLeft = viewportLeft + paneWidth;
if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport
destX = eleLeft - settings.horizontalGutter;
} else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport
destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
}
if (!isNaN(destX)) {
scrollToX(destX, animate);
}
}
function contentPositionX()
{
return -pane.position().left;
}
function contentPositionY()
{
return -pane.position().top;
}
function isCloseToBottom()
{
var scrollableHeight = contentHeight - paneHeight;
return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10);
}
function isCloseToRight()
{
var scrollableWidth = contentWidth - paneWidth;
return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10);
}
function initMousewheel()
{
container.unbind(mwEvent).bind(
mwEvent,
function (event, delta, deltaX, deltaY) {
var dX = horizontalDragPosition, dY = verticalDragPosition, factor = event.deltaFactor || settings.mouseWheelSpeed;
jsp.scrollBy(deltaX * factor, -deltaY * factor, false);
// return true if there was no movement so rest of screen can scroll
return dX == horizontalDragPosition && dY == verticalDragPosition;
}
);
}
function removeMousewheel()
{
container.unbind(mwEvent);
}
function nil()
{
return false;
}
function initFocusHandler()
{
pane.find(':input,a').unbind('focus.jsp').bind(
'focus.jsp',
function(e)
{
scrollToElement(e.target, false);
}
);
}
function removeFocusHandler()
{
pane.find(':input,a').unbind('focus.jsp');
}
function initKeyboardNav()
{
var keyDown, elementHasScrolled, validParents = [];
isScrollableH && validParents.push(horizontalBar[0]);
isScrollableV && validParents.push(verticalBar[0]);
// IE also focuses elements that don't have tabindex set.
pane.focus(
function()
{
elem.focus();
}
);
elem.attr('tabindex', 0)
.unbind('keydown.jsp keypress.jsp')
.bind(
'keydown.jsp',
function(e)
{
if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){
return;
}
var dX = horizontalDragPosition, dY = verticalDragPosition;
switch(e.keyCode) {
case 40: // down
case 38: // up
case 34: // page down
case 32: // space
case 33: // page up
case 39: // right
case 37: // left
keyDown = e.keyCode;
keyDownHandler();
break;
case 35: // end
scrollToY(contentHeight - paneHeight);
keyDown = null;
break;
case 36: // home
scrollToY(0);
keyDown = null;
break;
}
elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
return !elementHasScrolled;
}
).bind(
'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
function(e)
{
if (e.keyCode == keyDown) {
keyDownHandler();
}
return !elementHasScrolled;
}
);
if (settings.hideFocus) {
elem.css('outline', 'none');
if ('hideFocus' in container[0]){
elem.attr('hideFocus', true);
}
} else {
elem.css('outline', '');
if ('hideFocus' in container[0]){
elem.attr('hideFocus', false);
}
}
function keyDownHandler()
{
var dX = horizontalDragPosition, dY = verticalDragPosition;
switch(keyDown) {
case 40: // down
jsp.scrollByY(settings.keyboardSpeed, false);
break;
case 38: // up
jsp.scrollByY(-settings.keyboardSpeed, false);
break;
case 34: // page down
case 32: // space
jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
break;
case 33: // page up
jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
break;
case 39: // right
jsp.scrollByX(settings.keyboardSpeed, false);
break;
case 37: // left
jsp.scrollByX(-settings.keyboardSpeed, false);
break;
}
elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
return elementHasScrolled;
}
}
function removeKeyboardNav()
{
elem.attr('tabindex', '-1')
.removeAttr('tabindex')
.unbind('keydown.jsp keypress.jsp');
}
function observeHash()
{
if (location.hash && location.hash.length > 1) {
var e,
retryInt,
hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS
;
try {
e = $('#' + hash + ', a[name="' + hash + '"]');
} catch (err) {
return;
}
if (e.length && pane.find(hash)) {
// nasty workaround but it appears to take a little while before the hash has done its thing
// to the rendered page so we just wait until the container's scrollTop has been messed up.
if (container.scrollTop() === 0) {
retryInt = setInterval(
function()
{
if (container.scrollTop() > 0) {
scrollToElement(e, true);
$(document).scrollTop(container.position().top);
clearInterval(retryInt);
}
},
50
);
} else {
scrollToElement(e, true);
$(document).scrollTop(container.position().top);
}
}
}
}
function hijackInternalLinks()
{
// only register the link handler once
if ($(document.body).data('jspHijack')) {
return;
}
// remember that the handler was bound
$(document.body).data('jspHijack', true);
// use live handler to also capture newly created links
$(document.body).delegate('a[href*=#]', 'click', function(event) {
// does the link point to the same page?
// this also takes care of cases with a <base>-Tag or Links not starting with the hash #
// e.g. <a href="index.html#test"> when the current url already is index.html
var href = this.href.substr(0, this.href.indexOf('#')),
locationHref = location.href,
hash,
element,
container,
jsp,
scrollTop,
elementTop;
if (location.href.indexOf('#') !== -1) {
locationHref = location.href.substr(0, location.href.indexOf('#'));
}
if (href !== locationHref) {
// the link points to another page
return;
}
// check if jScrollPane should handle this click event
hash = escape(this.href.substr(this.href.indexOf('#') + 1));
// find the element on the page
element;
try {
element = $('#' + hash + ', a[name="' + hash + '"]');
} catch (e) {
// hash is not a valid jQuery identifier
return;
}
if (!element.length) {
// this link does not point to an element on this page
return;
}
container = element.closest('.jspScrollable');
jsp = container.data('jsp');
// jsp might be another jsp instance than the one, that bound this event
// remember: this event is only bound once for all instances.
jsp.scrollToElement(element, true);
if (container[0].scrollIntoView) {
// also scroll to the top of the container (if it is not visible)
scrollTop = $(window).scrollTop();
elementTop = element.offset().top;
if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
container[0].scrollIntoView();
}
}
// jsp handled this event, prevent the browser default (scrolling :P)
event.preventDefault();
});
}
// Init touch on iPad, iPhone, iPod, Android
function initTouch()
{
var startX,
startY,
touchStartX,
touchStartY,
moved,
moving = false;
container.unbind('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').bind(
'touchstart.jsp',
function(e)
{
var touch = e.originalEvent.touches[0];
startX = contentPositionX();
startY = contentPositionY();
touchStartX = touch.pageX;
touchStartY = touch.pageY;
moved = false;
moving = true;
}
).bind(
'touchmove.jsp',
function(ev)
{
if(!moving) {
return;
}
var touchPos = ev.originalEvent.touches[0],
dX = horizontalDragPosition, dY = verticalDragPosition;
jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);
moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
// return true if there was no movement so rest of screen can scroll
return dX == horizontalDragPosition && dY == verticalDragPosition;
}
).bind(
'touchend.jsp',
function(e)
{
moving = false;
/*if(moved) {
return false;
}*/
}
).bind(
'click.jsp-touchclick',
function(e)
{
if(moved) {
moved = false;
return false;
}
}
);
}
function destroy(){
var currentY = contentPositionY(),
currentX = contentPositionX();
elem.removeClass('jspScrollable').unbind('.jsp');
elem.replaceWith(originalElement.append(pane.children()));
originalElement.scrollTop(currentY);
originalElement.scrollLeft(currentX);
// clear reinitialize timer if active
if (reinitialiseInterval) {
clearInterval(reinitialiseInterval);
}
}
// Public API
$.extend(
jsp,
{
// Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
// was initialised). The settings object which is passed in will override any settings from the
// previous time it was initialised - if you don't pass any settings then the ones from the previous
// initialisation will be used.
reinitialise: function(s)
{
s = $.extend({}, settings, s);
initialise(s);
},
// Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
// that it can be seen within the viewport. If stickToTop is true then the element will appear at
// the top of the viewport, if it is false then the viewport will scroll as little as possible to
// show the element. You can also specify if you want animation to occur. If you don't provide this
// argument then the animateScroll value from the settings object is used instead.
scrollToElement: function(ele, stickToTop, animate)
{
scrollToElement(ele, stickToTop, animate);
},
// Scrolls the pane so that the specified co-ordinates within the content are at the top left
// of the viewport. animate is optional and if not passed then the value of animateScroll from
// the settings object this jScrollPane was initialised with is used.
scrollTo: function(destX, destY, animate)
{
scrollToX(destX, animate);
scrollToY(destY, animate);
},
// Scrolls the pane so that the specified co-ordinate within the content is at the left of the
// viewport. animate is optional and if not passed then the value of animateScroll from the settings
// object this jScrollPane was initialised with is used.
scrollToX: function(destX, animate)
{
scrollToX(destX, animate);
},
// Scrolls the pane so that the specified co-ordinate within the content is at the top of the
// viewport. animate is optional and if not passed then the value of animateScroll from the settings
// object this jScrollPane was initialised with is used.
scrollToY: function(destY, animate)
{
scrollToY(destY, animate);
},
// Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
// is optional and if not passed then the value of animateScroll from the settings object this
// jScrollPane was initialised with is used.
scrollToPercentX: function(destPercentX, animate)
{
scrollToX(destPercentX * (contentWidth - paneWidth), animate);
},
// Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
// is optional and if not passed then the value of animateScroll from the settings object this
// jScrollPane was initialised with is used.
scrollToPercentY: function(destPercentY, animate)
{
scrollToY(destPercentY * (contentHeight - paneHeight), animate);
},
// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
scrollBy: function(deltaX, deltaY, animate)
{
jsp.scrollByX(deltaX, animate);
jsp.scrollByY(deltaY, animate);
},
// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
scrollByX: function(deltaX, animate)
{
var destX = contentPositionX() + Math[deltaX<0 ? 'floor' : 'ceil'](deltaX),
percentScrolled = destX / (contentWidth - paneWidth);
positionDragX(percentScrolled * dragMaxX, animate);
},
// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
scrollByY: function(deltaY, animate)
{
var destY = contentPositionY() + Math[deltaY<0 ? 'floor' : 'ceil'](deltaY),
percentScrolled = destY / (contentHeight - paneHeight);
positionDragY(percentScrolled * dragMaxY, animate);
},
// Positions the horizontal drag at the specified x position (and updates the viewport to reflect
// this). animate is optional and if not passed then the value of animateScroll from the settings
// object this jScrollPane was initialised with is used.
positionDragX: function(x, animate)
{
positionDragX(x, animate);
},
// Positions the vertical drag at the specified y position (and updates the viewport to reflect
// this). animate is optional and if not passed then the value of animateScroll from the settings
// object this jScrollPane was initialised with is used.
positionDragY: function(y, animate)
{
positionDragY(y, animate);
},
// This method is called when jScrollPane is trying to animate to a new position. You can override
// it if you want to provide advanced animation functionality. It is passed the following arguments:
// * ele - the element whose position is being animated
// * prop - the property that is being animated
// * value - the value it's being animated to
// * stepCallback - a function that you must execute each time you update the value of the property
// You can use the default implementation (below) as a starting point for your own implementation.
animate: function(ele, prop, value, stepCallback)
{
var params = {};
params[prop] = value;
ele.animate(
params,
{
'duration' : settings.animateDuration,
'easing' : settings.animateEase,
'queue' : false,
'step' : stepCallback
}
);
},
// Returns the current x position of the viewport with regards to the content pane.
getContentPositionX: function()
{
return contentPositionX();
},
// Returns the current y position of the viewport with regards to the content pane.
getContentPositionY: function()
{
return contentPositionY();
},
// Returns the width of the content within the scroll pane.
getContentWidth: function()
{
return contentWidth;
},
// Returns the height of the content within the scroll pane.
getContentHeight: function()
{
return contentHeight;
},
// Returns the horizontal position of the viewport within the pane content.
getPercentScrolledX: function()
{
return contentPositionX() / (contentWidth - paneWidth);
},
// Returns the vertical position of the viewport within the pane content.
getPercentScrolledY: function()
{
return contentPositionY() / (contentHeight - paneHeight);
},
// Returns whether or not this scrollpane has a horizontal scrollbar.
getIsScrollableH: function()
{
return isScrollableH;
},
// Returns whether or not this scrollpane has a vertical scrollbar.
getIsScrollableV: function()
{
return isScrollableV;
},
// Gets a reference to the content pane. It is important that you use this method if you want to
// edit the content of your jScrollPane as if you access the element directly then you may have some
// problems (as your original element has had additional elements for the scrollbars etc added into
// it).
getContentPane: function()
{
return pane;
},
// Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
// animateScroll value from settings is used instead.
scrollToBottom: function(animate)
{
positionDragY(dragMaxY, animate);
},
// Hijacks the links on the page which link to content inside the scrollpane. If you have changed
// the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
// contents of your scroll pane will work then call this function.
hijackInternalLinks: $.noop,
// Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
// initialised.
destroy: function()
{
destroy();
}
}
);
initialise(s);
}
// Pluginifying code...
settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
// Apply default speed
$.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function() {
settings[this] = settings[this] || settings.speed;
});
return this.each(
function()
{
var elem = $(this), jspApi = elem.data('jsp');
if (jspApi) {
jspApi.reinitialise(settings);
} else {
$("script",elem).filter('[type="text/javascript"],:not([type])').remove();
jspApi = new JScrollPane(elem, settings);
elem.data('jsp', jspApi);
}
}
);
};
$.fn.jScrollPane.defaults = {
showArrows : false,
maintainPosition : true,
stickToBottom : false,
stickToRight : false,
clickOnTrack : true,
autoReinitialise : false,
autoReinitialiseDelay : 500,
verticalDragMinHeight : 0,
verticalDragMaxHeight : 99999,
horizontalDragMinWidth : 0,
horizontalDragMaxWidth : 99999,
contentWidth : undefined,
animateScroll : false,
animateDuration : 300,
animateEase : 'linear',
hijackInternalLinks : false,
verticalGutter : 4,
horizontalGutter : 4,
mouseWheelSpeed : 3,
arrowButtonSpeed : 0,
arrowRepeatFreq : 50,
arrowScrollOnHover : false,
trackClickSpeed : 0,
trackClickRepeatFreq : 70,
verticalArrowPositions : 'split',
horizontalArrowPositions : 'split',
enableKeyboardNavigation : true,
hideFocus : false,
keyboardSpeed : 0,
initialDelay : 300, // Delay before starting repeating
speed : 30, // Default speed when others falsey
scrollPagePercent : .8 // Percent of visible area scrolled when pageUp/Down or track area pressed
};
})(jQuery,this);
/*!
* jScrollPane - v2.0.19 - 2013-11-16
* http://jscrollpane.kelvinluck.com/
*
* Copyright (c) 2013 Kelvin Luck
* Dual licensed under the MIT or GPL licenses.
*/
!function(a,b,c){a.fn.jScrollPane=function(d){function e(d,e){function f(b){var e,h,j,l,m,n,q=!1,r=!1;if(P=b,Q===c)m=d.scrollTop(),n=d.scrollLeft(),d.css({overflow:"hidden",padding:0}),R=d.innerWidth()+tb,S=d.innerHeight(),d.width(R),Q=a('<div class="jspPane" />').css("padding",sb).append(d.children()),T=a('<div class="jspContainer" />').css({width:R+"px",height:S+"px"}).append(Q).appendTo(d);else{if(d.css("width",""),q=P.stickToBottom&&C(),r=P.stickToRight&&D(),l=d.innerWidth()+tb!=R||d.outerHeight()!=S,l&&(R=d.innerWidth()+tb,S=d.innerHeight(),T.css({width:R+"px",height:S+"px"})),!l&&ub==U&&Q.outerHeight()==V)return d.width(R),void 0;ub=U,Q.css("width",""),d.width(R),T.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end()}Q.css("overflow","auto"),U=b.contentWidth?b.contentWidth:Q[0].scrollWidth,V=Q[0].scrollHeight,Q.css("overflow",""),W=U/R,X=V/S,Y=X>1,Z=W>1,Z||Y?(d.addClass("jspScrollable"),e=P.maintainPosition&&(ab||db),e&&(h=A(),j=B()),g(),i(),k(),e&&(y(r?U-R:h,!1),x(q?V-S:j,!1)),H(),E(),N(),P.enableKeyboardNavigation&&J(),P.clickOnTrack&&o(),L(),P.hijackInternalLinks&&M()):(d.removeClass("jspScrollable"),Q.css({top:0,left:0,width:T.width()-tb}),F(),I(),K(),p()),P.autoReinitialise&&!rb?rb=setInterval(function(){f(P)},P.autoReinitialiseDelay):!P.autoReinitialise&&rb&&clearInterval(rb),m&&d.scrollTop(0)&&x(m,!1),n&&d.scrollLeft(0)&&y(n,!1),d.trigger("jsp-initialised",[Z||Y])}function g(){Y&&(T.append(a('<div class="jspVerticalBar" />').append(a('<div class="jspCap jspCapTop" />'),a('<div class="jspTrack" />').append(a('<div class="jspDrag" />').append(a('<div class="jspDragTop" />'),a('<div class="jspDragBottom" />'))),a('<div class="jspCap jspCapBottom" />'))),eb=T.find(">.jspVerticalBar"),fb=eb.find(">.jspTrack"),$=fb.find(">.jspDrag"),P.showArrows&&(jb=a('<a class="jspArrow jspArrowUp" />').bind("mousedown.jsp",m(0,-1)).bind("click.jsp",G),kb=a('<a class="jspArrow jspArrowDown" />').bind("mousedown.jsp",m(0,1)).bind("click.jsp",G),P.arrowScrollOnHover&&(jb.bind("mouseover.jsp",m(0,-1,jb)),kb.bind("mouseover.jsp",m(0,1,kb))),l(fb,P.verticalArrowPositions,jb,kb)),hb=S,T.find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow").each(function(){hb-=a(this).outerHeight()}),$.hover(function(){$.addClass("jspHover")},function(){$.removeClass("jspHover")}).bind("mousedown.jsp",function(b){a("html").bind("dragstart.jsp selectstart.jsp",G),$.addClass("jspActive");var c=b.pageY-$.position().top;return a("html").bind("mousemove.jsp",function(a){r(a.pageY-c,!1)}).bind("mouseup.jsp mouseleave.jsp",q),!1}),h())}function h(){fb.height(hb+"px"),ab=0,gb=P.verticalGutter+fb.outerWidth(),Q.width(R-gb-tb);try{0===eb.position().left&&Q.css("margin-left",gb+"px")}catch(a){}}function i(){Z&&(T.append(a('<div class="jspHorizontalBar" />').append(a('<div class="jspCap jspCapLeft" />'),a('<div class="jspTrack" />').append(a('<div class="jspDrag" />').append(a('<div class="jspDragLeft" />'),a('<div class="jspDragRight" />'))),a('<div class="jspCap jspCapRight" />'))),lb=T.find(">.jspHorizontalBar"),mb=lb.find(">.jspTrack"),bb=mb.find(">.jspDrag"),P.showArrows&&(pb=a('<a class="jspArrow jspArrowLeft" />').bind("mousedown.jsp",m(-1,0)).bind("click.jsp",G),qb=a('<a class="jspArrow jspArrowRight" />').bind("mousedown.jsp",m(1,0)).bind("click.jsp",G),P.arrowScrollOnHover&&(pb.bind("mouseover.jsp",m(-1,0,pb)),qb.bind("mouseover.jsp",m(1,0,qb))),l(mb,P.horizontalArrowPositions,pb,qb)),bb.hover(function(){bb.addClass("jspHover")},function(){bb.removeClass("jspHover")}).bind("mousedown.jsp",function(b){a("html").bind("dragstart.jsp selectstart.jsp",G),bb.addClass("jspActive");var c=b.pageX-bb.position().left;return a("html").bind("mousemove.jsp",function(a){t(a.pageX-c,!1)}).bind("mouseup.jsp mouseleave.jsp",q),!1}),nb=T.innerWidth(),j())}function j(){T.find(">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow").each(function(){nb-=a(this).outerWidth()}),mb.width(nb+"px"),db=0}function k(){if(Z&&Y){var b=mb.outerHeight(),c=fb.outerWidth();hb-=b,a(lb).find(">.jspCap:visible,>.jspArrow").each(function(){nb+=a(this).outerWidth()}),nb-=c,S-=c,R-=b,mb.parent().append(a('<div class="jspCorner" />').css("width",b+"px")),h(),j()}Z&&Q.width(T.outerWidth()-tb+"px"),V=Q.outerHeight(),X=V/S,Z&&(ob=Math.ceil(1/W*nb),ob>P.horizontalDragMaxWidth?ob=P.horizontalDragMaxWidth:ob<P.horizontalDragMinWidth&&(ob=P.horizontalDragMinWidth),bb.width(ob+"px"),cb=nb-ob,u(db)),Y&&(ib=Math.ceil(1/X*hb),ib>P.verticalDragMaxHeight?ib=P.verticalDragMaxHeight:ib<P.verticalDragMinHeight&&(ib=P.verticalDragMinHeight),$.height(ib+"px"),_=hb-ib,s(ab))}function l(a,b,c,d){var e,f="before",g="after";"os"==b&&(b=/Mac/.test(navigator.platform)?"after":"split"),b==f?g=b:b==g&&(f=b,e=c,c=d,d=e),a[f](c)[g](d)}function m(a,b,c){return function(){return n(a,b,this,c),this.blur(),!1}}function n(b,c,d,e){d=a(d).addClass("jspActive");var f,g,h=!0,i=function(){0!==b&&vb.scrollByX(b*P.arrowButtonSpeed),0!==c&&vb.scrollByY(c*P.arrowButtonSpeed),g=setTimeout(i,h?P.initialDelay:P.arrowRepeatFreq),h=!1};i(),f=e?"mouseout.jsp":"mouseup.jsp",e=e||a("html"),e.bind(f,function(){d.removeClass("jspActive"),g&&clearTimeout(g),g=null,e.unbind(f)})}function o(){p(),Y&&fb.bind("mousedown.jsp",function(b){if(b.originalTarget===c||b.originalTarget==b.currentTarget){var d,e=a(this),f=e.offset(),g=b.pageY-f.top-ab,h=!0,i=function(){var a=e.offset(),c=b.pageY-a.top-ib/2,f=S*P.scrollPagePercent,k=_*f/(V-S);if(0>g)ab-k>c?vb.scrollByY(-f):r(c);else{if(!(g>0))return j(),void 0;c>ab+k?vb.scrollByY(f):r(c)}d=setTimeout(i,h?P.initialDelay:P.trackClickRepeatFreq),h=!1},j=function(){d&&clearTimeout(d),d=null,a(document).unbind("mouseup.jsp",j)};return i(),a(document).bind("mouseup.jsp",j),!1}}),Z&&mb.bind("mousedown.jsp",function(b){if(b.originalTarget===c||b.originalTarget==b.currentTarget){var d,e=a(this),f=e.offset(),g=b.pageX-f.left-db,h=!0,i=function(){var a=e.offset(),c=b.pageX-a.left-ob/2,f=R*P.scrollPagePercent,k=cb*f/(U-R);if(0>g)db-k>c?vb.scrollByX(-f):t(c);else{if(!(g>0))return j(),void 0;c>db+k?vb.scrollByX(f):t(c)}d=setTimeout(i,h?P.initialDelay:P.trackClickRepeatFreq),h=!1},j=function(){d&&clearTimeout(d),d=null,a(document).unbind("mouseup.jsp",j)};return i(),a(document).bind("mouseup.jsp",j),!1}})}function p(){mb&&mb.unbind("mousedown.jsp"),fb&&fb.unbind("mousedown.jsp")}function q(){a("html").unbind("dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp"),$&&$.removeClass("jspActive"),bb&&bb.removeClass("jspActive")}function r(a,b){Y&&(0>a?a=0:a>_&&(a=_),b===c&&(b=P.animateScroll),b?vb.animate($,"top",a,s):($.css("top",a),s(a)))}function s(a){a===c&&(a=$.position().top),T.scrollTop(0),ab=a;var b=0===ab,e=ab==_,f=a/_,g=-f*(V-S);(wb!=b||yb!=e)&&(wb=b,yb=e,d.trigger("jsp-arrow-change",[wb,yb,xb,zb])),v(b,e),Q.css("top",g),d.trigger("jsp-scroll-y",[-g,b,e]).trigger("scroll")}function t(a,b){Z&&(0>a?a=0:a>cb&&(a=cb),b===c&&(b=P.animateScroll),b?vb.animate(bb,"left",a,u):(bb.css("left",a),u(a)))}function u(a){a===c&&(a=bb.position().left),T.scrollTop(0),db=a;var b=0===db,e=db==cb,f=a/cb,g=-f*(U-R);(xb!=b||zb!=e)&&(xb=b,zb=e,d.trigger("jsp-arrow-change",[wb,yb,xb,zb])),w(b,e),Q.css("left",g),d.trigger("jsp-scroll-x",[-g,b,e]).trigger("scroll")}function v(a,b){P.showArrows&&(jb[a?"addClass":"removeClass"]("jspDisabled"),kb[b?"addClass":"removeClass"]("jspDisabled"))}function w(a,b){P.showArrows&&(pb[a?"addClass":"removeClass"]("jspDisabled"),qb[b?"addClass":"removeClass"]("jspDisabled"))}function x(a,b){var c=a/(V-S);r(c*_,b)}function y(a,b){var c=a/(U-R);t(c*cb,b)}function z(b,c,d){var e,f,g,h,i,j,k,l,m,n=0,o=0;try{e=a(b)}catch(p){return}for(f=e.outerHeight(),g=e.outerWidth(),T.scrollTop(0),T.scrollLeft(0);!e.is(".jspPane");)if(n+=e.position().top,o+=e.position().left,e=e.offsetParent(),/^body|html$/i.test(e[0].nodeName))return;h=B(),j=h+S,h>n||c?l=n-P.horizontalGutter:n+f>j&&(l=n-S+f+P.horizontalGutter),isNaN(l)||x(l,d),i=A(),k=i+R,i>o||c?m=o-P.horizontalGutter:o+g>k&&(m=o-R+g+P.horizontalGutter),isNaN(m)||y(m,d)}function A(){return-Q.position().left}function B(){return-Q.position().top}function C(){var a=V-S;return a>20&&a-B()<10}function D(){var a=U-R;return a>20&&a-A()<10}function E(){T.unbind(Bb).bind(Bb,function(a,b,c,d){var e=db,f=ab,g=a.deltaFactor||P.mouseWheelSpeed;return vb.scrollBy(c*g,-d*g,!1),e==db&&f==ab})}function F(){T.unbind(Bb)}function G(){return!1}function H(){Q.find(":input,a").unbind("focus.jsp").bind("focus.jsp",function(a){z(a.target,!1)})}function I(){Q.find(":input,a").unbind("focus.jsp")}function J(){function b(){var a=db,b=ab;switch(c){case 40:vb.scrollByY(P.keyboardSpeed,!1);break;case 38:vb.scrollByY(-P.keyboardSpeed,!1);break;case 34:case 32:vb.scrollByY(S*P.scrollPagePercent,!1);break;case 33:vb.scrollByY(-S*P.scrollPagePercent,!1);break;case 39:vb.scrollByX(P.keyboardSpeed,!1);break;case 37:vb.scrollByX(-P.keyboardSpeed,!1)}return e=a!=db||b!=ab}var c,e,f=[];Z&&f.push(lb[0]),Y&&f.push(eb[0]),Q.focus(function(){d.focus()}),d.attr("tabindex",0).unbind("keydown.jsp keypress.jsp").bind("keydown.jsp",function(d){if(d.target===this||f.length&&a(d.target).closest(f).length){var g=db,h=ab;switch(d.keyCode){case 40:case 38:case 34:case 32:case 33:case 39:case 37:c=d.keyCode,b();break;case 35:x(V-S),c=null;break;case 36:x(0),c=null}return e=d.keyCode==c&&g!=db||h!=ab,!e}}).bind("keypress.jsp",function(a){return a.keyCode==c&&b(),!e}),P.hideFocus?(d.css("outline","none"),"hideFocus"in T[0]&&d.attr("hideFocus",!0)):(d.css("outline",""),"hideFocus"in T[0]&&d.attr("hideFocus",!1))}function K(){d.attr("tabindex","-1").removeAttr("tabindex").unbind("keydown.jsp keypress.jsp")}function L(){if(location.hash&&location.hash.length>1){var b,c,d=escape(location.hash.substr(1));try{b=a("#"+d+', a[name="'+d+'"]')}catch(e){return}b.length&&Q.find(d)&&(0===T.scrollTop()?c=setInterval(function(){T.scrollTop()>0&&(z(b,!0),a(document).scrollTop(T.position().top),clearInterval(c))},50):(z(b,!0),a(document).scrollTop(T.position().top)))}}function M(){a(document.body).data("jspHijack")||(a(document.body).data("jspHijack",!0),a(document.body).delegate("a[href*=#]","click",function(c){var d,e,f,g,h,i,j=this.href.substr(0,this.href.indexOf("#")),k=location.href;if(-1!==location.href.indexOf("#")&&(k=location.href.substr(0,location.href.indexOf("#"))),j===k){d=escape(this.href.substr(this.href.indexOf("#")+1));try{e=a("#"+d+', a[name="'+d+'"]')}catch(l){return}e.length&&(f=e.closest(".jspScrollable"),g=f.data("jsp"),g.scrollToElement(e,!0),f[0].scrollIntoView&&(h=a(b).scrollTop(),i=e.offset().top,(h>i||i>h+a(b).height())&&f[0].scrollIntoView()),c.preventDefault())}}))}function N(){var a,b,c,d,e,f=!1;T.unbind("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick").bind("touchstart.jsp",function(g){var h=g.originalEvent.touches[0];a=A(),b=B(),c=h.pageX,d=h.pageY,e=!1,f=!0}).bind("touchmove.jsp",function(g){if(f){var h=g.originalEvent.touches[0],i=db,j=ab;return vb.scrollTo(a+c-h.pageX,b+d-h.pageY),e=e||Math.abs(c-h.pageX)>5||Math.abs(d-h.pageY)>5,i==db&&j==ab}}).bind("touchend.jsp",function(){f=!1}).bind("click.jsp-touchclick",function(){return e?(e=!1,!1):void 0})}function O(){var a=B(),b=A();d.removeClass("jspScrollable").unbind(".jsp"),d.replaceWith(Ab.append(Q.children())),Ab.scrollTop(a),Ab.scrollLeft(b),rb&&clearInterval(rb)}var P,Q,R,S,T,U,V,W,X,Y,Z,$,_,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb,mb,nb,ob,pb,qb,rb,sb,tb,ub,vb=this,wb=!0,xb=!0,yb=!1,zb=!1,Ab=d.clone(!1,!1).empty(),Bb=a.fn.mwheelIntent?"mwheelIntent.jsp":"mousewheel.jsp";"border-box"===d.css("box-sizing")?(sb=0,tb=0):(sb=d.css("paddingTop")+" "+d.css("paddingRight")+" "+d.css("paddingBottom")+" "+d.css("paddingLeft"),tb=(parseInt(d.css("paddingLeft"),10)||0)+(parseInt(d.css("paddingRight"),10)||0)),a.extend(vb,{reinitialise:function(b){b=a.extend({},P,b),f(b)},scrollToElement:function(a,b,c){z(a,b,c)},scrollTo:function(a,b,c){y(a,c),x(b,c)},scrollToX:function(a,b){y(a,b)},scrollToY:function(a,b){x(a,b)},scrollToPercentX:function(a,b){y(a*(U-R),b)},scrollToPercentY:function(a,b){x(a*(V-S),b)},scrollBy:function(a,b,c){vb.scrollByX(a,c),vb.scrollByY(b,c)},scrollByX:function(a,b){var c=A()+Math[0>a?"floor":"ceil"](a),d=c/(U-R);t(d*cb,b)},scrollByY:function(a,b){var c=B()+Math[0>a?"floor":"ceil"](a),d=c/(V-S);r(d*_,b)},positionDragX:function(a,b){t(a,b)},positionDragY:function(a,b){r(a,b)},animate:function(a,b,c,d){var e={};e[b]=c,a.animate(e,{duration:P.animateDuration,easing:P.animateEase,queue:!1,step:d})},getContentPositionX:function(){return A()},getContentPositionY:function(){return B()},getContentWidth:function(){return U},getContentHeight:function(){return V},getPercentScrolledX:function(){return A()/(U-R)},getPercentScrolledY:function(){return B()/(V-S)},getIsScrollableH:function(){return Z},getIsScrollableV:function(){return Y},getContentPane:function(){return Q},scrollToBottom:function(a){r(_,a)},hijackInternalLinks:a.noop,destroy:function(){O()}}),f(e)}return d=a.extend({},a.fn.jScrollPane.defaults,d),a.each(["arrowButtonSpeed","trackClickSpeed","keyboardSpeed"],function(){d[this]=d[this]||d.speed}),this.each(function(){var b=a(this),c=b.data("jsp");c?c.reinitialise(d):(a("script",b).filter('[type="text/javascript"],:not([type])').remove(),c=new e(b,d),b.data("jsp",c))})},a.fn.jScrollPane.defaults={showArrows:!1,maintainPosition:!0,stickToBottom:!1,stickToRight:!1,clickOnTrack:!0,autoReinitialise:!1,autoReinitialiseDelay:500,verticalDragMinHeight:0,verticalDragMaxHeight:99999,horizontalDragMinWidth:0,horizontalDragMaxWidth:99999,contentWidth:c,animateScroll:!1,animateDuration:300,animateEase:"linear",hijackInternalLinks:!1,verticalGutter:4,horizontalGutter:4,mouseWheelSpeed:3,arrowButtonSpeed:0,arrowRepeatFreq:50,arrowScrollOnHover:!1,trackClickSpeed:0,trackClickRepeatFreq:70,verticalArrowPositions:"split",horizontalArrowPositions:"split",enableKeyboardNavigation:!0,hideFocus:!1,keyboardSpeed:0,initialDelay:300,speed:30,scrollPagePercent:.8}}(jQuery,this);
\ No newline at end of file
<html>
<head>
<title>Domotika By Unixmedia</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=0.85, maximum-scale=0.85, minimum-scale=0.85, user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=0.85" />
<style>
body {
background: none repeat scroll 0 0 #FBFBFB;
......@@ -13,6 +17,10 @@ body {
padding: 0;
}
.theme_dmblack {
background-color: #000 !important;
}
.login * {
margin: 0;
padding: 0;
......@@ -20,6 +28,7 @@ body {
.login form {
margin-left: 8px;
margin-right: 8px;
padding: 26px 24px 46px;
font-weight: normal;
background: #fff;
......@@ -28,6 +37,10 @@ body {
box-shadow: rgba(200, 200, 200, 0.7) 0px 4px 10px -1px;
}
.login form .theme_dmblack {
background-color: #c2c2c2;
}
.login .button-primary {
float: right;
}
......@@ -101,7 +114,8 @@ body {
}
#login form {
padding: 40px;
padding: 20px;
padding-bottom: 40px;
background: #fff;
}
.login #pass-strength-result {
......@@ -139,7 +153,7 @@ h4 {
}
img {
padding-left: 40px;
padding-left: 20px;
}
/** LOgin button */
......@@ -179,10 +193,10 @@ img {
@SCRIPT@
</head>
<div id="login">
<img src="/img/logo_unixmedia_white.png">
<form name="loginform" id="login" class="login" action="@PATH@" method="post">
<body class="@THEME@">
<div id="login" class="@THEME@" >
<img src="/img/logo_unixmedia_@THEME@.png">
<form name="loginform" id="login" class="login @THEME@" action="@PATH@" method="post">
<h4>Domotika Login</h4>
<p>
<label for="user_login">Username<br />
......
......@@ -78,6 +78,7 @@ enablemysqlgui: yes
enableajaxgui: yes
enablerestgui: yes
enablemediagui: yes
logintheme: theme_dmblack
interface: 0.0.0.0
sslport: 443
port: 81
......
......@@ -748,7 +748,8 @@ def getUsersInGroup(group, activeonly=True):
return UsersGroup.find(where=["group=?", group])
def updateUserData(username, pwd, email, dhome, mhome, tts=False, lang="it",slide=False, webspeech='touch', speechlang='it-IT'):
def updateUserData(username, pwd, email, dhome, mhome, tts=False,
lang="it",slide=False, webspeech='touch', speechlang='it-IT', theme='dmblack'):
def onRes(res):
if res>0:
return defer.succeed(username+" correctly updated")
......@@ -769,6 +770,7 @@ def updateUserData(username, pwd, email, dhome, mhome, tts=False, lang="it",slid
qstring+=",slide=0"
qstring+=",webspeech='%s'" % webspeech
qstring+=",speechlang='%s'" % speechlang
qstring+=",gui_theme='%s'" % str(theme)
qstring+=" WHERE username='%s' AND active > 0" %(username)
log.debug(qstring)
return runOperation(qstring).addCallback(onRes)
......
......@@ -2218,8 +2218,9 @@ class domotikaService(service.Service):
def web_on_getUserFromName(self, name):
return dmdb.Users.find(where=['username=?', name], limit=1)
def web_on_updateUserData(self, username, pwd, email, dhome, mhome, tts, lang, slide=False, webspeech='touch', speechlang='it-IT'):
return dmdb.updateUserData(username, pwd, email, dhome, mhome, tts, lang,slide, webspeech, speechlang)
def web_on_updateUserData(self, username, pwd, email, dhome, mhome, tts,
lang, slide=False, webspeech='touch', speechlang='it-IT', theme='dmblack'):
return dmdb.updateUserData(username, pwd, email, dhome, mhome, tts, lang,slide, webspeech, speechlang, theme)
def web_on_getMaxLocalTranscode(self):
return int(self.config.get('media', 'localtranscode'))
......
......@@ -335,6 +335,23 @@ class UserRest(RestCore):
def userbyname(self, request=None, username='', *a, **kw):
return self.callbackResponse(self.core.getUserFromName(username), request)
@route("/refreshme")
@wrapResponse
def refreshme(self, request=None,*a, **kw):
def setUserSession(res):
self.session.mind.perms.gui_theme=res.gui_theme
self.session.mind.perms.email=res.email
self.session.mind.perms.tts=res.tts
self.session.mind.perms.language=res.language
self.session.mind.perms.slide=res.slide
self.session.mind.perms.webspeech=res.webspeech
self.session.mind.perms.speechlang=res.speechlang
return res
log.info('Refresh session for user '+str(self.session.mind.perms.username))
d=self.core.getUserFromName(self.session.mind.perms.username).addCallback(setUserSession)
return self.callbackResponse(d, request)
@route("/me")
@wrapResponse
def getme(self, request=None,*a, **kw):
......@@ -344,9 +361,12 @@ class UserRest(RestCore):
@wrapResponse
def setme(self, request=None,*a, **kw):
def onOk(res):
log.info(res)
return self.callbackResponse(self.core.getUserFromName(self.session.mind.perms.username), request)
def onError(res):
log.info(res)
return ResponseConversion(request, code=404, entity="User not found")
log.info("REST Update user "+str(self.session.mind.perms.username))
r = self._getRequestArgs(request)
pwd=False
tts=False
......@@ -354,6 +374,7 @@ class UserRest(RestCore):
slide=False
webspeech="touch"
speechlang="it-IT"
theme='dmblack'
if 'lang' in r.keys():
lang=r['lang']
if 'tts' in r.keys():
......@@ -362,15 +383,18 @@ class UserRest(RestCore):
pwd=r['passwd']
if 'slide' in r.keys():
slide=True
if 'gui_theme' in r.keys():
theme=str(r['gui_theme'])
if 'webspeech' in r.keys() and r['webspeech'] in ['no','touch','continuous']:
webspeech=r['webspeech']
if 'speechlang' in r.keys() and r['speechlang'] in ['it-IT','it-CH','en-US','en-GB']:
speechlang=r['speechlang']
if 'desktop_homepath' in r.keys() and 'mobile_homepath' in r.keys() and 'email' in r.keys():
return self.core.updateUserData(self.session.mind.perms.username, pwd,
r['email'], r['desktop_homepath'], r['mobile_homepath'], tts, lang, slide, webspeech, speechlang).addCallbacks(onOk, onError)
r['email'], r['desktop_homepath'], r['mobile_homepath'],
tts, lang, slide, webspeech, speechlang, theme).addCallbacks(onOk, onError)
log.info('Erroneous request on update my userdata! ('+str(self.session.mind.perms.username)+')')
return ResponseConversion(request, code=400, entity="Bad request - error in parameters")
#return self.callbackResponse(self.core.updateUserFromName(self.session.mind.perms.username), request)
class ActionRest(RestCore):
......
......@@ -249,7 +249,7 @@ class RootPage(rend.Page):
if headers.hasHeader("DMSESSION"):
headers.removeHeader("DMSESSION")
headervalue = str(session.uid)
cols=['username','passwd','id','homepath','email','tts','language','slide','webspeech','speechlang']
cols=['username','passwd','id','homepath','email','tts','language','slide','webspeech','speechlang','gui_theme']
try:
headervalue = session.mind.perms.toHash(cols)
except:
......@@ -264,6 +264,7 @@ class RootPage(rend.Page):
headervalue['slide'] = 0
headervalue['webspeech'] = 'touch'
headervalue['speechlang'] = 'it-IT'
headervalue['gui_theme' ] = 'dmblack'
headervalue['sessionid'] = session.uid
headervalue['logged'] = self.logged
log.debug('DMSESSION SEND '+str(headervalue))
......@@ -461,6 +462,7 @@ class LoginPage(rend.Page):
<title>Domotika By Unixmedia</title>
@SCRIPT@
</head>
<body class="@THEME@">
<form method="post" name="loginform" action="@PATH@">
<fieldset id="form"><legend>Login</legend>
<p>Username: <input type="text" name="username" size="20" value="@USERNAME@" /></p>
......@@ -533,6 +535,7 @@ class LoginPage(rend.Page):
html = html.replace("@USERNAME@", '')
html = html.replace("@PASSWORD@", '')
html = html.replace("@SCRIPT@", "")
html = html.replace("@THEME@", str(self.core.configGet('web', 'logintheme')))
html = html.replace("@CHECKED@", "")
return html
......@@ -564,6 +567,7 @@ class LoginPage(rend.Page):
html = html.replace("@PASSWORD@", str(lp))
html = html.replace("@CHECKED@", "checked")
html = html.replace("@SCRIPT@", str(self.getScript(req.path)))
html = html.replace("@THEME@", str(self.core.configGet('web', 'logintheme')))
log.debug("login html")
return html
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment