PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 1.0.2
Page Builder: Pagelayer – Drag and Drop website builder v1.0.2
2.2.1 2.2.0 2.1.9 2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 trunk 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 1.0.0 1.0.2 1.0.3 1.0.4 1.0.5 All 129 releases
pagelayer / js / pagelayer-editor.js

pagelayer-editor.js in Page Builder: Pagelayer – Drag and Drop website builder 1.0.2, at js/pagelayer-editor.js

4,185 lines 107.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 PAGELAYER
3 http://pagelayer.com/
4 (c) Pagelayer Team
5 */
6
7 pagelayer = {
8 $: jQuery,
9 $$ : function(select){
10 return jQuery(select, window.parent.document);
11 },
12 p : this,
13 copy_selected: '',
14 mouse: {x: -1, y: -1},
15 history_action : true,
16 }
17
18 var pagelayer_history_obj = {}, pagelayer_revision_obj = {};
19 var pagelayer_add_section_data = {};
20
21 // Lets start
22 jQuery(document).ready(function(){
23
24 // Set the title of the parent window
25 try{ pagelayer.$$('head').append(pagelayer.$('title')[0].outerHTML); }catch(e){};
26
27 pagelayer.blank_img = pagelayer_url+'/images/default-image.png';
28
29 pagelayer_shortcodes['pl_inner_row'] = JSON.parse(JSON.stringify(pagelayer_shortcodes['pl_row']));
30 pagelayer_shortcodes['pl_inner_row']['name'] = 'Inner Row';
31 pagelayer_groups['grid'].push('pl_inner_row');
32
33 // Make the Topbar
34 pagelayer_bottombar();
35
36 // Make the Leftbar
37 pagelayer_leftbar();
38
39 // Add widget section
40 pagelayer_add_widget();
41
42 // Setup the ELPD
43 pagelayer_elpd_setup();
44
45 // Setup the properties of the elements
46 pagelayer_element_setup();
47
48 // An image to show for drag
49 jQuery('body').append('<img src="'+pagelayer_url+'/images/drag-ghost.png" class="pagelayer-drag-show" />');
50
51 // Setup the grid drag
52 pagelayer_setup_drag();
53
54 // Set left bar draggable
55 pagelayer_make_leftbar_movable();
56
57 // Set to desktop
58 pagelayer_set_screen_mode('desktop');
59
60 // Set up right click
61 pagelayer_left_click();
62 pagelayer_right_click();
63
64 // Setup pagelayer history handle
65 pagelayer_history_obj['action_data'] = [];
66 pagelayer_history_setup(true);
67
68 // Do any actions here
69 pagelayer_trigger_action('pagelayer_setup_history');
70
71 // Editor Tooltips
72 pagelayer_tooltip_setup();
73
74 // Load Fonts
75 for(var x in pagelayer_loaded_icons){
76 var item = pagelayer_loaded_icons[x];
77 jQuery.when(
78 pagelayer_get_stored_data(pagelayer_url+'/fonts/'+item+'.json', pagelayer_ver)
79 ).then(function(){
80 pagelayer_icons[item] = JSON.parse(pagelayer_get_stored_data(pagelayer_url+'/fonts/'+item+'.json', pagelayer_ver));
81 });
82 };
83
84 });
85
86 // The jQuery Object of the ELPD
87 var pagelayer_elpd;
88
89 // Store data values
90 function pagelayer_get_stored_data(url, version){
91 var name = 'pagelayer_'+url;
92 var data = {};
93 var force = false;
94
95 // Try to parse the data
96 try{
97 data = JSON.parse(localStorage.getItem(name));
98
99 if(data['version'] !== version){
100 force = true;
101 }
102
103 }catch(e){
104 force = true;
105 }
106
107 // Force download
108 if(force){
109 return jQuery.ajax({
110 url: url,
111 type: 'GET',
112 dataType: 'text',
113 success:function(newData){
114 var data = {};
115 data['version'] = version;
116 data['val'] = newData;
117 localStorage.setItem(name, JSON.stringify(data));
118 }
119 });
120 }
121
122 return data['val'];
123
124 }
125
126 function pagelayer_closest_corner(jEle){
127 var corners = [];
128 var w = jEle.outerWidth();
129 var h = jEle.outerHeight();
130 var topleft = jEle.offset();
131
132 // 0 - Top Left
133 corners.push(topleft);
134
135 // 1 - Top Right
136 corners.push({top: topleft.top, left: topleft.left+w});
137
138 // 2 - Bottom Right
139 corners.push({top: topleft.top+h, left: topleft.left+w});
140
141 // 3 - Bottom Left
142 corners.push({top: topleft.top+h, left: topleft.left});
143
144 //console.log(corners);
145
146 // Calculate the closest to the mouse
147 var distances = {};
148 for(var c in corners){
149 var dist = Math.hypot(pagelayer.mouse.x - corners[c].left, pagelayer.mouse.y - corners[c].top);
150 distances[c] = dist;
151 }
152 //console.log(distances);
153
154 var corner = Object.keys(distances).sort(function(a,b){return distances[a]-distances[b]})[0];
155 //console.log(corner);
156
157 return corner;
158
159 };
160
161 // Make left bar draggable
162 function pagelayer_make_leftbar_movable(){
163 var pl_iframe = pagelayer.$$('.pagelayer-iframe'),
164 pl_leftbar = pagelayer.$$('.pagelayer-leftbar-table');
165
166 // On mouse down in pagelayer-topbar-holder
167 pagelayer.$$('.pagelayer-topbar-holder').on('mousedown', function(e){
168 e = e || window.event;
169 e.preventDefault();
170
171 // Get leftbar position
172 var orig_eleX = pl_leftbar.offset().left;
173 var orig_eleY = pl_leftbar.offset().top;
174
175 // Get the mouse cursor position at startup:
176 var posX = e.clientX;
177 var posY = e.clientY;
178
179 // The variable needs to be empty.
180 var newMethod = '',
181 par_doc = jQuery(window.parent.document).add(document),
182 change = true;
183
184 var leftbar_mousemove = function(e){
185 e = e || window.event;
186
187 if(change){
188 // Add class to leftbar
189 pl_leftbar.addClass('pagelayer-leftbar-moving');
190
191 // Add left-right overlay
192 pl_iframe.before('<div class="pagelayer-leftbar-move pagelayer-moveto-left"></div>');
193 pl_iframe.after('<div class="pagelayer-leftbar-move pagelayer-moveto-right"></div>');
194 pagelayer.$$('body').addClass('pagelayer-overflow-hidden');
195 change = false;
196 }
197
198 // calculate the new cursor position and set the element left-top position
199 var top = orig_eleY + (e.clientY - posY);
200 var left = orig_eleX + (e.clientX - posX);
201
202 // set the element's new position:
203 pl_leftbar.css({'top': top +'px','left': left +'px'});
204 pagelayer.$$('.pagelayer-leftbar-toggle').hide();
205
206 // Make a copy of new method
207 var _newMethod = newMethod;
208 newMethod = '';
209
210 // Get near by corner
211 var offleft = pl_iframe.offset().left;
212
213 if(offleft + 100 > e.clientX){
214 newMethod = 'before';
215 }else if(offleft+pl_iframe.outerWidth()- 100 < e.clientX){
216 newMethod = 'after';
217 }
218
219 if(_newMethod != newMethod){
220 pagelayer.$$('.pagelayer-leftbar-move').css({'width' :'', 'opacity': '0.33'});
221
222 if(newMethod == 'after'){
223 pagelayer.$$('.pagelayer-moveto-right').animate({'width' :'60px', 'opacity': '0.66'}, 200);
224 pl_leftbar.addClass('pagelayer-rightbar');
225 }else if(newMethod == 'before'){
226 pagelayer.$$('.pagelayer-moveto-left').animate({'width' : '60px', 'opacity': '0.66'}, 200);
227 pl_leftbar.removeClass('pagelayer-rightbar');
228 }
229 }
230
231 };
232
233 var leftbar_mouseup = function(e){
234
235 // Remove events
236 par_doc.off('mousemove', leftbar_mousemove);
237 par_doc.off('mouseup', leftbar_mouseup);
238
239 // Remove class to leftbar
240 pagelayer.$$('.pagelayer-leftbar-move').remove();
241
242 var windowHeight = jQuery(window).height();
243
244 if(pl_leftbar.offset().top < 0){
245 pl_leftbar.css({'top': '10px'});
246 }else if( (windowHeight - e.clientY) < 10){
247 pl_leftbar.css({'top': ''+windowHeight - 40+'px'});
248 }
249
250 if( !pagelayer_empty(newMethod)){
251 pl_leftbar.removeClass('pagelayer-leftbar-moving');
252 pl_leftbar.removeAttr('style');
253 pagelayer.$$('.pagelayer-leftbar-toggle').show();
254 pagelayer.$$('body').removeClass('pagelayer-overflow-hidden');
255 pl_iframe[newMethod](pl_leftbar);
256 }
257
258 // make change true
259 change = true;
260 };
261
262 par_doc.on('mouseup', leftbar_mouseup);
263 par_doc.on('mousemove', leftbar_mousemove);
264
265 });
266
267 }
268
269 // Make rows and cols draggable
270 function pagelayer_setup_drag(){
271
272 // The object to show as drag
273 var shower = jQuery('.pagelayer-drag-show');
274
275 // Delete any prospect
276 var clear_prospect = function(){
277 jQuery('.pagelayer-drag-prospect').remove();
278
279 // Shows the wrap as active
280 jQuery('.pagelayer-drag-ele-hover').removeClass('pagelayer-drag-ele-hover');
281 }
282
283 // Reset the complete drag stuff
284 var reset_dragging = function(){
285 pagelayer.dragging = false;
286 pagelayer.drag_is_new = false;
287 pagelayer.drag_mouse = {x: 0, y: 0};
288 reset_on_drag();
289 }
290
291 // Reset the element on you were last
292 var reset_on_drag = function(){
293 pagelayer.drag_closest = false;
294 pagelayer.drag_closest_corner = null;
295 }
296
297 // Scroll by
298 var scrollPx = 7;
299 var scrollDist = 30;
300
301 // If we are too close too the window edge, then scroll
302 var handle_scroll = function(e){
303
304 var windowHeight = jQuery(window).height();
305 var windowWidth = jQuery(window).width();
306
307 // Are we to close to the top or bottom
308 if(e.clientY < scrollDist){
309 window.scrollBy(0, -scrollPx);
310 }else if((windowHeight - e.clientY) < scrollDist){
311 window.scrollBy(0, scrollPx);
312 }
313
314 // Are we to close to the top or bottom
315 if(e.clientX < scrollDist){
316 window.scrollBy(-scrollPx, 0);
317 }else if((windowWidth - e.clientX) < scrollDist){
318 window.scrollBy(scrollPx, 0);
319 }
320
321 }
322
323 // SET the values
324 reset_dragging();
325
326 var ondragover = function(e) {
327 //console.log(e);
328
329 pagelayer.mouse.x = parseInt(e.pageX);
330 pagelayer.mouse.y = parseInt(e.pageY);
331 //console.log(pagelayer.mouse);
332
333 // Are we dragging ?
334 if(pagelayer.dragging){
335
336 //console.log(e);
337
338 e.preventDefault();
339 //e.stopPropagation();
340
341 // The wrap of the element being dragged
342 var wrap = pagelayer.dragging;
343
344 // New addition
345 var is_new = pagelayer.drag_is_new;
346 var ele;
347 var tag = pagelayer_tag(wrap);
348 var id = pagelayer_id(wrap);
349
350 // If existing element then add we are dragging
351 if(!is_new){
352
353 // Start Dragging
354 if(!wrap.hasClass('pagelayer-is-dragging')){
355 wrap.addClass('pagelayer-is-dragging');
356 }
357
358 //shower.hide();
359
360 ele = document.elementFromPoint(e.clientX, e.clientY);
361 //console.log(ele);
362
363 // Drag the show object
364 //shower.show();
365 //var offset = {top: (e.pageY-10)+'px', left: (e.pageX-10)+'px'}
366 //shower.css(offset);
367
368 }else{
369 ele = document.elementFromPoint(e.clientX, e.clientY);
370 }
371 //console.log(e);
372
373 // Have we moved more than 5px;
374 var dist = Math.hypot(pagelayer.mouse.x - pagelayer.drag_mouse.x, pagelayer.mouse.y - pagelayer.drag_mouse.y);
375 //console.log(dist);
376 /*if(dist && dist < 5){
377 return false;
378 }*/
379
380 // Handle the scroll
381 handle_scroll(e);
382
383 // Find the closest wrap
384 var onWrap;
385
386 // If we are a column, we can be over another column or row
387 if(tag == 'pl_col'){
388 onWrap = jQuery(ele).closest('.pagelayer-wrap-col,.pagelayer-wrap-row,.pagelayer-wrap-inner-row');
389 //console.log(pagelayer_id(onWrap));
390
391 // If we are a row, we can be over another row or a column
392 }else if(tag == 'pl_row'){
393 onWrap = jQuery(ele).closest('.pagelayer-wrap-row');
394 //console.log(pagelayer_id(onWrap));
395
396 // For inner row we restrict to 1 level only
397 }else if(tag == 'pl_inner_row'){
398 var ele_wrap = jQuery(ele).parents('.pagelayer-wrap-col');
399 if(ele_wrap.length == 1 && !jQuery(ele).hasClass('pagelayer-wrap-col')){
400 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-col,.pagelayer-wrap-inner-row');
401 }else{
402 onWrap = jQuery(ele).closest('.pagelayer-wrap-inner-row');
403 }
404 // For every other element, we can be over a col or ele
405 }else{
406 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-col,.pagelayer-wrap-inner-row');
407 }
408 //console.log(onWrap);
409
410 // If we find nothing
411 if(pagelayer_empty(onWrap) || onWrap.length < 1){
412 clear_prospect();// Clear existing prospects
413 reset_on_drag();// Also reset the last on item
414 return false;
415 }
416
417 /*// If the columns more than 12 inside the row then return - As of now not enabled the below code
418 if(tag == 'pl_col'){
419 var _onTag = pagelayer_tag(onWrap);
420 var colEles;
421
422 // Is on col
423 if(_onTag == 'pl_col'){
424 colEles = onWrap.closest('.pagelayer-row-holder').children('.pagelayer-ele-wrap');
425 }else{
426 colEles = onWrap.find('.pagelayer-row-holder').first().children('.pagelayer-ele-wrap');
427 }
428
429 // If the columns more than 12
430 if(colEles.length >= 12){
431 return false;
432 }
433 }*/
434
435 // Get the ID
436 var onId = onWrap.attr('pagelayer-wrap-id');
437 var onEle = onWrap.children('.pagelayer-ele');
438
439 // Do we have a parent ?
440 var pOnId = pagelayer_get_parent(onEle);
441
442 if(pOnId){
443 onId = pOnId;
444 onEle = pagelayer_ele_by_id(onId);
445 onWrap = pagelayer_wrap_by_id(onId);
446 }
447
448 var changed = false;
449
450 // Was it the same ID like the one we were on before
451 if(pagelayer.drag_closest != onId){
452 pagelayer.drag_closest = onId;
453 changed = true;
454 }
455 //console.log(onId+' '+pagelayer.drag_closest)
456
457 var req_corners = {0: 'top', 1: 'top', 2: 'bottom', 3: 'bottom'};
458
459 // For columns we redefine the top and bottom
460 if(tag == 'pl_col'){
461 req_corners[1] = 'bottom';
462 req_corners[3] = 'top';
463 }
464
465 // Determine the previous and next
466 var next = wrap.next('.pagelayer-ele-wrap');
467 var prev = wrap.prev('.pagelayer-ele-wrap');
468
469 if(next.length == 1 && pagelayer_id(next) == onId){
470 req_corners = {0: 'bottom', 1: 'bottom', 2: 'bottom', 3: 'bottom'};
471 }
472
473 if(prev.length == 1 && pagelayer_id(prev) == onId){
474 req_corners = {0: 'top', 1: 'top', 2: 'top', 3: 'top'};
475 }
476
477 // Which corner are we closest to ?
478 var corner_num = pagelayer_closest_corner(onWrap);
479 var corner = req_corners[corner_num];
480
481 //console.log(corner+' != '+pagelayer.drag_closest_corner)
482 if(corner != pagelayer.drag_closest_corner){
483 pagelayer.drag_closest_corner = corner;
484 changed = true;
485 }
486
487 //console.log(changed);
488
489 // If we are on our self then clear return false
490 if(onId == id){
491 clear_prospect();// Clear existing prospects
492 reset_on_drag();// Also reset the last on item
493 return false;
494 }
495
496 // Then lets start showing
497 if(changed){
498
499 // Record the mouse points
500 pagelayer.drag_mouse.x = parseInt(e.pageX);
501 pagelayer.drag_mouse.y = parseInt(e.pageY);
502
503 // Clear any existing prospect
504 clear_prospect();
505
506 // Add new prospect
507 var prospect = '<div class="pagelayer-drag-prospect" pagelayer-corner="'+corner+'"></div>';
508
509 if(corner == 'bottom'){
510 onWrap.append(prospect);
511 }else if(corner == 'top'){
512 onWrap.prepend(prospect);
513 }
514
515 prospect = jQuery('.pagelayer-drag-prospect')
516 var animate_props = {height: '5px'};
517
518 // For column add a special class
519 if(tag == 'pl_col'){
520 prospect.addClass('pagelayer-drag-prospect-col');
521 animate_props['width'] = '5px';
522
523 // Adjust the left and right
524 var css = {};
525 css[(corner == 'bottom' ? 'right' : 'left')] = '0px';
526 prospect.css(css);
527 }
528
529 // Animate the prospect
530 prospect.animate(animate_props, 200);
531
532 // Highlight the wrap via overlay
533 onWrap.children('.pagelayer-ele-overlay').addClass('pagelayer-drag-ele-hover');
534
535 }
536
537 }
538 }
539
540 // When mouse is pressed down
541 var ondragstart = function(e){
542
543 //console.log(e);
544
545 // Target
546 var tEle = jQuery(e.target);
547 var wrap = tEle.closest('.pagelayer-ele-wrap');
548 //console.log(jEle[0]);
549
550 // Is it an existing element ?
551 if(wrap.length < 1){
552 return false;
553 }
554
555 // Do we have a parent ?
556 var id = pagelayer_id(wrap);
557 var jEle = pagelayer_ele_by_id(id);
558 var pId = pagelayer_get_parent(jEle);
559
560 if(pId){
561 wrap = pagelayer_wrap_by_id(pId);
562 }
563
564 //e.preventDefault();
565
566 var tag = pagelayer_tag(wrap);
567
568 e.originalEvent.dataTransfer.setData('Text', 1);
569 var img = document.createElement('img');
570 img.src = shower.attr('src');
571 e.originalEvent.dataTransfer.setDragImage(img, 32, 32);
572
573 pagelayer.dragging = wrap;
574
575 }
576
577 // When mouse is pressed down
578 var ondrop = function(e){
579
580 //console.log(e);
581
582 // Stop dragging ?
583 if(pagelayer.dragging){
584
585 e.preventDefault();
586
587 var wrap = pagelayer.dragging;
588 var tag = pagelayer_tag(wrap);
589 var fromEl = wrap.parent();
590 var id;
591 wrap.removeClass('pagelayer-is-dragging');
592
593 // Find any prospect
594 var prospect = jQuery('.pagelayer-drag-prospect');
595 //console.log(prospect[0]);
596
597 // It should be exactly 1
598 if(prospect.length == 1){
599
600 var onWrap = prospect.parent();
601 var onId = pagelayer_id(onWrap);
602 var onTag = pagelayer_tag(onWrap);
603 var dropped;
604 var corner = prospect.attr('pagelayer-corner');
605 var method = (corner == 'top') ? 'before' : 'after';
606 var before_loc; // Location before the drop
607
608 // Create the element if it needs to be created
609 if(pagelayer.drag_is_new){
610 dropped = jQuery('<div pagelayer-tag="'+tag+'"></div>');
611
612 // Move the object
613 }else{
614
615 // Get near by element before move
616 before_loc = pagelayer_near_by_ele(pagelayer_id(wrap), tag);
617
618 dropped = wrap;
619 dropped.detach();
620 }
621
622 // If I am a column or row, then I go only before or after my same type !
623 if((onTag == 'pl_col' || onTag == 'pl_row') && onTag == tag){
624
625 // If I am a column and I am on a row
626 // OR I am a normal element and I am on column
627 }else if((tag == 'pl_col' && (onTag == 'pl_row' || onTag == 'pl_inner_row')) || onTag == 'pl_col'){
628 // We need to find the holder and add the prospect there
629 var holder = pagelayer_shortcodes[onTag]['holder'];
630 onWrap = onWrap.children('.pagelayer-ele').children(holder);
631 method = (corner == 'top') ? 'prepend' : 'append';
632 }
633
634 // Attach or shift the element
635 onWrap[method](dropped);
636 //console.log(dropped);
637
638 // Trigger the onadd
639 if(pagelayer.drag_is_new){
640 id = pagelayer_onadd(dropped);
641
642 // Existing elements
643 }else{
644 id = pagelayer_id(wrap);
645
646 // Save in action history
647 pagelayer_history_action_push({
648 'title' : pagelayer_shortcodes[tag]['name'],
649 'action' : 'Moved',
650 'pl_id' : id,
651 'before_loc' : before_loc,
652 'after_loc' : {'method' : method, 'cEle' : onWrap}
653 });
654 }
655
656 // Defining the variables as needed
657 var jEle = pagelayer_ele_by_id(id);
658 wrap = pagelayer_wrap_by_id(id);
659 var toEl = wrap.parent();
660
661 // Column number handle
662 if(tag == 'pl_col'){
663
664 var row_holder = jEle.parent().closest('.pagelayer-row-holder');
665
666 // Renumber the col where you are going
667 pagelayer_renumber_col(row_holder);
668
669 // Renumber the old columns as well
670 if(!pagelayer.drag_is_new){
671 var from_row = fromEl.closest('.pagelayer-row-holder');
672 pagelayer_renumber_col(from_row);
673 }
674 }
675
676 // Handle the empty col
677 if(tag != 'pl_col'){
678
679 pagelayer_empty_col(toEl.closest('.pagelayer-col-holder'));
680
681 if(!pagelayer.drag_is_new){
682 pagelayer_empty_col(fromEl.closest('.pagelayer-col-holder'));
683 }
684
685 }
686
687 }
688
689 // Clear prospect
690 clear_prospect();
691 }
692
693 reset_dragging();
694
695 }
696
697 // Add the events for inner content - as we are using the drag API
698 jQuery(document).on('dragstart', ondragstart);
699 jQuery(document).on('dragover', ondragover);
700 jQuery(document).on('drop', ondrop);
701
702 // For addition of new elements
703 pagelayer.$$('[pagelayer-tag]').on('dragstart', function(e){
704 //console.log(e);
705
706 var tEle = jQuery(e.target);
707 var jEle = tEle.closest('.pagelayer-shortcode-drag');
708
709 // Is it an existing element ?
710 if(jEle.length < 1){
711 return false;
712 }
713
714 e.originalEvent.dataTransfer.setData('tag', pagelayer_tag(jEle));
715
716 pagelayer.dragging = jEle;
717 pagelayer.drag_is_new = true;
718
719 });
720
721 // Handle editable content by removing drag
722 var onmousedown = function(e){
723
724 var tEle = jQuery(e.originalEvent.explicitOriginalTarget);
725
726 if(tEle.closest('[pagelayer-editable]').length > 0){
727 //console.log('Is Editable MouseDown');
728 tEle.parents('[draggable]').attr('draggable', 'false');
729 }
730
731 }
732
733 // Handle editable content by adding drag that was removed
734 var onmouseup = function(e){
735 jQuery(document).find('[draggable=false]').attr('draggable', 'true');
736 }
737
738 // Handle editable contents by temprarily removing drag
739 jQuery(document).on('mousedown', onmousedown);
740 jQuery(document).on('mouseup', onmouseup);
741
742 };
743
744 // Handle empty col
745 // selector should be col holder
746 function pagelayer_empty_col(selector){
747
748 // Loop through
749 jQuery(selector).each(function(){
750
751 var jEle = jQuery(this);// jEle is the COL HOLDER
752
753 // Are we a col ?
754 if(!jEle.hasClass('pagelayer-col-holder')){
755 return;
756 }
757
758 // Column is becoming blank, so show add ele
759 if(jEle.children().length < 1){
760 //from.addClass('pagelayer-empty-col');
761 jEle.append('<div class="pagelayer-add-ele pagelayer-ele-wrap"><i class="fa fa-plus"><br /><span>Empty column please Drag Widgets</span></i></div>');
762 //var h = jEle.parent().parent().children('.pagelayer-ele-overlay').height();
763 //jEle.children('.pagelayer-add-ele').height(h);
764 jEle.find('>.pagelayer-add-ele .fa').unbind('click');
765 jEle.find('>.pagelayer-add-ele .fa').on('click', function(event){
766 event.stopPropagation();
767 pagelayer.$$('.pagelayer-elpd-close').click();
768
769 // Show left bar
770 pagelayer.$$('.pagelayer-leftbar-table').removeClass('pagelayer-leftbar-hidden pagelayer-leftbar-minimize');
771
772 });
773
774 // Any add ele sign with non-empty columns here ?
775 }else if(jEle.children('.pagelayer-add-ele').length > 0 && jEle.children().length > 1){
776 jEle.children('.pagelayer-add-ele').remove();
777 }
778
779 });
780
781 };
782
783 // Reset the column widths
784 // The selector should be a ROW HOLDER
785 function pagelayer_renumber_col(selector){
786
787 var pEle = jQuery(selector);
788 var children = pEle.children('.pagelayer-ele-wrap');
789 var cols = Math.floor(12 / (children.length));
790 var obj = {col: cols};
791
792 // Find out the number of cols of other cols
793 children.each(function(){
794
795 // This is the wrapper
796 var jEle = jQuery(this);
797
798 // The real element
799 var Ele = jEle.find('>.pagelayer-ele');
800
801 for(var x=1; x<=12; x++){
802 if(jEle.hasClass('pagelayer-col-'+x)){
803 jEle.removeClass('pagelayer-col-'+x);
804 Ele.removeClass('pagelayer-col-'+x);
805 break;
806 }
807 }
808 jEle.addClass('pagelayer-col-'+cols);
809 jEle.css({'width': ''});
810 Ele.addClass('pagelayer-col-'+cols);
811 Ele.css({'width': ''});
812
813 // Set the att
814 pagelayer_set_atts(Ele, obj);
815 });
816 }
817
818 // Make column resizable handler
819 function pagelayer_col_make_resizable(wrap){
820
821 // Resize handler element
822 var rHandler = jQuery('<div class="pagelayer-resize-handler"><div class="pagelayer-resize-icon"></div></div>');
823
824 var pResize = wrap.children('.pagelayer-ele-overlay').find('.pagelayer-resize-handler');
825
826 if(pResize.length > 0){
827 return;
828 }
829
830 // Append it
831 wrap.children('.pagelayer-ele-overlay').append(rHandler);
832
833 // Resize start
834 rHandler.on('mousedown', function(e) {
835 e.preventDefault();
836
837 var next_ele = wrap.next();
838 var rHolder_width = wrap.closest('.pagelayer-row-holder').width();
839 var new_width, nEle_new_width;
840
841 // Original width
842 var original_width = wrap.width();
843 var original_mouse_x = e.pageX;
844
845 // Add the element width and next element width
846 both_width = (original_width / rHolder_width *100) + (next_ele.width() / rHolder_width *100);
847
848 if(both_width > 100){
849 return false;
850 }
851
852 jQuery('body').css({'cursor': 'ew-resize'});
853 rHandler.css({'display': 'block'});
854
855 var r_mousemove = function(e){
856 var width = original_width + (e.pageX - original_mouse_x);
857
858 // Covert width in percentage
859 new_width = (width / rHolder_width *100).toFixed(2);
860
861 if(both_width > new_width && new_width > 0){
862 nEle_new_width = (both_width - new_width).toFixed(2);
863 wrap.css({'width': new_width+'%'});
864 next_ele.css({'width': nEle_new_width+'%'});
865
866 rHandler.attr({'pre-width': new_width+'%', 'next-width': nEle_new_width+'%'});
867 }
868
869 };
870
871 var r_mouseup = function(e){
872
873 jQuery(document).off('mousemove', r_mousemove);
874 jQuery('body').css({'cursor': ''});
875 rHandler.removeAttr('style pre-width next-width');
876
877 // find real element and next real element
878 var jEle = wrap.find('>.pagelayer-ele');
879 var nEle = next_ele.find('>.pagelayer-ele');
880
881 // Set the element attrs
882 jEle.attr({'pagelayer-a-col_width': new_width, 'pagelayer-a-col': ''});
883 nEle.attr({'pagelayer-a-col_width': nEle_new_width, 'pagelayer-a-col': ''});
884 jQuery(document).off('mouseup', r_mouseup);
885
886 };
887
888 // Resize start
889 jQuery(document).on('mousemove', r_mousemove);
890 jQuery(document).on('mouseup', r_mouseup);
891 });
892 }
893
894 // Handle addition of elements from the left
895 // NOTE : At this point the addition is FINALIZED
896 // The add element cannot be prevented !
897 function pagelayer_onadd(jEle, toClick){
898
899 toClick = arguments.length == 2 ? toClick : true;
900
901 //console.log(jEle);
902 var id = pagelayer_element_added(jEle);
903 var jEle = jQuery("[pagelayer-id="+id+"]");
904
905 if(toClick){
906 //console.log('here');
907 jEle.click();
908 }
909
910 return id;
911
912 };
913
914 // Add an element into the POST
915 function pagelayer_element_added(jEle){
916
917 var sc = jEle.attr('pagelayer-tag');
918 var id, par_id;
919
920 // Set Pagelayer History FALSE to prevent saving attributes in action history
921 pagelayer.history_action = false;
922
923 // Generate the HTML
924 html = pagelayer_create_sc(sc);
925 id = pagelayer_assign_id(html);
926 par_id = id;
927
928 // Insert the HTML
929 jEle[0].outerHTML = html[0].outerHTML;
930
931 // Setup the properties of the elements
932 pagelayer_element_setup("[pagelayer-id="+par_id+"], [pagelayer-id="+par_id+"] .pagelayer-ele", true);
933
934 // Any children to add ?
935 if(!('widget' in pagelayer_shortcodes[sc])){
936
937 // The element props
938 var props = pagelayer_shortcodes[sc];
939
940 // Do we have to create children ?
941 if('has_group' in props){
942
943 var has_group = props['has_group'];
944 var gProp = props[has_group['section']][has_group['prop']];
945
946 for(var i=0; i < gProp['count']; i++){
947 var cid = pagelayer_element_add_child(jQuery("[pagelayer-id="+id+"]"), gProp['sc']);
948 //pagelayer_element_setup('[pagelayer-id='+cid+']', true);
949 }
950
951 }
952
953 }
954
955 // Save in action history
956 var cEle = pagelayer_near_by_ele(id, sc);
957
958 pagelayer_history_action_push({
959 'title' : pagelayer_shortcodes[sc]['name'],
960 'action' : 'Added',
961 'pl_id' : id,
962 'html' : jQuery("[pagelayer-id="+id+"]"),
963 'cEle' : cEle
964 });
965
966 // Set pagelayer history TRUE
967 pagelayer.history_action = true;
968
969 return id;
970
971 };
972
973 // Add an element
974 function pagelayer_element_add_child(pEle, sc){
975 var child = pagelayer_create_sc(sc);
976 var cid = pagelayer_assign_id(child);
977 pagelayer_set_parent(child, pagelayer_assign_id(pEle));
978
979 // Does the parent have a holder ?
980 var tag = pagelayer_tag(pEle);
981
982 // There is a holder
983 if('holder' in pagelayer_shortcodes[tag]){
984
985 pEle.find(pagelayer_shortcodes[tag]['holder']).append(child);
986
987 // No holder, just append
988 }else{
989 pEle.append(child);
990 }
991
992 pagelayer_element_setup('[pagelayer-id='+cid+']', true);
993
994 // Do we have to create children ?
995 if('has_group' in pagelayer_shortcodes[sc]){
996
997 var has_group = pagelayer_shortcodes[sc]['has_group'];
998 var gProp = pagelayer_shortcodes[sc][has_group['section']][has_group['prop']];
999
1000 for(var i=0; i < gProp['count']; i++){
1001 var in_cid = pagelayer_element_add_child(jQuery("[pagelayer-id="+cid+"]"), gProp['sc']);
1002 }
1003
1004 }
1005
1006 return cid;
1007 };
1008
1009 // Return an element by ID
1010 function pagelayer_ele_by_id(id){
1011 return jQuery('[pagelayer-id='+id+']');
1012 };
1013
1014 // Return the wrap by ID
1015 function pagelayer_wrap_by_id(id){
1016 return jQuery('[pagelayer-wrap-id='+id+']');
1017 };
1018
1019 // Give the Pagelayer ID
1020 function pagelayer_id(jEle){
1021
1022 var id = jEle.attr('pagelayer-wrap-id');
1023 if(id){
1024 return id;
1025 }
1026
1027 id = jEle.attr('pagelayer-id');
1028
1029 return id;
1030
1031 }
1032
1033 // Assign the jQuery object an ID
1034 function pagelayer_assign_id(jEle){
1035
1036 // Do you have the pagelayer id
1037 var id = jEle.attr("pagelayer-id");
1038 if(!id || id.length < 1){
1039 id = pagelayer_randstr(16);
1040 jEle.attr("pagelayer-id", id);
1041 }
1042
1043 return id;
1044
1045 }
1046
1047 // Show the edit options
1048 function pagelayer_element_clicked(selector, e){
1049
1050 var jEle = jQuery(selector);
1051 e = e || false;
1052 //console.log(e);
1053
1054 // You must be a element atleast
1055 if(!jEle.hasClass('pagelayer-ele')){
1056 return false;
1057 }
1058
1059 // Get the parent
1060 var pId = pagelayer_get_parent(jEle);
1061
1062 // If we found a parent
1063 if(pId){
1064 jEle = pagelayer_ele_by_id(pId);
1065 }
1066
1067 // Make the editable fields active
1068 //pagelayer_clear_editable();// First clear
1069 jEle.find('[pagelayer-editable]').each(function (){
1070 pagelayer_make_editable(jQuery(this), e);
1071 });
1072
1073 // Show left bar
1074 pagelayer.$$('.pagelayer-leftbar-table').removeClass('pagelayer-leftbar-hidden pagelayer-leftbar-minimize');
1075
1076 // Lets not rebuild everything to make it faster
1077 if(pagelayer_is_active(jEle)){
1078 return false;
1079 }
1080
1081 // Set this as the active element
1082 pagelayer_set_active(jEle);
1083
1084 // Show the properties
1085 pagelayer_elpd_open(jEle);
1086
1087 }
1088
1089 // The edit option
1090 function pagelayer_edit_element(selector){
1091 pagelayer_element_clicked(selector);
1092 }
1093
1094 // Setup the properties on a single click
1095 function pagelayer_element_setup(selector, render){
1096
1097 var selector = selector || ".pagelayer-ele";
1098 render = render || false;
1099
1100 // Loop through
1101 jQuery(pagelayer_editable+' '+selector).each(function(){
1102
1103 var jEle = jQuery(this);
1104
1105 // Assign an ID if not there
1106 var id = pagelayer_assign_id(jEle);
1107 var pId = pagelayer_get_parent(jEle) || '';// Options to show on hover
1108 var selector = '[pagelayer-id='+id+']';
1109
1110 if(render){
1111 pagelayer_sc_render(jEle);
1112 }
1113
1114 // Get the tag
1115 var tag = pagelayer_tag(jEle);
1116
1117 // Lets check if we are the child of a parent i.e. element of a group
1118 if(pagelayer_empty(pId)){
1119
1120 // Get the parent
1121 var pEle = jEle.parent().closest('.pagelayer-ele');
1122
1123 // If we found a parent
1124 if(pEle.length > 0){
1125
1126 var pTag = pagelayer_tag(pEle);
1127
1128 // Is the parent a group of this child ?
1129 if(!pagelayer_empty(pagelayer_shortcodes[pTag]) && pagelayer_is_group(pTag)){
1130
1131 var has_group = pagelayer_shortcodes[pTag]['has_group'];
1132 var child_type = pagelayer_shortcodes[pTag][has_group['section']][has_group['prop']]['sc'];
1133
1134 // If the type is the same as jEle
1135 if(child_type == pagelayer_tag(jEle)){
1136 pId = pagelayer_assign_id(pEle);
1137 pagelayer_set_parent(jEle, pId);
1138 }
1139 }
1140
1141 }
1142
1143 }
1144
1145 // Make the wraps
1146 jEle.wrap('<div class="pagelayer-ele-wrap" pagelayer-wrap-id="'+id+'"></div>');
1147 var wrap = jEle.parent();
1148
1149 // For column we have to do some kidas !
1150 if(tag == 'pl_col'){
1151
1152 var col;
1153 for(var x=1; x<=12; x++){
1154 if(jEle.hasClass('pagelayer-col-'+x)){
1155 col = 'pagelayer-col-'+x;
1156 break;
1157 }
1158 }
1159
1160 var is_custom_width = pagelayer_get_att(jEle, 'col');
1161 var col_width = pagelayer_get_att(jEle, 'col_width');
1162 if(pagelayer_empty(is_custom_width) && col_width){
1163 wrap.css('width', col_width+'%');
1164 }
1165
1166 wrap.addClass('pagelayer-col '+col);
1167 //jEle.removeClass('pagelayer-col '+col);
1168 wrap.addClass('pagelayer-wrap-col');
1169
1170 }else if(tag == 'pl_row'){
1171 wrap.addClass('pagelayer-wrap-row');
1172 }else if(tag == 'pl_inner_row'){
1173 wrap.addClass('pagelayer-wrap-inner-row');
1174 }else{
1175 wrap.addClass('pagelayer-wrap-ele');
1176 }
1177
1178 // Create the overlay
1179 wrap.prepend('<div class="pagelayer-ele-overlay"></div>');
1180
1181 var overlay = wrap.children('.pagelayer-ele-overlay');
1182 var html;
1183
1184 if(tag == 'pl_row' || tag == 'pl_inner_row'){
1185
1186 overlay.addClass('pagelayer-row-hover');
1187
1188 if(jEle.hasClass('pagelayer-row-stretch-full')){
1189 pagelayer_sc_render(jEle);
1190 }
1191
1192 html = '<div class="pagelayer-row-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
1193 '<i class="fa fa-clone pagelayer-eoi" onclick="pagelayer_copy_element(\''+selector+'\')" />'+
1194 '<i class="fa fa-trash pagelayer-eoi" onclick="pagelayer_delete_element(\''+selector+'\')" />'+
1195 '<i class="fa fa-pencil pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
1196 '</div>';
1197
1198 }else if(tag == 'pl_col'){
1199
1200 overlay.addClass('pagelayer-col-hover');
1201
1202 html = '<div class="pagelayer-col-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
1203 '<i class="fa fa-columns pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
1204 '</div>';
1205
1206 // Is it an empty col ?
1207 pagelayer_empty_col(jEle.children('.pagelayer-col-holder'));
1208
1209 // Make col resizable
1210 pagelayer_col_make_resizable(wrap);
1211
1212 }else{
1213
1214 html = '<div class="pagelayer-ele-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
1215 '<i class="fa fa-clone pagelayer-eoi" onclick="pagelayer_copy_element(\''+selector+'\')" />'+
1216 '<i class="fa fa-trash pagelayer-eoi" onclick="pagelayer_delete_element(\''+selector+'\')" />'+
1217 '<i class="fa fa-pencil pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
1218 '</div>';
1219
1220 }
1221
1222 // Append to the child
1223 overlay.append(html);
1224 jQuery('[pagelayer-option-id='+id+']').hide();
1225
1226 // Setup the HOVER events ABD create WRAPS IF we dont have a parent
1227 if(pId.length > 0){
1228 return;
1229 }
1230
1231 // Make the wrap draggable, but only of independent or parent elements
1232 wrap.attr('draggable', 'true');
1233
1234 wrap.hover(function(){
1235
1236 // Is there an element option shower ?
1237 var opts = jQuery('[pagelayer-option-id='+id+']');
1238
1239 // Give the overlay the hover class
1240 opts.parent().addClass('pagelayer-ele-hover');
1241
1242 // Show them
1243 opts.show();
1244
1245 }, function(){
1246
1247 // Is there an element option shower ?
1248 var opts = jQuery('[pagelayer-option-id='+id+']');
1249
1250 // Remove hover class
1251 opts.parent().removeClass('pagelayer-ele-hover');
1252
1253 // Hide opts
1254 opts.hide();
1255
1256 });
1257
1258 });
1259 }
1260
1261 // Left Click
1262 function pagelayer_left_click(){
1263
1264 jQuery(pagelayer_editable).on('click', function(e){
1265
1266 e.preventDefault();// Added by Jivan in Actions / Revisions version
1267
1268 // Hide the context menu
1269 jQuery('.pagelayer-right-click-options').hide();
1270
1271 // Target
1272 var tEle = jQuery(e.target);
1273
1274 // If its an edit option click
1275 if(tEle.hasClass('pagelayer-eoi')){
1276 return false;
1277 }
1278
1279 pagelayer_element_clicked(tEle.closest('.pagelayer-ele'), e);
1280
1281 return false;
1282
1283 });
1284 };
1285
1286 // Right Click Menu
1287 function pagelayer_right_click(){
1288
1289 var html = '<div class="pagelayer-right-click-options" style="display:none;">'+
1290 '<ul>'+
1291 '<li><a class="pagelayer-right-edit">Edit</a></li>'+
1292 '<li><a class="pagelayer-right-duplicate"><i class="fa fa-clone" /> Duplicate</a></li>'+
1293 '<li><a class="pagelayer-right-copy"><i class="fa fa-files-o" /> Copy</a></li>'+
1294 '<li><a class="pagelayer-right-paste"><i class="fa fa-clipboard" /> Paste</a></li>'+
1295 '<li><a class="pagelayer-right-delete"><i class="fa fa-trash-o" /> Delete</a></li>'+
1296 '</ul>'+
1297 '</div>';
1298
1299 jQuery('body').append(html);
1300
1301 var $contextMenu = jQuery('.pagelayer-right-click-options');
1302
1303 jQuery(pagelayer_editable).on('contextmenu', function(e){
1304
1305 var tEle = jQuery(e.target);
1306 var jEle = tEle.closest('.pagelayer-ele-wrap').children('.pagelayer-ele');
1307
1308 // Get the parent
1309 var pId = pagelayer_get_parent(jEle);
1310
1311 // If we found a parent
1312 if(pId){
1313 jEle = pagelayer_ele_by_id(pId);
1314 }
1315
1316 // The basics
1317 var id = pagelayer_assign_id(jEle);
1318 var tag = pagelayer_tag(jEle);
1319
1320 $contextMenu.find('.pagelayer-right-edit').attr('onclick', 'pagelayer_edit_element("[pagelayer-id='+id+']")').html('<i class="fa fa-pencil-square-o" /> Edit '+pagelayer_shortcodes[tag]['name']);
1321 $contextMenu.find('.pagelayer-right-duplicate').attr('onclick', 'pagelayer_copy_element("[pagelayer-id='+id+']")');
1322 $contextMenu.find('.pagelayer-right-copy').attr('onclick', 'pagelayer_copy_select("[pagelayer-id='+id+']")');
1323 $contextMenu.find('.pagelayer-right-paste').attr('onclick', 'pagelayer_paste_element("[pagelayer-id='+id+']")');
1324 $contextMenu.find('.pagelayer-right-delete').attr('onclick', 'pagelayer_delete_element("[pagelayer-id='+id+']")');
1325
1326 // If copy_selected is empty then copy data from localStorage
1327 if(pagelayer_empty(pagelayer.copy_selected)){
1328 pagelayer_copy_from_localStorage();
1329 }
1330
1331 // Are we to hide the paste ?
1332 if(!pagelayer_empty(pagelayer.copy_selected) && pagelayer_can_copy_to(jEle)){
1333 //console.log(pagelayer_can_copy_to(jEle));
1334 $contextMenu.find('.pagelayer-right-paste').parent().show();
1335 }else{
1336 $contextMenu.find('.pagelayer-right-paste').parent().hide();
1337 }
1338
1339 $contextMenu.css({
1340 display: "block",
1341 left: e.pageX,
1342 top: e.pageY
1343 });
1344
1345 return false;
1346
1347 });
1348
1349 jQuery('html').on('click', function(e){
1350 $contextMenu.hide();
1351 });
1352 }
1353
1354 // Set the parent for the group
1355 function pagelayer_set_parent(jEle, id){
1356 jEle.attr('pagelayer-parent', id);
1357 };
1358
1359 // Set the parent for the group
1360 function pagelayer_get_parent(jEle){
1361 return jEle.attr('pagelayer-parent');
1362 };
1363
1364 // Sets the screen mode
1365 function pagelayer_set_screen_mode(mode){
1366 var modes = ['desktop', 'tablet', 'mobile'];
1367 var body = pagelayer.$$('.pagelayer-iframe-holder iframe');
1368 var current = '';
1369
1370 for(var x in modes){
1371
1372 if(body.hasClass('pagelayer-screen-'+modes[x]) && modes[x] != mode){
1373 current = modes[x];
1374 body.removeClass('pagelayer-screen-'+modes[x]);
1375 }
1376 }
1377
1378 // Add the class
1379 body.addClass('pagelayer-screen-'+mode);
1380
1381 // Add the class to the button
1382 pagelayer.$$('.pagelayer-mode-button').removeClass('pli-'+current).addClass('pli-'+mode);
1383
1384 // Add the class to the button
1385 pagelayer.$$('.pagelayer-prop-screen').removeClass('pli-'+current).addClass('pli-'+mode);
1386
1387 // Trigger screen change if any
1388 pagelayer.$$('.pagelayer-elp-screen').trigger('pagelayer-screen-changed');
1389
1390 };
1391
1392 // Get the current screen mode
1393 function pagelayer_get_screen_mode(){
1394 var modes = ['desktop', 'tablet', 'mobile'];
1395 var body = pagelayer.$$('.pagelayer-iframe-holder iframe');
1396
1397 for(var x in modes){
1398 if(body.hasClass('pagelayer-screen-'+modes[x])){
1399 return modes[x];
1400 }
1401 }
1402 }
1403
1404 // Handle key press events
1405 jQuery(document).keydown(function(event){
1406 //alert(String.fromCharCode(event.which));
1407
1408 // Delete
1409 if(event.keyCode == 46){
1410 var tEle = jQuery(event.target);
1411
1412 // Is this a delete call in the editable area ?
1413 if (!tEle.is('input, textarea') && tEle.closest('[contenteditable]').length < 1) {
1414 pagelayer_delete_element('[pagelayer-active]');
1415 }
1416
1417 }
1418
1419 // ctrl+z handle
1420 if(event.keyCode == 90 && event.ctrlKey){
1421 pagelayer_do_history('undo');
1422 }
1423
1424 // ctrl+y handle
1425 if(event.keyCode == 89 && event.ctrlKey){
1426 pagelayer_do_history('redo');
1427 }
1428
1429 // ctrl+d handle
1430 if(event.keyCode == 68 && event.ctrlKey){
1431
1432 // If we have an active element
1433 if( pagelayer_active.el && pagelayer_active.el.id ){
1434 event.preventDefault();
1435 pagelayer_copy_element('[pagelayer-id='+pagelayer_active.el.id+']');
1436 }
1437
1438 }
1439 });
1440
1441 // Handle Copy of content
1442 jQuery(document).on('copy', function(copyEvent){
1443
1444 // Check the active element
1445 if(pagelayer_active.el && pagelayer_active.el.id){
1446
1447 // Save the active element id
1448 pagelayer_copy_select("[pagelayer-id='"+pagelayer_active.el.id+"']");
1449
1450 }
1451
1452 });
1453
1454 // Handle Paste in the editor
1455 jQuery(document).on('paste', function(pasteEvent){
1456
1457 var pEle_target = jQuery((pasteEvent.originalEvent || pasteEvent).target);
1458 var pagelayer_ajax_func = {};
1459 var contenteditable = false;
1460
1461 if(pEle_target.closest('[contenteditable]').length > 0 || pEle_target.is('input, textarea')){
1462 pEle_target = pEle_target.closest('[contenteditable]');
1463 contenteditable = true;
1464 }
1465
1466 // This function for ajax before send call back
1467 pagelayer_ajax_func['beforeSend'] = function(xhr){
1468
1469 // If target is not content editable
1470 if( pagelayer_empty(contenteditable) ){
1471
1472 // If we dont have an active element then return false and stop ajax
1473 if( !(pagelayer_active.el && pagelayer_active.el.id) ){
1474 return false;
1475 }
1476
1477 pagelayer.copy_selected = jQuery('<div pagelayer-tag="pl_image"></div>');
1478
1479 // Is it to be pastable
1480 if(!pagelayer_can_copy_to('[pagelayer-id="'+pagelayer_active.el.id+'"]')){
1481 pagelayer.copy_selected = '';
1482 return false;
1483 }
1484 }
1485
1486 pEle_target.css({'opacity': '0.33' , 'transition' : '0.1s'});
1487 }
1488
1489 // This function for ajax success call back
1490 pagelayer_ajax_func['success'] = function(obj){
1491
1492 // Successfully Uploaded
1493 if(obj['success']){
1494
1495 // For content editable e.g. Rich Text
1496 if( !pagelayer_empty(contenteditable) ){
1497 document.execCommand('insertImage', false, obj['data']['url']);
1498
1499 // For our widgets
1500 }else{
1501 var fTo = pagelayer_can_copy_to('[pagelayer-id="'+pagelayer_active.el.id+'"]');
1502 // We need to empty pagelayer.copy_selected
1503 pagelayer.copy_selected = '';
1504
1505 // Create image html
1506 var html = jQuery( pagelayer_create_sc('pl_image') );
1507 html.attr('pagelayer-a-id', obj['data']['id']);
1508 html.attr('pagelayer-tmp-id-url', obj['data']['url']);
1509
1510 // Copy the element
1511 var id = pagelayer_copy_element(html, fTo);
1512 jQuery('[pagelayer-id="'+id+'"]').click();
1513 }
1514
1515 // Some error occured
1516 }else{
1517 alert(obj['data']['message']);
1518 }
1519 }
1520
1521 // This function for ajax complete call back
1522 pagelayer_ajax_func['complete'] = function(xhr){
1523 //console.log(xhr);
1524 pEle_target.css({'opacity': '1' , 'transition' : '0.1s'});
1525 }
1526
1527 var findImg = pagelayer_editable_paste_handler(pasteEvent, pagelayer_ajax_func);
1528
1529 if(pagelayer_empty(findImg) && pagelayer_empty(contenteditable)){
1530
1531 // Check the active element
1532 if(pagelayer_active.el && pagelayer_active.el.id){
1533
1534 var jEle = jQuery("[pagelayer-id='"+pagelayer_active.el.id+"']");
1535
1536 // Check if the any element is copied
1537 if(pagelayer_can_copy_to(jEle)){
1538 pagelayer_paste_element("[pagelayer-id='"+pagelayer_active.el.id+"']");
1539 }
1540
1541 }
1542 }
1543 });
1544
1545 // Delete an element as per the selector
1546 function pagelayer_delete_element(selector){
1547 var jEle = jQuery(selector);
1548
1549 // Anything found ?
1550 if(jEle.length > 0){
1551
1552 var id = pagelayer_assign_id(jEle);
1553 var sc = pagelayer_tag(jEle);
1554
1555 // Is there a wrap
1556 var wrap = jQuery('[pagelayer-wrap-id="'+id+'"]');
1557
1558 var par = wrap.parent();
1559
1560 // Save this element in history action
1561 if(pagelayer.history_action){
1562 var cEle = pagelayer_near_by_ele(id, sc);
1563
1564 // To save in history, we need to save only element not the wraps as we call setup if we redo or undo
1565 jEle.find('style').remove();
1566 jEle.find('.pagelayer-ele-overlay').remove();
1567
1568 // Unwrap the wraps
1569 jEle.find('.pagelayer-ele').each(function (){
1570 var ele = jQuery(this);
1571 if(ele.parent().is('.pagelayer-ele-wrap')){
1572 ele.unwrap();
1573 }
1574 });
1575
1576 pagelayer_history_action_push({
1577 'title' : pagelayer_shortcodes[sc]['name'],
1578 'action' : 'Deleted',
1579 'pl_id' : id,
1580 'html' : jEle,
1581 'cEle' : cEle
1582 });
1583 }
1584
1585 wrap.remove();
1586
1587 pagelayer_empty_col(par);
1588
1589 if(pagelayer_active.el && pagelayer_active.el.id == id){
1590 pagelayer.$$('.pagelayer-elpd-close').click();
1591 }
1592
1593 }
1594
1595 pagelayer_isDirty = true;
1596 };
1597
1598 // Select an element
1599 function pagelayer_copy_select(selector){
1600
1601 var eHtml = jQuery(selector)[0].outerHTML;
1602
1603 // Copy data on localStorage
1604 localStorage.setItem("pagelayer_ele", eHtml);
1605
1606 pagelayer.copy_selected = selector;
1607 }
1608
1609 function pagelayer_can_copy_to(to){
1610 var jEle = jQuery(pagelayer.copy_selected);
1611 var tEle = jQuery(to);
1612
1613 var eTag = pagelayer_tag(jEle);
1614 var tTag = pagelayer_tag(tEle);
1615 //console.log(eTag+' - '+tTag);
1616 // Final to
1617 var fTo;
1618
1619 // Selected element is a Row, can go only after a row
1620 if(eTag == 'pl_row'){
1621 fTo = tEle.closest('.pagelayer-ele.pagelayer-row');
1622 if(fTo.length != 1) return false;
1623 return fTo;
1624 }
1625
1626 // Selected element is a Column, can go only after a col
1627 if(eTag == 'pl_col'){
1628 fTo = tEle.closest('.pagelayer-ele.pagelayer-col');
1629 if(fTo.length != 1) return false;
1630 return fTo;
1631 }
1632
1633 // Is the TARGET a row or column when the selected item is a element
1634 if(tTag == 'pl_row' || tTag == 'pl_col'){
1635 return false;
1636 }
1637
1638 return tEle;
1639
1640 }
1641
1642 // Select an element
1643 function pagelayer_paste_element(to){
1644
1645 // Copy data from localStorage
1646 pagelayer_copy_from_localStorage();
1647
1648 var fTo = pagelayer_can_copy_to(to);
1649
1650 // Is it a valid to
1651 if(!fTo){
1652 return false;
1653 }
1654
1655 if(!pagelayer_empty(pagelayer.copy_selected)){
1656 pagelayer_copy_element(pagelayer.copy_selected, fTo);
1657 }
1658
1659 return false;
1660
1661 }
1662
1663 // If copy_selected is empty then copy data from localStorage
1664 function pagelayer_copy_from_localStorage(){
1665 if(!pagelayer_empty(localStorage.getItem("pagelayer_ele"))){
1666 // Set copy data from localStorage
1667 pagelayer.copy_selected = localStorage.getItem("pagelayer_ele");
1668 }
1669 }
1670
1671 // Copy an element
1672 // Note : insertAfter should always be an pagelayer-ele
1673 function pagelayer_copy_element(selector, insertAfter){
1674 var src = jQuery(selector);
1675 var html = src[0].outerHTML;
1676 var tag = pagelayer_tag(src);
1677 insertAfter = insertAfter || src;
1678 insertAfter = insertAfter.parent();
1679
1680 var jEle = jQuery(html);
1681 jEle.removeAttr('pagelayer-id');
1682 jEle.find('[pagelayer-id]').removeAttr('pagelayer-id');
1683 jEle.find('[pagelayer-parent]').removeAttr('pagelayer-parent');// Remove the parent attribute as it will be reset during pagelayer_element_setup
1684 jEle.find('style').remove();
1685 jEle.find('.pagelayer-ele-overlay').remove();
1686
1687 // Unwrap the wraps
1688 jEle.find('.pagelayer-ele').each(function (){
1689 var ele = jQuery(this);
1690 if(ele.parent().is('.pagelayer-ele-wrap')){
1691 ele.unwrap();
1692 }
1693 });
1694
1695 // Give it an ID
1696 var id = pagelayer_assign_id(jEle);
1697
1698 jQuery(insertAfter).after(jEle);
1699
1700 pagelayer_element_setup('[pagelayer-id='+id+'], [pagelayer-id='+id+'] .pagelayer-ele', true);
1701
1702 // Save this element in history action
1703 if(pagelayer.history_action){
1704 var cEle = pagelayer_near_by_ele(id, tag);
1705 pagelayer_history_action_push({
1706 'title' : pagelayer_shortcodes[tag]['name'],
1707 'action' : 'Copied',
1708 'pl_id' : id,
1709 'html' : jEle,
1710 'cEle' : cEle
1711 });
1712 }
1713
1714 //If column then renumber columns
1715 if(tag == 'pl_col'){
1716 var row = src.parent().closest('.pagelayer-row');
1717 pagelayer_renumber_col(row);
1718 }
1719
1720 pagelayer_isDirty = true;
1721
1722 return id;
1723 };
1724
1725 // Language key
1726 function pagelayer_l(k){
1727 return k;
1728 }
1729
1730 // Get props based on the tag
1731 function pagelayer_get_props(jEle){
1732 var props = pagelayer_shortcodes[pagelayer_tag(jEle)];
1733 return props;
1734 }
1735
1736 // Set the given jELE as active
1737 function pagelayer_set_active(jEle){
1738
1739 // Make all other element as inactive
1740 jQuery('[pagelayer-active]').each(function(){
1741 var $j = jQuery(this);
1742 $j.removeAttr('pagelayer-active');
1743 });
1744
1745 jEle.attr('pagelayer-active', 1);
1746
1747 // Add and remove the class
1748 jQuery('.pagelayer-active').removeClass('pagelayer-active');
1749
1750 jEle.parent().children('.pagelayer-ele-overlay').addClass('pagelayer-active');
1751
1752 // Hide active when not supported by tag
1753 var props = pagelayer_get_props(jEle);
1754 if(!pagelayer_empty(props['hide_active'])){
1755 jEle.parent().children('.pagelayer-ele-overlay').addClass('pagelayer-hide-active');
1756 }
1757
1758 }
1759
1760 function pagelayer_sc(sc){
1761 return sc.replace('pl_', '');
1762 };
1763
1764 // Create a HTML dom element of the Short code
1765 // Return the jEle
1766 function pagelayer_create_sc(sc){
1767
1768 var html;
1769 var _sc = pagelayer_sc(sc);
1770 var func = window['pagelayer_create_sc_'+sc];
1771
1772 // Generate the HTML
1773 if(typeof func == 'function'){
1774 html = window['pagelayer_create_sc_'+sc]();
1775 }else{
1776 html = '<div '+pagelayer_sc_atts('pagelayer-'+_sc)+'></div>';
1777 }
1778
1779 html = jQuery(html);
1780
1781 // Add the tag
1782 html.attr('pagelayer-tag', sc);
1783
1784 // Give it an ID
1785 id = pagelayer_assign_id(html);
1786
1787 // Try to set the default values over 5 loops
1788 pagelayer_set_default_atts(html, 5);
1789
1790 return html;
1791
1792 };
1793
1794 // Returns a list of default attributes to set as per the current selection
1795 function pagelayer_set_default_atts(jEle, set){
1796
1797 set = set || 0;
1798 var hasSet = false;
1799
1800 for(var i = 1; i <= set;i++){
1801
1802 //console.log('[pagelayer_set_default_atts] Loop :'+i);
1803 //console.log(jEle);
1804
1805 // Get existing data
1806 var el = pagelayer_data(jEle, true);
1807
1808 // If it is the last loop and we are greater than 1
1809 if(i > 1 && i == set){
1810 console.log('[pagelayer_default_atts] Still vars to set. Please check your shortcode params !');
1811 }
1812
1813 // We are supposed to set !
1814 if('set' in el && !pagelayer_empty(el.set)){
1815 pagelayer_set_atts(jEle, el.set);
1816 hasSet = true;
1817 }else{
1818 break;
1819 }
1820 }
1821
1822 return hasSet;
1823 }
1824
1825 // Returns the tag
1826 function pagelayer_tag(jEle){
1827
1828 // It could be the wrap
1829 if(jEle.hasClass('pagelayer-ele-wrap')){
1830 return jEle.children('.pagelayer-ele').attr('pagelayer-tag');
1831 }
1832
1833 // It could be the row or col holder
1834 if(jEle.hasClass('pagelayer-row-holder') || jEle.hasClass('pagelayer-col-holder')){
1835 return jEle.parent().attr('pagelayer-tag');
1836 }
1837
1838 return jEle.attr('pagelayer-tag');
1839 }
1840
1841 // Gets a single attribute value
1842 function pagelayer_get_att(jEle, att){
1843 return jEle.attr('pagelayer-a-'+att);
1844 };
1845
1846 // Gets a single attribute value
1847 function pagelayer_get_tmp_att(jEle, att){
1848 return jEle.attr('pagelayer-tmp-'+att);
1849 };
1850
1851 // This function will just set atts and not do anything else
1852 // Atts can be string or object. If its string, then val is needed
1853 function pagelayer_set_atts(jEle, atts, val){
1854
1855 if(typeof atts == 'string'){
1856 var tmp = {};
1857 tmp[atts] = val;
1858 atts = tmp;
1859 }
1860
1861 if(typeof atts != 'object'){
1862 return false;
1863 }
1864
1865 var tag = pagelayer_tag(jEle);
1866 var trigger_onchange = 0;
1867
1868 if(pagelayer_empty(tag)){
1869 console.log('Set atts found no tag');
1870 console.log(jEle);
1871 return;
1872 }
1873
1874 // All props
1875 var all_props = pagelayer_shortcodes[tag];//console.log(tag);console.log(jEle);
1876 var trigger_props = {};
1877 var no_val = {};
1878 var defaults = {};
1879 var _props = {};
1880
1881 // Loop through all props
1882 for(var i in pagelayer_tabs){
1883
1884 var tab = pagelayer_tabs[i];
1885
1886 for(var section in all_props[tab]){
1887
1888 var props = section in pagelayer_shortcodes[tag] ? pagelayer_shortcodes[tag][section] : pagelayer_styles[section];
1889
1890 for(var x in props){
1891
1892 if('default' in props[x]){
1893 defaults[x] = 1;
1894 }
1895
1896 // Create an easy REFERENCE for access
1897 _props[x] = props[x];
1898
1899 // Screen option REFERENCE is also needed for lookup
1900 if('screen' in _props[x]){
1901 _props[x+'_tablet'] = props[x];
1902 _props[x+'_mobile'] = props[x];
1903 }
1904
1905 // Dont set any val, but we set temp value
1906 if('no_val' in props[x]){
1907 no_val[x] = 1;
1908 }
1909
1910 if('req' in props[x] || 'show' in props[x]){
1911 var show = 'req' in props[x] ? props[x]['req'] : props[x]['show'];
1912 for(var showParam in show){
1913 var val = show[showParam];
1914 var except = showParam.substr(0, 1) == '!' ? true : false;
1915 showParam = except ? showParam.substr(1) : showParam;
1916 trigger_props[showParam] = 1;
1917 }
1918
1919 }
1920
1921 }
1922
1923 }
1924
1925 }
1926
1927 for(var x in atts){
1928
1929 // Are we to trigger change
1930 if(x in trigger_props){
1931 trigger_onchange = 1;
1932 }
1933
1934 //console.log(x+'-'+atts[x]);
1935
1936 // Is this a pro feature and we are not pro ? Then we dont do anything and continue !
1937 if('pro' in _props[x] && pagelayer_empty(pagelayer_pro)){
1938 continue;
1939 }
1940
1941 if(x in no_val){
1942 pagelayer_set_tmp_atts(jEle, x, atts[x]);
1943 continue;
1944 }
1945
1946 // Record History
1947 if(pagelayer.history_action){
1948 var old_val = pagelayer_get_att(jEle, x) || '';
1949 pagelayer_history_action_push({
1950 'title' : all_props['name'],
1951 'subTitle' : _props[x]['label'],
1952 'action' : 'Edited',
1953 'attrType' : 'a_attr',
1954 'pl_id' : pagelayer_id(jEle),
1955 'atts' : x,
1956 'oldVal' : old_val,
1957 'newVal' : atts[x]
1958 });
1959 }
1960
1961 // Remove the attribute if its BLANK and there is no default for it
1962 // If there is a default, we set it to blank to keep record of the current val
1963 if(atts[x].length < 1){
1964
1965 // Dont remove the value as there is a default
1966 if(!(x in defaults)){
1967 jEle.removeAttr('pagelayer-a-'+x);
1968 // Otherwise blank it
1969 }else{
1970 jEle.attr('pagelayer-a-'+x, atts[x]);
1971 }
1972
1973 // Remove the tmp atts anyway
1974 var to_del = new Array();
1975 var regexp = new RegExp('pagelayer\-tmp\-'+x, 'gi');
1976
1977 jQuery.each(jEle[0].attributes, function(index, att){
1978 if(!att) return;
1979 if(att.name.match(regexp)){
1980 to_del.push(att.name);
1981 }
1982 });
1983
1984 //console.log(to_del);
1985 for(var n in to_del){
1986 jEle.removeAttr(to_del[n]);
1987 }
1988
1989 // Set the value
1990 }else{
1991 jEle.attr('pagelayer-a-'+x, atts[x]);
1992 }
1993
1994 // Are you the active element
1995 if(pagelayer_is_active(jEle)){
1996
1997 // TODO : Record Undo and Redo
1998
1999 }
2000
2001 }
2002
2003 // Trigger the change of the parameter and show the required properties
2004 if(trigger_onchange){
2005 pagelayer_elpd_show_rows();
2006 }
2007
2008 pagelayer_isDirty = true;
2009 };
2010
2011 // This function will just set atts and not do anything else
2012 // Atts can be string or object. If its string, then val is needed
2013 function pagelayer_set_tmp_atts(jEle, atts, val){
2014
2015 if(typeof atts == 'string'){
2016 var tmp = {};
2017 tmp[atts] = val;
2018 atts = tmp;
2019 }
2020
2021 if(typeof atts != 'object'){
2022 return false;
2023 }
2024
2025 for(var x in atts){
2026
2027 // Record history
2028 if(pagelayer.history_action){
2029
2030 var old_val = pagelayer_get_tmp_att(jEle, x) || '';
2031 pagelayer_history_action_push({
2032 'title' : pagelayer_shortcodes[pagelayer_tag(jEle)]['name'],
2033 'subTitle' : x,
2034 'action' : 'Edited',
2035 'attrType' : 'tmp_attr',
2036 'pl_id' : pagelayer_id(jEle),
2037 'atts' : x,
2038 'oldVal' : old_val,
2039 'newVal' : atts[x]
2040 });
2041
2042 }
2043
2044 jEle.attr('pagelayer-tmp-'+x, atts[x]);
2045 }
2046
2047 };
2048
2049 // Set the att and classes of an HTML which is not yet created
2050 function pagelayer_sc_atts(classes, atts){
2051
2052 if(typeof atts != 'object'){
2053 atts = new Object();
2054 }
2055
2056 var r = new Array();
2057
2058 for(var x in atts){
2059 r.push('pagelayer-a-'+x+'="'+atts[x]+'"');
2060 }
2061
2062 return 'class="'+classes+' pagelayer-ele" '+r.join(' ');
2063 }
2064
2065 // Is the jEle the active element ?
2066 function pagelayer_is_active(jEle){
2067
2068 // Is this the active Element ?
2069 if(pagelayer_empty(pagelayer_active.el) || jEle.attr('pagelayer-id') != pagelayer_active.el.id){
2070 return false;
2071 }
2072
2073 return true;
2074
2075 };
2076
2077 // Removes {{}} from the variable name
2078 function pagelayer_var(val){
2079 return val.substring(2, (val.length - 2));
2080 }
2081
2082 // Take care of the CSS
2083 function pagelayer_css_render(css, val, seperator){
2084 //console.log('CSS '+css+' | '+val);
2085
2086 // Seperator
2087 seperator = seperator || ',';
2088
2089 // Replace the val
2090 css = css.split('{{val}}').join(val);
2091
2092 // If there is an array
2093 if(css.match(/val\[\d/)){
2094 val = val.split(seperator);
2095 for(var i in val){
2096 css = css.split('{{val['+i+']}}').join(val[i]);
2097 }
2098 }
2099
2100 //console.log('Final CSS '+css);
2101
2102 return css;
2103
2104 };
2105
2106 // Replace the variables
2107 function pagelayer_parse_el_vars(str, el){
2108
2109 str = str.split('{{element}}').join(el.CSS.sel);
2110 str = str.split('{{wrap}}').join(el.CSS.wrap);
2111 str = str.split('{{ele_id}}').join(el.id);
2112
2113 return str;
2114
2115 }
2116
2117 // Replace the variables
2118 function pagelayer_parse_vars(str, el){
2119
2120 for(var x in el.tmp){
2121 str = str.split('{{{'+x+'}}}').join(el.tmp[x]);
2122 }
2123
2124 for(var x in el.atts){
2125 str = str.split('{{'+x+'}}').join(el.atts[x]);
2126 }
2127
2128 return str;
2129 };
2130
2131 // Render the Element
2132 function pagelayer_sc_render(jEle){
2133
2134 // We render only the active element
2135 if(!pagelayer_is_active(jEle)){
2136 //return false;
2137 }
2138
2139 //console.log('Rendering');
2140
2141 // Handle the CSS part
2142 // Get the id, tag, atts, data, etc
2143 var el = pagelayer_data(jEle, true);
2144 var all_props = pagelayer_shortcodes[el.tag];
2145 var elCSS = {
2146 classes: [],
2147 remove_classes: [],
2148 attr: [],
2149 remove_attr: [],
2150 css: [],
2151 edit: [],
2152 sel: '[pagelayer-id="'+el.id+'"]',
2153 wrap: '[pagelayer-wrap-id="'+el.id+'"]'
2154 };
2155
2156 // Create a reference
2157 el.CSS = elCSS;
2158
2159 //console.log(el.atts);
2160
2161 for(var i in pagelayer_tabs){
2162 var tab = pagelayer_tabs[i];
2163 for(var section in all_props[tab]){ //console.log(tab+' '+section);
2164
2165 var props = section in pagelayer_shortcodes[el.tag] ? pagelayer_shortcodes[el.tag][section] : pagelayer_styles[section];//console.log(props);
2166
2167 // Loop the props
2168 for(var x in props){
2169
2170 // pagelayer_data will return attributes even if they are BLANK e.g. attr=""
2171 // Render doesnt consider BLANK values as values, and we are unsetting them now
2172 // If in any situation you need to consider blank values, please handle in the JS / PHP function of the Shortcode
2173 if(x in el.atts && el.atts[x].length < 1){
2174 delete el.atts[x];
2175 }
2176
2177 // Any editor ?
2178 if('edit' in props[x]){
2179 elCSS.edit.push({prop: x, sel: props[x]['edit']});
2180 }
2181
2182 // Do we have a addClass ?
2183 // We are checking before the element has a value so that we can add or remove the class
2184 if('addClass' in props[x]){
2185
2186 var addClasses;
2187
2188 // Convert the string to an array
2189 if(typeof props[x]['addClass'] === 'string'){
2190 addClasses = [props[x]['addClass']];
2191 }else{
2192 addClasses = props[x]['addClass'];
2193 }
2194
2195 for(var c in addClasses){
2196
2197 // The selector
2198 var tSel = jQuery.isNumeric(c) ? '' : c;
2199
2200 // If there is a VAL
2201 // NOTE : Only val is allowed when there is a list
2202 if(addClasses[c].match(/\{\{val\}\}/) && 'list' in props[x]){
2203
2204 for(var l in props[x]['list']){
2205
2206 var tmp = {'sel': tSel, 'val': addClasses[c].replace('{{val}}', l)};
2207
2208 if(el.atts[x] == l){
2209 elCSS['classes'].push(tmp);
2210 }else{
2211 elCSS['remove_classes'].push(tmp);
2212 }
2213
2214 }
2215
2216 }else{
2217
2218 var tmp = {'sel': tSel, 'val': addClasses[c]};
2219
2220 // If the value is there
2221 if(x in el.atts){
2222 elCSS['classes'].push(tmp);
2223 }else{
2224 elCSS['remove_classes'].push(tmp);
2225 }
2226
2227 }
2228 }
2229 }
2230
2231 // Do we have a addAttr ?
2232 // We are checking before the element has a value so that we can add or remove the attr
2233 if('addAttr' in props[x]){
2234
2235 var addAttr;
2236
2237 // Convert the string to an array
2238 if(typeof props[x]['addAttr'] === 'string'){
2239 addAttr = [props[x]['addAttr']];
2240 }else{
2241 addAttr = props[x]['addAttr'];
2242 }
2243
2244 for(var c in addAttr){
2245
2246 // The selector
2247 var tSel = jQuery.isNumeric(c) ? '' : c;
2248 var tmp = {'sel': tSel, 'val': addAttr[c]};
2249
2250 // If the value is there
2251 if(x in el.atts){
2252 elCSS['attr'].push(tmp);
2253 }else{
2254 elCSS['remove_attr'].push(tmp);
2255 }
2256 }
2257 }
2258
2259 // Do we have a CSS ?
2260 if('css' in props[x]){
2261
2262 var css;
2263
2264 // Convert the string to an array
2265 if(typeof props[x]['css'] === 'string'){
2266 css = [props[x]['css']];
2267 }else{
2268 css = props[x]['css'];
2269 }
2270
2271 // Screen modes
2272 var modes = {desktop: '', tablet: '_tablet', mobile: '_mobile'};
2273
2274 for(var m in modes){
2275
2276 var xm = x+modes[m];
2277
2278 // If the value is there
2279 if(!(xm in el.atts)){
2280 continue;
2281 }
2282
2283 for(var c in css){
2284
2285 // The selector
2286 var tSel = jQuery.isNumeric(c) ? '{{element}}' : c;
2287 var tmp = {
2288 sel: tSel,
2289 val: pagelayer_css_render(css[c], el.atts[xm], (props[x].sep || ',')),
2290 };
2291
2292 // Is this a tablet
2293 if(m == 'tablet'){
2294 tmp.sel = '@media (max-width: 768px) and (min-width: 361px){'+tmp.sel;
2295 tmp.val = tmp.val+'}';
2296 }
2297
2298 // Is this a mobile mode ?
2299 if(m == 'mobile'){
2300 tmp.sel = '@media (max-width: 360px){'+tmp.sel;
2301 tmp.val = tmp.val+'}';
2302 }
2303
2304 // Push to store
2305 elCSS.css.push(tmp);
2306 }
2307
2308 }
2309
2310 }
2311
2312 }
2313
2314 }
2315
2316 }
2317
2318 // If there is an HTML, then process it
2319 if('html' in pagelayer_shortcodes[el.tag]){
2320
2321 el.iHTML = jQuery('<div>'+pagelayer_shortcodes[el.tag]['html']+'</div>');
2322
2323 // Lets process the 'if-ext'
2324 el.iHTML.find('[if-ext]').each(function (){
2325 var $j = jQuery(this);
2326 var reqvar = pagelayer_var($j.attr('if-ext'));
2327 $j.removeAttr('if-ext');
2328
2329 // Is the element there ?
2330 if(!(reqvar in el.atts && !pagelayer_empty(el.atts[reqvar]))){
2331 //console.log('HERE');
2332 $j[0].outerHTML = $j.html();
2333 }
2334
2335 });
2336
2337 // Lets process the 'if'
2338 el.iHTML.find('[if]').each(function (){
2339 var $j = jQuery(this);
2340 var reqvar = pagelayer_var($j.attr('if'));
2341 $j.removeAttr('if');
2342
2343 // Is the element there ?
2344 if(!(reqvar in el.atts && !pagelayer_empty(el.atts[reqvar]))){
2345 //console.log('HERE');
2346 $j.remove();
2347 }
2348
2349 });
2350
2351 // Is there a function to render ?
2352 var fn = window['pagelayer_render_'+jEle.attr('pagelayer-tag')];
2353
2354 if(typeof fn == 'function'){
2355 fn(el);
2356 }
2357
2358 //console.log(el.atts);
2359
2360 // Parse the variables
2361 var new_html = pagelayer_parse_vars(el.iHTML.html(), el);
2362 el.iHTML.html(new_html);
2363
2364 // Do we have to wrap the innerHTML ?
2365 if('holder' in pagelayer_shortcodes[el.tag]){
2366
2367 var hSel = pagelayer_shortcodes[el.tag]['holder'];
2368 var holder = jEle.find(hSel).first();
2369
2370 // Detach the holder
2371 holder.detach();
2372
2373 // Add the new HTML
2374 el.$.html(el.iHTML.html());
2375
2376 // reAttach the children only
2377 el.$.find(hSel).html(holder.children());
2378
2379 // No holder
2380 }else{
2381
2382 //console.log(el.iHTML.html());
2383 el.$.html(el.iHTML.html());
2384
2385 }
2386
2387 // Rows, Cols and Groups
2388 }else{
2389
2390 // Is there a function to render ?
2391 var fn = window['pagelayer_sc_render_'+jEle.attr('pagelayer-tag')];
2392
2393 if(typeof fn == 'function'){
2394 fn(el);
2395 }
2396
2397 }
2398
2399 // Is there a function to render after HTML insertion but before CSS and attr ?
2400 var post = window['pagelayer_render_html_'+jEle.attr('pagelayer-tag')];
2401
2402 if(typeof post == 'function'){
2403 post(el);
2404 }
2405
2406 ////////////////////////////
2407 // Are there any edit fields ?
2408 ////////////////////////////
2409
2410 if(elCSS.edit.length > 0){
2411
2412 for(var c in elCSS.edit){
2413 var prop = elCSS.edit[c]['prop'];
2414 var tSel = elCSS.edit[c]['sel'];
2415 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
2416 node.attr('pagelayer-editable', prop);
2417 }
2418
2419 }
2420
2421 ////////////////////////////
2422 // Are there any addClass ?
2423 ////////////////////////////
2424
2425 // If we have any classes to add
2426 if(elCSS.classes.length > 0){
2427 //console.log(elCSS.classes);
2428
2429 for(var c in elCSS.classes){
2430 var tSel = elCSS.classes[c]['sel'];
2431 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
2432 if(!node.hasClass(elCSS.classes[c]['val'])){
2433 node.addClass(elCSS.classes[c]['val']);
2434 }
2435 }
2436 }
2437
2438 // If we have any classes to remove
2439 if(elCSS.remove_classes.length > 0){
2440 //console.log(elCSS.remove_classes);
2441
2442 for(var c in elCSS.remove_classes){
2443 var tSel = elCSS.remove_classes[c]['sel'];
2444 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
2445 if(node.hasClass(elCSS.remove_classes[c]['val'])){
2446 node.removeClass(elCSS.remove_classes[c]['val']);
2447 }
2448 }
2449 }
2450
2451 ////////////////////////////
2452 // Are there any addAttr ?
2453 ////////////////////////////
2454
2455 // If we have any attributes to add
2456 if(elCSS.attr.length > 0){
2457 //console.log(elCSS.attr);
2458
2459 for(var c in elCSS.attr){
2460 var tSel = elCSS.attr[c]['sel'].replace('{{element}}', '');
2461 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
2462 var att = elCSS.attr[c]['val'].split('=');
2463 att[1] = pagelayer_parse_vars(att[1], el);
2464 att[1] = pagelayer_trim(att[1], '"');
2465
2466 // Is it the same val ?
2467 if(!node.attr(att[0]) !== att[1]){
2468 node.attr(att[0], att[1]);
2469 }
2470 }
2471 }
2472
2473 // If we have any attributes to add
2474 if(elCSS.remove_attr.length > 0){
2475 //console.log(elCSS.remove_attr);
2476
2477 for(var c in elCSS.remove_attr){
2478 var tSel = elCSS.remove_attr[c]['sel'].replace('{{element}}', '');
2479 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
2480 var att = elCSS.remove_attr[c]['val'].split('=');
2481
2482 if(node.is('['+att[0]+']')){
2483 node.removeAttr(att[0]);
2484 }
2485 }
2486 }
2487
2488 // The style element
2489 var style = pagelayer.$('[pagelayer-style-id='+el.id+']');
2490
2491 // If we have any RULES CSS, then handle it
2492 if(elCSS.css.length > 0){
2493
2494 // Did we find it ?
2495 if(style.length < 1){
2496 jEle.prepend('<style pagelayer-style-id="'+el.id+'"></style>');
2497 }
2498
2499 // Get it again
2500 style = pagelayer.$('[pagelayer-style-id='+el.id+']');
2501
2502 // Make the rules
2503 var rules = [];
2504
2505 // Loop
2506 for(var c in elCSS.css){
2507 var tSel = pagelayer_parse_el_vars(elCSS.css[c]['sel'], el);
2508 var rule = pagelayer_parse_vars(elCSS.css[c]['val'], el);
2509 if(tSel.length > 0){
2510 rules.push(tSel+'{'+rule+'}');
2511 }else{
2512 rules.push(pagelayer_parse_el_vars(rule, el));
2513 }
2514 }
2515
2516 // CSS Selector overide
2517 if(!pagelayer_empty(all_props['overide_css_selector'])){
2518 for(var r in rules){
2519 rules[r] = rules[r].split(el.CSS.sel).join(all_props['overide_css_selector']);
2520 rules[r] = rules[r].split(el.CSS.wrap).join(all_props['overide_css_selector']);
2521 }
2522 }
2523
2524 // Set the style
2525 style.html(rules.join("\n"));
2526 //console.log(style);
2527 }else{
2528 style.remove();
2529 }
2530
2531 // Is there a function to render at the end ?
2532 var end = window['pagelayer_render_end_'+jEle.attr('pagelayer-tag')];
2533
2534 if(typeof end == 'function'){
2535 end(el);
2536 }
2537
2538 // If the element have any parent
2539 var par = pagelayer_get_parent(jEle);
2540 if(par){
2541 pagelayer_sc_render(pagelayer_ele_by_id(par));
2542 }
2543
2544 };
2545
2546 // Is the given tag a group
2547 function pagelayer_is_group(tag){
2548
2549 if('has_group' in pagelayer_shortcodes[tag] && !pagelayer_empty(pagelayer_shortcodes[tag]['has_group'])){
2550 return true;
2551 }
2552
2553 return false;
2554
2555 }
2556
2557 // Do action / event
2558 function pagelayer_trigger_action(act){
2559 jQuery(document).trigger(act);
2560 }
2561
2562 // Perform a function on an action / event
2563 function pagelayer_add_action(act, func){
2564 jQuery(document).on(act, func);
2565 }
2566
2567 // Save the post
2568 function pagelayer_save(){
2569
2570 pagelayer_trigger_action('pagelayer_save');
2571
2572 var pagelayerajaxurl = pagelayer_ajax_url+'&action=pagelayer_save_content&postID='+pagelayer_postID;
2573 var post = pagelayer_generate_sc(pagelayer_editable);//alert(post);return;
2574
2575 // Do we have page properties ?
2576 var jEle = jQuery(pagelayer_editable+' [pagelayer-tag=pl_post_props]');
2577 var props = {};
2578 if(jEle.length > 0){
2579 var tmp = pagelayer_data(jEle);
2580 //console.log(props);
2581 props = tmp.atts;
2582 }
2583
2584 jQuery.ajax({
2585 type: "POST",
2586 url: pagelayerajaxurl,
2587 data: {
2588 pagelayer_update_content : post,
2589 pagelayer_nonce: pagelayer_ajax_nonce,
2590 page_props: props
2591 },
2592 success: function(response, status, xhr){
2593 //alert(data);
2594 var obj = jQuery.parseJSON(response);
2595 //alert(obj);
2596 if(obj['error']){
2597 alert(obj['error']);
2598 }else{
2599 pagelayer_isDirty = false;
2600 alert(obj['success']);
2601 pagelayer_get_revision();
2602 }
2603 },
2604 error: function(errorThrown){
2605 console.log(errorThrown);
2606 }
2607 });
2608
2609 };
2610
2611 //Close the Editor
2612 function pagelayer_close(){
2613 if(pagelayer_isDirty == true){
2614 var r = confirm('Your Data has not been Saved yet! \n Press OK to stay on the Page.'+
2615 '\n Press Cancel to Close Editor. ');
2616 if(r == false){
2617 window.top.location.href = pagelayer_returnURL;
2618 }
2619 }else{
2620 window.top.location.href = pagelayer_returnURL;
2621 }
2622 };
2623
2624 // Generate Shortcode Post to save
2625 function pagelayer_generate_sc(selector){
2626
2627 var txt = '';
2628
2629 jQuery(selector).children(".pagelayer-ele-wrap").each(function(){
2630
2631 var jEle = jQuery(this).children('.pagelayer-ele');
2632
2633 // The ID
2634 var id = jEle.attr('pagelayer-id');
2635
2636 // If there is an Add element wrapper
2637 if(pagelayer_empty(id)){
2638 return;
2639 }
2640
2641 // Find the type of tag
2642 var tag = jEle.attr('pagelayer-tag');
2643 var final_tag = tag;
2644 var closestEle = jQuery(this).closest('.pagelayer-col-holder');
2645
2646 // Define inner row | Note : Commented as we now have a new widget of type inner_row
2647 /*if(tag == 'pl_row' && closestEle.length > 0 && closestEle.closest(pagelayer_editable).length > 0){
2648 final_tag = 'pl_inner_row';
2649 }*/
2650
2651 // Define inner column
2652 if(tag == 'pl_col' && closestEle.length > 0 && closestEle.closest(pagelayer_editable).length > 0){
2653 final_tag = 'pl_inner_col';
2654 }
2655 //console.log(tag);
2656
2657 // Is there an innerHTML ele
2658 var inner = '';
2659 if('innerHTML' in pagelayer_shortcodes[tag]){
2660 inner = pagelayer_shortcodes[tag]['innerHTML'];
2661 }
2662
2663 // Create the tag
2664 var data = '['+final_tag;
2665
2666 // Get the attributes to store
2667 jQuery.each(jEle[0].attributes, function(i, attrib){
2668 var res = attrib.name.match(/^pagelayer-a-(.+)/i);
2669 if(res && res[1] != inner){
2670 //console.log(attrib.name+' '+res[1]);
2671 data += ' '+res[1]+'="'+pagelayer_escapeHTML(attrib.value)+'"';
2672 }
2673 });
2674
2675 data = data+']';
2676
2677 // Add to the text
2678 txt = txt+data+"\n";
2679
2680 // Any internal function to handle the save ?
2681 var func = window['pagelayer_tag_'+tag];
2682 if(typeof func == 'function'){
2683
2684 var content = '';
2685 content = func(jEle);
2686
2687 if(content.length > 0){
2688 txt = txt+content;
2689 }
2690
2691 // If its a Row or Column or Group then it will have children
2692 }else if(jEle.hasClass('pagelayer-row') || jEle.hasClass('pagelayer-col') || jEle.hasClass('pagelayer-inner_row') || pagelayer_is_group(tag)){
2693
2694 var sel = "[pagelayer-id="+id+"]";
2695
2696 // Any holder which holds children ?
2697 if('holder' in pagelayer_shortcodes[tag]){
2698 sel = sel+' '+pagelayer_shortcodes[tag]['holder'];
2699 }
2700
2701 // Select the top-most element
2702 sel = jQuery(sel).first();
2703
2704 // Any child selector - Majorly for owl carousel
2705 // NOTE : Child selector should be very specific with immediate child selection at all levels
2706 var child_selector = false;
2707 if('child_selector' in pagelayer_shortcodes[tag]){
2708 sel = sel.find(pagelayer_shortcodes[tag]['child_selector']);
2709 }
2710
2711 var childrens = pagelayer_generate_sc(sel);
2712 if(childrens.length > 0){
2713 txt = txt+childrens;
2714 }
2715
2716 // Its a normal element so we might need to handle the content
2717 }else{
2718
2719 var content = '';
2720 if(inner.length > 0){
2721 content = jEle.attr('pagelayer-a-'+inner);
2722 if(!content){
2723 content = '';
2724 }
2725 }else{
2726 content = '';//jEle.html();
2727 }
2728
2729 if(content.length > 0){
2730 txt = txt+content;
2731 }
2732
2733 }
2734
2735 // Close the tag
2736 txt = txt+"[/"+final_tag+"]\n";
2737
2738 });
2739
2740 return txt;
2741
2742 };
2743
2744 // Escape charaters in attributes
2745 var pagelayer_escapeChars = {
2746 '\\]' : '#93',
2747 '\\[' : '#91',
2748 //'=' : '#61',
2749 '<' : 'lt',
2750 '>' : 'gt',
2751 '"' : 'quot',
2752 //'&' : 'amp',
2753 '\'' : '#39'
2754 };
2755
2756 // To unescape
2757 var pagelayer_unescapeChars = {
2758 '#93' : ']',
2759 '#91' : '[',
2760 //'#61' : '=',
2761 'lt' : '<',
2762 'gt' : '>',
2763 'quot' : '"',
2764 //'amp' : '&',
2765 '#39' : '\''
2766 };
2767
2768 var pagelayer_escaperegex_S = '[';
2769 for(var key in pagelayer_escapeChars) {
2770 pagelayer_escaperegex_S += key;
2771 }
2772 pagelayer_escaperegex_S += ']';
2773
2774 var pagelayer_escaperegex = new RegExp( pagelayer_escaperegex_S, 'g');
2775
2776 // The function which escapes everything
2777 function pagelayer_escapeHTML(str) {
2778 return str.replace(pagelayer_escaperegex, function(m) {
2779 if(m == '[' || m == ']') m = '\\'+m;
2780 return '&' + pagelayer_escapeChars[m] + ';';
2781 });
2782 };
2783
2784 // This will unescape everything
2785 function pagelayer_unescapeHTML(str){
2786 return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
2787 if(entityCode in pagelayer_unescapeChars){
2788 return pagelayer_unescapeChars[entityCode];
2789 }else{
2790 return entity;
2791 }
2792 });
2793 };
2794
2795 // Show the required leftbar tab
2796 function pagelayer_leftbar_tab(tab){
2797 pagelayer.$$('.pagelayer-leftbar-tab').hide();
2798 pagelayer.$$('#'+tab).show();
2799 }
2800
2801 // Sets up the leftbar
2802 function pagelayer_leftbar(){
2803
2804 // Toggle the holder
2805 pagelayer.$$('.pagelayer-leftbar-toggle').on('click', function(){
2806 pagelayer.$$('.pagelayer-leftbar-table').toggleClass('pagelayer-leftbar-hidden');
2807 pagelayer_trigger_action('pagelayer-leftbar-toggle');
2808 });
2809
2810 // Close leftbar
2811 pagelayer.$$('.pagelayer-leftbar-close').on('click', function(){
2812 pagelayer.$$('.pagelayer-leftbar-toggle').click();
2813 });
2814
2815 // Minimize leftbar
2816 pagelayer.$$('.pagelayer-leftbar-minimize').on('click', function(){
2817 pagelayer.$$('.pagelayer-leftbar-table').toggleClass('pagelayer-leftbar-minimize');
2818 });
2819
2820 var html = '<div class="pagelayer-leftbar">'+
2821 '<div class="pagelayer-leftbar-scroll">'+
2822 '<div id="pagelayer-shortcodes" class="pagelayer-leftbar-tab pagelayer-shortcodes">'+
2823 '<div class="pagelayer-leftbar-search">'+
2824 '<i class="pli pli-search" /><input class="pagelayer-search-field" /><i class="pagelayer-sf-empty pli">&times;</i>'+
2825 '</div>';
2826
2827 for(var x in pagelayer_groups){
2828
2829 // Title
2830 html += '<div class="pagelayer-leftbar-group"><h5>'+x+'</h5>';
2831
2832 // Indivdual icon
2833 for(var y in pagelayer_groups[x]){
2834
2835 var sc = pagelayer_groups[x][y];
2836
2837 if(!(sc in pagelayer_shortcodes) || 'not_visible' in pagelayer_shortcodes[sc]){
2838 continue;
2839 }
2840
2841 html += '<div class="pagelayer-shortcode-drag" draggable="true" pagelayer-tag="'+sc+'">'+
2842 '<div class="pagelayer-sc">'+
2843 '<center class="pagelayer-shortcode-inner">';
2844
2845 if('icon' in pagelayer_shortcodes[sc]){
2846 html += '<i class="pagelayer-shortcode '+pagelayer_shortcodes[sc]['icon']+'"></i>';
2847 }else{
2848 html += '<i class="pagelayer-shortcode pli pagelayer-'+sc+'"></i>';
2849 }
2850
2851 html += '</center>'+
2852 '<span class="pagelayer-shortcode-text">'+pagelayer_shortcodes[sc]['name']+'</span>'+
2853 '</div>'+
2854 '</div>';
2855
2856 }
2857
2858 html += '</div>';
2859
2860 }
2861
2862 html += '</div>'+
2863 '<div id="pagelayer-elpd" class="pagelayer-leftbar-tab pagelayer-elpd"></div>'+
2864 '<div id="pagelayer-options" class="pagelayer-leftbar-tab pagelayer-options"></div>'+
2865 '<div id="pagelayer-history" class="pagelayer-leftbar-tab pagelayer-history"></div>'+
2866 '<div id="pagelayer-post-settings" class="pagelayer-leftbar-tab pagelayer-post-settings"></div>'+
2867 '<div id="pagelayer-navigator" class="pagelayer-leftbar-tab pagelayer-navigator"></div>'+
2868 '</div>'+
2869 '</div>';
2870
2871 pagelayer.$$('.pagelayer-leftbar-holder').prepend(html);
2872 pagelayer_leftbar_tab('pagelayer-shortcodes');
2873
2874 pagelayer.$$('.pagelayer-leftbar-scroll').slimScroll({
2875 height: '100%',
2876 railVisible: false,
2877 alwaysVisible: true,
2878 color: '#000',
2879 size: '5px',
2880 });
2881
2882 // Hide the ones which are not supposed to be shown
2883 pagelayer.$$('.pagelayer-search-field').on('input', function(){
2884
2885 var val = jQuery(this).val();
2886 var re = new RegExp(val, 'i');
2887
2888 // Show only the required tags
2889 pagelayer.$$('.pagelayer-leftbar-group').each(function(){
2890
2891 var group = jQuery(this);
2892 var res = group.find('[pagelayer-tag]');
2893 var hidden = 0;
2894
2895 res.each(function(){
2896
2897 var tEle = jQuery(this);
2898 if(tEle.find('.pagelayer-shortcode-text').html().match(re)){
2899 tEle.show();
2900 }else{
2901 hidden += 1;
2902 tEle.hide();
2903 }
2904
2905 });
2906
2907 // Hide the whole group
2908 if(hidden == res.length){
2909 group.hide();
2910 }else{
2911 group.show();
2912 }
2913
2914 });
2915 });
2916
2917 // On click Pagelayer setting icon
2918 pagelayer.$$('.pagelayer-settings-icon').click(function(){
2919 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text('Post Settings');
2920 pagelayer.$$('.pagelayer-logo').hide();
2921 pagelayer_leftbar_tab('pagelayer-post-settings');
2922 pagelayer_active = {};
2923 pagelayer_post_settings();
2924 });
2925
2926 // On click search empty
2927 pagelayer.$$('.pagelayer-leftbar-search>.pagelayer-sf-empty').click(function(){
2928 pagelayer.$$('.pagelayer-search-field').val('').trigger('input');
2929 });
2930
2931 };
2932
2933 // Post setting holder
2934 function pagelayer_post_settings(){
2935
2936 // Is there a post settings ?
2937 var jEle = jQuery(pagelayer_editable+' [pagelayer-tag=pl_post_props]');
2938
2939 // Could not find
2940 if(jEle.length < 1){
2941 jEle = pagelayer_create_sc('pl_post_props');
2942 var id = pagelayer_id(jEle);
2943 jQuery(pagelayer_editable).prepend(jEle);
2944 pagelayer_element_setup('[pagelayer-id='+id+']');
2945 }
2946
2947 jEle.click();
2948
2949 return;
2950 }
2951
2952 // Get the closest element and method
2953 function pagelayer_near_by_ele(id, sc){
2954
2955 // Get the previous element of the id element
2956 var prevEle_id = jQuery('[pagelayer-wrap-id="'+id+'"]').prev().attr('pagelayer-wrap-id') || '';
2957 var method, cEle, args = {};
2958
2959 if(prevEle_id.length > 0){
2960
2961 // If have previous element of the id element
2962 // Set the method and previous element selector
2963 args = {'method' : 'after', 'cEle' : '[pagelayer-wrap-id="'+prevEle_id+'"]'};
2964
2965 }else{
2966
2967 // If don't have previous element of the id element then get parent element
2968 if(sc == "pl_row"){
2969 args = {'method' : 'prepend', 'cEle' : pagelayer_editable};
2970 }else{
2971
2972 // Get the parent element
2973 var pEle_id = pagelayer_id(jQuery('[pagelayer-wrap-id="'+id+'"]').closest('.pagelayer-ele'));
2974
2975 // Get the parent element tag
2976 var pEle_tag = pagelayer_tag(jQuery('[pagelayer-id="'+pEle_id+'"]'));
2977 var holder = pagelayer_shortcodes[pEle_tag]['holder'] || '';
2978 args = {'method' : 'prepend', 'cEle' : '[pagelayer-id="'+pEle_id+'"] '+ holder+' '};
2979
2980 }
2981
2982 }
2983
2984 return args;
2985
2986 };
2987
2988 // Push the action data in the pagelayer_history_obj object
2989 function pagelayer_history_action_push(args){
2990
2991 var history_obj_len = pagelayer_history_obj['action_data'].length;
2992
2993 // If the history_obj_len is less then 1 then set the data in array 0 position
2994 if(history_obj_len < 1){
2995 pagelayer_history_obj['action_data'][0] = {'title' : 'Start Editing', 'action' : 'Start' };
2996 pagelayer_history_obj['current_active_item_id'] = 0;
2997 }
2998
2999 // Remove the second array element if the history_obj_len greater then 100
3000 if(history_obj_len > 100){
3001 pagelayer_history_obj['action_data'].splice(1, 1);
3002 }
3003
3004 // Get current active history action id
3005 var action_id = parseInt(pagelayer_history_obj['current_active_item_id']) || 0;
3006
3007 // Remove the all array element after the active array element
3008 var del_ele = history_obj_len - action_id - 1;
3009 pagelayer_history_obj['action_data'].splice(action_id + 1, del_ele);
3010
3011 // Check if the same attr set as current active history
3012 if(args.action == "Edited" && history_obj_len > 1){
3013 var atts = pagelayer_history_obj['action_data'][action_id] || '';
3014 if(atts['atts'] == args['atts']){
3015 args['oldVal'] = atts['oldVal'];
3016 pagelayer_history_obj['action_data'][action_id] = args;
3017 pagelayer_history_setup();
3018 return true;
3019 }
3020 }
3021
3022 pagelayer_history_obj['action_data'].push(args);
3023 pagelayer_history_obj['current_active_item_id'] = pagelayer_history_obj['action_data'].length - 1;
3024 pagelayer_history_setup();
3025
3026 }
3027
3028 // Setup pagelayer history
3029 function pagelayer_history_setup(force){
3030
3031 var force = force || false;
3032
3033 // If the history tab is visible, only then setup
3034 if(!pagelayer.$$('#pagelayer-history').is(':visible') && !force){
3035 return;
3036 }
3037
3038 // The current active action id
3039 var current_id = pagelayer_history_obj['current_active_item_id'];
3040
3041 // pagelayer-HISTORY - Element Properties Dialog
3042 var pagelayer_history_html = '<div class="pagelayer-history-tabs">'+
3043 '<div class="pagelayer-history-tab" pagelayer-history-tab="actions" pagelayer-history-active-tab="1">Actions</div>'+
3044 '<div class="pagelayer-history-tab" pagelayer-history-tab="revisions">Revisions</div>'+
3045 '</div>'+
3046 '<div class="pagelayer-history-body">'+
3047 '<div class="pagelayer-history-section active" pagelayer-show-tab="actions">';
3048
3049 // Any actions
3050 if(pagelayer_history_obj['action_data'].length > 0){
3051
3052 for(var x in pagelayer_history_obj['action_data']){
3053
3054 if(pagelayer_empty(pagelayer_history_obj['action_data'][x])){continue;}
3055
3056 var title = pagelayer_history_obj['action_data'][x]['title'] || '';
3057 var subTitle = pagelayer_history_obj['action_data'][x]['subTitle'] || '';
3058 var action = pagelayer_history_obj['action_data'][x]['action'] || '';
3059 var tmp_attr = pagelayer_history_obj['action_data'][x]['attrType'] || '';
3060 var eAttr = '';
3061
3062 if(!pagelayer_empty(tmp_attr) && tmp_attr == "tmp_attr"){
3063 eAttr = "pagelayer-history-hidden";
3064 }
3065
3066 pagelayer_history_html += '<div class="pagelayer-history-holder '+((current_id == x) ? 'current_active_item' : '' )+' '+eAttr+'" history-action-id="'+x+'" >'+
3067 '<div class="pagelayer-history-detail-holder">'+
3068 '<span class="pagelayer-history-title"><b> '+title+' </b></span>'+
3069 '<span class="pagelayer-history-subtitle"> '+subTitle+' </span>'+
3070 '<span class="pagelayer-history-action"><i> '+action+' </i></span>'+
3071 '</div>'+
3072 '<div class="pagelayer-history-icon">'+
3073 '<span class="pagelayer-history-check pli pli-checkmark" aria-hidden="true"></span>'+
3074 '</div>'+
3075 '</div>';
3076 }
3077
3078 }else{
3079 pagelayer_history_html += 'No Actions history available yet';
3080 }
3081
3082 pagelayer_history_html += '</div>'+
3083 '<div class="pagelayer-history-section" pagelayer-show-tab="revisions">';
3084
3085 // Any revisions ?
3086 if(pagelayer_revision_obj){
3087 for(var x in pagelayer_revision_obj){
3088 pagelayer_history_html += '<div class="pagelayer-revision-holder" revision-id="'+pagelayer_revision_obj[x]['ID']+'">'+
3089 '<div class="pagelayer-revision-img-holder">'+
3090 '<img src="'+pagelayer_revision_obj[x]['post_author_url']+'" />'+
3091 '</div>'+
3092 '<div class="pagelayer-revision-detail-holder">'+
3093 '<div class="pagelayer-revision-date">'+
3094 pagelayer_revision_obj[x]['post_date_ago']+
3095 '('+pagelayer_revision_obj[x]['post_date']+')'+
3096 '</div>'+
3097 '<div class="pagelayer-revision-author">'+
3098 pagelayer_revision_obj[x]['post_type'] +' by '+
3099 pagelayer_revision_obj[x]['post_author_name']+
3100 '</div>'+
3101 '</div>'+
3102 '<div class="pagelayer-revision-icon-holder">'+
3103 '<i class="pagelayer-revision-delete pli pli-cross"></i>'+
3104 '</div>'+
3105 '</div>';
3106 }
3107
3108 }else{
3109 pagelayer_history_html += 'No Revisions history available';
3110 }
3111
3112 pagelayer_history_html += '</div>'+
3113 '</div>';
3114
3115 // Create the dialog box
3116 pagelayer.$$('#pagelayer-history').html(pagelayer_history_html);
3117 var holder = pagelayer.$$('#pagelayer-history');
3118
3119 // Set active history holder
3120 holder.find('.pagelayer-history-holder').on('click', function(){
3121 var hEle = jQuery(this);
3122 var prev_item_id = pagelayer_history_obj['current_active_item_id'];
3123 hEle.parent().children().removeClass('current_active_item');
3124 hEle.addClass('current_active_item');
3125 var do_item_id = parseInt(hEle.attr('history-action-id'));
3126 pagelayer_history_action_setup(do_item_id, prev_item_id);
3127 });
3128
3129 // Apply revision
3130 holder.find('.pagelayer-revision-holder').on('click', function(){
3131 var revision_id = jQuery(this).attr('revision-id');
3132
3133 jQuery.ajax({
3134 url: pagelayer_ajax_url+'&action=pagelayer_apply_revision&revisionID='+revision_id,
3135 type: 'post',
3136 data: {
3137 pagelayer_nonce: pagelayer_ajax_nonce,
3138 'pagelayer-live' : 1,
3139 },
3140 success: function(response, status, xhr){
3141
3142 var obj = jQuery.parseJSON(response);
3143 if(obj['error']){
3144 alert(obj['error']);
3145 }else{
3146 jQuery(pagelayer_editable).html(obj['content']);
3147 alert(obj['success']);
3148 pagelayer_element_setup();
3149 pagelayer_add_widget();
3150 }
3151 }
3152 });
3153 });
3154
3155 // Delete the revision
3156 holder.find('.pagelayer-revision-delete').click(function(e){
3157
3158 e.stopPropagation();
3159 var rEle = jQuery(this).closest('.pagelayer-revision-holder');
3160 var revision_id = rEle.attr('revision-id');
3161
3162 if(confirm("Are you sure you want to delete the revision ?")){
3163 jQuery.ajax({
3164 url: pagelayer_ajax_url+'&action=pagelayer_delete_revision&revisionID='+revision_id,
3165 type: 'post',
3166 data: {pagelayer_nonce: pagelayer_ajax_nonce},
3167 success: function(response, status, xhr){
3168
3169 var obj = jQuery.parseJSON(response);
3170 if(obj['error']){
3171 alert(obj['error']);
3172 }else{
3173 alert(obj['success']);
3174 rEle.hide();
3175 }
3176
3177 }
3178 });
3179 }
3180
3181 });
3182
3183 // The tabs
3184 holder.find('.pagelayer-history-tab').on('click', function(){
3185 var attr = 'pagelayer-history-active-tab';
3186 holder.find('.pagelayer-history-tab').each(function(){
3187 jQuery(this).removeAttr(attr);
3188 });
3189 jQuery(this).attr(attr, 1);
3190
3191 // Get the active tab
3192 var active_tab = holder.find('[pagelayer-history-active-tab]').attr('pagelayer-history-tab');
3193
3194 // Trigger the showing of rows
3195 holder.find('[pagelayer-show-tab]').each(function(){
3196 var sec = jQuery(this);
3197
3198 // Is it the active tab ?
3199 if(sec.attr('pagelayer-show-tab') != active_tab){
3200 sec.hide();
3201 }else{
3202 sec.show();
3203 }
3204 });
3205 });
3206 }
3207
3208 // Get evisions Handler
3209 function pagelayer_get_revision(){
3210
3211 jQuery.ajax({
3212 url: pagelayer_ajax_url+'&action=pagelayer_get_revision&postID='+pagelayer_postID,
3213 type: 'post',
3214 data: {
3215 pagelayer_nonce: pagelayer_ajax_nonce,
3216 },
3217 //async:false,
3218 success: function(response, status, xhr){
3219 var obj = jQuery.parseJSON(response);
3220
3221 if(!pagelayer_empty(obj['error'])){
3222 alert(obj['error']);
3223 }else{
3224 pagelayer_revision_obj = obj;
3225 pagelayer_history_setup(true);
3226 }
3227 }
3228 });
3229 };
3230
3231 // Do the history action - use for ctrl-z and ctrl-y
3232 function pagelayer_do_history(action){
3233
3234 var cur_id = pagelayer_history_obj['current_active_item_id'];
3235 var new_id = cur_id;
3236 var action_data_len = pagelayer_history_obj['action_data'].length;
3237
3238
3239 if(action == 'undo'){
3240
3241 // You cannot undo from the first movement
3242 if(cur_id == 0){
3243 return true;
3244 }
3245
3246 for(var i = (cur_id - 1); i => 0; i--){
3247
3248 var action = pagelayer_history_obj['action_data'][i];
3249
3250 if('attrType' in action && action['attrType'] == 'tmp_attr'){
3251 continue;
3252 }
3253
3254 new_id = i;
3255 break;
3256
3257 }
3258
3259 }else if(action == 'redo'){
3260 for(var i = cur_id + 1; i < action_data_len; i++){
3261
3262 var action = pagelayer_history_obj['action_data'][i];
3263
3264 if('attrType' in action && action['attrType'] == 'tmp_attr'){
3265 continue;
3266 }
3267
3268 new_id = i;
3269 break;
3270
3271 }
3272 }
3273
3274 // Do the action
3275 pagelayer_history_action_setup(new_id, cur_id);
3276 pagelayer_history_setup();
3277
3278 };
3279
3280 // Action setup handle on ctrl-z and ctrl-y
3281 function pagelayer_history_action_setup(current_item_id, prev_item_id){
3282
3283 // Set this as the current active
3284 pagelayer_history_obj['current_active_item_id'] = current_item_id;
3285
3286 // Delete the element
3287 var delete_ele = function(id){
3288
3289 // Set Pagelayer History FALSE to prevent saving delete action in action history
3290 pagelayer.history_action = false;
3291
3292 pagelayer_delete_element('[pagelayer-id='+id+']');
3293
3294 // Set Pagelayer History TRUE
3295 pagelayer.history_action = true;
3296
3297 };
3298
3299 // Re-setup the element
3300 var resetup_ele = function(history_array){
3301 jQuery(history_array.cEle.cEle)[history_array.cEle.method](history_array.html);
3302 pagelayer_element_setup('[pagelayer-id='+history_array.pl_id+'], [pagelayer-id='+history_array.pl_id+'] .pagelayer-ele', true);
3303 pagelayer_empty_col(jQuery('[pagelayer-id="'+history_array.pl_id+'"]').closest('.pagelayer-col-holder'));
3304 };
3305
3306 // Re-setup the element attr
3307 var reset_ele_attr = function(hEle, atts, val, attrType){
3308
3309 // Set Pagelayer History FALSE to prevent saving attributes in action history
3310 pagelayer.history_action = false;
3311 if(attrType == "tmp_attr"){
3312 pagelayer_set_tmp_atts(hEle, atts, val);
3313 }else{
3314 pagelayer_set_atts(hEle, atts, val);
3315 }
3316
3317 // The property holder
3318 var holder = pagelayer.$$('.pagelayer-elpd-body');
3319 holder.html(' ');
3320 pagelayer_sc_render(hEle);
3321 pagelayer_elpd_generate(hEle, holder);
3322 pagelayer.history_action = true;
3323
3324 };
3325
3326 // Move element
3327 var pagelayer_move_ele = function(id, move_loc){
3328 var eWrap = pagelayer_wrap_by_id(id);
3329 var pCol = eWrap.closest('.pagelayer-col-holder') || '';
3330
3331 jQuery(move_loc.cEle)[move_loc.method](eWrap);
3332
3333 // Ensure the column is not empty
3334 if(!pagelayer_empty(pCol)){
3335 pagelayer_empty_col(pCol);
3336 pagelayer_empty_col(pagelayer_wrap_by_id(id).closest('.pagelayer-col-holder'));
3337 }
3338 }
3339
3340 if(prev_item_id > current_item_id){
3341
3342 // All Actions for undo here
3343 var i = parseInt(prev_item_id);
3344
3345 for(i; i > current_item_id; i--){
3346
3347 var history_array = pagelayer_history_obj['action_data'][i];
3348 var action = history_array.action;
3349 var id = history_array.pl_id;
3350
3351 if(action == "Edited"){
3352 hEle = jQuery('[pagelayer-id="'+id+'"]');
3353 reset_ele_attr(hEle, history_array.atts, history_array.oldVal, history_array.attrType);
3354 }else if(action == "Added"){
3355 delete_ele(id);
3356 }else if(action == "Deleted"){
3357 resetup_ele(history_array);
3358 }else if(action == "Copied"){
3359 delete_ele(id);
3360 }else if(action == "Moved"){
3361 pagelayer_move_ele(id, history_array.before_loc);
3362 }
3363
3364 }
3365
3366 }else{
3367
3368 // All Actions for redo here
3369 var i = parseInt(prev_item_id)+1;
3370
3371 for(i; i <= current_item_id; i++){
3372
3373 var history_array = pagelayer_history_obj['action_data'][i];
3374 var action = history_array.action;
3375 var id = history_array.pl_id;
3376
3377 if(action == "Edited"){
3378 hEle = jQuery('[pagelayer-id="'+id+'"]');
3379 reset_ele_attr(hEle, history_array.atts, history_array.newVal, history_array.attrType);
3380 }else if(action == "Added"){
3381 resetup_ele(history_array);
3382
3383 if(history_array.tag != "pl_row" && history_array.tag != "pl_col" ){
3384 // Ensure the column is not empty
3385 pagelayer_empty_col(history_array.cEle.cEle);
3386 }
3387 }else if(action == "Deleted"){
3388 delete_ele(id);
3389 }else if(action == "Copied"){
3390 resetup_ele(history_array);
3391 }else if(action == "Moved"){
3392 pagelayer_move_ele(id, history_array.after_loc);
3393 }
3394
3395 }
3396 }
3397
3398 };
3399
3400 // Report an error
3401 function pagelayer_error(error, func){
3402 var prefix = func || '';
3403 alert(prefix+error);
3404 };
3405
3406 function pagelayer_bottombar(){
3407 var holder = pagelayer.$$('.pagelayer-bottombar-holder');
3408 var html = '<div class="pagelayer-bottombar">'+
3409 '<div class="pagelayer-bottombar-rightbuttons">'+
3410 '<button data-tlite="Save Changes" class="pagelayer-update-button pagelayer-success-btn">Update</button>'+
3411 '<button data-tlite="Close and Return to Admin Panel" class="pagelayer-close-button">Close</button>'+
3412 '<div class="pagelayer-mode-wrapper">'+
3413 '<div class="pagelayer-mode-buttons-wrapper">'+
3414 '<i class="screen-mode pli pli-desktop" pagelayer-mode-data="desktop"></i>'+
3415 '<i class="screen-mode pli pli-tablet" pagelayer-mode-data="tablet"></i>'+
3416 '<i class="screen-mode pli pli-mobile" pagelayer-mode-data="mobile"></i>'+
3417 '</div>'+
3418 '</div>'+
3419 '<i class="pagelayer-mode-button pli pli-desktop"></i>'+
3420 '<span data-tlite="Preview Changes"><i class="pagelayer-preview pli pli-eye"></i></span>'+
3421 '<span data-tlite="History and Revisions"><i class="pagelayer-history-icon pli pli-history"></i></span>'+
3422 '<span data-tlite="navigator"><i class="pagelayer-navigator-icon pli pli-tree"></i></span>'+
3423 //'<span data-tlite="Close and Return to Admin Panel"><i class="pagelayer-close-button fa fa-close"></i></span>'+
3424 '</div>'+
3425 '</div>';
3426
3427 holder.html(html);
3428 holder.find('.pagelayer-update-button').on('click', function(){
3429 pagelayer_save();
3430 pagelayer_history_setup();// Setup history tab after update
3431 });
3432
3433 holder.find('.pagelayer-close-button').on('click', function(){
3434 pagelayer_close();
3435 });
3436 holder.find('.screen-mode').on('click', function(){
3437 var screen_mode = jQuery(this).attr('pagelayer-mode-data');
3438 pagelayer_set_screen_mode(screen_mode);
3439 holder.find('.pagelayer-mode-buttons-wrapper').toggle();
3440 });
3441
3442 holder.find('.pagelayer-mode-button').on('click', function(){
3443 holder.find('.pagelayer-mode-buttons-wrapper').toggle();
3444 });
3445
3446 holder.find('.pagelayer-history-icon').click(function(){
3447 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text('Pagelayer History');
3448 pagelayer.$$('.pagelayer-logo').hide();
3449 pagelayer_leftbar_tab('pagelayer-history');
3450 pagelayer_active = {};
3451 pagelayer_history_setup();
3452 });
3453
3454 holder.find('.pagelayer-navigator-icon').click(function(){
3455 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text('Pagelayer Navigator');
3456 pagelayer.$$('.pagelayer-logo').hide();
3457
3458 // If the navigator tab visible, then don't setup
3459 if(!pagelayer.$$('#pagelayer-navigator').is(':visible')){
3460 pagelayer_navigator_setup();
3461 }
3462
3463 pagelayer_leftbar_tab('pagelayer-navigator');
3464 pagelayer_active = {};
3465 });
3466
3467 holder.find('.pagelayer-preview').click(function(){
3468
3469 // If the page is not dirty
3470 if(!pagelayer_isDirty){
3471
3472 // Open in new tab the existing page itself
3473 window.open(pagelayer_post_permalink, '_blank');
3474 return;
3475
3476 }
3477
3478 // Get post content
3479 var post = pagelayer_generate_sc(pagelayer_editable);//alert(post);return;
3480
3481 pagelayer.$$('.pagelayer-body').css({'opacity' : '0.33'});
3482 jQuery.ajax({
3483 url: pagelayer_ajax_url+'&action=pagelayer_create_post_autosave&postID='+pagelayer_postID,
3484 type: 'POST',
3485 data: {
3486 'pagelayer_nonce': pagelayer_ajax_nonce,
3487 'pagelayer_post_content': post
3488 },
3489 success: function(data) {
3490 var data = JSON.parse(data);
3491
3492 // If there is some error
3493 if(!pagelayer_empty(data['error']) || pagelayer_empty(data['id'])){
3494 alert('Unable to set preview for some reason');
3495 return;
3496 }
3497
3498 var url = data['url']+'&preview_id='+pagelayer_postID+'&preview_nonce='+
3499 pagelayer_preview_nonce;
3500
3501 // Open in new tab
3502 window.open(url, '_blank');
3503 },
3504 complete: function(){
3505 pagelayer.$$('.pagelayer-body').css({'opacity' : '1'});
3506 }
3507 });
3508 });
3509 };
3510
3511
3512 ///////////////////////////////
3513 // Miscellaneuos Functions
3514 ///////////////////////////////
3515
3516 // Setup navigator
3517 function pagelayer_navigator_setup(){
3518
3519 var navigator_ele = pagelayer.$$('#pagelayer-navigator'),
3520 navigator_padding = 10,
3521 navigator_html = '';
3522
3523 // Get the child elements list
3524 var pagelayer_create_navi_list = function(selector){
3525
3526 var navigator_list = '';
3527
3528 selector.children('.pagelayer-ele-wrap, .pagelayer-ele').each(function(){
3529
3530 var cEle = jQuery(this),
3531 tag = pagelayer_tag(cEle),
3532 id = pagelayer_id(cEle),
3533 child_ele = false,
3534 ele_class = '';
3535
3536 // If tag is not found then return
3537 if(pagelayer_empty(tag)){
3538 return;
3539 }
3540
3541 // if is row or col or inner-row
3542 if(tag == 'pl_row' || tag == 'pl_col' || tag == 'pl_inner_row'){
3543 ele_class = 'pagelayer-navigator-toggle';
3544 child_ele = true;
3545 }
3546
3547 navigator_list += '<div class="pagelayer-navigetor-ele" pagelayer-id="'+id+'">'+
3548 '<div class="pagelayer-ele-name '+ ele_class +'" pagelayer-tag="'+tag+'" style="padding-left:'+navigator_padding+'px">'+
3549 '<i class="fa pagalayer-arrow"></i><i class="fa pagelayer-'+tag+'"></i>'+
3550 pagelayer_shortcodes[tag]['name']+
3551 '</div>';
3552
3553 // Create the list of child element
3554 if(child_ele){
3555 navigator_padding += 15; // Increment padding left for widget
3556 navigator_list += pagelayer_create_navi_list( cEle.find(pagelayer_shortcodes[tag]['holder']).first() );
3557 navigator_padding -= 15; // Decrement padding left for widget
3558 }
3559
3560 navigator_list += '</div>';
3561 });
3562
3563 return navigator_list;
3564 }
3565
3566 // Create list of all rows and their child widgets
3567 jQuery(pagelayer_editable).children('.pagelayer-wrap-row').each(function(){
3568 navigator_html += pagelayer_create_navi_list(jQuery(this));
3569 });
3570
3571 // Put the navigator list
3572 navigator_ele.html('<div class="pagelayer-leftbar-prop-body">'+navigator_html+'</div>');
3573
3574 // On click toggle the element
3575 navigator_ele.find('.pagelayer-ele-name').on('click', function(){
3576
3577 var tEle = jQuery(this);
3578 var pl_id = tEle.parent().attr('pagelayer-id'); // Get Pagelayer id
3579 var jEle = pagelayer_ele_by_id(pl_id);
3580
3581 // If the class "pagelayer-navigator-toggle" exist then toggle
3582 if(tEle.hasClass('pagelayer-navigator-toggle')){
3583 tEle.parent().toggleClass('pagelayer-navigator-open');
3584 }
3585
3586 // Also open all parents
3587 tEle.parent().parents('.pagelayer-navigetor-ele').addClass('pagelayer-navigator-open');
3588
3589 // Set the click element active
3590 navigator_ele.find('.pagelayer-ele-name').removeClass('pagelayer-navi-active');
3591 tEle.addClass('pagelayer-navi-active')
3592
3593 // Set the element active
3594 if(jEle.length > 0){
3595 //pagelayer_active.el = pagelayer_data(jEle);
3596 pagelayer_set_active(jEle);
3597 pagelayer_scroll_to_viewport(jEle);
3598 }
3599
3600 });
3601
3602 // Do active ele tab open
3603 if( pagelayer_active.el && pagelayer_active.el.id ){
3604 navigator_ele.find('[pagelayer-id="'+pagelayer_active.el.id+'"]').children('.pagelayer-ele-name').click();
3605 }
3606
3607 /* var posY = 0, orig_eleY= 0;
3608
3609 // On mouse down in pagelayer-ele-name
3610 navigator_ele.find('.pagelayer-ele-name').on('mousedown', function(e){
3611 e = e || window.event;
3612 e.preventDefault();
3613
3614 // Get ele position
3615 orig_eleY = jQuery(this).offset().top;
3616
3617 // Get the mouse cursor at startup:
3618 posY = e.clientY;
3619
3620 // The variable needs to be empty.
3621 newMethod = '';
3622
3623 // Mouse up handler
3624 var ele_mousemove = function(){
3625
3626 }
3627
3628 // Mouse move handler
3629 var ele_mouseup = function(){
3630 pagelayer.$$(document).off('mouseup', ele_mouseup);
3631 pagelayer.$$(document).off('mousemove', ele_mousemove);
3632 }
3633
3634 pagelayer.$$(document).on('mouseup', ele_mouseup);
3635 pagelayer.$$(document).on('mousemove', ele_mousemove);
3636
3637 }); */
3638
3639
3640 }
3641
3642 // Scroll page to element view port
3643 function pagelayer_scroll_to_viewport(jEle, timeout, parentEle){
3644
3645 var scrolled = parentEle || jQuery('html, body');
3646 timeout = timeout || 500;
3647 parentEle = parentEle || jQuery(window);
3648
3649 setTimeout(function () {
3650 var parentHeight = parentEle.height(),
3651 parentScrollTop = parentEle.scrollTop(),
3652 elementTop = jEle.offset().top,
3653 topToCheck = elementTop - parentScrollTop;
3654
3655 if (topToCheck > 0 && topToCheck < parentHeight) {
3656 return;
3657 }
3658
3659 var scrolling = elementTop - parentHeight / 2;
3660 scrolled.stop(true).animate({
3661 scrollTop: scrolling
3662 }, 1000);
3663 }, timeout);
3664 }
3665
3666 // Generates a random string of "n" characters
3667 function pagelayer_randstr(n, special){
3668 var text = '';
3669 var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
3670
3671 special = special || 0;
3672 if(special){
3673 possible = possible + '&#$%@';
3674 }
3675
3676 for(var i=0; i < n; i++){
3677 text += possible.charAt(Math.floor(Math.random() * possible.length));
3678 }
3679
3680 return text;
3681 };
3682
3683 function pagelayer_update_site_title(val){
3684 if(!pagelayer_empty(val)){
3685 var site_name = jQuery('.pagelayer-wp-title').attr('pagelayer-a-site_name');
3686 if(!pagelayer_empty(site_name)){
3687 var site_title = jQuery.ajax({
3688 url: pagelayer_ajax_url+'&action=pagelayer_fetch_site_title',
3689 type: 'post',
3690 async: false
3691 }).responseText;
3692
3693 if(site_title != site_name){
3694 var site_title = jQuery.ajax({
3695 url: pagelayer_ajax_url+'&action=pagelayer_update_site_title',
3696 type: 'post',
3697 data: {'site_title': site_name},
3698 async: false
3699 }).responseText;
3700 }
3701 }
3702 }
3703 }
3704
3705 function pagelayer_trim(str, charlist){
3706 // discuss at: http://locutus.io/php/trim/
3707
3708 if(typeof str != 'string'){
3709 return str;
3710 }
3711
3712 var whitespace = [' ', '\n', '\r', '\t', '\f', '\x0b', '\xa0', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u200b', '\u2028', '\u2029', '\u3000' ].join('')
3713 var l = 0
3714 var i = 0
3715 str += ''
3716
3717 if (charlist) {
3718 whitespace = (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1')
3719 }
3720
3721 l = str.length
3722 for (i = 0; i < l; i++) {
3723 if (whitespace.indexOf(str.charAt(i)) === -1) {
3724 str = str.substring(i)
3725 break
3726 }
3727 }
3728
3729 l = str.length
3730 for (i = l - 1; i >= 0; i--) {
3731 if (whitespace.indexOf(str.charAt(i)) === -1) {
3732 str = str.substring(0, i + 1)
3733 break
3734 }
3735 }
3736
3737 return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''
3738 };
3739
3740 // Convert the regular URL of a Video to a Embed URL
3741 function pagelayer_video_url(src){
3742
3743 var youtubeRegExp = /youtube\.com|youtu\.be/;
3744 var vimeoRegExp = /vimeo\.com/;
3745 var match = '';
3746 var videoId = '';
3747
3748 if (youtubeRegExp.exec(src)) {
3749 match = 'youtube';
3750 } else if (vimeoRegExp.exec(src)) {
3751 match = 'vimeo';
3752 }
3753
3754 switch(match){
3755 case 'youtube':
3756
3757 var youtubeRegExp1 = /youtube\.com/;
3758 var youtubewatch = /watch/;
3759 var youtubeembed = /embed/;
3760 var youtube = /youtu\.be/;
3761
3762 if (youtubeRegExp1.exec(src)) {
3763
3764 if (youtubewatch.exec(src)) {
3765 videoId = src.split('?v=');
3766
3767 } else if (youtubewatch.exec(src)) {
3768 videoId = src.split('embed/');
3769 }
3770
3771 } else if (youtube.exec(src)) {
3772 videoId = src.split('.be/');
3773 }
3774
3775 return '//youtube.com/embed/'+videoId[1];
3776
3777 break;
3778
3779 case 'vimeo':
3780
3781 var vimeoplayer = /player\.vimeo\.com/;
3782 var vimeovideo = /video/;
3783
3784 if (vimeoplayer.exec(src) && vimeovideo.exec(src)) {
3785 videoId = src.split('video/');
3786 } else if (vimeoRegExp.exec(src)) {
3787 videoId = src.split('.com/');
3788 }
3789
3790 return '//player.vimeo.com/video/'+videoId[1];
3791
3792 break;
3793 default:
3794 return src;
3795 }
3796 };
3797
3798 // Add widget section
3799 function pagelayer_add_widget(){
3800
3801 html='<div class="pagelayer-add-widget-area">'+
3802 '<button class="pagelayer-add-button pagelayer-add-section"><i class="pagelayer-add-row fa fa-file-text"></i> &nbsp;Add New Section</button>'+
3803 '<button class="pagelayer-add-button pagelayer-add-row"><i class="pagelayer-add-row fa fa-plus-circle"></i> &nbsp;Add New Row</button>'+
3804 '<p>Click here to add new row OR drag widgets</p>'+
3805 '</div>';
3806
3807 jQuery(pagelayer_editable).append(html);
3808
3809 var add_area = jQuery('.pagelayer-add-widget-area');
3810
3811 // Add a code before this
3812 var add_sc = function(tag){
3813
3814 // Create Row
3815 var row = jQuery('<div pagelayer-tag="pl_row"></div>');
3816 add_area.before(row);
3817 var row_id = pagelayer_onadd(row, false);
3818 var rEle = pagelayer_ele_by_id(row_id);
3819
3820 if(tag == 'pl_row'){
3821 rEle.click();
3822 return row_id;
3823 }
3824
3825 // Create Column
3826 var col = jQuery('<div pagelayer-tag="pl_col"></div>');
3827 rEle.find('.pagelayer-row-holder').append(col);
3828 var col_id = pagelayer_onadd(col, false);
3829 var cEle = pagelayer_ele_by_id(col_id);
3830
3831 if(tag == 'pl_col'){
3832 cEle.click();
3833 return col_id;
3834 }
3835
3836 // Create element
3837 var ele = jQuery('<div pagelayer-tag="'+tag+'"></div>');
3838 cEle.find('.pagelayer-col-holder').append(ele);
3839 var id = pagelayer_onadd(ele);
3840
3841 // Ensure the column is not empty
3842 pagelayer_empty_col(cEle.find('.pagelayer-col-holder'));
3843
3844 return id;
3845
3846 }
3847
3848 // Handle Click
3849 add_area.on('click', function(e){
3850 e.stopPropagation();
3851 add_sc('pl_col');
3852 });
3853
3854 // Handle Click
3855 add_area.find('.pagelayer-add-section').on('click', function(e){
3856 e.stopPropagation();
3857 pagelayer_add_section_area();// Setup and show sections modal
3858 });
3859
3860 // Handle Drag over
3861 add_area.on('dragover', function(e){
3862 //console.log(e)
3863 add_area.addClass('pagelayer-add-widget-drag');
3864 });
3865
3866 // Handle Drag Leave
3867 add_area.on('dragleave', function(e){
3868 //console.log(e)
3869 add_area.removeClass('pagelayer-add-widget-drag');
3870 });
3871
3872 // Handle On Drop
3873 add_area.on('drop', function(e){
3874
3875 //console.log(e);
3876 //console.log(e.originalEvent.dataTransfer.getData('tag'));
3877 add_area.removeClass('pagelayer-add-widget-drag');
3878 jQuery('.pagelayer-is-dragging').removeClass('pagelayer-is-dragging');
3879
3880 var tag = e.originalEvent.dataTransfer.getData('tag');
3881
3882 // Is it an existing element ?
3883 if(tag.length < 1){
3884 return false;
3885 }
3886
3887 e.preventDefault();
3888
3889 //console.log(tag);
3890
3891 add_sc(tag);
3892 });
3893 };
3894
3895 // Append section modal into body
3896 function pagelayer_add_section_area(){
3897
3898 var body = pagelayer.$$('body');
3899 var mEle = body.find('.pagelayer-add-section-modal-container');
3900
3901 if(mEle.length > 0){
3902 mEle.show();
3903 return;
3904 }
3905
3906 var section_modal = '<div class="pagelayer-add-section-modal-container">'+
3907 '<div class="pagelayer-add-section-modal-holder">'+
3908 '<div class="pagelayer-add-section-modal">'+
3909 '<div class="pagelayer-add-section-modal-header">'+
3910 '<i class="pagelayer-add-section-modal-close">&times;</i>'+
3911 '<span>Add Sections</span>'+
3912 '</div>'+
3913 '<div class="pagelayer-add-section-modal-body">'+
3914 '</div>'+
3915 '<div class="pagelayer-add-section-modal-overlay" style="display:none;">'+
3916 '<div class="pagelayer-section-wait">'+
3917 '<i class="fa fa-spinner fa-spin"></i><br/><span>Please wait a moment</span>'+
3918 '</div>'+
3919 '</div>'+
3920 '</div>'+
3921 '</div>'+
3922 '</div>';
3923
3924 mEle = jQuery(section_modal);
3925
3926 // Append the element in the body
3927 body.append(mEle);
3928
3929 // On click close modal
3930 mEle.find('.pagelayer-add-section-modal-close').on('click', function(){
3931 mEle.hide();
3932 });
3933
3934 // Append the list items into modal body
3935 pagelayer_add_sections_list_setup();
3936
3937 mEle.show();// Show the modal
3938
3939 };
3940
3941 // Append section list into modal body
3942 function pagelayer_add_sections_list_setup(type){
3943
3944 var mEle = pagelayer.$$('.pagelayer-add-section-modal-container');
3945 var add_area = jQuery('.pagelayer-add-widget-area');
3946 type = type || 'section';
3947
3948 var default_content = '<div style="display:inline-block;position:absolute;top:0;left:0;right:0;text-align:center;"><h1>Coming Soon</h1>'+
3949 '<span>We will soon add some pre-defined '+type+' layouts which you can add to your post with just one click !</span>'+
3950 '</div>';
3951
3952 // Set coming soon
3953 mEle.find('.pagelayer-add-section-modal-body').html(default_content);
3954 return;
3955
3956 // Create list of items
3957 var pagelayer_section_list = function(){
3958
3959 var section_html = '';
3960 var data = pagelayer_add_section_data[type];
3961
3962 // Get data form pagelayer_add_section_data object to create list
3963 for(var section in data['list']){
3964
3965 var id = data['list'][section];
3966
3967 section_html += '<div class="pagelayer-section-item" pagelayer-add-section-id="'+ id +'">'+
3968 '<img src="'+ data['image_url'] + id +'.png" alt="Pagelayer code screenshot">'+
3969 '</div>';
3970
3971 }
3972
3973 // Create items list
3974 mEle.find('.pagelayer-add-section-modal-body').html(section_html);
3975 mEle.find('.pagelayer-section-item').unbind('click');
3976 mEle.find('.pagelayer-section-item').on('click', function(e){
3977 pagelayer_section_item_clickable(jQuery(this));
3978 });
3979
3980 };
3981
3982 // On click items
3983 var pagelayer_section_item_clickable = function(jEle){
3984
3985 var section_id = jEle.attr('pagelayer-add-section-id');
3986
3987 // IF section id not found
3988 if(pagelayer_empty(section_id)){
3989 return false;
3990 }
3991
3992 // Show the overlay
3993 mEle.find('.pagelayer-add-section-modal-overlay').show();
3994
3995 // Do shortcode the content
3996 jQuery.ajax({
3997 url: pagelayer_ajax_url+'&action=pagelayer_get_section_shortcodes&postID='+pagelayer_postID,
3998 type: 'POST',
3999 data: {
4000 'pagelayer_nonce': pagelayer_ajax_nonce,
4001 'pagelayer_section_id': section_id,
4002 'pagelayer-live': 1
4003 },
4004 success: function(data) {
4005
4006 var data = JSON.parse(data);
4007 var cEle = jQuery(data['code']);
4008
4009 // Add section before add widget area
4010 add_area.before(cEle);
4011
4012 // We need to it setup
4013 cEle.each(function(){
4014 var pl_id = pagelayer_id(jQuery(this));
4015
4016 if(!pagelayer_empty(pl_id)){
4017 pagelayer_element_setup('[pagelayer-id="'+pl_id+'"], [pagelayer-id='+pl_id+'] .pagelayer-ele', true);
4018 }
4019 });
4020
4021 },
4022 complete: function(){
4023 mEle.find('.pagelayer-add-section-modal-overlay').hide();
4024 mEle.hide();
4025 }
4026 });
4027 }
4028
4029 // Load the data if not there
4030 if(!(type in pagelayer_add_section_data)){
4031
4032 // Get the sections list data and append it
4033 jQuery.ajax({
4034 url: pagelayer_api_url+'/library.php?give='+type,
4035 type: 'post',
4036 success: function(response){
4037 var tmp = JSON.parse(response);
4038
4039 // Is the list there ?
4040 if( !('list' in tmp && !pagelayer_empty(tmp['list'])) ){
4041 return;
4042 }
4043
4044 pagelayer_add_section_data[type] = tmp;
4045
4046 // Create the Type
4047 pagelayer_section_list(type);
4048
4049 }
4050 });
4051
4052 // We have the data, so show it
4053 }else{
4054 pagelayer_section_list(type);
4055 }
4056 }
4057
4058 // On editable area image paste handler
4059 function pagelayer_editable_paste_handler(pasteEvent, pagelayer_ajax_func){
4060
4061 try {
4062 var items = (pasteEvent.originalEvent || pasteEvent).clipboardData.items,
4063 mustPreventDefault = false,
4064 reader;
4065
4066 for (var i = items.length - 1; i >= 0; i -= 1) {
4067
4068 if (items[i].type.match(/^image\//)) {
4069
4070 reader = new FileReader();
4071 /* jshint -W083 */
4072 reader.onloadend = function (event) {
4073
4074 var src = event.target.result;
4075
4076 if( src.indexOf('data:image') === 0 ) {
4077
4078 var block = src.split(";");
4079 var contentType = block[0].split(":")[1];
4080 var realData = block[1].split(",")[1];
4081 var fileName = "image."+contentType.split("/")[1];
4082
4083 // Convert it to a blob to upload
4084 var blob = pagelayer_b64toBlob(realData, contentType);
4085
4086 var formData = new FormData();
4087 formData.append('action', 'upload-attachment');
4088 formData.append('_ajax_nonce', pagelayer_media_ajax_nonce);
4089 formData.append('async-upload', blob, fileName);
4090
4091 $.ajax({
4092 url:pagelayer_ajax_url,
4093 data: formData,// the formData function is available in almost all new browsers.
4094 type:"post",
4095 contentType:false,
4096 processData:false,
4097 cache:false,
4098 beforeSend: function( xhr ) {
4099 if(typeof pagelayer_ajax_func.beforeSend == 'function'){
4100 pagelayer_ajax_func.beforeSend(xhr);
4101 }
4102 },
4103 error:function(err){
4104 //console.error(err);
4105 alert("Unable to upload image for some reason.");
4106 },
4107 success:function(response){
4108 var obj = jQuery.parseJSON(response);
4109 if(typeof pagelayer_ajax_func.success == 'function'){
4110 pagelayer_ajax_func.success(obj);
4111 }
4112 },
4113 complete:function(xhr){
4114 if(typeof pagelayer_ajax_func.complete == 'function'){
4115 pagelayer_ajax_func.complete(xhr);
4116 }
4117 }
4118 });
4119
4120 }
4121
4122 };
4123 /* jshint +W083 */
4124 reader.readAsDataURL(items[i].getAsFile());
4125 mustPreventDefault = true;
4126 }
4127 }
4128
4129 if(mustPreventDefault){
4130 pasteEvent.stopPropagation();
4131 pasteEvent.preventDefault();
4132 }
4133
4134 }catch(err){}
4135
4136 return mustPreventDefault;
4137
4138 }
4139
4140 // Convert base64 to Blob
4141 function pagelayer_b64toBlob(b64Data, contentType, sliceSize) {
4142 contentType = contentType || '';
4143 sliceSize = sliceSize || 512;
4144
4145 var byteCharacters = atob(b64Data);
4146 var byteArrays = [];
4147
4148 for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
4149 var slice = byteCharacters.slice(offset, offset + sliceSize);
4150
4151 var byteNumbers = new Array(slice.length);
4152 for (var i = 0; i < slice.length; i++) {
4153 byteNumbers[i] = slice.charCodeAt(i);
4154 }
4155
4156 var byteArray = new Uint8Array(byteNumbers);
4157
4158 byteArrays.push(byteArray);
4159 }
4160
4161 var blob = new Blob(byteArrays, {type: contentType});
4162 return blob;
4163 }
4164
4165 // Function to check if the URL is external
4166 function pagelayer_parse_theme_vars(img_url){
4167
4168 for(x in pagelayer_theme_vars){
4169 img_url = img_url.replace(x, pagelayer_theme_vars[x]);
4170 }
4171
4172 return img_url;
4173 };
4174
4175 // Tooltip Setup for Editor
4176 function pagelayer_tooltip_setup(){
4177 //pagelayer.$$('[data-tlite]').each(function(){pagelayer_tlite.show(jQuery(this).get(0));});return;
4178 pagelayer.$$('[data-tlite]').on('hover', function(){
4179 pagelayer_tlite.show(jQuery(this).get(0));
4180 }).on('mouseleave', function(){
4181 pagelayer_tlite.hide(jQuery(this).get(0));
4182 });
4183
4184 }
4185