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('&', "&amp;")
    .replaceAll('<', "&lt;")
    .replaceAll('>', "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");
}

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 )