/* Pagelayer Pen editor */ var pagelayer_customColor = ["#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc", "#9933ff", "#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc", "#cce0f5", "#ebd6ff", "#bbbbbb", "#f06666", "#ffc266", "#ffff66", "#66b966", "#66a3e0", "#c285ff", "#888888", "#a10000", "#b26b00", "#b2b200", "#006100", "#0047b2", "#6b24b2", "#444444", "#5c0000", "#663d00", "#666600", "#003700", "#002966", "#3d1466"]; var pagelayer_pen_sizeList = ['normal', 'x-small', 'small', 'medium', 'large', 'x-large']; var pagelayer_pen_lineHeight = ['0.9', '1', '1.5', '2.0', '2.5','3.0', '3.5', '4.0', '4.5', '5.0']; class PagelayerPen{ constructor(jEle, options) { var t = this; t.editor = jQuery(jEle); t.options = options; // Get the document of the element. It use to makes the plugin // compatible on iframes. t.doc = jEle.ownerDocument || document; t.tagToButton = {}; t.optionsCounter = 0; t.destroyEd = true; t.semantic = null; t.DEFAULT_SEMANTIC_MAP = { 'b': 'strong', 'i': 'em', 's': 'strike', //'strike': 'del', 'div': 'p' }; // Init editor t.addHandlers(); t.init(); } init(){ var t = this; // Init Editor t.editor.addClass('pagelayer-pen'); t.penHolder = t.addContainer(); t.addEvents(); } addHandlers(){ // TODO : Add for custom plugins // TODO remove all execCommands this.handlers = { bold:{ tag: 'STRONG', icon: '' }, italic:{ tag: 'EM', icon: '' }, underline:{ tag: 'U', icon: '' }, strike:{ tag: 'strike', fn: 'strikethrough', icon: '' }, h1:{ fn: 'formatBlock', icon: 'H1' }, h2:{ fn: 'formatBlock', icon: 'H2' }, h3:{ fn: 'formatBlock', icon: 'H3' }, h4:{ fn: 'formatBlock', icon: 'H4' }, h5:{ fn: 'formatBlock', icon: 'H5' }, h6:{ fn: 'formatBlock', icon: 'H6' }, p:{ fn: 'formatBlock', icon: '' }, blockquote:{ fn: 'formatBlock', icon: '' }, formating:{ fn: 'formatBlock', fixIcon: '' }, unorderedlist:{ tag: 'UL', fn: 'insertUnorderedList', icon: '' }, orderedlist:{ tag: 'OL', fn: 'insertOrderedList', icon: '' }, sub:{ tag: 'sub', fn: 'subscript', icon: '' }, super:{ tag: 'sup', fn: 'superscript', icon: '' }, link:{ fn: 'setLinkHandler', tag: 'a', icon: '', }, image:{ fn: 'imageBtnHandler', icon: '' }, align:{ style: 'text-align', fn: 'formatBlock', icon: { 'left': '', 'center': '', 'right': '', 'justify': '', } }, color:{ class: 'pagelayer-pen-color-picker', style: 'color', fn: 'commandHandler', fixIcon: ' ', buildBtn : 'buildColorBtnHandler', default : pagelayer_customColor, customInpute: true }, background:{ class: 'pagelayer-pen-color-picker', style: 'background-color', fn: 'commandHandler', fixIcon: ' ', buildBtn: 'buildColorBtnHandler', default : pagelayer_customColor, customInpute: true }, size:{ class: 'pagelayer-pen-size-picker', style: 'font-size', fn: 'commandHandler', default : pagelayer_pen_sizeList, customInpute: true }, lineheight:{ style: 'line-height', fn: 'commandHandler', fixIcon: '', default : pagelayer_pen_lineHeight, customInpute: true }, font:{ style: 'font-family', fn: 'commandHandler', fixIcon: '', default : pagelayer_fonts, buildBtn : 'buildfontBtnHandler', }, viewHTML:{ fn: 'viewHTMLBtnHandler', icon: '' }, removeformat:{ icon: '' } } } addContainer(className){ className = className || false; // Add Container var container = jQuery('.pagelayer-pen-holder'); if(container.length < 1){ jQuery('body').append('
'); container = jQuery('.pagelayer-pen-holder'); } if(!className){ return container; } if(container.find('.'+className).length < 1){ container.append('
'); } return container.find('.'+className); } addToolbar(){ // Add Toolbar var t = this; var groups = t.options.toolbar; var toolbar = t.toolbar = t.addContainer('pagelayer-pen-toolbar'); // Make it empty toolbar.empty(); if (!Array.isArray(groups[0])) { groups = [groups]; } var addButton = function(container, format, value){ var btn = t.handlers[format]; var icon = ''; if('icon' in btn){ var _icon = btn['icon']; if(typeof _icon == 'object' && !pagelayer_empty(_icon[value])){ icon = _icon[value]; }else if(typeof icon == 'string'){ icon = _icon; } } var input = document.createElement('button'); input.setAttribute('type', 'button'); input.setAttribute('data-format', format); input.classList.add('pagelayer-pen-' + format); if('class' in btn){ input.classList.add(btn['class']); } if( pagelayer_empty(value) && 'default' in btn ){ value = btn['default']; } input.innerHTML = icon; if(value != null) { input.value = value; } container.appendChild(input); } var createoption = function(val, lang, type){ type = type || ''; var lang = pagelayer_empty(lang) ? 'Default' : lang; return ''; } var addSelect = function(container, format, values) { var input = document.createElement('select'); input.classList.add('pagelayer-pen-' + format); if('class' in t.handlers[format]){ input.classList.add(t.handlers[format]['class']); } input.setAttribute('data-format', format); if( pagelayer_empty(values) && 'default' in t.handlers[format] ){ values = t.handlers[format]['default']; } for(var kk in values){ var options = ''; var value = values[kk]; if(typeof value == 'object') { if(kk != 'default'){ options += ''; } for(y in value){ options += createoption((jQuery.isNumeric(y) ? value[y] : x), value[y], kk); } }else if(value !== false) { options += createoption(value, value); } else { options += createoption('', ''); } jQuery(input).append(options); } container.appendChild(input); } groups.forEach(function(controls){ var group = document.createElement('span'); group.classList.add('pagelayer-pen-formats'); controls.forEach(function (control){ var format = control; if(typeof control === 'object'){ format = Object.keys(control)[0]; } if( pagelayer_empty(t.handlers[format]) ){ return; } if( typeof control === 'string' ){ addButton(group, control); } else { var value = control[format]; if (Array.isArray(value)) { addSelect(group, format, value); } else { addButton(group, format, value); } } var btn = t.handlers[format]; t.tagToButton[(btn.tag || btn.style || format).toLowerCase()] = format; }); // TODO skip if format is not exist toolbar[0].appendChild(group); }); toolbar.find('button').on('click', function(){ var bEle = jQuery(this); var format = bEle.data('format'); if(! format in t.handlers){ return; } var btn = t.handlers[format]; t.currentFormat = format; t.execCmd(btn.fn || format, btn.param || format, btn.forceCss); }); toolbar.find('select').on('change', function(e){ var bEle = jQuery(this); var format = bEle.data('format'); var val = bEle.val(); if(! format in t.handlers){ return; } var btn = t.handlers[format]; t.currentFormat = format; t.execCmd(btn.fn || format, val, btn.forceCss); }); toolbar.find('select').each(function(){ var format = jQuery(this).data('format'); if('buildBtn' in t.handlers[format]){ try{ t[t.handlers[format]['buildBtn']](this); }catch(e){ try{ t.handlers[format]['buildBtn'](this); }catch(e2){ t.buildDropdown(this); } } return true; } t.buildDropdown(this); }); // Add close button toolbar.append(''); // Hide editor on click close tool handler toolbar.find('.pagelayer-pen-close').on('mousedown', function(e){ //e.preventDefault(); t.destroyEd = true; t.editor.trigger('blur'); }); } execCmd(cmd, param, forceCss, skipPen){ var t = this; skipPen = !!skipPen || ''; if(cmd !== 'dropdown'){ t.focus(); t.restoreRange(); } try{ document.execCommand('styleWithCSS', false, forceCss || false); }catch(c){} try{ t[cmd + skipPen](param); }catch(c){ try{ cmd(param); }catch(e2){ if(cmd === 'insertHorizontalRule'){ param = undefined; }else if (cmd === 'formatBlock'){ // TODO: check for && t.isIE param = '<' + param + '>'; } document.execCommand(cmd, false, param); t.semanticCode(); t.restoreRange(); } } if(cmd !== 'dropdown'){ t.updateButtonStatus(); t.editor.trigger('input'); } } commandHandler(value){ var t = this; var format = t.currentFormat; if( pagelayer_empty(format) ){ return; } var btn = t.handlers[format]; var sel = window.getSelection(); var text = t.range.commonAncestorContainer; var selectedText = t.range.cloneContents(); selectedText = jQuery('
').append(selectedText).html(); // Also select the tag if(text.nodeType === Node.TEXT_NODE){ text = text.parentNode; } if (text.innerHTML === selectedText && text != t.editor[0]) { var ele = jQuery(text); if('tag' in btn){ // Replace tag }else if('style' in btn){ var style = {}; style[btn.style] = value; ele.css(style); }else if('atts' in btn){ // Add attribute or toggle the element } } else { // TODO for toggle tags and add tags var html = jQuery('' + selectedText + ''); // Remove style from all childrend var style = {}; style[btn.style] = ''; html.find('[style]').css(style); // TODO: remove span element that have no atts var node = html[0]; var firstInsertedNode = node.firstChild; var lastInsertedNode = node.lastChild; t.range.deleteContents(); t.range.insertNode(node); if(firstInsertedNode) { t.range.setStartBefore(firstInsertedNode); t.range.setEndAfter(lastInsertedNode); } // Is previous element empty? var prev = jQuery(node).prev(); if( prev.length > 0 && prev.is(':empty') ){ prev.remove(); } } sel.removeAllRanges(); sel.addRange(t.range); } formatBlock(value){ var t = this, format = t.currentFormat, btn = t.handlers[format], startNode = t.range.startContainer, endNode = t.range.endContainer; if( startNode.nodeType == Node.TEXT_NODE && startNode.parentNode != t.editor[0] ){ startNode = startNode.parentNode; } if( endNode.nodeType == Node.TEXT_NODE && endNode.parentNode != t.editor[0] ){ endNode = endNode.parentNode; } // TODO: only for seleced content // Wrap text nodes in span for easier processing t.editor.contents().filter(function () { return this.nodeType === 3 && this.nodeValue.trim().length > 0; }).wrap(''); var isLineEnd = function(lEle){ return lEle == null || lEle.nodeName == 'BR' || t.isline(lEle); } var wrapLine = function(pLine){ var pLine = jQuery(pLine), lineFele, lineEele, finalP; // Get Parent Element if(pLine.parentsUntil(t.editor).length > 0){ pLine = pLine.parentsUntil(t.editor).last(); } if(t.isline(pLine)){ return pLine; } // Get line first element if(isLineEnd(pLine[0].previousSibling)){ lineFele = pLine; }else{ lineFele = pLine.prevAll().filter(function(){ return isLineEnd(this.previousSibling); }).first(); } // Get line last element if(isLineEnd(lineFele[0].nextSibling)){ lineEele = lineFele; }else{ lineEele = lineFele.nextAll().filter(function(){ return isLineEnd(this.nextSibling); }).first(); } // Wrap all with p tag if(lineFele.is(lineEele)){ finalP = lineFele.wrap('

').parent() }else{ finalP = lineFele.nextUntil(lineEele.next()).addBack().wrapAll('

').parent(); } finalP.next('br').remove(); return finalP; } // Get start block lavel elements var $sNode = jQuery(t.blockNode(startNode)); if($sNode.is(t.editor)){ $sNode = wrapLine(startNode); } var $eNode = jQuery(t.blockNode(endNode)); if($eNode.is(t.editor)){ $eNode = wrapLine(endNode); } var $oldEle = $sNode; if(! $sNode.is($eNode) ){ var findEnd = false; var addElement = function(addEle){ if(addEle[0].nodeName == 'UL' || addEle[0].nodeName == 'OL') { addEle.children().each(function(){ $oldEle = $oldEle.add(jQuery(this)); }); return; } $oldEle = $oldEle.add(addEle); } var wrapAllEle = function(nextEle){ if(nextEle.is($eNode) || nextEle.find($eNode).length > 0){ findEnd = true; return; } if(nextEle.length < 1){ return; } if(!t.isline(nextEle[0])){ nextEle = wrapLine(nextEle); } addElement(nextEle); wrapAllEle( nextEle.next() ); } wrapAllEle($sNode.next()); // Is start Element have a another parent var pars = $sNode.parentsUntil(t.editor); pars.each(function(){ var $par = jQuery(this); wrapAllEle($par.next()); }); if( pars.length > 0 ){ $sNode = pars.last(); } var nextEnd = $sNode.nextAll().filter(function(){ return jQuery(this).is($eNode) || jQuery(this).find($eNode).length > 0; }).first(); // Add elements if( nextEnd.length > 0 ){ var $nextEle = $sNode.nextUntil(nextEnd); $nextEle.each(function(){ var ulEle = jQuery(this); if($oldEle.has(ulEle)) return; addElement(ulEle); }); } // Add end element if(nextEnd.length > 0 && !nextEnd.is($eNode) && (nextEnd[0].nodeName == 'UL' || nextEnd[0].nodeName == 'OL')){ nextEnd.children().each(function(){ var li = jQuery(this); $oldEle = $oldEle.add(li); if(li.is($eNode) || li.find($eNode).length > 0) return false; }); }else{ $oldEle = $oldEle.add($eNode); } } if('style' in btn){ var style = {}; style[btn.style] = value; $oldEle.css(style); }else if('atts' in btn){ // Add attribute or toggle the element var attr = {}; attr[btn.atts] = value; $oldEle.attr(attr); }else{ // Replace tag var tag = value.toLowerCase(); // need to find all block ele and replace this $oldEle.each( function(){ var $cEle = jQuery(this); if($cEle.is(t.editor)){ return; } // Is List element if($cEle.css('display') == 'list-item'){ if( t.isline($cEle[0].firstChild)){ $cEle.children().each(function(){ var liChild = jQuery(this); if(t.isline(liChild[0])){ t.replaceTag(liChild, tag, true); return; } // TODO: Check and need to correct liChild.wrap('<' + tag + '/>'); liChild.next('br').remove(); }); return } $cEle.contents().wrapAll('<' + tag + '/>'); return; } t.replaceTag($cEle, tag, true); }); } // Get rid of pen temporary span's jQuery('[data-pts]', t.editor).contents().unwrap(); t.semanticCode(); t.restoreRange(); } blockNode( node ){ var t = this; while( !t.isline(node) && node != t.editor[0] ) { node = node.parentNode; } return node; } isline(node){ if (node.nodeType !== Node.ELEMENT_NODE) return false; if (node.childNodes.length === 0) return false; // Exclude embed blocks var style = window.getComputedStyle(node); return ['block', 'list-item'].indexOf(style.display) > -1; } replaceTag(ele, tag, copyAttr){ ele.wrap('<' + tag + '/>'); var par = ele.parent(); if(copyAttr){ jQuery.each(ele.prop('attributes'), function () { par.attr(this.name, this.value); }); } ele.contents().unwrap(); return par; } semanticCode(){ var t = this; t.semanticTag('b'); t.semanticTag('i'); t.semanticTag('s'); t.semanticTag('strike'); t.semanticTag('div', true); } semanticTag(oldTag, copyAttributes){ var t = this; var newTag; if(t.semantic != null && typeof t.semantic === 'object' && t.semantic.hasOwnProperty(oldTag)){ newTag = t.semantic[oldTag]; } else if (t.DEFAULT_SEMANTIC_MAP.hasOwnProperty(oldTag)) { newTag = t.DEFAULT_SEMANTIC_MAP[oldTag]; } else { return; } jQuery(oldTag, t.editor).each(function () { var $oldTag = jQuery(this); if($oldTag.contents().length === 0) { return false; } t.replaceTag($oldTag, newTag, copyAttributes); }); } addEvents(){ // Add Events var t = this, editor = t.editor, ctrl = false, debounceButtonStatus; var showToolBar = function(){ var jEle = t.penHolder.children(':visible'); if(jEle.length < 1){ jEle = t.toolbar; } t.showPen(jEle); }; // Save rage editor.on('focusout', function(e){ if(t.destroyEd){ t.editor.removeClass('pagelayer-pen-focused'); t.range = null; return; } t.saveRange(); }); // Prevent to hide toolbar t.penHolder.on('mousedown', function(e){ // TODO: taget only require Element t.destroyEd = false; }); // On editor blur editor.on('blur', function(){ if(!t.destroyEd){ return; } t.destroy(); }); editor.on('keydown', function(){ t.penHolder.hide(); }); editor.on('mousedown', function(){ if(t.editor.attr('contenteditable') == 'true'){ t.showPen(); } }); editor.on('mouseup keyup keydown', function(e){ if ((!e.ctrlKey && !e.metaKey) || e.altKey) { setTimeout(function () { // "hold on" to the ctrl key for 50ms ctrl = false; }, 50); } clearTimeout(debounceButtonStatus); debounceButtonStatus = setTimeout(function () { t.updateButtonStatus(); }, 50); }); // Set focus on editor editor.on('click', function(e){ if(t.editor.hasClass('pagelayer-pen-focused')){ return; } t.editor.attr('contenteditable', 'true'); t.editor.focus(); }); // Set focus on editor editor.on('focus', function(){ t.destroyEd = true; t.addToolbar(); t.showPen(); t.editor.addClass('pagelayer-pen-focused'); jQuery(window).unbind('scroll.penToobar'); jQuery(window).on('scroll.penToobar', showToolBar); jQuery(document).unbind('mousemove.penToobar'); jQuery(document).on('mousemove.penToobar', showToolBar); }); t.semanticCode(); } destroy(){ var t = this; //t.editor.attr('contenteditable', ''); t.penHolder.hide(); // Removing event listeners jQuery(document).unbind('mousemove.penToobar'); jQuery(window).unbind('scroll.penToobar'); } hasFocus(){ var t = this; return ( t.doc.activeElement === t.editor || t.contains( t.editor[0], t.doc.activeElement) ); } contains(parent, descendant) { try { // Firefox inserts inaccessible nodes around video elements descendant.parentNode; // eslint-disable-line no-unused-expressions } catch (e) { return false; } return parent.contains(descendant); } saveRange(){ var t = this, selection = t.doc.getSelection(); t.range = null; if (!selection || !selection.rangeCount) { return; } var savedRange = t.range = selection.getRangeAt(0), range = t.doc.createRange(), rangeStart; range.selectNodeContents(t.editor[0]); range.setEnd(savedRange.startContainer, savedRange.startOffset); rangeStart = (range + '').length; t.metaRange = { start: rangeStart, end: rangeStart + (savedRange + '').length }; } restoreRange(){ var t = this, metaRange = t.metaRange, savedRange = t.range, selection = t.doc.getSelection(), range; if(!savedRange){ return; } if(metaRange && metaRange.start !== metaRange.end){ // Algorithm from http://jsfiddle.net/WeWy7/3/ var charIndex = 0, nodeStack = [t.editor[0]], node, foundStart = false, stop = false; range = t.doc.createRange(); while(!stop && (node = nodeStack.pop())){ if (node.nodeType === 3){ var nextCharIndex = charIndex + node.length; if (!foundStart && metaRange.start >= charIndex && metaRange.start <= nextCharIndex) { range.setStart(node, metaRange.start - charIndex); foundStart = true; } if (foundStart && metaRange.end >= charIndex && metaRange.end <= nextCharIndex) { range.setEnd(node, metaRange.end - charIndex); stop = true; } charIndex = nextCharIndex; } else { var cn = node.childNodes, i = cn.length; while (i > 0) { i -= 1; nodeStack.push(cn[i]); } } } } selection.removeAllRanges(); selection.addRange(range || savedRange); } getRange(){ var t = this; var selection = t.doc.getSelection(); if (selection == null || selection.rangeCount <= 0) return null; var range = selection.getRangeAt(0); if(range == null) return null; return range; } getRangeText(range){ return range + ''; } focus(){ var t = this; if(t.hasFocus()) return; t.editor.click(); t.editor.focus(); t.restoreRange(); } getBounds(range){ var rect = range.getBoundingClientRect(); return { bottom: rect.top + rect.height, height: rect.height, left: rect.left, right: rect.right, top: rect.top, width: 0 }; } showPen(jEle){ var t = this; jEle = jEle || jQuery(t.toolbar); var toolBar = jQuery(t.penHolder); var tooltipHeight = parseInt(toolBar.css('height')); var range = null; if(! t.hasFocus() && t.range != null){ range = t.range; }else{ range = t.getRange(); } if(range == null){ toolBar.hide(); return; } // Set left of toolbar var editorOffset = t.editor[0].getBoundingClientRect(); var editorTop = editorOffset.top; var editorLeft = editorOffset.left; var editorbottom = editorTop + editorOffset.height - tooltipHeight; var toolBarTop = editorTop - 10; var bound = t.getBounds(range); if(bound.height == 0 && bound.top == 0 && bound.left == 0){ toolBar.hide(); return; } var boundTop = bound.top - 15; // Set top of toolbar if( boundTop - tooltipHeight < 0 && bound.bottom > -5){ toolBarTop = bound.bottom + tooltipHeight + 15; }else if( editorbottom - 30 < 0 ){ toolBarTop = editorbottom + 20; }else if( toolBarTop - tooltipHeight < 0 ){ toolBarTop = tooltipHeight + 10; } // Show Toolbar toolBar.children().hide(); toolBar.show(); jEle.show(); // Set top of toolbar toolBar.css('top', toolBarTop); // Set left of toobar var docW = jQuery(window).width() - 10; var toolW = toolBar.width(); var edW = t.editor.width(); if(toolW > edW){ editorLeft = editorLeft - (toolW - edW) / 2 } toolBar.css('left', editorLeft+'px'); var tooltipLeft = toolBar.offset().left; if(tooltipLeft < 0){ toolBar.css('left', '1px'); } var toolRight = tooltipLeft + toolW; if(docW < toolRight){ toolBar.css('left', tooltipLeft - (toolRight - docW)+'px'); } } getContent(){ var editor = this.editor; var html = editor.html(); return html; } setContent(html){ var t = this; html = html || ''; t.editor.html(html); t.editor.trigger('input'); } updateButtonStatus(){ var t = this, toolbar = jQuery(t.toolbar), tags = t.getTagsRecursive(t.doc.getSelection().focusNode), activeClasses = 'pagelayer-pen-active'; jQuery('.' + activeClasses, toolbar).removeClass(activeClasses); jQuery.each(tags, function (i, tag){ var btnName; if(pagelayer_is_string(tag)){ btnName = t.tagToButton[tag.toLowerCase()]; }else{ btnName = t.tagToButton[Object.keys(tag)[0].toLowerCase()] } var $btn = jQuery('[data-format="'+btnName+'"]', toolbar); if($btn.length < 1){ return; } if($btn.find('.pagelayer-pen-picker-label').length > 0){ $btn.find('.pagelayer-pen-picker-label').addClass(activeClasses); return; } $btn.addClass(activeClasses); }); } getTagsRecursive(element, tags) { var t = this; var jEle = jQuery(element); tags = tags || (element && element.tagName ? [element.tagName] : []); if (element && element.parentNode) { element = element.parentNode; } else { return tags; } var tag = element.tagName; // Is this editor if (tag === 'DIV') { return tags; } // TODO: for all block element if (tag === 'P' && element.style.textAlign !== '') { tags.push(element.style.textAlign); } jQuery.each(t.tagHandlers, function (i, tagHandler) { tags = tags.concat(tagHandler(element, t)); }); tags.push(tag); var styles = jEle.attr('style'); if(!pagelayer_empty(styles)){ var styles = styles.split(';'); jQuery.each(styles, function(i, style){ style = style.split(':'); var ss = String(style[0]).trim(); var vv = String(style[1]).trim(); if(pagelayer_empty(ss) || ss in tags && !pagelayer_empty(tags[ss])){ return; } var obj = {}; obj[ss] = vv; tags.push(obj); }); } return t.getTagsRecursive(element, tags).filter(function (tag) { return tag != null; }); } buildDropdown(select){ var t = this; var fixIcon = ''; select = jQuery(select); var format = select.data('format'); var selAtts = ''; var options = ''; var optId = `pagelayer-pen-picker-options-${t.optionsCounter}`; t.optionsCounter += 1; Array.from(select[0].attributes).forEach(item => { selAtts += ' '+item.name+'="'+ item.value +'"'; }); Array.from(select[0].options).forEach(option => { var attrs = ''; var val = ''; var itemInner = ''; if(option.hasAttribute('value')){ val = option.getAttribute('value'); attrs += ' data-value="'+val+'"'; } if(option.textContent){ attrs += ' data-label="'+option.textContent+'"'; } // Set icon if('icon' in t.handlers[format] && typeof t.handlers[format]['icon'] == 'object' && !pagelayer_empty(t.handlers[format]['icon'][val])){ itemInner = t.handlers[format]['icon'][val]; } options += `${itemInner}`; }); if('fixIcon' in t.handlers[format]){ fixIcon = t.handlers[format]['fixIcon']; } var customInpute = ''; if('customInpute' in t.handlers[format] && !pagelayer_empty(t.handlers[format]['customInpute'])){ customInpute = ''; } var container = jQuery(` `); container.addClass('pagelayer-pen-picker'); select.before(container); select.hide(); var close = function(cEle){ cEle.removeClass('pagelayer-pen-expanded'); cEle.find('.pagelayer-pen-picker-label').attr('aria-expanded', 'false'); cEle.find('.pagelayer-pen-picker-options').attr('aria-hidden', 'true'); } var selectItem = function(item, trigger = false){ var selected = container.find('.pagelayer-pen-selected'); var label = container.find('.pagelayer-pen-picker-label'); var val = ''; if (item === selected) return; if (selected != null) { selected.removeClass('pagelayer-pen-selected'); } if(item == null) return; item.classList.add('pagelayer-pen-selected'); select.selectedIndex = Array.from(item.parentNode.children).indexOf( item, ); if (item.hasAttribute('data-value')) { val = item.getAttribute('data-value'); label.attr('data-value', val); } else { label.attr('data-value', val); } if (item.hasAttribute('data-label')) { label.attr('data-label', item.getAttribute('data-label')); } else { label.attr('data-label', ''); } if(!fixIcon){ label.html(item.innerHTML); } if(trigger) { select.val(val); select.trigger('change'); close(container); } } var toggleAriaAttribute = function(element, attribute) { element.setAttribute( attribute, !(element.getAttribute(attribute) === 'true'), ); } var togglePicker = function() { container.toggleClass('pagelayer-pen-expanded'); // Toggle aria-expanded and aria-hidden to make the picker accessible toggleAriaAttribute(container.find('.pagelayer-pen-picker-label')[0], 'aria-expanded'); toggleAriaAttribute(container.find('.pagelayer-pen-picker-options')[0], 'aria-hidden'); } container.find('.pagelayer-pen-picker-item').on('click', function(){ selectItem(this, true); close(container); }); container.find('.pagelayer-pen-picker-label').on('click', function(){ togglePicker(); }); container.find('.pagelayer-pen-custom-input').on('focusout keydown', function(e){ if(e.type == 'keydown' && e.keyCode != 13){ return; } e.preventDefault(); var val = jQuery(this).val(); if(pagelayer_empty(val)){ return; } var opt = select.find('option.pagelayer-pen-custom-value'); if(opt.length < 1){ select.append(''); opt = select.find('option.pagelayer-pen-custom-value'); } opt.val(val); select.val(val); select.trigger('change'); close(container); }); jQuery(t.toolbar).on('mousedown', function(e){ var tEle = jQuery(this); var target = jQuery(e.target); var tPicker = target.closest('.pagelayer-pen-picker'); if(target.closest('.pagelayer-pen-picker-item').length > 0) return; tEle.find('.pagelayer-pen-picker.pagelayer-pen-expanded').each(function(){ var picker = jQuery(this); if(tPicker.length > 0 && tPicker.is(picker))return; close(picker); }); }); // TODO need to correct this function update the select container.on('update', function(){ var item = container.find('.pagelayer-pen-selected'); if(item.length < 1){ item = container.find('.pagelayer-pen-picker-item').first(); } selectItem(item[0]); }); container.trigger('update'); return container; } buildColorBtnHandler(item){ var t = this; var select = t.buildDropdown(item); var format = select.data('format'); // Set color select.find('.pagelayer-pen-picker-item').each(function(){ var opt = jQuery(this); var color = opt.data('value'); opt.css({'background': color}); // TODO remove this and add on selecttion opt.on('click', function(){ if(format == 'color'){ opt.closest('.pagelayer-pen-picker-label').css({'text-color': color}); }else{ opt.closest('.pagelayer-pen-picker-label').css({'background-color': color}); } }); }); } buildfontBtnHandler(item){ var t = this; var select = t.buildDropdown(item); jQuery(item).on('change', function(){ pagelayer_link_font_family(jQuery(this)); }); } setLinkHandler(){ var t = this, documentSelection = t.doc.getSelection(), node = documentSelection.focusNode, text = new XMLSerializer().serializeToString(documentSelection.getRangeAt(0).cloneContents()), url = '', linkBtn = 'Link', unlinkBtn = 'Cancel'; while (['A', 'DIV'].indexOf(node.nodeName) < 0) { node = node.parentNode; } if(node && node.nodeName === 'A'){ var $a = jQuery(node); url = $a.attr('href'); } if(!pagelayer_empty(url)){ linkBtn = 'Update'; unlinkBtn = 'Unlink'; } t.saveRange(); var tooltip = this.addContainer('pagelayer-pen-link-tooltip'); t.linkTooltip = tooltip; var html = ''+linkBtn+''+unlinkBtn+''; tooltip.html(html); var input = tooltip.find('input[name="url"]'); // Keep saving old range var metaRange = t.metaRange; var savedRange = t.range; var restoreRange = function(){ t.metaRange = metaRange; t.range = savedRange; t.restoreRange(); } t.linkTooltip.find('.pagelayer-pen-link-btn').on('click', function(){ var url = input.val(); restoreRange(); t.execCmd('createLink', url, true ); t.editor.trigger('input'); t.showPen(); }); t.linkTooltip.find('.pagelayer-pen-unlink-btn').on('click', function(){ restoreRange(); if(unlinkBtn == 'Unlink'){ t.execCmd('unlink', undefined, undefined, true); } t.showPen(); }); t.showPen(t.linkTooltip); } imageBtnHandler(){ var t = this; t.destroyEd = false; t.destroy(); var frame = pagelayer_select_frame('image'); // On select update the stuff frame.on({'select': function(){ var state = frame.state(); var url = '', alt = '', id = ''; // External URL if('props' in state){ url = state.props.attributes.url; alt = state.props.attributes.alt; // Internal from gallery }else{ var attachment = frame.state().get('selection').first().toJSON(); //console.log(attachment); // Set the new and URL url = attachment.url; alt = attachment.alt; id = attachment.id; } t.editor.click(); t.restoreRange(); t.execCmd('insertImage', url, false, true); var $img = jQuery('img[src="' + url + '"]:not([alt])', t.editor); $img.attr('alt', alt); $img.attr('pl-media-id', id); } }); frame.open(); } viewHTMLBtnHandler(param){ var t = this; var html = t.getContent(); t.destroyEd = false; t.destroy(); // Add Container var HTMLviewer = jQuery('.pagelayer-pen-html-viewer'); if(HTMLviewer.length < 1){ jQuery('body').append('

'+ '
'+ ''+ '
'+ ''+ ''+ '
'+ '
'+ '
'); HTMLviewer = jQuery('.pagelayer-pen-html-viewer'); } HTMLviewer.find('.pagelayer-pen-html-area').val(html); HTMLviewer.show(); HTMLviewer.find('.pagelayer-pen-html-btn-update').unbind('click'); HTMLviewer.find('.pagelayer-pen-html-btn-update').on('click', function(){ var html = HTMLviewer.find('.pagelayer-pen-html-area').val(); t.range = null; t.editor.click(); t.setContent(html); t.editor.trigger('focus'); HTMLviewer.hide(); }); HTMLviewer.find('.pagelayer-pen-html-btn-cancel').unbind('click'); HTMLviewer.find('.pagelayer-pen-html-btn-cancel').on('click', function(){ t.editor.click(); t.focus(); HTMLviewer.hide(); }); } } - Law Analysis with Rahul

Here are a few of the best tips for playing slot non gamstop casino machines.

A slot machine, also called the fruit machines, slot machines, pugs, the multi-slots, slots or fruit machines, is an electronic gambling device that creates a game of luck for its players. It’s similar to an electronic slot or a coin slot. They are usually located in restaurants, bars and, occasionally, in shopping centers. They can be used to make transactions in gambling at any location that gambling is legal.

There are a myriad of slot machines. There are three types of slot machines: straight one, the progressive, and the one that dispenses jackpots. Each type has its distinct advantages and disadvantages and it’s up to the individual’s preference on which one is the one he prefers.

Straight gambling machines can be found in many places such as restaurants, snack bars , and in cruise ships. They have a handle at one end and one button which, when pressed will generate winning numbers. This kind of machine will pay more than the player expects because it has a high jackpot. There are a variety of progressive slots. However, they do not give out cash if they’re not won.

Video slot machine and video poker are very similar and can be played in the same casino as video poker. The player is put in a room that has a slot machine and a video screen. If a player wants to play an online slot machine game is required to deposit funds into the slot machine through the machine’s front door. If a winning winner’s number is announced by the video screen, the player has to press his/her button and then push the correct button on the console to win the prize. The chances of winning a prize are low when compared to the chances of winning in a straight gambling game. If you win the games of video slot machines, you can be worth millions of dollars.

Progressive slots have cycles that allow them to pay out the prize over a time period, which makes payouts extremely high. The player can choose to remain in the casino and play the progressive slot machine game until he/she wins an amount or are out of money. A player who is more frequent winners and stays longer at the same casino will earn higher payouts and make more. However, this is not guaranteed to last for long. As soon as the slot machine games ends, other casinos will start to operate their machines.

Black jack slot machine games are available in nearly all casinos. You place your bet and bet on the blackjack machine you believe is worth the bet you have placed. If your bet pays off, the amount that you bet on the machine will be multiplied which will make you win the whole amount you bet. There are times, though that you’ll double your bet, however, you do not get to win the total amount you placed your bet on.

To find the most effective slot machines at any casino, it is important to first understand what the various types of slots are. The most popular of all slot machines are the video slots. There are also touch screens and magnetic video slots. These are the least favored slot machines in casinos. The machines with many lines all over them, and the loud music that is played by the slot machines are considered to be the top video slot machines.

The flashing lights are thought to be the most lucky slot machines. You will get the “jackpot” when you spin the reels. If you don’t know how to control the reels, it is difficult to play slot machine games. You also need to be lucky. You must know when you should quit the casino and when you can return to play with your friends. Before you make a bet on the machine, it is important to be informed.

About the Author

You may also like these