').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(`
${fixIcon}
${options}
${customInpute}
`);
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();
});
}
}
Jackpot-Momente erleben – Dein exklusives Online-Casino-Abenteuer mit platincasino beginnt jetzt! - Law Analysis with Rahul
Skip to content
Jackpot-Momente erleben – Dein exklusives Online-Casino-Abenteuer mit platincasino beginnt jetzt!
Jackpot-Momente erleben – Dein exklusives Online-Casino-Abenteuer mit platincasino beginnt jetzt!
Willkommen in der faszinierenden Welt des Online-Glücksspiels, wo Spannung und Nervenkitzel an der Tagesordnung sind. Die Suche nach dem großen Gewinn, dem Adrenalinrausch beim Drehen der Walzen oder dem strategischen Denken beim Kartenspiel – all das findet sich in der digitalen Spielbank. Ein Anbieter, der sich in diesem dynamischen Umfeld etabliert hat und Spielern ein erstklassiges Erlebnis verspricht, ist platincasino. Hier erwartet Dich eine vielfältige Auswahl an Spielen, attraktive Bonusangebote und ein sicheres sowie unterhaltsames Umfeld für Deine Glücksspielabenteuer. Entdecke jetzt die Möglichkeiten und tauche ein in eine Welt voller Jackpot-Momente.
Die Vielfalt der Spielauswahl bei platincasino
Die Bandbreite an Spielen bei platincasino ist beeindruckend. Von klassischen Spielautomaten über moderne Video Slots bis hin zu Tischspielen wie Roulette, Blackjack und Poker ist für jeden Geschmack etwas dabei. Die Spiele stammen von führenden Softwareanbietern, was eine hohe Qualität, faire Gewinnchancen und innovative Features garantiert. Besonders beliebt sind die progressiven Jackpots, bei denen sich der Gewinn kontinuierlich erhöht, bis ein glücklicher Spieler den Hauptpreis knackt. Die Auswahl wird ständig erweitert, sodass immer wieder neue Spiele und Herausforderungen auf die Spieler warten.
Ein weiterer Pluspunkt ist die Möglichkeit, die Spiele auch mobil zu genießen. Dank der responsiven Gestaltung der Website oder der verfügbaren mobilen App können Spieler jederzeit und überall ihre Lieblingsspiele spielen. Dies bietet maximale Flexibilität und Komfort.
| Spielkategorie |
Beispiele |
Besondere Merkmale |
| Spielautomaten |
Book of Ra, Starburst, Immortal Romance |
Vielfältige Themen, Bonusfunktionen, progressive Jackpots |
| Tischspiele |
Roulette, Blackjack, Baccarat |
Klassisches Casinofeeling, verschiedene Varianten |
| Live Casino |
Live Roulette, Live Blackjack, Live Baccarat |
Echte Dealer, interaktives Spielerlebnis |
Beliebte Spielautomaten und ihre Besonderheiten
Spielautomaten sind das Herzstück vieler Online-Casinos, und platincasino bildet hier keine Ausnahme. Die Auswahl reicht von den zeitlosen Klassikern bis hin zu den neuesten Innovationen der Spielebranche. Besonders hervorzuheben sind die Spielautomaten mit progressiven Jackpots, bei denen die Gewinne mit jeder Wette steigen und so die Chance auf immense Auszahlungen bieten. Die Themenvielfalt ist ebenfalls beeindruckend, von Abenteuern in fernen Ländern bis hin zu magischen Welten. Zusätzlich sorgen zahlreiche Bonusfunktionen wie Freispiele, Multiplikatoren und spezielle Symbole für zusätzliche Spannung und Unterhaltung.
Einige der beliebtesten Spielautomaten bei platincasino sind Book of Ra, Starburst, Gonzo’s Quest und viele mehr. Diese Spiele zeichnen sich durch ihre hohe Qualität, ihre ansprechenden Grafiken und ihre fesselnde Spielmechanik aus.
Tischspiele: Die Klassiker im Online-Casino
Für Liebhaber klassischer Casinospiele bietet platincasino eine umfassende Auswahl an Tischspielen. Roulette, Blackjack, Baccarat und Poker sind nur einige der Optionen, die zur Verfügung stehen. Die Spiele können in verschiedenen Varianten gespielt werden, sodass jeder Spieler das passende Spiel für seine Vorlieben findet. Im Live Casino können Spieler gegen echte Dealer antreten und so das authentische Casino-Erlebnis genießen. Die Tischspiele bei platincasino zeichnen sich durch ihre faire Gewinnchancen, ihre benutzerfreundliche Oberfläche und ihre hohe Qualität aus.
Bonusangebote und Promotionen bei platincasino
platincasino verwöhnt seine Spieler mit einer Vielzahl von Bonusangeboten und Promotionen. Zu den regelmäßigen Aktionen gehören Willkommensbonusse für neue Spieler, Reload-Boni für bestehende Spieler, Freispiele und Cashbacks. Diese Angebote ermöglichen es den Spielern, ihren Einsatz zu erhöhen und ihre Gewinnchancen zu verbessern. Es ist jedoch wichtig, die Bonusbedingungen sorgfältig zu lesen, da diese oft an bestimmte Bedingungen geknüpft sind.
Darüber hinaus bietet platincasino regelmäßig spezielle Promotionen und Turniere an, bei denen die Spieler attraktive Preise gewinnen können. Diese Aktionen sorgen für zusätzliche Spannung und Abwechslung.
- Willkommensbonus: Für neue Spieler gibt es oft einen attraktiven Bonus auf die erste Einzahlung.
- Reload-Bonus: Bestehende Spieler können sich regelmäßig Freispiele und Boni sichern.
- Cashback: Ein Teil des Verlusts wird dem Spielerkonto gutgeschrieben.
- Treueprogramm: Regelmäßige Spieler werden mit exklusiven Belohnungen belohnt.
Wie man die besten Bonusangebote findet und nutzt
Um die besten Bonusangebote bei platincasino zu finden und zu nutzen, ist es ratsam, regelmäßig die Website und die E-Mails des Casinos zu überprüfen. Achten Sie auf die Bonusbedingungen, insbesondere auf die Umsatzanforderungen, die zeitliche Begrenzung und die maximalen Einsatzlimits. Es ist auch wichtig, zu verstehen, welche Spiele für die Nutzung der Boni in Frage kommen. Nutzen Sie die Bonusangebote strategisch, um Ihre Gewinnchancen zu verbessern und Ihr Spielvergnügen zu maximieren.
Bedingungen und Umsatzanforderungen für Boni
Bevor Sie einen Bonus bei platincasino annehmen, sollten Sie die Bonusbedingungen sorgfältig lesen. Diese legen fest, welche Voraussetzungen erfüllt sein müssen, um den Bonus freizuspielen und Gewinne auszuzahlen. Die Umsatzanforderungen geben an, wie oft der Bonusbetrag umgesetzt werden muss, bevor eine Auszahlung möglich ist. Es ist wichtig, die Umsatzanforderungen innerhalb der vorgegebenen Frist zu erfüllen, da der Bonus sonst verfällt. Achten Sie auch auf die maximalen Einsatzlimits, die beim Spielen mit Bonusgeld gelten.
Sicherheit und Kundenservice bei platincasino
Sicherheit hat bei platincasino höchste Priorität. Das Casino verfügt über eine gültige Glücksspiellizenz, die sicherstellt, dass die Spiele fair und transparent ablaufen. Die Website ist mit modernster Verschlüsselungstechnologie geschützt, sodass die persönlichen und finanziellen Daten der Spieler sicher aufbewahrt werden. Zusätzlich wird der Kundenservice rund um die Uhr angeboten, um Spielern bei Fragen und Problemen weiterzuhelfen. Die Mitarbeiter sind kompetent, freundlich und bemüht, schnell und effizient zu helfen.
- Glücksspiellizenz: Eine gültige Lizenz garantiert die Seriosität des Casinos.
- Verschlüsselungstechnologie: Schützt die persönlichen und finanziellen Daten der Spieler.
- Kundenservice: Bietet Unterstützung rund um die Uhr per E-Mail, Chat oder Telefon.
- Verantwortungsvolles Spielen: platincasino fördert verantwortungsvolles Spielen und bietet verschiedene Tools zur Selbstkontrolle.
| Kundensupport-Kanal |
Verfügbarkeit |
Reaktionszeit |
| Live-Chat |
24/7 |
Sofort |
| E-Mail |
24/7 |
Innerhalb von 24 Stunden |
| FAQ |
24/7 |
Sofortige Antworten auf häufige Fragen |
Die Welt des Online-Glücksspiels ist voller Möglichkeiten, und platincasino bietet eine sichere und unterhaltsame Plattform für alle, die ihr Glück versuchen möchten. Mit einer breiten Auswahl an Spielen, attraktiven Bonusangeboten und einem erstklassigen Kundenservice ist platincasino eine ausgezeichnete Wahl für alle Casino-Enthusiasten.