App-SlideServer
view release on metacpan or search on metacpan
share/public/slides.js view on Meta::CPAN
function _num_is_in_ranges(num, ranges) {
if (ranges)
for (var i= 0; i < ranges.length; i++)
if (num >= ranges[i][0] && (ranges[i].length == 1 || num <= ranges[i][1]))
return true;
return false;
}
Slide.prototype.showStep= function(step_num, view_mode) {
var self= this;
if (step_num < 0) step_num= this.max_step + 1 + step_num;
if (step_num < 0) step_num= 0;
this.steps.each(function() {
var step= $(this);
// If a step is not visible, behavior depends on whether we are the presenter
// and whether the element is temporary. Non-temporary elements need to remain
// in the document flow so that the layout of the rest doesn't jump around.
// But temporary have to be removed from the layout so that they don't occupy
// space. Meanwhile the presenter gets to see all hidden elements.
if (_num_is_in_ranges(step_num, self.parseSteps(this.dataset.step)))
step.css('visibility','visible').css('position','relative').css('opacity',1);
else {
if (view_mode == 'presenter')
step.css('visibility','visible').css('opacity', .3);
else
step.css('visibility','hidden');
if (step.hasClass('temporary-step'))
step.css('position','absolute');
}
});
this.cur_step= step_num;
}
function escape_html(unsafe) {
return (''+unsafe)
.replaceAll('&', "&")
.replaceAll('<', "<")
.replaceAll('>', ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}
window.slides= {
config: {},
slides: [],
cur_slide: null,
roles: {},
sharedState: {},
init: function(config) {
var self= this
if (!config)
config= self.config
if (!config.websocket_url)
config.websocket_url= 'slidelink.io'
if (!config.mode)
config.mode= 'obs';
if (config.code_highlight === undefined && window.hljs)
config.code_highlight= function(el){ window.hljs.highlightElement(el) }
if (config.mode == 'presenter' && (config.key == null || config.key.length == 0))
config.key= null;//TODO: getCookieVal('access_key');
self.config= config
// Generic button and checkbox handlers
this._button_dispatch= function(ev) {
try {
self[this.dataset.method].call(self, ev);
} catch (e) {
console.log('Calling slides.'+this.dataset.method+': ', e);
}
};
this._enter_dispatch= function(ev) {
if (ev.keyCode == 13) // Enter
try {
self[this.dataset.enter_method].call(self, ev);
} catch (e) {
console.log('Calling slides.'+this.dataset.enter_method+': ', e);
}
};
this._ckbox_dispatch= function(ev) {
try {
self[this.dataset.method].call(self, this.checked, ev);
} catch(e) {
console.log('Calling slides.'+this.dataset.method+' : ', e);
}
};
this.slides= this.buildSlidesArray();
this.resizeSlides();
window.addEventListener('resize', function(event) { self.resizeSlides() }, true);
self._build_ui()
this._show_slide(1,1);
// The presenter needs a chance to enter the key before connecting
if (config.mode == 'presenter' && config.key == null) {
self.togglemenu();
self.root.find('.status-actions .login').show();
self.root.find('.status-actions .reconnect-btn').show();
} else {
self.reconnect()
}
},
// Perform alterations to the HTML structure of the page to allow
// less-strict hand-edited content to be automatically upgraded.
buildSlidesArray: function(root_el) {
var self= this;
if (!root_el) {
if (!self.root) {
if (self.config.root) self.root= self.config.root;
else if ($('div.slides').length) self.root= $($('div.slides')[0]);
else {
// TODO: upgrade body to div.slides
throw "Can't find div.slides element in document";
}
}
root_el= self.root;
}
// Wrap each slide with a Slide object, which initializes its steps
var slides= [];
var slides_jq= root_el.find('.slide');
for (var i=0; i < slides_jq.length; i++)
slides.push(self.wrapSlideEl(slides_jq[i], i+1))
return slides;
},
( run in 0.813 second using v1.01-cache-2.11-cpan-2398b32b56e )