/* 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

Депозит баланса и обналичивание финансов в онлайн казино

Депозит баланса и обналичивание финансов в онлайн казино

Игра на деньги в интернет-казино предусматривает пополнение и снятие денег. Эти процедуры пользователи выполняют в профиле, независимо определяя объемы, что необходимо зачислить или вывести с сайта. У монетарных транзакций есть свои правила – их важно выполнять для предотвращения затруднений с операциями. Для практичности пользователей в легзо казино требования наиболее облегчены – на их ознакомление тратятся считанные секунды.

В сертифицированных казино транзакции выполняются с учетом определенных сроков. Для пополнения и вывода средств доступно несколько методов оплаты. Участники могут применять реальные деньги и цифровую валюту. Обилие опций позволяет безопасно произвести денежный перевод с любой территории и назад.

Пополнение денег на аккаунт геймера в онлайн клубе

Депозит баланса в виртуальном казино с поощрениями – важная процесс, после выполнения которой можно начинать играть на реальные деньги. Вход к этому процедуре имеется только у авторизованных юзеров. Если профиль в казино создан, геймеру нужно залогиниться и перейти на раздел для депозита. Далее необходимо осуществить обычные операции:

  1. Определить подходящего финансового оператора из представленных.
  2. Указать индивидуальные данные.
  3. Определить сумму, что зачислится на баланс в казино в казино.
  4. Утвердить проведение платежа.

Внесение баланса осуществляется немедленно. Обычно на операцию уходит не дольше часа. Такое позволяет игрокам без промедления приступить к платным ставкам в слотовых машинах. Если перевод не был завершен за период 60 минут, следует уведомить поддержку клиентов. Профессионалы поддержки разберутся в ситуации и содействуют решить ее в минимальные сроки. Если транзакция с определенным провайдером не выполняется, может быть предоставлен иной платежный способ.

Для того чтобы внесения баланса в казино legzo casino предусмотрены многочисленные способы. Наиболее популярны сегодня переводы с помощью пластиковых карт международных банков, онлайн платежных сервисов и биткоин-кошельков. Данные манят геймеров абсолютной приватностью финансовых сделок. Во разнообразных заведениях также доступна функция увеличения баланса с аккаунта мобильного телефона и стационарных терминалов оплаты. Необходимо принимать во внимание, что наличие определенных платежных методов часто зависит от места жительства клиента. Просмотреть с полным перечнем компаний можно при подготовке финансовой заявки.

Платежи при внесении баланса, как в большинстве случаев, не удерживаются ни платежными системами, ни самим игорным заведением. Пределы перечислений определяются каждым поставщиком индивидуально. Самые низкие ограничения по объемам как правило существуют при переводах с использованием цифровых и крипто-валютных аккаунтов. Для удобного использования пользователей ограничения прописываются внутри заявке на финансы.

По правилам большинства лучших онлайн игорных заведений, переводы допускаются только на персональные данные клиентов. В случае если в дальнейшем выяснится, что денежный инструмент относится к третьему лицу, игрок подвергается риску блокировки на ресурсе. Необходимо также учитывать, что к транзакциям, как и к входу, в онлайн-клубах допускаются только персоны, достигшие совершеннолетнего возраста.

Вывод выигрышей в игорном заведении

При получения выигрыша из онлайн казино с использованием акций пользователи обязуются вводить те же данные. Изменяться может только размер перечисления. Платежный сервис и реквизиты должны сходиться. Данное положение используется в основном в любых игровых домах. Оно используется для устранения монетарных перечислений на счета и аккаунты третьих лиц. Выполнение указанного нормы проверяется безопасностью игорного клуба. Тогда после этого заявка, поданная пользователем, пересылается оператору платежей. Далее выполняется её обработки – клиент забирает средства на свои счета.

Важно иметь в виду, что при обналичивании призов могут устанавливаться сборы со стороны платежных операторов. Следовательно, на банковские карты и электронные кошельки поступает чуть меньше финансов. Сертифицированные казино как правило сборы за переводы не берут. Пределы транзакций способны значительно варьироваться. Всё зависит от определенного платежного оператора. Отличаются также временные рамки монетарных операций. На виртуальные и электронные аккаунты пользователей средства зачисляются в течение пары часов. Денежные операции возможно занимают максимум до пяти рабочих суток. На деле обращения обрабатываются значительно быстрее.

Согласно правилам множества рейтинговых казино, внесенные деньги на счет немедленно обналичивать невозможно. Такое будет воспринято в качестве стремление отмывания денежных средств. Следовательно нужно тщательно размышлять, перед тем как пополнять счет на игровой площадке. Внесенный баланс нужно использовать целиком в аппаратах не менее одного раза. Исключительно по окончании указанного средства окажутся возможны на вывод из легзо казино casino. На заработанные средства это положение не применяется. Они можно будет немедленно запрашивать на вывод, если достигнут нижний лимит кешаута.

В сертифицированных азартных казино сроки выплат всегда соблюдаются. Для этого платформы подписывают соглашения с аккредитованными транзакционными услугами, у них сложилась прекрасная репутация на рынке. Такие компании контролируют за своим образом, обрабатывая все обращения своевременно и конфиденциально. Перемещение финансов они выполняют по зашифрованным каналам связи, к коим не могут получить доступ посторонние лица.

Подтверждение личности при обналичивании призов

В лицензионных онлайн игорных заведениях с акциями геймерам, запрашивающим начальную вывод средств, предлагается пройти верификацию. У пользователей требуют эту проверку чтобы установить возрастное соответствие клиента и его государство. Если геймер дошел до возраста 18 лет и находится в регионе, из которого допущена учетная запись на сайте, проверка личности пройдет успешно. В обратном случае руководство будет вынуждена заморозить профиль и конфисковать средства со счета за несоблюдение правил сайта.

Помимо этого, проверка необходима для гарантии усиленной защиты аккаунтов. По окончании указанной манипуляции транзакционные данные игрока синхронизируются с её учетной записью в legzo. Данное полностью исключает обман с транзакциями, поскольку вывод капитала из учетной записи чужими пользователями будет запрещен.

С целью завершения верификации пользователи совершают несколько несложных действий:

  1. Входят в индивидуальный аккаунт.
  2. Обнаруживают раздел с процедурой идентификации.
  3. Оформляют анкету личными сведениями (если нужно).
  4. Отправляют скан идентифицирующего паспорта (обычно подходит разворота паспорта либо удостоверения).
  5. Посылают прошение на рассмотрение.

В большинстве интернет казино проверка верификации идентичности занимает от небольшого времени до 2 24 часов. Конкретные периоды обусловлены в зависимости от занятости экспертов. О итогах проверки можете узнать через личной учетной записи. Здесь необходимо показаться уровень проверенного юзера. Данное означает, что можно без препятствий снимать выигрыши из казино. Впоследствии будущем подобная процедура будет не нужна. Исключительный случай – случаи, когда с ресурса выплачиваются большие деньги, как вариант, куш. В данной ситуации игроки часто осуществляют проверку повторно.

В случае, если подтверждение не засчитана, скорее всего, обнаружены несоответствия в документах и сведениях, указанных в заявке. Потребуется внимательно проверить информацию, корректируя несоответствия. Дополнительная обычная основание неудачи в идентификации – предоставление дубликатов документов низкого качества. Таким образом необходимо проверить, дабы любые информация на них были хорошо различимы. В случае, если и со второго раза проверение не подтверждена, стоит обратиться в техническую поддержку за помощью. Важно принимать во внимание, что в некоторых казино, вдобавок к идентификационного документа, требуется показывать скрины финансового инструмента. Эту самую сведения ещё возможно уточнить посредством службе поддержки.

Какие действия следует сделать до внесением средств на счета

Чтобы входа к денежным сделкам в онлайн-казино требуется быть зарегистрированным на этой сайте. Данный ранг становится доступным лишь по окончании завершения регистрационной процедуры. Открыть учетную запись в legzo casino казино имеют возможность все взрослые гости, проживающие в государствах, которые принимает клуб. Процесс содержит прохождение различных стадий. Если выбрали регистрация аккаунта через мобильный номер, выполняются следующие шаги:

  1. На маленькой анкете вписывается контактный номер.
  2. Придумывается надежный пароль, состоящий из цифр и символов алфавита.
  3. Анализируется юзерское соглашение и фиксируется принятие с ним.
  4. Выполняется проверка мобильного (присланный в смс-сообщении код вписывается в регистрационном поле).

Совместно с указанным способом регистрации почти постоянно доступно оформление профиля через e-mail. Метод тоже включает оформление короткой анкеты. Только игроки вписывают взамен цифры смартфона свой адрес почтового ящика в сети. К пользователя в течение нескольких секунд отправляется линк чтобы авторизации в личном аккаунте. Когда сообщение не поступила во «Входящие», возможно, следует проверить его в разделе «Спам».

Гостям также часто предлагается более простой метод регистрации – с применением аккаунта в соцсети. Предстоящим пользователям казино требуется лишь зарегистрироваться на стороннем платформе или дать согласие на интеграцию данных. Дальше система организует всё автоматически, создав персональный кабинет. При выбора этого варианта учета следует, дабы сведения на социальной сети были правдивыми и обновленными. Данное исключит трудности с получением заработанных средств.

Сразу после входа в аккаунте необходимо начинать с увеличению баланса. Желательно также заранее выполнить идентификацию. Когда осуществляются первоначальные беты в казино, документы проходят проверку администрацией. В итоге не потребуется ожидать исходов верификации 1-2 суток при запросе первой выплаты.

Поощрения за пополнение баланса

Внесение счета в казино позволяет не только начать делать денежные ставки, но и воспользоваться бонусами. Подарки в многих интернет-клубов предоставляются как за первые, так и дальнейшие депозиты. На первые внесения счета процент финансовой бонуса выше. Обычно первым пользователям начисляется весь объем из зачисленных денег. Одновременно с финансами зачастую предоставляются бонусные бесплатные вращения для определенных игровых автоматов. За следующие вклады пользователи приобретают от десяти до двадцати процентов надбавки. Определенные условия предоставления бонусов указываются на соответствующих веб-страницах.

В случае желании геймеры на интернет-казино легзо казино могут отказаться от получения призов за пополнение счета. Довольно не нажимать кнопку «Активировать» на табличке с подарком. Тем не менее большинство игроков позитивно относится к бонусам на пополнение. После этих начисления появляется дополнительный ресурс, который можно задействовать для ставочных беттинга. Такое повышает шансы на получение выигрыша и помогает в разы продлить геймплей. После результативного использования премиальных фондов есть шанс достичь чистый доход благодаря казино.

Использовать бонусы за увеличение баланса легко. Достаточно точно соблюдать требованиям акции. Во этих всегда прописывается wager – объем ставок с использованием бонусных фондов. Например, в случае, если данный множитель равен ×35, размер премии потребуется поставить на кону в аппаратах не менее 35 раз. После того как этого отработанные акционные фонд можно будет вывести.

В правилах промоции также может прописывать величина бетов. Нарушив регламент нельзя, если нет программа не учтет ставку. Важно также учитывать, что временные рамки предложения зачастую лимитированы коротким сроком. Когда не успеете отыграть подарок за отведенное время, он будет аннулирован.

Внесение и обналичивание финансов на дубликате казино

Если официальный вебсайт казино недоступен, с высокой вероятностью он попал под санкции регуляторов. Такая картина распространена в государствах, где различные типы игорных забав под запретом. Чтобы достичь право к финансовым сделкам и пари на деньги, посетителям legzo требуется применить альтернативным сайтом. Копия подлинного сайта отправит в заведение, давая вход к идентичным:

  • бонусам и привилегиям;
  • игровым машинам
  • соревнованиям и лотереям;
  • способам регистрационного процесса и входа;
  • методам взаимодействия с службой поддержки.

Всецело хранятся на отражениях также платежные способы. Условия операций сохраняются прежними. Чтобы внесения начального счета новичкам пользователям необходимо зарегистрироваться. В случае наличия аккаунта в платформе, можно просто осуществить вход. Когда в учетной записи на балансе были финансы, они сохранятся в целости и сохранности. Доступны также станут запущенные бонусы и достигнутый уровень в программе лояльности. Чтобы авторизации на зеркале необходимо вводить свои данные аккаунта (пароль и логин).

Денежные транзакции на альтернативных платформах осуществляются в те же периоды, что на главном сайте казино. Копии официальных онлайн-клубов находятся под жестким надзором игорных комиссий. Данное обеспечивает сохранность и оперативность монетарных переводов. Обязанности за них лежит на уполномоченные платежные сервисы. Контролировать положение денежной прошения клиенты обычно имеют возможность во личном кабинете. Здесь же регулярно предлагается страница с записями транзакций. В данной платформе отображена сведения обо всех монетарных переводах, совершенных пользователем в гэмблинге.

Через некоторых 24 часов или недельки актуальное зеркало может быть недоступным. Это значит, что онлайн-казино также оказалось под ограничение. Для возобновления авторизации к виртуальному казино и персональному аккаунту нужно переключиться на зеркало, действующий в настоящее время. Действующие зеркальные URL-адреса геймеры получают из систем поиска, на профильных ресурсов, через онлайн-чат с поддержкой.

Финансовые операции на мобильных девайсах

Вносить баланс и выводить призы игроки казино способны не только посредством ПК. Схожая функция доступна при применении гаджетов, айфонов, и планшетов. Вполне задействовать мобильную вариацию веб-ресурса. Их запуск возможен в Opera, Google Chrome и других распространенных браузерах. Главное – обладать в наличии модный девайс с доступным сетевым доступом. Получение данных такой способ посещения игрового клуба не предусматривает. Попадание в игорный дом осуществляется прямо после клика на актуальной гиперссылке. В этом состоит одно из ключевых преимуществ мобильной адаптации.

Для того чтобы депонировать счет с мобильного устройства либо таблета, первым игрокам онлайн-казино также необходимо пройти регистрацию. Регулярным пользователям необходимо авторизоваться в личный профиле. В мобильной вариации для авторизации в учетную запись используются те же идентификационные данные, что в настольной. Геймеры, пополнявшие аккаунт на персональном компьютере, получат полный допуск к своим финансам. Финансовые варианты в веб версии неизменны прежними. Когда онлайн-казино лицензионное, можно будет не сомневаться в защищенности денежных переводов.

Кроме онлайн варианта, для доступа в игорный дом подходит и апп для смартфона. В нем также предоставляются денежные сделки, игра на деньги, запуск бонусов и другие опции онлайн-казино. Внесение депозита и обналичивание добычи выполняются в периоды, заданные на официальном сайте клуба. Варианты оплаты, как правило, доступны идентичные. Изучить эти данные можно на секции для оформлением финансовых заявок. В случае если вклад делался в мобильной версии либо десктопной версии сайта платформы, в загруженном приложении он будет доступен целиком. Применить деньгами можно станет возможным после быстрой авторизации в сервисе.

Мобильное аппликацию геймеры сначала инсталлируют на свой смартфон. Приложения для Андроид обычно находятся на сайтах игорных заведений. После того как загрузки APK-файлик инсталлируется на смартфон. В дальнейшем логин внутрь систему производится одним щелчком без применения браузера. Всего лишь кликнуть на нужный значок на экране смартфона или планшета. За эксплуатацию аппликацией администраторы взнос не требуют.

Для айфонов с системой iOS приложение скачивается из плей-маркета. Функционально она не различается от софтвера для Андроид. В ней тоже можно депонировать и выводить финансы, запускать азартные игры, быть частью акций.

About the Author

Leave a Reply

Your email address will not be published. Required fields are marked *

You may also like these