PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 0.9.8
Page Builder: Pagelayer – Drag and Drop website builder v0.9.8
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 0.9.8, at js/pagelayer-editor.js

3,212 lines 80.3 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
20 // Lets start
21 jQuery(document).ready(function(){
22
23 pagelayer.blank_img = pagelayer_url+'/images/default-image.png';
24
25 pagelayer_shortcodes['pl_inner_row'] = JSON.parse(JSON.stringify(pagelayer_shortcodes['pl_row']));
26 pagelayer_shortcodes['pl_inner_row']['name'] = 'Inner Row';
27 pagelayer_groups['grid'].push('pl_inner_row');
28
29 // Make the Topbar
30 pagelayer_bottombar();
31
32 // Make the Leftbar
33 pagelayer_leftbar();
34
35 // Add widget section
36 pagelayer_add_widget();
37
38 // Setup the ELPD
39 pagelayer_elpd_setup();
40
41 // Setup the properties of the elements
42 pagelayer_element_setup();
43
44 // An image to show for drag
45 jQuery('body').append('<img src="'+pagelayer_url+'/images/drag-ghost.png" class="pagelayer-drag-show" />');
46
47 // Setup the grid drag
48 pagelayer_setup_drag();
49
50 // Set to desktop
51 pagelayer_set_screen_mode('desktop');
52
53 // Set up right click
54 pagelayer_left_click();
55 pagelayer_right_click();
56
57 // Setup pagelayer history
58 pagelayer_history_obj['action_data'] = [];
59 pagelayer_history_setup(true);
60
61 });
62
63 // The jQuery Object of the ELPD
64 var pagelayer_elpd;
65
66 function pagelayer_closest_corner(jEle){
67 var corners = [];
68 var w = jEle.outerWidth();
69 var h = jEle.outerHeight();
70 var topleft = jEle.offset();
71
72 // 0 - Top Left
73 corners.push(topleft);
74
75 // 1 - Top Right
76 corners.push({top: topleft.top, left: topleft.left+w});
77
78 // 2 - Bottom Right
79 corners.push({top: topleft.top+h, left: topleft.left+w});
80
81 // 3 - Bottom Left
82 corners.push({top: topleft.top+h, left: topleft.left});
83
84 //console.log(corners);
85
86 // Calculate the closest to the mouse
87 var distances = {};
88 for(var c in corners){
89 var dist = Math.hypot(pagelayer.mouse.x - corners[c].left, pagelayer.mouse.y - corners[c].top);
90 distances[c] = dist;
91 }
92 //console.log(distances);
93
94 var corner = Object.keys(distances).sort(function(a,b){return distances[a]-distances[b]})[0];
95 //console.log(corner);
96
97 return corner;
98
99 };
100
101 // Make rows and cols draggable
102 function pagelayer_setup_drag(){
103
104 // The object to show as drag
105 var shower = jQuery('.pagelayer-drag-show');
106
107 // Delete any prospect
108 var clear_prospect = function(){
109 jQuery('.pagelayer-drag-prospect').remove();
110
111 // Shows the wrap as active
112 jQuery('.pagelayer-drag-ele-hover').removeClass('pagelayer-drag-ele-hover');
113 }
114
115 // Reset the complete drag stuff
116 var reset_dragging = function(){
117 pagelayer.dragging = false;
118 pagelayer.drag_is_new = false;
119 pagelayer.drag_mouse = {x: 0, y: 0};
120 reset_on_drag();
121 }
122
123 // Reset the element on you were last
124 var reset_on_drag = function(){
125 pagelayer.drag_closest = false;
126 pagelayer.drag_closest_corner = null;
127 }
128
129 // Scroll by
130 var scrollPx = 7;
131 var scrollDist = 30;
132
133 // If we are too close too the window edge, then scroll
134 var handle_scroll = function(e){
135
136 var windowHeight = jQuery(window).height();
137 var windowWidth = jQuery(window).width();
138
139 // Are we to close to the top or bottom
140 if(e.clientY < scrollDist){
141 window.scrollBy(0, -scrollPx);
142 }else if((windowHeight - e.clientY) < scrollDist){
143 window.scrollBy(0, scrollPx);
144 }
145
146 // Are we to close to the top or bottom
147 if(e.clientX < scrollDist){
148 window.scrollBy(-scrollPx, 0);
149 }else if((windowWidth - e.clientX) < scrollDist){
150 window.scrollBy(scrollPx, 0);
151 }
152
153 }
154
155 // SET the values
156 reset_dragging();
157
158 var ondragover = function(e) {
159 //console.log(e);
160
161 pagelayer.mouse.x = parseInt(e.pageX);
162 pagelayer.mouse.y = parseInt(e.pageY);
163 //console.log(pagelayer.mouse);
164
165 // Are we dragging ?
166 if(pagelayer.dragging){
167
168 //console.log(e);
169
170 e.preventDefault();
171 //e.stopPropagation();
172
173 // The wrap of the element being dragged
174 var wrap = pagelayer.dragging;
175
176 // New addition
177 var is_new = pagelayer.drag_is_new;
178 var ele;
179 var tag = pagelayer_tag(wrap);
180 var id = pagelayer_id(wrap);
181
182 // If existing element then add we are dragging
183 if(!is_new){
184
185 // Start Dragging
186 if(!wrap.hasClass('pagelayer-is-dragging')){
187 wrap.addClass('pagelayer-is-dragging');
188 }
189
190 //shower.hide();
191
192 ele = document.elementFromPoint(e.clientX, e.clientY);
193 //console.log(ele);
194
195 // Drag the show object
196 //shower.show();
197 //var offset = {top: (e.pageY-10)+'px', left: (e.pageX-10)+'px'}
198 //shower.css(offset);
199
200 }else{
201 ele = document.elementFromPoint(e.clientX, e.clientY);
202 }
203 //console.log(e);
204
205 // Have we moved more than 5px;
206 var dist = Math.hypot(pagelayer.mouse.x - pagelayer.drag_mouse.x, pagelayer.mouse.y - pagelayer.drag_mouse.y);
207 //console.log(dist);
208 /*if(dist && dist < 5){
209 return false;
210 }*/
211
212 // Handle the scroll
213 handle_scroll(e);
214
215 // Find the closest wrap
216 var onWrap;
217
218 // If we are a column, we can be over another column or row
219 if(tag == 'pl_col'){
220 onWrap = jQuery(ele).closest('.pagelayer-wrap-col,.pagelayer-wrap-row,.pagelayer-wrap-inner-row');
221 //console.log(pagelayer_id(onWrap));
222
223 // If we are a row, we can be over another row or a column
224 }else if(tag == 'pl_row'){
225 onWrap = jQuery(ele).closest('.pagelayer-wrap-row');
226 //console.log(pagelayer_id(onWrap));
227
228 // For inner row we restrict to 1 level only
229 }else if(tag == 'pl_inner_row'){
230 var ele_wrap = jQuery(ele).parents('.pagelayer-wrap-col');
231 if(ele_wrap.length == 1 && !jQuery(ele).hasClass('pagelayer-wrap-col')){
232 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-col,.pagelayer-wrap-inner-row');
233 }else{
234 onWrap = jQuery(ele).closest('.pagelayer-wrap-inner-row');
235 }
236 // For every other element, we can be over a col or ele
237 }else{
238 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-col,.pagelayer-wrap-inner-row');
239 }
240 //console.log(onWrap);
241
242 // If we find nothing
243 if(pagelayer_empty(onWrap) || onWrap.length < 1){
244 clear_prospect();// Clear existing prospects
245 reset_on_drag();// Also reset the last on item
246 return false;
247 }
248
249 // Get the ID
250 var onId = onWrap.attr('pagelayer-wrap-id');
251 var onEle = onWrap.children('.pagelayer-ele');
252
253 // Do we have a parent ?
254 var pOnId = pagelayer_get_parent(onEle);
255
256 if(pOnId){
257 onId = pOnId;
258 onEle = pagelayer_ele_by_id(onId);
259 onWrap = pagelayer_wrap_by_id(onId);
260 }
261
262 var changed = false;
263
264 // Was it the same ID like the one we were on before
265 if(pagelayer.drag_closest != onId){
266 pagelayer.drag_closest = onId;
267 changed = true;
268 }
269 //console.log(onId+' '+pagelayer.drag_closest)
270
271 var req_corners = {0: 'top', 1: 'top', 2: 'bottom', 3: 'bottom'};
272
273 // For columns we redefine the top and bottom
274 if(tag == 'pl_col'){
275 req_corners[1] = 'bottom';
276 req_corners[3] = 'top';
277 }
278
279 // Determine the previous and next
280 var next = wrap.next('.pagelayer-ele-wrap');
281 var prev = wrap.prev('.pagelayer-ele-wrap');
282
283 if(next.length == 1 && pagelayer_id(next) == onId){
284 req_corners = {0: 'bottom', 1: 'bottom', 2: 'bottom', 3: 'bottom'};
285 }
286
287 if(prev.length == 1 && pagelayer_id(prev) == onId){
288 req_corners = {0: 'top', 1: 'top', 2: 'top', 3: 'top'};
289 }
290
291 // Which corner are we closest to ?
292 var corner_num = pagelayer_closest_corner(onWrap);
293 var corner = req_corners[corner_num];
294
295 //console.log(corner+' != '+pagelayer.drag_closest_corner)
296 if(corner != pagelayer.drag_closest_corner){
297 pagelayer.drag_closest_corner = corner;
298 changed = true;
299 }
300
301 //console.log(changed);
302
303 // If we are on our self then clear return false
304 if(onId == id){
305 clear_prospect();// Clear existing prospects
306 reset_on_drag();// Also reset the last on item
307 return false;
308 }
309
310 // Then lets start showing
311 if(changed){
312
313 // Record the mouse points
314 pagelayer.drag_mouse.x = parseInt(e.pageX);
315 pagelayer.drag_mouse.y = parseInt(e.pageY);
316
317 // Clear any existing prospect
318 clear_prospect();
319
320 // Add new prospect
321 var prospect = '<div class="pagelayer-drag-prospect" pagelayer-corner="'+corner+'"></div>';
322
323 if(corner == 'bottom'){
324 onWrap.append(prospect);
325 }else if(corner == 'top'){
326 onWrap.prepend(prospect);
327 }
328
329 prospect = jQuery('.pagelayer-drag-prospect')
330 var animate_props = {height: '5px'};
331
332 // For column add a special class
333 if(tag == 'pl_col'){
334 prospect.addClass('pagelayer-drag-prospect-col');
335 animate_props['width'] = '5px';
336
337 // Adjust the left and right
338 var css = {};
339 css[(corner == 'bottom' ? 'right' : 'left')] = '0px';
340 prospect.css(css);
341 }
342
343 // Animate the prospect
344 prospect.animate(animate_props, 200);
345
346 // Highlight the wrap via overlay
347 onWrap.children('.pagelayer-ele-overlay').addClass('pagelayer-drag-ele-hover');
348
349 }
350
351 }
352 }
353
354 // When mouse is pressed down
355 var ondragstart = function(e){
356
357 //console.log(e);
358
359 // Target
360 var tEle = jQuery(e.target);
361 var wrap = tEle.closest('.pagelayer-ele-wrap');
362 //console.log(jEle[0]);
363
364 // Is it an existing element ?
365 if(wrap.length < 1){
366 return false;
367 }
368
369 // Do we have a parent ?
370 var id = pagelayer_id(wrap);
371 var jEle = pagelayer_ele_by_id(id);
372 var pId = pagelayer_get_parent(jEle);
373
374 if(pId){
375 wrap = pagelayer_wrap_by_id(pId);
376 }
377
378 //e.preventDefault();
379
380 var tag = pagelayer_tag(wrap);
381
382 e.originalEvent.dataTransfer.setData('Text', 1);
383 var img = document.createElement('img');
384 img.src = shower.attr('src');
385 e.originalEvent.dataTransfer.setDragImage(img, 32, 32);
386
387 pagelayer.dragging = wrap;
388
389 }
390
391 // When mouse is pressed down
392 var ondrop = function(e){
393
394 //console.log(e);
395
396 // Stop dragging ?
397 if(pagelayer.dragging){
398
399 e.preventDefault();
400
401 var wrap = pagelayer.dragging;
402 var tag = pagelayer_tag(wrap);
403 var fromEl = wrap.parent();
404 var id;
405 wrap.removeClass('pagelayer-is-dragging');
406
407 // Find any prospect
408 var prospect = jQuery('.pagelayer-drag-prospect');
409 //console.log(prospect[0]);
410
411 // It should be exactly 1
412 if(prospect.length == 1){
413
414 var onWrap = prospect.parent();
415 var onId = pagelayer_id(onWrap);
416 var onTag = pagelayer_tag(onWrap);
417 var dropped;
418 var corner = prospect.attr('pagelayer-corner');
419 var method = (corner == 'top') ? 'before' : 'after';
420
421 // Create the element if it needs to be created
422 if(pagelayer.drag_is_new){
423 dropped = jQuery('<div pagelayer-tag="'+tag+'"></div>');
424
425 // Move the object
426 }else{
427 dropped = wrap;
428 dropped.detach();
429 }
430
431 // If I am a column or row, then I go only before or after my same type !
432 if((onTag == 'pl_col' || onTag == 'pl_row') && onTag == tag){
433
434 // If I am a column and I am on a row
435 // OR I am a normal element and I am on column
436 }else if((tag == 'pl_col' && (onTag == 'pl_row' || onTag == 'pl_inner_row')) || onTag == 'pl_col'){
437 // We need to find the holder and add the prospect there
438 var holder = pagelayer_shortcodes[onTag]['holder'];
439 onWrap = onWrap.children('.pagelayer-ele').children(holder);
440 method = (corner == 'top') ? 'prepend' : 'append';
441 }
442
443 // Attach or shift the element
444 onWrap[method](dropped);
445 //console.log(dropped);
446
447 // Trigger the onadd
448 if(pagelayer.drag_is_new){
449 id = pagelayer_onadd(dropped);
450
451 // Existing elements
452 }else{
453 id = pagelayer_id(wrap);
454 }
455
456 // Defining the variables as needed
457 var jEle = pagelayer_ele_by_id(id);
458 wrap = pagelayer_wrap_by_id(id);
459 var toEl = wrap.parent();
460
461 // Column number handle
462 if(tag == 'pl_col'){
463
464 var row_holder = jEle.parent().closest('.pagelayer-row-holder');
465
466 // Renumber the col where you are going
467 pagelayer_renumber_col(row_holder);
468
469 // Renumber the old columns as well
470 if(!pagelayer.drag_is_new){
471 var from_row = fromEl.closest('.pagelayer-row-holder');
472 pagelayer_renumber_col(from_row);
473 }
474 }
475
476 // Handle the empty col
477 if(tag != 'pl_col'){
478
479 pagelayer_empty_col(toEl.closest('.pagelayer-col-holder'));
480
481 if(!pagelayer.drag_is_new){
482 pagelayer_empty_col(fromEl.closest('.pagelayer-col-holder'));
483 }
484
485 }
486
487 }
488
489 // Clear prospect
490 clear_prospect();
491 }
492
493 reset_dragging();
494
495 }
496
497 // Add the events for inner content - as we are using the drag API
498 jQuery(document).on('dragstart', ondragstart);
499 jQuery(document).on('dragover', ondragover);
500 jQuery(document).on('drop', ondrop);
501
502 // For addition of new elements
503 pagelayer.$$('[pagelayer-tag]').on('dragstart', function(e){
504 //console.log(e);
505
506 var tEle = jQuery(e.target);
507 var jEle = tEle.closest('.pagelayer-shortcode-drag');
508
509 // Is it an existing element ?
510 if(jEle.length < 1){
511 return false;
512 }
513
514 e.originalEvent.dataTransfer.setData('tag', pagelayer_tag(jEle));
515
516 pagelayer.dragging = jEle;
517 pagelayer.drag_is_new = true;
518
519 });
520
521 };
522
523 // Handle empty col
524 // selector should be col holder
525 function pagelayer_empty_col(selector){
526
527 // Loop through
528 jQuery(selector).each(function(){
529
530 var jEle = jQuery(this);// jEle is the COL HOLDER
531
532 // Are we a col ?
533 if(!jEle.hasClass('pagelayer-col-holder')){
534 return;
535 }
536
537 // Column is becoming blank, so show add ele
538 if(jEle.children().length < 1){
539 //from.addClass('pagelayer-empty-col');
540 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>');
541 //var h = jEle.parent().parent().children('.pagelayer-ele-overlay').height();
542 //jEle.children('.pagelayer-add-ele').height(h);
543
544 // Any add ele sign with non-empty columns here ?
545 }else if(jEle.children('.pagelayer-add-ele').length > 0){
546 jEle.children('.pagelayer-add-ele').remove();
547 }
548
549 });
550
551 };
552
553 // Reset the column widths
554 // The selector should be a ROW HOLDER
555 function pagelayer_renumber_col(selector){
556
557 var pEle = jQuery(selector);
558 var children = pEle.children('.pagelayer-ele-wrap');
559 var cols = Math.floor(12 / (children.length));
560 var obj = {col: cols};
561
562 // Find out the number of cols of other cols
563 children.each(function(){
564
565 // This is the wrapper
566 var jEle = jQuery(this);
567
568 // The real element
569 var Ele = jEle.find('>.pagelayer-ele');
570
571 for(var x=1; x<=12; x++){
572 if(jEle.hasClass('pagelayer-col-'+x)){
573 jEle.removeClass('pagelayer-col-'+x);
574 Ele.removeClass('pagelayer-col-'+x);
575 break;
576 }
577 }
578 jEle.addClass('pagelayer-col-'+cols);
579 Ele.addClass('pagelayer-col-'+cols);
580
581 // Set the att
582 pagelayer_set_atts(Ele, obj);
583 });
584 }
585
586 // Handle addition of elements from the left
587 // NOTE : At this point the addition is FINALIZED
588 // The add element cannot be prevented !
589 function pagelayer_onadd(jEle, toClick){
590
591 toClick = arguments.length == 2 ? toClick : true;
592
593 //console.log(jEle);
594 var id = pagelayer_element_added(jEle);
595 var jEle = jQuery("[pagelayer-id="+id+"]");
596
597 if(toClick){
598 //console.log('here');
599 jEle.click();
600 }
601
602 return id;
603
604 };
605
606 // Add an element into the POST
607 function pagelayer_element_added(jEle){
608
609 var sc = jEle.attr('pagelayer-tag');
610 var id, par_id;
611
612 // Set Pagelayer History FALSE to prevent saving attributes in action history
613 pagelayer.history_action = false;
614
615 // Generate the HTML
616 html = pagelayer_create_sc(sc);
617 id = pagelayer_assign_id(html);
618 par_id = id;
619
620 // Insert the HTML
621 jEle[0].outerHTML = html[0].outerHTML;
622
623 // Setup the properties of the elements
624 pagelayer_element_setup("[pagelayer-id="+par_id+"], [pagelayer-id="+par_id+"] .pagelayer-ele", true);
625
626 // Any children to add ?
627 if(!('widget' in pagelayer_shortcodes[sc])){
628
629 // The element props
630 var props = pagelayer_shortcodes[sc];
631
632 // Do we have to create children ?
633 if('has_group' in props){
634
635 var has_group = props['has_group'];
636 var gProp = props[has_group['section']][has_group['prop']];
637
638 for(var i=0; i < gProp['count']; i++){
639 var cid = pagelayer_element_add_child(jQuery("[pagelayer-id="+id+"]"), gProp['sc']);
640 //pagelayer_element_setup('[pagelayer-id='+cid+']', true);
641 }
642
643 }
644
645 }
646
647 // Save in action history
648 var cEle = pagelayer_near_by_ele(id, sc);
649
650 pagelayer_history_action_push({
651 'title' : pagelayer_shortcodes[sc]['name'],
652 'action' : 'Added',
653 'pl_id' : id,
654 'html' : html[0].outerHTML,
655 'cEle' : cEle
656 });
657
658 // Set pagelayer history TRUE
659 pagelayer.history_action = true;
660
661 return id;
662
663 };
664
665 // Add an element
666 function pagelayer_element_add_child(pEle, sc){
667 var child = pagelayer_create_sc(sc);
668 var cid = pagelayer_assign_id(child);
669 pagelayer_set_parent(child, pagelayer_assign_id(pEle));
670
671 // Does the parent have a holder ?
672 var tag = pagelayer_tag(pEle);
673
674 // There is a holder
675 if('holder' in pagelayer_shortcodes[tag]){
676
677 pEle.find(pagelayer_shortcodes[tag]['holder']).append(child);
678
679 // No holder, just append
680 }else{
681 pEle.append(child);
682 }
683
684 pagelayer_element_setup('[pagelayer-id='+cid+']', true);
685
686 // Do we have to create children ?
687 if('has_group' in pagelayer_shortcodes[sc]){
688
689 var has_group = pagelayer_shortcodes[sc]['has_group'];
690 var gProp = pagelayer_shortcodes[sc][has_group['section']][has_group['prop']];
691
692 for(var i=0; i < gProp['count']; i++){
693 var in_cid = pagelayer_element_add_child(jQuery("[pagelayer-id="+cid+"]"), gProp['sc']);
694 }
695
696 }
697
698 return cid;
699 };
700
701 // Return an element by ID
702 function pagelayer_ele_by_id(id){
703 return jQuery('[pagelayer-id='+id+']');
704 };
705
706 // Return the wrap by ID
707 function pagelayer_wrap_by_id(id){
708 return jQuery('[pagelayer-wrap-id='+id+']');
709 };
710
711 // Give the Pagelayer ID
712 function pagelayer_id(jEle){
713
714 var id = jEle.attr('pagelayer-wrap-id');
715 if(id){
716 return id;
717 }
718
719 id = jEle.attr('pagelayer-id');
720
721 return id;
722
723 }
724
725 // Assign the jQuery object an ID
726 function pagelayer_assign_id(jEle){
727
728 // Do you have the pagelayer id
729 var id = jEle.attr("pagelayer-id");
730 if(!id || id.length < 1){
731 id = pagelayer_randstr(16);
732 jEle.attr("pagelayer-id", id);
733 }
734
735 return id;
736
737 }
738
739 // Show the edit options
740 function pagelayer_element_clicked(selector, e){
741
742 var jEle = jQuery(selector);
743 e = e || false;
744
745 // You must be a element atleast
746 if(!jEle.hasClass('pagelayer-ele')){
747 return false;
748 }
749
750 // Get the parent
751 var pId = pagelayer_get_parent(jEle);
752
753 // If we found a parent
754 if(pId){
755 jEle = pagelayer_ele_by_id(pId);
756 }
757
758 // Lets not rebuild everything to make it faster
759 if(pagelayer_is_active(jEle)){
760 return false;
761 }
762
763 // Make the editable fields active
764 pagelayer_clear_editable();// First clear
765 jEle.find('[pagelayer-editable]').each(function (){
766 pagelayer_make_editable(jQuery(this), e);
767 });
768
769 // Set this as the active element
770 pagelayer_set_active(jEle);
771
772 // Show the properties
773 pagelayer_elpd_open(jEle);
774
775 }
776
777 // The edit option
778 function pagelayer_edit_element(selector){
779 pagelayer_element_clicked(selector);
780 }
781
782 // Setup the properties on a single click
783 function pagelayer_element_setup(selector, render){
784
785 var selector = selector || ".pagelayer-ele";
786 render = render || false;
787
788 // Loop through
789 jQuery(pagelayer_editable+' '+selector).each(function(){
790
791 var jEle = jQuery(this);
792
793 // Assign an ID if not there
794 var id = pagelayer_assign_id(jEle);
795 var pId = pagelayer_get_parent(jEle) || '';// Options to show on hover
796 var selector = '[pagelayer-id='+id+']';
797
798 if(render){
799 pagelayer_sc_render(jEle);
800 }
801
802 // Get the tag
803 var tag = pagelayer_tag(jEle);
804
805 // Lets check if we are the child of a parent i.e. element of a group
806 if(pagelayer_empty(pId)){
807
808 // Get the parent
809 var pEle = jEle.parent().closest('.pagelayer-ele');
810
811 // If we found a parent
812 if(pEle.length > 0){
813
814 var pTag = pagelayer_tag(pEle);
815
816 // Is the parent a group of this child ?
817 if(!pagelayer_empty(pagelayer_shortcodes[pTag]) && pagelayer_is_group(pTag)){
818
819 var has_group = pagelayer_shortcodes[pTag]['has_group'];
820 var child_type = pagelayer_shortcodes[pTag][has_group['section']][has_group['prop']]['sc'];
821
822 // If the type is the same as jEle
823 if(child_type == pagelayer_tag(jEle)){
824 pId = pagelayer_assign_id(pEle);
825 pagelayer_set_parent(jEle, pId);
826 }
827 }
828
829 }
830
831 }
832
833 // Make the wraps
834 jEle.wrap('<div class="pagelayer-ele-wrap" pagelayer-wrap-id="'+id+'"></div>');
835 var wrap = jEle.parent();
836
837 // For column we have to do some kidas !
838 if(tag == 'pl_col'){
839
840 var col;
841 for(var x=1; x<=12; x++){
842 if(jEle.hasClass('pagelayer-col-'+x)){
843 col = 'pagelayer-col-'+x;
844 break;
845 }
846 }
847
848 var is_custom_width = pagelayer_get_att(jEle, 'col');
849 var col_width = pagelayer_get_att(jEle, 'col_width');
850 if(pagelayer_empty(is_custom_width) && col_width){
851 wrap.css('width', col_width+'%');
852 }
853
854 wrap.addClass('pagelayer-col '+col);
855 //jEle.removeClass('pagelayer-col '+col);
856 wrap.addClass('pagelayer-wrap-col');
857
858 }else if(tag == 'pl_row'){
859 wrap.addClass('pagelayer-wrap-row');
860 }else if(tag == 'pl_inner_row'){
861 wrap.addClass('pagelayer-wrap-inner-row');
862 }else{
863 wrap.addClass('pagelayer-wrap-ele');
864 }
865
866 // Create the overlay
867 wrap.prepend('<div class="pagelayer-ele-overlay"></div>');
868
869 var overlay = wrap.children('.pagelayer-ele-overlay');
870 var html;
871
872 if(tag == 'pl_row' || tag == 'pl_inner_row'){
873
874 overlay.addClass('pagelayer-row-hover');
875
876 if(jEle.hasClass('pagelayer-row-stretch-full')){
877 pagelayer_sc_render(jEle);
878 }
879
880 html = '<div class="pagelayer-row-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
881 '<i class="fa fa-clone pagelayer-eoi" onclick="pagelayer_copy_element(\''+selector+'\')" />'+
882 '<i class="fa fa-trash pagelayer-eoi" onclick="pagelayer_delete_element(\''+selector+'\')" />'+
883 '<i class="fa fa-pencil pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
884 '</div>';
885
886 }else if(tag == 'pl_col'){
887
888 overlay.addClass('pagelayer-col-hover');
889
890 html = '<div class="pagelayer-col-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
891 '<i class="fa fa-columns pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
892 '</div>';
893
894 // Is it an empty col ?
895 pagelayer_empty_col(jEle.children('.pagelayer-col-holder'));
896
897 }else{
898
899 html = '<div class="pagelayer-ele-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
900 '<i class="fa fa-clone pagelayer-eoi" onclick="pagelayer_copy_element(\''+selector+'\')" />'+
901 '<i class="fa fa-trash pagelayer-eoi" onclick="pagelayer_delete_element(\''+selector+'\')" />'+
902 '<i class="fa fa-pencil pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
903 '</div>';
904
905 }
906
907 // Append to the child
908 overlay.append(html);
909 jQuery('[pagelayer-option-id='+id+']').hide();
910
911 // Setup the HOVER events ABD create WRAPS IF we dont have a parent
912 if(pId.length > 0){
913 return;
914 }
915
916 // Make the wrap draggable, but only of independent or parent elements
917 wrap.attr('draggable', 'true');
918
919 wrap.hover(function(){
920
921 // Is there an element option shower ?
922 var opts = jQuery('[pagelayer-option-id='+id+']');
923
924 // Give the overlay the hover class
925 opts.parent().addClass('pagelayer-ele-hover');
926
927 // Show them
928 opts.show();
929
930 }, function(){
931
932 // Is there an element option shower ?
933 var opts = jQuery('[pagelayer-option-id='+id+']');
934
935 // Remove hover class
936 opts.parent().removeClass('pagelayer-ele-hover');
937
938 // Hide opts
939 opts.hide();
940
941 });
942
943 });
944 }
945
946 // Left Click
947 function pagelayer_left_click(){
948
949 jQuery(pagelayer_editable).on('click', function(e){
950
951 e.preventDefault();// Added by Jivan in Actions / Revisions version
952
953 // Hide the context menu
954 jQuery('.pagelayer-right-click-options').hide();
955
956 // Target
957 var tEle = jQuery(e.target);
958
959 // If its an edit option click
960 if(tEle.hasClass('pagelayer-eoi')){
961 return false;
962 }
963
964 pagelayer_element_clicked(tEle.closest('.pagelayer-ele'), e);
965
966 return false;
967
968 });
969 };
970
971 // Right Click Menu
972 function pagelayer_right_click(){
973
974 var html = '<div class="pagelayer-right-click-options" style="display:none;">'+
975 '<ul>'+
976 '<li><a class="pagelayer-right-edit">Edit</a></li>'+
977 '<li><a class="pagelayer-right-duplicate"><i class="fa fa-clone" /> Duplicate</a></li>'+
978 '<li><a class="pagelayer-right-copy"><i class="fa fa-files-o" /> Copy</a></li>'+
979 '<li><a class="pagelayer-right-paste"><i class="fa fa-clipboard" /> Paste</a></li>'+
980 '<li><a class="pagelayer-right-delete"><i class="fa fa-trash-o" /> Delete</a></li>'+
981 '</ul>'+
982 '</div>';
983
984 jQuery('body').append(html);
985
986 var $contextMenu = jQuery('.pagelayer-right-click-options');
987
988 jQuery(pagelayer_editable).on('contextmenu', function(e){
989
990 var tEle = jQuery(e.target);
991 var jEle = tEle.closest('.pagelayer-ele-wrap').children('.pagelayer-ele');
992
993 // Get the parent
994 var pId = pagelayer_get_parent(jEle);
995
996 // If we found a parent
997 if(pId){
998 jEle = pagelayer_ele_by_id(pId);
999 }
1000
1001 // The basics
1002 var id = pagelayer_assign_id(jEle);
1003 var tag = pagelayer_tag(jEle);
1004
1005 $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']);
1006 $contextMenu.find('.pagelayer-right-duplicate').attr('onclick', 'pagelayer_copy_element("[pagelayer-id='+id+']")');
1007 $contextMenu.find('.pagelayer-right-copy').attr('onclick', 'pagelayer_copy_select("[pagelayer-id='+id+']")');
1008 $contextMenu.find('.pagelayer-right-paste').attr('onclick', 'pagelayer_paste_element("[pagelayer-id='+id+']")');
1009 $contextMenu.find('.pagelayer-right-delete').attr('onclick', 'pagelayer_delete_element("[pagelayer-id='+id+']")');
1010
1011 // Are we to hide the paste ?
1012 if(!pagelayer_empty(pagelayer.copy_selected) && pagelayer_can_copy_to(jEle)){
1013 //console.log(pagelayer_can_copy_to(jEle));
1014 $contextMenu.find('.pagelayer-right-paste').parent().show();
1015 }else{
1016 $contextMenu.find('.pagelayer-right-paste').parent().hide();
1017 }
1018
1019 $contextMenu.css({
1020 display: "block",
1021 left: e.pageX,
1022 top: e.pageY
1023 });
1024
1025 return false;
1026
1027 });
1028
1029 jQuery('html').on('click', function(e){
1030 $contextMenu.hide();
1031 });
1032 }
1033
1034 // Set the parent for the group
1035 function pagelayer_set_parent(jEle, id){
1036 jEle.attr('pagelayer-parent', id);
1037 };
1038
1039 // Set the parent for the group
1040 function pagelayer_get_parent(jEle){
1041 return jEle.attr('pagelayer-parent');
1042 };
1043
1044 // Sets the screen mode
1045 function pagelayer_set_screen_mode(mode){
1046 var modes = ['desktop', 'tablet', 'mobile'];
1047 var body = pagelayer.$$('.pagelayer-iframe-holder iframe');
1048 var current = '';
1049
1050 for(var x in modes){
1051
1052 if(body.hasClass('pagelayer-screen-'+modes[x]) && modes[x] != mode){
1053 current = modes[x];
1054 body.removeClass('pagelayer-screen-'+modes[x]);
1055 }
1056 }
1057
1058 // Add the class
1059 body.addClass('pagelayer-screen-'+mode);
1060
1061 // Add the class to the button
1062 pagelayer.$$('.pagelayer-mode-button').removeClass('fa-'+current).addClass('fa-'+mode);
1063
1064 // Add the class to the button
1065 pagelayer.$$('.pagelayer-prop-screen').removeClass('fa-'+current).addClass('fa-'+mode);
1066
1067 // Trigger screen change if any
1068 pagelayer.$$('.pagelayer-elp-screen').trigger('pagelayer-screen-changed');
1069
1070 };
1071
1072 // Get the current screen mode
1073 function pagelayer_get_screen_mode(){
1074 var modes = ['desktop', 'tablet', 'mobile'];
1075 var body = pagelayer.$$('.pagelayer-iframe-holder iframe');
1076
1077 for(var x in modes){
1078 if(body.hasClass('pagelayer-screen-'+modes[x])){
1079 return modes[x];
1080 }
1081 }
1082 }
1083
1084 // Handle key press events
1085 jQuery(document).keydown(function(event){
1086 //alert(String.fromCharCode(event.which));
1087
1088 // Delete
1089 if(event.keyCode == 46){
1090 pagelayer_delete_element('[pagelayer-active]');
1091 }
1092
1093 // ctrl+z handle
1094 if(event.keyCode == 90 && event.ctrlKey){
1095 pagelayer_do_history('undo');
1096 }
1097
1098 // ctrl+y handle
1099 if(event.keyCode == 89 && event.ctrlKey){
1100 pagelayer_do_history('redo');
1101 }
1102
1103 // ctrl+c handle
1104 if(event.keyCode == 67 && event.ctrlKey){
1105
1106 // Check the active element
1107 if(pagelayer_active.el && pagelayer_active.el.id){
1108 pagelayer_copy_select("[pagelayer-id='"+pagelayer_active.el.id+"']");
1109 }
1110
1111 }
1112
1113 // ctrl+v handle
1114 if(event.keyCode == 86 && event.ctrlKey){
1115
1116 // Check the active element
1117 if(pagelayer_active.el && pagelayer_active.el.id){
1118
1119 var jEle = jQuery("[pagelayer-id='"+pagelayer_active.el.id+"']");
1120
1121 // Check if the any element is copied
1122 if(!pagelayer_empty(pagelayer.copy_selected) && pagelayer_can_copy_to(jEle)){
1123 pagelayer_paste_element("[pagelayer-id='"+pagelayer_active.el.id+"']");
1124 }
1125
1126 }
1127 }
1128 });
1129
1130 // Delete an element as per the selector
1131 function pagelayer_delete_element(selector){
1132 var jEle = jQuery(selector);
1133
1134 // Anything found ?
1135 if(jEle.length > 0){
1136
1137 var id = pagelayer_assign_id(jEle);
1138 var sc = pagelayer_tag(jEle);
1139
1140 // Is there a wrap
1141 var wrap = jQuery('[pagelayer-wrap-id="'+id+'"]');
1142
1143 var par = wrap.parent();
1144
1145 // Save this element in history action
1146 if(pagelayer.history_action){
1147 var cEle = pagelayer_near_by_ele(id, sc);
1148
1149 // To save in history, we need to save only element not the wraps as we call setup if we redo or undo
1150 jEle.find('style').remove();
1151 jEle.find('.pagelayer-ele-overlay').remove();
1152
1153 // Unwrap the wraps
1154 jEle.find('.pagelayer-ele').each(function (){
1155 var ele = jQuery(this);
1156 if(ele.parent().is('.pagelayer-ele-wrap')){
1157 ele.unwrap();
1158 }
1159 });
1160
1161 pagelayer_history_action_push({
1162 'title' : pagelayer_shortcodes[sc]['name'],
1163 'action' : 'Deleted',
1164 'pl_id' : id,
1165 'html' : jEle,
1166 'cEle' : cEle
1167 });
1168 }
1169
1170 wrap.remove();
1171
1172 pagelayer_empty_col(par);
1173
1174 if(pagelayer_active.el && pagelayer_active.el.id == id){
1175 pagelayer.$$('.pagelayer-elpd-close').click();
1176 }
1177
1178 }
1179
1180 pagelayer_isDirty = true;
1181 };
1182
1183 // Select an element
1184 function pagelayer_copy_select(selector){
1185 pagelayer.copy_selected = selector;
1186 }
1187
1188 function pagelayer_can_copy_to(to){
1189 var jEle = jQuery(pagelayer.copy_selected);
1190 var tEle = jQuery(to);
1191
1192 var eTag = pagelayer_tag(jEle);
1193 var tTag = pagelayer_tag(tEle);
1194 //console.log(eTag+' - '+tTag);
1195 // Final to
1196 var fTo;
1197
1198 // Selected element is a Row, can go only after a row
1199 if(eTag == 'pl_row'){
1200 fTo = tEle.closest('.pagelayer-ele.pagelayer-row');
1201 if(fTo.length != 1) return false;
1202 return fTo;
1203 }
1204
1205 // Selected element is a Column, can go only after a col
1206 if(eTag == 'pl_col'){
1207 fTo = tEle.closest('.pagelayer-ele.pagelayer-col');
1208 if(fTo.length != 1) return false;
1209 return fTo;
1210 }
1211
1212 // Is the TARGET a row or column when the selected item is a element
1213 if(tTag == 'pl_row' || tTag == 'pl_col'){
1214 return false;
1215 }
1216
1217 return tEle;
1218
1219 }
1220
1221 // Select an element
1222 function pagelayer_paste_element(to){
1223
1224 var fTo = pagelayer_can_copy_to(to);
1225
1226 // Is it a valid to
1227 if(!fTo){
1228 return false;
1229 }
1230
1231 pagelayer_copy_element(pagelayer.copy_selected, fTo);
1232 }
1233
1234 // Copy an element
1235 // Note : insertAfter should always be an pagelayer-ele
1236 function pagelayer_copy_element(selector, insertAfter){
1237 var src = jQuery(selector);
1238 var html = src[0].outerHTML;
1239 var tag = pagelayer_tag(src);
1240 insertAfter = insertAfter || src;
1241 insertAfter = insertAfter.parent();
1242
1243 var jEle = jQuery(html);
1244 jEle.removeAttr('pagelayer-id');
1245 jEle.find('[pagelayer-id]').removeAttr('pagelayer-id');
1246 jEle.find('[pagelayer-parent]').removeAttr('pagelayer-parent');// Remove the parent attribute as it will be reset during pagelayer_element_setup
1247 jEle.find('style').remove();
1248 jEle.find('.pagelayer-ele-overlay').remove();
1249
1250 // Unwrap the wraps
1251 jEle.find('.pagelayer-ele').each(function (){
1252 var ele = jQuery(this);
1253 if(ele.parent().is('.pagelayer-ele-wrap')){
1254 ele.unwrap();
1255 }
1256 });
1257
1258 // Give it an ID
1259 var id = pagelayer_assign_id(jEle);
1260
1261 jQuery(insertAfter).after(jEle);
1262
1263 pagelayer_element_setup('[pagelayer-id='+id+'], [pagelayer-id='+id+'] .pagelayer-ele', true);
1264
1265 // Save this element in history action
1266 if(pagelayer.history_action){
1267 var cEle = pagelayer_near_by_ele(id, tag);
1268 pagelayer_history_action_push({
1269 'title' : pagelayer_shortcodes[tag]['name'],
1270 'action' : 'Copied',
1271 'pl_id' : id,
1272 'html' : jEle,
1273 'cEle' : cEle
1274 });
1275 }
1276
1277 //If column then renumber columns
1278 if(tag == 'pl_col'){
1279 var row = src.parent().closest('.pagelayer-row');
1280 pagelayer_renumber_col(row);
1281 }
1282
1283 pagelayer_isDirty = true;
1284
1285 return id;
1286 };
1287
1288 // Language key
1289 function pagelayer_l(k){
1290 return k;
1291 }
1292
1293 // Set the given jELE as active
1294 function pagelayer_set_active(jEle){
1295
1296 // Make all other element as inactive
1297 jQuery('[pagelayer-active]').each(function(){
1298 var $j = jQuery(this);
1299 $j.removeAttr('pagelayer-active');
1300 });
1301
1302 jEle.attr('pagelayer-active', 1);
1303
1304 // Add and remove the class
1305 jQuery('.pagelayer-active').removeClass('pagelayer-active');
1306
1307 jEle.parent().children('.pagelayer-ele-overlay').addClass('pagelayer-active');
1308
1309 }
1310
1311 function pagelayer_sc(sc){
1312 return sc.replace('pl_', '');
1313 };
1314
1315 // Create a HTML dom element of the Short code
1316 // Return the jEle
1317 function pagelayer_create_sc(sc){
1318
1319 var html;
1320 var _sc = pagelayer_sc(sc);
1321 var func = window['pagelayer_sc_'+sc];
1322
1323 // Generate the HTML
1324 if(typeof func == 'function'){
1325 html = window['pagelayer_sc_'+sc]();
1326 }else{
1327 html = '<div '+pagelayer_sc_atts('pagelayer-'+_sc)+'></div>';
1328 }
1329
1330 html = jQuery(html);
1331
1332 // Add the tag
1333 html.attr('pagelayer-tag', sc);
1334
1335 // Give it an ID
1336 id = pagelayer_assign_id(html);
1337
1338 // Try to set the default values over 5 loops
1339 pagelayer_set_default_atts(html, 5);
1340
1341 return html;
1342
1343 };
1344
1345 // Returns a list of default attributes to set as per the current selection
1346 function pagelayer_set_default_atts(jEle, set){
1347
1348 set = set || 0;
1349 var hasSet = false;
1350
1351 for(var i = 1; i <= set;i++){
1352
1353 //console.log('[pagelayer_set_default_atts] Loop :'+i);
1354 //console.log(jEle);
1355
1356 // Get existing data
1357 var el = pagelayer_data(jEle, true);
1358
1359 // If it is the last loop and we are greater than 1
1360 if(i > 1 && i == set){
1361 console.log('[pagelayer_default_atts] Still vars to set. Please check your shortcode params !');
1362 }
1363
1364 // We are supposed to set !
1365 if('set' in el && !pagelayer_empty(el.set)){
1366 pagelayer_set_atts(jEle, el.set);
1367 hasSet = true;
1368 }else{
1369 break;
1370 }
1371 }
1372
1373 return hasSet;
1374 }
1375
1376 // Returns the tag
1377 function pagelayer_tag(jEle){
1378
1379 // It could be the wrap
1380 if(jEle.hasClass('pagelayer-ele-wrap')){
1381 return jEle.children('.pagelayer-ele').attr('pagelayer-tag');
1382 }
1383
1384 // It could be the row or col holder
1385 if(jEle.hasClass('pagelayer-row-holder') || jEle.hasClass('pagelayer-col-holder')){
1386 return jEle.parent().attr('pagelayer-tag');
1387 }
1388
1389 return jEle.attr('pagelayer-tag');
1390 }
1391
1392 // Gets a single attribute value
1393 function pagelayer_get_att(jEle, att){
1394 return jEle.attr('pagelayer-a-'+att);
1395 };
1396
1397 // Gets a single attribute value
1398 function pagelayer_get_tmp_att(jEle, att){
1399 return jEle.attr('pagelayer-tmp-'+att);
1400 };
1401
1402 // This function will just set atts and not do anything else
1403 // Atts can be string or object. If its string, then val is needed
1404 function pagelayer_set_atts(jEle, atts, val){
1405
1406 if(typeof atts == 'string'){
1407 var tmp = {};
1408 tmp[atts] = val;
1409 atts = tmp;
1410 }
1411
1412 if(typeof atts != 'object'){
1413 return false;
1414 }
1415
1416 var tag = pagelayer_tag(jEle);
1417 var trigger_onchange = 0;
1418
1419 if(pagelayer_empty(tag)){
1420 console.log('Set atts found no tag');
1421 console.log(jEle);
1422 return;
1423 }
1424
1425 // All props
1426 var all_props = pagelayer_shortcodes[tag];//console.log(tag);console.log(jEle);
1427 var trigger_props = {};
1428 var no_val = {};
1429 var defaults = {};
1430
1431 // Loop through all props
1432 for(var i in pagelayer_tabs){
1433
1434 var tab = pagelayer_tabs[i];
1435
1436 for(var section in all_props[tab]){
1437
1438 var props = section in pagelayer_shortcodes[tag] ? pagelayer_shortcodes[tag][section] : pagelayer_styles[section];
1439
1440 for(var x in props){
1441
1442 if('default' in props[x]){
1443 defaults[x] = 1;
1444 }
1445
1446 // Dont set any val, but we set temp value
1447 if('no_val' in props[x]){
1448 no_val[x] = 1;
1449 }
1450
1451 if('req' in props[x] || 'show' in props[x]){
1452 var show = 'req' in props[x] ? props[x]['req'] : props[x]['show'];
1453 for(var showParam in show){
1454 var val = show[showParam];
1455 var except = showParam.substr(0, 1) == '!' ? true : false;
1456 showParam = except ? showParam.substr(1) : showParam;
1457 trigger_props[showParam] = 1;
1458 }
1459
1460 }
1461
1462 }
1463
1464 }
1465
1466 }
1467
1468 for(var x in atts){
1469
1470 // Are we to trigger change
1471 if(x in trigger_props){
1472 trigger_onchange = 1;
1473 }
1474
1475 //console.log(x+'-'+atts[x]);
1476
1477 if(x in no_val){
1478 pagelayer_set_tmp_atts(jEle, x, atts[x]);
1479 continue;
1480 }
1481
1482 // Record History
1483 if(pagelayer.history_action){
1484 var attr_label = '';
1485 for(var section in all_props){
1486 for(var props in all_props[section]){
1487 if(props == x){
1488 attr_label = all_props[section][props]['label'];
1489 }
1490 }
1491
1492 }
1493
1494 var old_val = pagelayer_get_att(jEle, x) || '';
1495 pagelayer_history_action_push({
1496 'title' : all_props['name'],
1497 'subTitle' : attr_label,
1498 'action' : 'Edited',
1499 'attrType' : 'a_attr',
1500 'pl_id' : pagelayer_id(jEle),
1501 'atts' : x,
1502 'oldVal' : old_val,
1503 'newVal' : atts[x]
1504 });
1505 }
1506
1507 // Remove the attribute if its BLANK and there is no default for it
1508 // If there is a default, we set it to blank to keep record of the current val
1509 if(atts[x].length < 1){
1510
1511 // Dont remove the value as there is a default
1512 if(!(x in defaults)){
1513 jEle.removeAttr('pagelayer-a-'+x);
1514 // Otherwise blank it
1515 }else{
1516 jEle.attr('pagelayer-a-'+x, atts[x]);
1517 }
1518
1519 // Remove the tmp atts anyway
1520 var to_del = new Array();
1521 var regexp = new RegExp('pagelayer\-tmp\-'+x, 'gi');
1522
1523 jQuery.each(jEle[0].attributes, function(index, att){
1524 if(!att) return;
1525 if(att.name.match(regexp)){
1526 to_del.push(att.name);
1527 }
1528 });
1529
1530 //console.log(to_del);
1531 for(var n in to_del){
1532 jEle.removeAttr(to_del[n]);
1533 }
1534
1535 // Set the value
1536 }else{
1537 jEle.attr('pagelayer-a-'+x, atts[x]);
1538 }
1539
1540 // Are you the active element
1541 if(pagelayer_is_active(jEle)){
1542
1543 // TODO : Record Undo and Redo
1544
1545 }
1546
1547 }
1548
1549 // Trigger the change of the parameter and show the required properties
1550 if(trigger_onchange){
1551 pagelayer_elpd_show_rows();
1552 }
1553
1554 pagelayer_isDirty = true;
1555 };
1556
1557 // This function will just set atts and not do anything else
1558 // Atts can be string or object. If its string, then val is needed
1559 function pagelayer_set_tmp_atts(jEle, atts, val){
1560
1561 if(typeof atts == 'string'){
1562 var tmp = {};
1563 tmp[atts] = val;
1564 atts = tmp;
1565 }
1566
1567 if(typeof atts != 'object'){
1568 return false;
1569 }
1570
1571 for(var x in atts){
1572
1573 // Record history
1574 if(pagelayer.history_action){
1575
1576 var old_val = pagelayer_get_tmp_att(jEle, x) || '';
1577 pagelayer_history_action_push({
1578 'title' : pagelayer_shortcodes[pagelayer_tag(jEle)]['name'],
1579 'subTitle' : x,
1580 'action' : 'Edited',
1581 'attrType' : 'tmp_attr',
1582 'pl_id' : pagelayer_id(jEle),
1583 'atts' : x,
1584 'oldVal' : old_val,
1585 'newVal' : atts[x]
1586 });
1587
1588 }
1589
1590 jEle.attr('pagelayer-tmp-'+x, atts[x]);
1591 }
1592
1593 };
1594
1595 // Set the att and classes of an HTML which is not yet created
1596 function pagelayer_sc_atts(classes, atts){
1597
1598 if(typeof atts != 'object'){
1599 atts = new Object();
1600 }
1601
1602 var r = new Array();
1603
1604 for(var x in atts){
1605 r.push('pagelayer-a-'+x+'="'+atts[x]+'"');
1606 }
1607
1608 return 'class="'+classes+' pagelayer-ele" '+r.join(' ');
1609 }
1610
1611 // Is the jEle the active element ?
1612 function pagelayer_is_active(jEle){
1613
1614 // Is this the active Element ?
1615 if(pagelayer_empty(pagelayer_active.el) || jEle.attr('pagelayer-id') != pagelayer_active.el.id){
1616 return false;
1617 }
1618
1619 return true;
1620
1621 };
1622
1623 // Removes {{}} from the variable name
1624 function pagelayer_var(val){
1625 return val.substring(2, (val.length - 2));
1626 }
1627
1628 // Take care of the CSS
1629 function pagelayer_css_render(css, val, seperator){
1630 //console.log('CSS '+css+' | '+val);
1631
1632 // Seperator
1633 seperator = seperator || ',';
1634
1635 // Replace the val
1636 css = css.split('{{val}}').join(val);
1637
1638 // If there is an array
1639 if(css.match(/val\[\d/)){
1640 val = val.split(seperator);
1641 for(var i in val){
1642 css = css.split('{{val['+i+']}}').join(val[i]);
1643 }
1644 }
1645
1646 //console.log('Final CSS '+css);
1647
1648 return css;
1649
1650 };
1651
1652 // Replace the variables
1653 function pagelayer_parse_vars(str, el){
1654
1655 for(var x in el.tmp){
1656 str = str.split('{{{'+x+'}}}').join(el.tmp[x]);
1657 }
1658
1659 for(var x in el.atts){
1660 str = str.split('{{'+x+'}}').join(el.atts[x]);
1661 }
1662
1663 return str;
1664 };
1665
1666 // Render the Element
1667 function pagelayer_sc_render(jEle){
1668
1669 // We render only the active element
1670 if(!pagelayer_is_active(jEle)){
1671 //return false;
1672 }
1673
1674 // Handle the CSS part
1675 // Get the id, tag, atts, data, etc
1676 var el = pagelayer_data(jEle, true);
1677 var all_props = pagelayer_shortcodes[el.tag];
1678 var elCSS = {
1679 classes: [],
1680 remove_classes: [],
1681 attr: [],
1682 remove_attr: [],
1683 css: [],
1684 edit: [],
1685 sel: '[pagelayer-id="'+el.id+'"]'
1686 };
1687
1688 // Create a reference
1689 el.CSS = elCSS;
1690
1691 //console.log(el.atts);
1692
1693 for(var i in pagelayer_tabs){
1694 var tab = pagelayer_tabs[i];
1695 for(var section in all_props[tab]){ //console.log(tab+' '+section);
1696
1697 var props = section in pagelayer_shortcodes[el.tag] ? pagelayer_shortcodes[el.tag][section] : pagelayer_styles[section];//console.log(props);
1698
1699 // Loop the props
1700 for(var x in props){
1701
1702 // pagelayer_data will return attributes even if they are BLANK e.g. attr=""
1703 // Render doesnt consider BLANK values as values, and we are unsetting them now
1704 // If in any situation you need to consider blank values, please handle in the JS / PHP function of the Shortcode
1705 if(x in el.atts && el.atts[x].length < 1){
1706 delete el.atts[x];
1707 }
1708
1709 // Any editor ?
1710 if('edit' in props[x]){
1711 elCSS.edit.push({prop: x, sel: props[x]['edit']});
1712 }
1713
1714 // Do we have a addClass ?
1715 // We are checking before the element has a value so that we can add or remove the class
1716 if('addClass' in props[x]){
1717
1718 var addClasses;
1719
1720 // Convert the string to an array
1721 if(typeof props[x]['addClass'] === 'string'){
1722 addClasses = [props[x]['addClass']];
1723 }else{
1724 addClasses = props[x]['addClass'];
1725 }
1726
1727 for(var c in addClasses){
1728
1729 // The selector
1730 var tSel = jQuery.isNumeric(c) ? '' : c;
1731
1732 // If there is a VAL
1733 // NOTE : Only val is allowed when there is a list
1734 if(addClasses[c].match(/\{\{val\}\}/) && 'list' in props[x]){
1735
1736 for(var l in props[x]['list']){
1737
1738 var tmp = {'sel': tSel, 'val': addClasses[c].replace('{{val}}', l)};
1739
1740 if(el.atts[x] == l){
1741 elCSS['classes'].push(tmp);
1742 }else{
1743 elCSS['remove_classes'].push(tmp);
1744 }
1745
1746 }
1747
1748 }else{
1749
1750 var tmp = {'sel': tSel, 'val': addClasses[c]};
1751
1752 // If the value is there
1753 if(x in el.atts){
1754 elCSS['classes'].push(tmp);
1755 }else{
1756 elCSS['remove_classes'].push(tmp);
1757 }
1758
1759 }
1760 }
1761 }
1762
1763 // Do we have a addAttr ?
1764 // We are checking before the element has a value so that we can add or remove the attr
1765 if('addAttr' in props[x]){
1766
1767 var addAttr;
1768
1769 // Convert the string to an array
1770 if(typeof props[x]['addAttr'] === 'string'){
1771 addAttr = [props[x]['addAttr']];
1772 }else{
1773 addAttr = props[x]['addAttr'];
1774 }
1775
1776 for(var c in addAttr){
1777
1778 // The selector
1779 var tSel = jQuery.isNumeric(c) ? '' : c;
1780 var tmp = {'sel': tSel, 'val': addAttr[c]};
1781
1782 // If the value is there
1783 if(x in el.atts){
1784 elCSS['attr'].push(tmp);
1785 }else{
1786 elCSS['remove_attr'].push(tmp);
1787 }
1788 }
1789 }
1790
1791 // Do we have a CSS ?
1792 if('css' in props[x]){
1793
1794 var css;
1795
1796 // Convert the string to an array
1797 if(typeof props[x]['css'] === 'string'){
1798 css = [props[x]['css']];
1799 }else{
1800 css = props[x]['css'];
1801 }
1802
1803 // Screen modes
1804 var modes = {desktop: '', tablet: '_tablet', mobile: '_mobile'};
1805
1806 for(var m in modes){
1807
1808 var xm = x+modes[m];
1809
1810 // If the value is there
1811 if(!(xm in el.atts)){
1812 continue;
1813 }
1814
1815 for(var c in css){
1816
1817 // The selector
1818 var tSel = jQuery.isNumeric(c) ? '{{element}}' : c;
1819 var tmp = {
1820 sel: tSel,
1821 val: pagelayer_css_render(css[c], el.atts[xm], (props[x].sep || ',')),
1822 };
1823
1824 // Is this a tablet
1825 if(m == 'tablet'){
1826 tmp.sel = '@media (max-width: 768px) and (min-width: 361px){'+tmp.sel;
1827 tmp.val = tmp.val+'}';
1828 }
1829
1830 // Is this a mobile mode ?
1831 if(m == 'mobile'){
1832 tmp.sel = '@media (max-width: 360px){'+tmp.sel;
1833 tmp.val = tmp.val+'}';
1834 }
1835
1836 // Push to store
1837 elCSS.css.push(tmp);
1838 }
1839
1840 }
1841
1842 }
1843
1844 }
1845
1846 }
1847
1848 }
1849
1850 // If there is an HTML, then process it
1851 if('html' in pagelayer_shortcodes[el.tag]){
1852
1853 el.iHTML = jQuery('<div>'+pagelayer_shortcodes[el.tag]['html']+'</div>');
1854
1855 // Lets process the 'if-ext'
1856 el.iHTML.find('[if-ext]').each(function (){
1857 var $j = jQuery(this);
1858 var reqvar = pagelayer_var($j.attr('if-ext'));
1859 $j.removeAttr('if-ext');
1860
1861 // Is the element there ?
1862 if(!(reqvar in el.atts && !pagelayer_empty(el.atts[reqvar]))){
1863 //console.log('HERE');
1864 $j[0].outerHTML = $j.html();
1865 }
1866
1867 });
1868
1869 // Lets process the 'if'
1870 el.iHTML.find('[if]').each(function (){
1871 var $j = jQuery(this);
1872 var reqvar = pagelayer_var($j.attr('if'));
1873 $j.removeAttr('if');
1874
1875 // Is the element there ?
1876 if(!(reqvar in el.atts && !pagelayer_empty(el.atts[reqvar]))){
1877 //console.log('HERE');
1878 $j.remove();
1879 }
1880
1881 });
1882
1883 // Is there a function to render ?
1884 var fn = window['pagelayer_render_'+jEle.attr('pagelayer-tag')];
1885
1886 if(typeof fn == 'function'){
1887 fn(el);
1888 }
1889
1890 //console.log(el.atts);
1891
1892 // Parse the variables
1893 var new_html = pagelayer_parse_vars(el.iHTML.html(), el);
1894 el.iHTML.html(new_html);
1895
1896 // Do we have to wrap the innerHTML ?
1897 if('holder' in pagelayer_shortcodes[el.tag]){
1898
1899 var hSel = pagelayer_shortcodes[el.tag]['holder'];
1900 var holder = jEle.find(hSel).first();
1901
1902 // Detach the holder
1903 holder.detach();
1904
1905 // Add the new HTML
1906 el.$.html(el.iHTML.html());
1907
1908 // reAttach the children only
1909 el.$.find(hSel).html(holder.children());
1910
1911 // No holder
1912 }else{
1913
1914 //console.log(el.iHTML.html());
1915 el.$.html(el.iHTML.html());
1916
1917 }
1918
1919 // Rows, Cols and Groups
1920 }else{
1921
1922 // Is there a function to render ?
1923 var fn = window['pagelayer_sc_render_'+jEle.attr('pagelayer-tag')];
1924
1925 if(typeof fn == 'function'){
1926 fn(el);
1927 }
1928
1929 }
1930
1931 // Is there a function to render after HTML insertion but before CSS and attr ?
1932 var post = window['pagelayer_render_html_'+jEle.attr('pagelayer-tag')];
1933
1934 if(typeof post == 'function'){
1935 post(el);
1936 }
1937
1938 ////////////////////////////
1939 // Are there any edit fields ?
1940 ////////////////////////////
1941
1942 if(elCSS.edit.length > 0){
1943
1944 for(var c in elCSS.edit){
1945 var prop = elCSS.edit[c]['prop'];
1946 var tSel = elCSS.edit[c]['sel'];
1947 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1948 node.attr('pagelayer-editable', prop);
1949 }
1950
1951 }
1952
1953 ////////////////////////////
1954 // Are there any addClass ?
1955 ////////////////////////////
1956
1957 // If we have any classes to add
1958 if(elCSS.classes.length > 0){
1959 //console.log(elCSS.classes);
1960
1961 for(var c in elCSS.classes){
1962 var tSel = elCSS.classes[c]['sel'];
1963 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1964 if(!node.hasClass(elCSS.classes[c]['val'])){
1965 node.addClass(elCSS.classes[c]['val']);
1966 }
1967 }
1968 }
1969
1970 // If we have any classes to remove
1971 if(elCSS.remove_classes.length > 0){
1972 //console.log(elCSS.remove_classes);
1973
1974 for(var c in elCSS.remove_classes){
1975 var tSel = elCSS.remove_classes[c]['sel'];
1976 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1977 if(node.hasClass(elCSS.remove_classes[c]['val'])){
1978 node.removeClass(elCSS.remove_classes[c]['val']);
1979 }
1980 }
1981 }
1982
1983 ////////////////////////////
1984 // Are there any addAttr ?
1985 ////////////////////////////
1986
1987 // If we have any attributes to add
1988 if(elCSS.attr.length > 0){
1989 //console.log(elCSS.attr);
1990
1991 for(var c in elCSS.attr){
1992 var tSel = elCSS.attr[c]['sel'].replace('{{element}}', '');
1993 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1994 var att = elCSS.attr[c]['val'].split('=');
1995 att[1] = pagelayer_parse_vars(att[1], el);
1996 att[1] = pagelayer_trim(att[1], '"');
1997
1998 // Is it the same val ?
1999 if(!node.attr(att[0]) != att[1]){
2000 node.attr(att[0], att[1]);
2001 }
2002 }
2003 }
2004
2005 // If we have any attributes to add
2006 if(elCSS.remove_attr.length > 0){
2007 //console.log(elCSS.remove_attr);
2008
2009 for(var c in elCSS.remove_attr){
2010 var tSel = elCSS.remove_attr[c]['sel'].replace('{{element}}', '');
2011 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
2012 var att = elCSS.remove_attr[c]['val'].split('=');
2013
2014 if(node.is('['+att[0]+']')){
2015 node.removeAttr(att[0]);
2016 }
2017 }
2018 }
2019
2020 // The style element
2021 var style = pagelayer.$('[pagelayer-style-id='+el.id+']');
2022
2023 // If we have any RULES CSS, then handle it
2024 if(elCSS.css.length > 0){
2025
2026 // Did we find it ?
2027 if(style.length < 1){
2028 jEle.prepend('<style pagelayer-style-id="'+el.id+'"></style>');
2029 }
2030
2031 // Get it again
2032 style = pagelayer.$('[pagelayer-style-id='+el.id+']');
2033
2034 // Make the rules
2035 var rules = [];
2036
2037 // Loop
2038 for(var c in elCSS.css){
2039 var tSel = elCSS.css[c]['sel'].replace('{{element}}', elCSS.sel);
2040 var rule = pagelayer_parse_vars(elCSS.css[c]['val'], el);
2041 rules.push(tSel+'{'+rule+'}');
2042 }
2043
2044 // Set the style
2045 style.html(rules.join("\n"));
2046 //console.log(style);
2047 }else{
2048 style.remove();
2049 }
2050
2051 // Is there a function to render at the end ?
2052 var end = window['pagelayer_render_end_'+jEle.attr('pagelayer-tag')];
2053
2054 if(typeof end == 'function'){
2055 end(el);
2056 }
2057
2058 // If the element have any parent
2059 var par = pagelayer_get_parent(jEle);
2060 if(par){
2061 pagelayer_sc_render(pagelayer_ele_by_id(par));
2062 }
2063
2064 };
2065
2066 // Is the given tag a group
2067 function pagelayer_is_group(tag){
2068
2069 if('has_group' in pagelayer_shortcodes[tag] && !pagelayer_empty(pagelayer_shortcodes[tag]['has_group'])){
2070 return true;
2071 }
2072
2073 return false;
2074
2075 }
2076
2077 // Save the post
2078 function pagelayer_save(){
2079
2080 var post = pagelayer_generate_sc(pagelayer_editable);//alert(post);return;
2081 var pagelayerajaxurl = pagelayer_ajax_url+'&action=pagelayer_save_content&postID='+pagelayer_postID;
2082 jQuery.ajax({
2083 type: "POST",
2084 url: pagelayerajaxurl,
2085 data: {
2086 pagelayer_update_content : post,
2087 pagelayer_nonce: pagelayer_ajax_nonce
2088 },
2089 success: function(response, status, xhr){
2090 //alert(data);
2091 var obj = jQuery.parseJSON(response);
2092 //alert(obj);
2093 if(obj['error']){
2094 alert(obj['error']);
2095 }else{
2096 pagelayer_isDirty = false;
2097 alert(obj['success']);
2098 pagelayer_get_revision();
2099 }
2100 },
2101 error: function(errorThrown){
2102 console.log(errorThrown);
2103 }
2104 });
2105
2106 };
2107
2108 //Close the Editor
2109 function pagelayer_close(){
2110 if(pagelayer_isDirty == true){
2111 var r = confirm('Your Data has not been Saved yet! \n Press OK to stay on the Page.'+
2112 '\n Press Cancel to Close Editor. ');
2113 if(r == false){
2114 window.top.location.href = pagelayer_returnURL;
2115 }
2116 }else{
2117 window.top.location.href = pagelayer_returnURL;
2118 }
2119 };
2120
2121 // Generate Shortcode Post to save
2122 function pagelayer_generate_sc(selector){
2123
2124 var txt = '';
2125
2126 jQuery(selector).children(".pagelayer-ele-wrap").each(function(){
2127
2128 var jEle = jQuery(this).children('.pagelayer-ele');
2129
2130 // The ID
2131 var id = jEle.attr('pagelayer-id');
2132
2133 // If there is an Add element wrapper
2134 if(pagelayer_empty(id)){
2135 return;
2136 }
2137
2138 // Find the type of tag
2139 var tag = jEle.attr('pagelayer-tag');
2140 var final_tag = tag;
2141 var closestEle = jQuery(this).closest('.pagelayer-col-holder');
2142
2143 // Define inner row | Note : Commented as we now have a new widget of type inner_row
2144 /*if(tag == 'pl_row' && closestEle.length > 0 && closestEle.closest(pagelayer_editable).length > 0){
2145 final_tag = 'pl_inner_row';
2146 }*/
2147
2148 // Define inner column
2149 if(tag == 'pl_col' && closestEle.length > 0 && closestEle.closest(pagelayer_editable).length > 0){
2150 final_tag = 'pl_inner_col';
2151 }
2152 //console.log(tag);
2153
2154 // Is there an innerHTML ele
2155 var inner = '';
2156 if('innerHTML' in pagelayer_shortcodes[tag]){
2157 inner = pagelayer_shortcodes[tag]['innerHTML'];
2158 }
2159
2160 // Create the tag
2161 var data = '['+final_tag;
2162
2163 // Get the attributes to store
2164 jQuery.each(jEle[0].attributes, function(i, attrib){
2165 var res = attrib.name.match(/^pagelayer-a-(.+)/i);
2166 if(res && res[1] != inner){
2167 //console.log(attrib.name+' '+res[1]);
2168 data += ' '+res[1]+'="'+pagelayer_escapeHTML(attrib.value)+'"';
2169 }
2170 });
2171
2172 data = data+']';
2173
2174 // Add to the text
2175 txt = txt+data+"\n";
2176
2177 // Any internal function to handle the save ?
2178 var func = window['pagelayer_tag_'+tag];
2179 if(typeof func == 'function'){
2180
2181 var content = '';
2182 content = func(jEle);
2183
2184 if(content.length > 0){
2185 txt = txt+content;
2186 }
2187
2188 // If its a Row or Column or Group then it will have children
2189 }else if(jEle.hasClass('pagelayer-row') || jEle.hasClass('pagelayer-col') || jEle.hasClass('pagelayer-inner_row') || pagelayer_is_group(tag)){
2190
2191 var sel = "[pagelayer-id="+id+"]";
2192
2193 // Any holder which holds children ?
2194 if('holder' in pagelayer_shortcodes[tag]){
2195 sel = sel+' '+pagelayer_shortcodes[tag]['holder'];
2196 }
2197
2198 // Select the top-most element
2199 sel = jQuery(sel).first();
2200
2201 // Any child selector - Majorly for owl carousel
2202 // NOTE : Child selector should be very specific with immediate child selection at all levels
2203 var child_selector = false;
2204 if('child_selector' in pagelayer_shortcodes[tag]){
2205 sel = sel.find(pagelayer_shortcodes[tag]['child_selector']);
2206 }
2207
2208 var childrens = pagelayer_generate_sc(sel);
2209 if(childrens.length > 0){
2210 txt = txt+childrens;
2211 }
2212
2213 // Its a normal element so we might need to handle the content
2214 }else{
2215
2216 var content = '';
2217 if(inner.length > 0){
2218 content = jEle.attr('pagelayer-a-'+inner);
2219 if(!content){
2220 content = '';
2221 }
2222 }else{
2223 content = '';//jEle.html();
2224 }
2225
2226 if(content.length > 0){
2227 txt = txt+content;
2228 }
2229
2230 }
2231
2232 // Close the tag
2233 txt = txt+"[/"+final_tag+"]\n";
2234
2235 });
2236
2237 return txt;
2238
2239 };
2240
2241 // Escape charaters in attributes
2242 var pagelayer_escapeChars = {
2243 '\\]' : '#93',
2244 '\\[' : '#91',
2245 //'=' : '#61',
2246 '<' : 'lt',
2247 '>' : 'gt',
2248 '"' : 'quot',
2249 //'&' : 'amp',
2250 '\'' : '#39'
2251 };
2252
2253 // To unescape
2254 var pagelayer_unescapeChars = {
2255 '#93' : ']',
2256 '#91' : '[',
2257 //'#61' : '=',
2258 'lt' : '<',
2259 'gt' : '>',
2260 'quot' : '"',
2261 //'amp' : '&',
2262 '#39' : '\''
2263 };
2264
2265 var pagelayer_escaperegex_S = '[';
2266 for(var key in pagelayer_escapeChars) {
2267 pagelayer_escaperegex_S += key;
2268 }
2269 pagelayer_escaperegex_S += ']';
2270
2271 var pagelayer_escaperegex = new RegExp( pagelayer_escaperegex_S, 'g');
2272
2273 // The function which escapes everything
2274 function pagelayer_escapeHTML(str) {
2275 return str.replace(pagelayer_escaperegex, function(m) {
2276 if(m == '[' || m == ']') m = '\\'+m;
2277 return '&' + pagelayer_escapeChars[m] + ';';
2278 });
2279 };
2280
2281 // This will unescape everything
2282 function pagelayer_unescapeHTML(str){
2283 return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
2284 if(entityCode in pagelayer_unescapeChars){
2285 return pagelayer_unescapeChars[entityCode];
2286 }else{
2287 return entity;
2288 }
2289 });
2290 };
2291
2292 // Show the required leftbar tab
2293 function pagelayer_leftbar_tab(tab){
2294 pagelayer.$$('.pagelayer-leftbar-tab').hide();
2295 pagelayer.$$('#'+tab).show();
2296 }
2297
2298 // Sets up the leftbar
2299 function pagelayer_leftbar(){
2300
2301 // Toggle the holder
2302 pagelayer.$$('.pagelayer-leftbar-toggle').on('click', function(){
2303 pagelayer.$$('.pagelayer-leftbar-table').toggle();
2304 });
2305
2306 var html = '<div class="pagelayer-leftbar">'+
2307 '<div class="pagelayer-leftbar-scroll">'+
2308 '<div id="pagelayer-shortcodes" class="pagelayer-leftbar-tab pagelayer-shortcodes">'+
2309 '<div class="pagelayer-leftbar-search">'+
2310 '<i class="fa fa-search" /><input class="pagelayer-search-field" />'+
2311 '</div>';
2312
2313 for(var x in pagelayer_groups){
2314
2315 // Title
2316 html += '<div class="pagelayer-leftbar-group"><h5>'+x+'</h5>';
2317
2318 // Indivdual icon
2319 for(var y in pagelayer_groups[x]){
2320
2321 var sc = pagelayer_groups[x][y];
2322
2323 if(!(sc in pagelayer_shortcodes) || 'not_visible' in pagelayer_shortcodes[sc]){
2324 continue;
2325 }
2326
2327 html += '<div class="pagelayer-shortcode-drag" draggable="true" pagelayer-tag="'+sc+'">'+
2328 '<div class="pagelayer-sc">'+
2329 '<center class="pagelayer-shortcode-inner">';
2330
2331 if('icon' in pagelayer_shortcodes[sc]){
2332 html += '<i class="pagelayer-shortcode fa fa-'+pagelayer_shortcodes[sc]['icon']+'"></i>';
2333 }else{
2334 html += '<i class="pagelayer-shortcode pagelayer-'+sc+'"></i>';
2335 }
2336
2337 html += '</center>'+
2338 '<span class="pagelayer-shortcode-text">'+pagelayer_shortcodes[sc]['name']+'</span>'+
2339 '</div>'+
2340 '</div>';
2341
2342 }
2343
2344 html += '</div>';
2345
2346 }
2347
2348 html += '</div>'+
2349 '<div id="pagelayer-elpd" class="pagelayer-leftbar-tab pagelayer-elpd"></div>'+
2350 '<div id="pagelayer-history" class="pagelayer-leftbar-tab pagelayer-history"></div>'+
2351 '<div id="pagelayer-post-settings" class="pagelayer-leftbar-tab pagelayer-post-settings"></div>'+
2352 '</div>'+
2353 '</div>';
2354
2355 pagelayer.$$('.pagelayer-leftbar-holder').prepend(html);
2356 pagelayer_leftbar_tab('pagelayer-shortcodes');
2357
2358 pagelayer.$$('.pagelayer-leftbar-scroll').slimScroll({
2359 height: '100%',
2360 railVisible: false,
2361 alwaysVisible: true,
2362 color: '#000',
2363 size: '5px',
2364 });
2365
2366 // Hide the ones which are not supposed to be shown
2367 pagelayer.$$('.pagelayer-search-field').on('input', function(){
2368
2369 var val = jQuery(this).val();
2370 var re = new RegExp(val, 'i');
2371
2372 // Show only the required tags
2373 pagelayer.$$('.pagelayer-leftbar-group').each(function(){
2374
2375 var group = jQuery(this);
2376 var res = group.find('[pagelayer-tag]');
2377 var hidden = 0;
2378
2379 res.each(function(){
2380
2381 var tEle = jQuery(this);
2382 if(tEle.find('.pagelayer-shortcode-text').html().match(re)){
2383 tEle.show();
2384 }else{
2385 hidden += 1;
2386 tEle.hide();
2387 }
2388
2389 });
2390
2391 // Hide the whole group
2392 if(hidden == res.length){
2393 group.hide();
2394 }else{
2395 group.show();
2396 }
2397
2398 });
2399 });
2400
2401 // On click Pagelayer setting icon
2402 pagelayer.$$('.pagelayer-settings-icon').click(function(){
2403 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text('Post Settings');
2404 pagelayer.$$('.pagelayer-logo').hide();
2405 pagelayer_leftbar_tab('pagelayer-post-settings');
2406 pagelayer_active = {};
2407 pagelayer_post_settings();
2408 });
2409
2410 };
2411
2412 // Post setting holder
2413 function pagelayer_post_settings(){
2414
2415 // Start pagelayer settings holder
2416 var setting_holder = '<div class="pagelayer-post-settings-holder">';
2417
2418 // Start pagelayer settings content body
2419 setting_holder += '<div class="pagelayer-post-settings-acc">'+
2420 '<div class="pagelayer-post-settings-lable"><span>Title</span><i class="pagelayer-toggle fa"></i></div>'+
2421 '<div class="pagelayer-post-settings-fields">'+
2422 '<label for="post_title">Post Title</label> '+
2423 '<input type="text" name="post_title" value="'+ pagelayer_postTitle +'" id="title" spellcheck="true" autocomplete="off">'+
2424 '<button class="pagelayer-post-settings-apply pagelayer-success-btn" disabled>Apply</button>'+
2425 '</div>'+
2426 '</div>';
2427
2428 /*if(pagelayer_postType == pagelayer_cpt['name']){
2429 setting_holder += '<div class="pagelayer-post-settings-acc">'+
2430 '<div class="pagelayer-post-settings-lable"><span>Custom Template type</span><i class="pagelayer-toggle fa"></i></div>'+
2431 '<div class="pagelayer-post-settings-fields">'+ pagelayer_CPT_condi +
2432 '</div>'+
2433 '</div>';
2434 }*/
2435
2436 /* if(pagelayer_support_FI){
2437 setting_holder += '<div class="pagelayer-post-settings-acc">'+
2438 '<div class="pagelayer-post-settings-lable"><span>Featured Image</span><i class="pagelayer-toggle fa"></i></div>'+
2439 '<div class="pagelayer-post-settings-fields">Featured Image'+
2440 '</div>'+
2441 '</div>';
2442 } */
2443
2444 // End pagelayer settings content body
2445
2446 // End pagelayer settings holder
2447 setting_holder += '</div>';
2448 var holder = pagelayer.$$('#pagelayer-post-settings');
2449 holder.html(setting_holder);
2450
2451 // On change input fields enable the apply button
2452 holder.find('input, select, textarea').on('change input', function(){
2453 jQuery(this).closest('.pagelayer-post-settings-fields').find('.pagelayer-post-settings-apply').removeAttr('disabled');
2454 });
2455
2456 // On click the label toggle the setting field holder
2457 holder.find('.pagelayer-post-settings-lable').on('click', function(){
2458
2459 var lEle = jQuery(this);
2460 var lEle_next = lEle.next('.pagelayer-post-settings-fields');
2461
2462 holder.find('.pagelayer-post-settings-fields').each(function(){
2463 var fEle = jQuery(this);
2464 if(!fEle.is(lEle_next)){
2465 fEle.hide().prev('.pagelayer-post-settings-lable').find('.pagelayer-toggle').removeClass('pagelayer-open');
2466 }
2467 });
2468
2469 lEle.next('.pagelayer-post-settings-fields').toggle();
2470 lEle.find('.pagelayer-toggle').toggleClass('pagelayer-open');
2471
2472 });
2473
2474 // On click apply button
2475 holder.find('.pagelayer-post-settings-apply').click(function(){
2476 var fEle = jQuery(this).closest('.pagelayer-post-settings-fields');
2477 var data = fEle.find('input, select, textarea').serialize();
2478
2479 jQuery.ajax({
2480 url: pagelayer_ajax_url+'action=pagelayer_save_settings&postID='+pagelayer_postID,
2481 type: 'post',
2482 data : 'pagelayer_nonce='+ pagelayer_ajax_nonce +'&'+ data,
2483 success: function(response, status, xhr){
2484 //alert(data);
2485 var obj = jQuery.parseJSON(response);
2486 //alert(obj);
2487 if(obj['error']){
2488 alert(obj['error']);
2489 }else{
2490 alert(obj['success']);
2491 window.location.reload();
2492 }
2493 },
2494 error: function(errorThrown){
2495 console.log(errorThrown);
2496 }
2497 });
2498
2499 });
2500
2501 return;
2502 }
2503
2504 // Get the closest element and method
2505 function pagelayer_near_by_ele(id, sc){
2506
2507 // Get the previous element of the id element
2508 var prevEle_id = jQuery('[pagelayer-wrap-id="'+id+'"]').prev().attr('pagelayer-wrap-id') || '';
2509 var method, cEle, args = {};
2510
2511 if(prevEle_id.length > 0){
2512
2513 // If have previous element of the id element
2514 // Set the method and previous element selector
2515 args = {'method' : 'after', 'cEle' : '[pagelayer-wrap-id="'+prevEle_id+'"]'};
2516
2517 }else{
2518
2519 // If don't have previous element of the id element then get parent element
2520 if(sc == "pl_row"){
2521 args = {'method' : 'prepend', 'cEle' : pagelayer_editable};
2522 }else{
2523
2524 // Get the parent element
2525 var pEle_id = pagelayer_id(jQuery('[pagelayer-wrap-id="'+id+'"]').closest('.pagelayer-ele'));
2526
2527 // Get the parent element tag
2528 var pEle_tag = pagelayer_tag(jQuery('[pagelayer-id="'+pEle_id+'"]'));
2529 var holder = pagelayer_shortcodes[pEle_tag]['holder'] || '';
2530 args = {'method' : 'prepend', 'cEle' : '[pagelayer-id="'+pEle_id+'"] '+ holder+' '};
2531
2532 }
2533
2534 }
2535
2536 return args;
2537
2538 };
2539
2540 // Push the action data in the pagelayer_history_obj object
2541 function pagelayer_history_action_push(args){
2542
2543 var history_obj_len = pagelayer_history_obj['action_data'].length;
2544
2545 // If the history_obj_len is less then 1 then set the data in array 0 position
2546 if(history_obj_len < 1){
2547 pagelayer_history_obj['action_data'][0] = {'title' : 'Start Editing', 'action' : 'Start' };
2548 pagelayer_history_obj['current_active_item_id'] = 0;
2549 }
2550
2551 // Remove the second array element if the history_obj_len greater then 100
2552 if(history_obj_len > 100){
2553 pagelayer_history_obj['action_data'].splice(1, 1);
2554 }
2555
2556 // Get current active history action id
2557 var action_id = parseInt(pagelayer_history_obj['current_active_item_id']) || 0;
2558
2559 // Remove the all array element after the active array element
2560 var del_ele = history_obj_len - action_id - 1;
2561 pagelayer_history_obj['action_data'].splice(action_id + 1, del_ele);
2562
2563 // Check if the same attr set as current active history
2564 if(args.action == "Edited" && history_obj_len > 1){
2565 var atts = pagelayer_history_obj['action_data'][action_id] || '';
2566 if(atts['atts'] == args['atts']){
2567 args['oldVal'] = atts['oldVal'];
2568 pagelayer_history_obj['action_data'][action_id] = args;
2569 pagelayer_history_setup();
2570 return true;
2571 }
2572 }
2573
2574 pagelayer_history_obj['action_data'].push(args);
2575 pagelayer_history_obj['current_active_item_id'] = pagelayer_history_obj['action_data'].length - 1;
2576 pagelayer_history_setup();
2577
2578 }
2579
2580 // Setup pagelayer history
2581 function pagelayer_history_setup(force){
2582
2583 var force = force || false;
2584
2585 // If the history tab is visible, only then setup
2586 if(!pagelayer.$$('#pagelayer-history').is(':visible') && !force){
2587 return;
2588 }
2589
2590 // The current active action id
2591 var current_id = pagelayer_history_obj['current_active_item_id'];
2592
2593 // pagelayer-HISTORY - Element Properties Dialog
2594 var pagelayer_history_html = '<div class="pagelayer-history-tabs">'+
2595 '<div class="pagelayer-history-tab" pagelayer-history-tab="actions" pagelayer-history-active-tab="1">Actions</div>'+
2596 '<div class="pagelayer-history-tab" pagelayer-history-tab="revisions">Revisions</div>'+
2597 '</div>'+
2598 '<div class="pagelayer-history-body">'+
2599 '<div class="pagelayer-history-section active" pagelayer-show-tab="actions">';
2600
2601 // Any actions
2602 if(pagelayer_history_obj['action_data'].length > 0){
2603
2604 for(var x in pagelayer_history_obj['action_data']){
2605
2606 if(pagelayer_empty(pagelayer_history_obj['action_data'][x])){continue;}
2607
2608 var title = pagelayer_history_obj['action_data'][x]['title'] || '';
2609 var subTitle = pagelayer_history_obj['action_data'][x]['subTitle'] || '';
2610 var action = pagelayer_history_obj['action_data'][x]['action'] || '';
2611 var tmp_attr = pagelayer_history_obj['action_data'][x]['attrType'] || '';
2612 var eAttr = '';
2613
2614 if(!pagelayer_empty(tmp_attr) && tmp_attr == "tmp_attr"){
2615 eAttr = "pagelayer-history-hidden";
2616 }
2617
2618 pagelayer_history_html += '<div class="pagelayer-history-holder '+((current_id == x) ? 'current_active_item' : '' )+' '+eAttr+'" history-action-id="'+x+'" >'+
2619 '<div class="pagelayer-history-detail-holder">'+
2620 '<span class="pagelayer-history-title"><b> '+title+' </b></span>'+
2621 '<span class="pagelayer-history-subtitle"> '+subTitle+' </span>'+
2622 '<span class="pagelayer-history-action"><i> '+action+' </i></span>'+
2623 '</div>'+
2624 '<div class="pagelayer-history-icon">'+
2625 '<span class="pagelayer-history-check fa fa-check" aria-hidden="true"></span>'+
2626 '</div>'+
2627 '</div>';
2628 }
2629
2630 }else{
2631 pagelayer_history_html += 'No Actions history available yet';
2632 }
2633
2634 pagelayer_history_html += '</div>'+
2635 '<div class="pagelayer-history-section" pagelayer-show-tab="revisions">';
2636
2637 // Any revisions ?
2638 if(pagelayer_revision_obj){
2639 for(var x in pagelayer_revision_obj){
2640 pagelayer_history_html += '<div class="pagelayer-revision-holder" revision-id="'+pagelayer_revision_obj[x]['ID']+'">'+
2641 '<div class="pagelayer-revision-img-holder">'+
2642 '<img src="'+pagelayer_revision_obj[x]['post_author_url']+'" />'+
2643 '</div>'+
2644 '<div class="pagelayer-revision-detail-holder">'+
2645 '<div class="pagelayer-revision-date">'+
2646 pagelayer_revision_obj[x]['post_date_ago']+
2647 '('+pagelayer_revision_obj[x]['post_date']+')'+
2648 '</div>'+
2649 '<div class="pagelayer-revision-author">'+
2650 pagelayer_revision_obj[x]['post_type'] +' by '+
2651 pagelayer_revision_obj[x]['post_author_name']+
2652 '</div>'+
2653 '</div>'+
2654 '<div class="pagelayer-revision-icon-holder">'+
2655 '<i class="pagelayer-revision-delete fa fa-times"></i>'+
2656 '</div>'+
2657 '</div>';
2658 }
2659
2660 }else{
2661 pagelayer_history_html += 'No Revisions history available';
2662 }
2663
2664 pagelayer_history_html += '</div>'+
2665 '</div>';
2666
2667 // Create the dialog box
2668 pagelayer.$$('#pagelayer-history').html(pagelayer_history_html);
2669 var holder = pagelayer.$$('#pagelayer-history');
2670
2671 // Set active history holder
2672 holder.find('.pagelayer-history-holder').on('click', function(){
2673 var hEle = jQuery(this);
2674 var prev_item_id = pagelayer_history_obj['current_active_item_id'];
2675 hEle.parent().children().removeClass('current_active_item');
2676 hEle.addClass('current_active_item');
2677 var do_item_id = parseInt(hEle.attr('history-action-id'));
2678 pagelayer_history_action_setup(do_item_id, prev_item_id);
2679 });
2680
2681 // Apply revision
2682 holder.find('.pagelayer-revision-holder').on('click', function(){
2683 var revision_id = jQuery(this).attr('revision-id');
2684
2685 jQuery.ajax({
2686 url: pagelayer_ajax_url+'&action=pagelayer_apply_revision&revisionID='+revision_id,
2687 type: 'post',
2688 data: {
2689 pagelayer_nonce: pagelayer_ajax_nonce,
2690 'pagelayer-live' : 1,
2691 },
2692 success: function(response, status, xhr){
2693
2694 var obj = jQuery.parseJSON(response);
2695 if(obj['error']){
2696 alert(obj['error']);
2697 }else{
2698 jQuery(pagelayer_editable).html(obj['content']);
2699 alert(obj['success']);
2700 pagelayer_element_setup();
2701 pagelayer_add_widget();
2702 }
2703 }
2704 });
2705 });
2706
2707 // Delete the revision
2708 holder.find('.pagelayer-revision-delete').click(function(e){
2709
2710 e.stopPropagation();
2711 var rEle = jQuery(this).closest('.pagelayer-revision-holder');
2712 var revision_id = rEle.attr('revision-id');
2713
2714 if(confirm("Are you sure you want to delete the revision ?")){
2715 jQuery.ajax({
2716 url: pagelayer_ajax_url+'&action=pagelayer_delete_revision&revisionID='+revision_id,
2717 type: 'post',
2718 data: {pagelayer_nonce: pagelayer_ajax_nonce},
2719 success: function(response, status, xhr){
2720
2721 var obj = jQuery.parseJSON(response);
2722 if(obj['error']){
2723 alert(obj['error']);
2724 }else{
2725 alert(obj['success']);
2726 rEle.hide();
2727 }
2728
2729 }
2730 });
2731 }
2732
2733 });
2734
2735 // The tabs
2736 holder.find('.pagelayer-history-tab').on('click', function(){
2737 var attr = 'pagelayer-history-active-tab';
2738 holder.find('.pagelayer-history-tab').each(function(){
2739 jQuery(this).removeAttr(attr);
2740 });
2741 jQuery(this).attr(attr, 1);
2742
2743 // Get the active tab
2744 var active_tab = holder.find('[pagelayer-history-active-tab]').attr('pagelayer-history-tab');
2745
2746 // Trigger the showing of rows
2747 holder.find('[pagelayer-show-tab]').each(function(){
2748 var sec = jQuery(this);
2749
2750 // Is it the active tab ?
2751 if(sec.attr('pagelayer-show-tab') != active_tab){
2752 sec.hide();
2753 }else{
2754 sec.show();
2755 }
2756 });
2757 });
2758 }
2759
2760 // Get evisions Handler
2761 function pagelayer_get_revision(){
2762
2763 jQuery.ajax({
2764 url: pagelayer_ajax_url+'&action=pagelayer_get_revision&postID='+pagelayer_postID,
2765 type: 'post',
2766 data: {
2767 pagelayer_nonce: pagelayer_ajax_nonce,
2768 },
2769 //async:false,
2770 success: function(response, status, xhr){
2771 var obj = jQuery.parseJSON(response);
2772
2773 if(!pagelayer_empty(obj['error'])){
2774 alert(obj['error']);
2775 }else{
2776 pagelayer_revision_obj = obj;
2777 pagelayer_history_setup(true);
2778 }
2779 }
2780 });
2781 };
2782
2783 // Do the history action - use for ctrl-z and ctrl-y
2784 function pagelayer_do_history(action){
2785
2786 var cur_id = pagelayer_history_obj['current_active_item_id'];
2787 var new_id = cur_id;
2788 var action_data_len = pagelayer_history_obj['action_data'].length;
2789
2790
2791 if(action == 'undo'){
2792
2793 // You cannot undo from the first movement
2794 if(cur_id == 0){
2795 return true;
2796 }
2797
2798 for(var i = (cur_id - 1); i => 0; i--){
2799
2800 var action = pagelayer_history_obj['action_data'][i];
2801
2802 if('attrType' in action && action['attrType'] == 'tmp_attr'){
2803 continue;
2804 }
2805
2806 new_id = i;
2807 break;
2808
2809 }
2810
2811 }else if(action == 'redo'){
2812 for(var i = cur_id + 1; i < action_data_len; i++){
2813
2814 var action = pagelayer_history_obj['action_data'][i];
2815
2816 if('attrType' in action && action['attrType'] == 'tmp_attr'){
2817 continue;
2818 }
2819
2820 new_id = i;
2821 break;
2822
2823 }
2824 }
2825
2826 // Do the action
2827 pagelayer_history_action_setup(new_id, cur_id);
2828 pagelayer_history_setup();
2829
2830 };
2831
2832 // Action setup handle on ctrl-z and ctrl-y
2833 function pagelayer_history_action_setup(current_item_id, prev_item_id){
2834
2835 // Set this as the current active
2836 pagelayer_history_obj['current_active_item_id'] = current_item_id;
2837
2838 // Delete the element
2839 var delete_ele = function(id){
2840
2841 // Set Pagelayer History FALSE to prevent saving delete action in action history
2842 pagelayer.history_action = false;
2843
2844 pagelayer_delete_element('[pagelayer-id='+id+']');
2845
2846 // Set Pagelayer History TRUE
2847 pagelayer.history_action = true;
2848
2849 };
2850
2851 // Re-setup the element
2852 var resetup_ele = function(history_array){
2853 jQuery(history_array.cEle.cEle)[history_array.cEle.method](history_array.html);
2854 pagelayer_element_setup('[pagelayer-id='+history_array.pl_id+'], [pagelayer-id='+history_array.pl_id+'] .pagelayer-ele', true);
2855 pagelayer_empty_col(jQuery('[pagelayer-id="'+history_array.pl_id+'"]').closest('.pagelayer-col-holder'));
2856 };
2857
2858 // Re-setup the element attr
2859 var reset_ele_attr = function(hEle, atts, val, attrType){
2860
2861 // Set Pagelayer History FALSE to prevent saving attributes in action history
2862 pagelayer.history_action = false;
2863 if(attrType == "tmp_attr"){
2864 pagelayer_set_tmp_atts(hEle, atts, val);
2865 }else{
2866 pagelayer_set_atts(hEle, atts, val);
2867 }
2868
2869 // The property holder
2870 var holder = pagelayer.$$('.pagelayer-elpd-body');
2871 holder.html(' ');
2872 pagelayer_sc_render(hEle);
2873 pagelayer_elpd_generate(hEle, holder);
2874 pagelayer.history_action = true;
2875
2876 };
2877
2878 if(prev_item_id > current_item_id){
2879
2880 // All Actions for undo here
2881 var i = parseInt(prev_item_id);
2882
2883 for(i; i > current_item_id; i--){
2884
2885 var history_array = pagelayer_history_obj['action_data'][i];
2886 var action = history_array.action;
2887 var id = history_array.pl_id;
2888
2889 if(action == "Edited"){
2890 hEle = jQuery('[pagelayer-id="'+id+'"]');
2891 reset_ele_attr(hEle, history_array.atts, history_array.oldVal, history_array.attrType);
2892 }else if(action == "Added"){
2893 delete_ele(id);
2894 }else if(action == "Deleted"){
2895 resetup_ele(history_array);
2896 }else if(action == "Copied"){
2897 delete_ele(id);
2898 }
2899
2900 }
2901
2902 }else{
2903
2904 // All Actions for redo here
2905 var i = parseInt(prev_item_id)+1;
2906
2907 for(i; i <= current_item_id; i++){
2908
2909 var history_array = pagelayer_history_obj['action_data'][i];
2910 var action = history_array.action;
2911 var id = history_array.pl_id;
2912
2913 if(action == "Edited"){
2914 hEle = jQuery('[pagelayer-id="'+id+'"]');
2915 reset_ele_attr(hEle, history_array.atts, history_array.newVal, history_array.attrType);
2916 }else if(action == "Added"){
2917 resetup_ele(history_array);
2918
2919 if(history_array.tag != "pl_row" && history_array.tag != "pl_col" ){
2920 // Ensure the column is not empty
2921 pagelayer_empty_col(history_array.cEle.cEle);
2922 }
2923 }else if(action == "Deleted"){
2924 delete_ele(id);
2925 }else if(action == "Copied"){
2926 resetup_ele(history_array);
2927 }
2928
2929 }
2930 }
2931
2932 };
2933
2934 // Report an error
2935 function pagelayer_error(error, func){
2936 var prefix = func || '';
2937 alert(prefix+error);
2938 };
2939
2940 function pagelayer_bottombar(){
2941 var holder = pagelayer.$$('.pagelayer-bottombar-holder');
2942 var html = '<div class="pagelayer-bottombar">'+
2943 '<div class="pagelayer-bottombar-rightbuttons">'+
2944 '<button class="pagelayer-update-button pagelayer-success-btn">Update</button>'+
2945 '<button class="pagelayer-close-button">Close</button>'+
2946 '<div class="pagelayer-mode-wrapper">'+
2947 '<i class="pagelayer-mode-button fa fa-desktop"></i>'+
2948 '<div class="pagelayer-mode-buttons-wrapper">'+
2949 '<i class="screen-mode fa fa-desktop" pagelayer-mode-data="desktop"></i>'+
2950 '<i class="screen-mode fa fa-tablet" pagelayer-mode-data="tablet"></i>'+
2951 '<i class="screen-mode fa fa-mobile" pagelayer-mode-data="mobile"></i>'+
2952 '</div>'+
2953 '</div>'+
2954 '<i class="pagelayer-history-icon fa fa-history"></i>'+
2955 '</div>'+
2956 '</div>';
2957
2958 holder.html(html);
2959 holder.find('.pagelayer-update-button').on('click', function(){
2960 pagelayer_save();
2961 pagelayer_history_setup();// Setup history tab after update
2962 });
2963
2964 holder.find('.pagelayer-close-button').on('click', function(){
2965 pagelayer_close();
2966 });
2967 holder.find('.screen-mode').on('click', function(){
2968 var screen_mode = jQuery(this).attr('pagelayer-mode-data');
2969 pagelayer_set_screen_mode(screen_mode);
2970 holder.find('.pagelayer-mode-buttons-wrapper').toggle();
2971 });
2972
2973 holder.find('.pagelayer-mode-button').on('click', function(){
2974 holder.find('.pagelayer-mode-buttons-wrapper').toggle();
2975 });
2976
2977 holder.find('.pagelayer-history-icon').click(function(){
2978 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text('Pagelayer History');
2979 pagelayer.$$('.pagelayer-logo').hide();
2980 pagelayer_leftbar_tab('pagelayer-history');
2981 pagelayer_active = {};
2982 pagelayer_history_setup();
2983 });
2984 };
2985
2986
2987 ///////////////////////////////
2988 // Miscellaneuos Functions
2989 ///////////////////////////////
2990
2991 // Generates a random string of "n" characters
2992 function pagelayer_randstr(n, special){
2993 var text = '';
2994 var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2995
2996 special = special || 0;
2997 if(special){
2998 possible = possible + '&#$%@';
2999 }
3000
3001 for(var i=0; i < n; i++){
3002 text += possible.charAt(Math.floor(Math.random() * possible.length));
3003 }
3004
3005 return text;
3006 };
3007
3008 function pagelayer_update_site_title(val){
3009 if(!pagelayer_empty(val)){
3010 var site_name = jQuery('.pagelayer-wp-title').attr('pagelayer-a-site_name');
3011 if(!pagelayer_empty(site_name)){
3012 var site_title = jQuery.ajax({
3013 url: pagelayer_ajax_url+'&action=pagelayer_fetch_site_title',
3014 type: 'post',
3015 async: false
3016 }).responseText;
3017
3018 if(site_title != site_name){
3019 var site_title = jQuery.ajax({
3020 url: pagelayer_ajax_url+'&action=pagelayer_update_site_title',
3021 type: 'post',
3022 data: {'site_title': site_name},
3023 async: false
3024 }).responseText;
3025 }
3026 }
3027 }
3028 }
3029
3030 function pagelayer_trim(str, charlist){
3031 // discuss at: http://locutus.io/php/trim/
3032
3033 if(typeof str != 'string'){
3034 return str;
3035 }
3036
3037 var whitespace = [' ', '\n', '\r', '\t', '\f', '\x0b', '\xa0', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u200b', '\u2028', '\u2029', '\u3000' ].join('')
3038 var l = 0
3039 var i = 0
3040 str += ''
3041
3042 if (charlist) {
3043 whitespace = (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1')
3044 }
3045
3046 l = str.length
3047 for (i = 0; i < l; i++) {
3048 if (whitespace.indexOf(str.charAt(i)) === -1) {
3049 str = str.substring(i)
3050 break
3051 }
3052 }
3053
3054 l = str.length
3055 for (i = l - 1; i >= 0; i--) {
3056 if (whitespace.indexOf(str.charAt(i)) === -1) {
3057 str = str.substring(0, i + 1)
3058 break
3059 }
3060 }
3061
3062 return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''
3063 };
3064
3065 // Convert the regular URL of a Video to a Embed URL
3066 function pagelayer_video_url(src){
3067
3068 var youtubeRegExp = /youtube\.com|youtu\.be/;
3069 var vimeoRegExp = /vimeo\.com/;
3070 var match = '';
3071 var videoId = '';
3072
3073 if (youtubeRegExp.exec(src)) {
3074 match = 'youtube';
3075 } else if (vimeoRegExp.exec(src)) {
3076 match = 'vimeo';
3077 }
3078
3079 switch(match){
3080 case 'youtube':
3081
3082 var youtubeRegExp1 = /youtube\.com/;
3083 var youtubewatch = /watch/;
3084 var youtubeembed = /embed/;
3085 var youtube = /youtu\.be/;
3086
3087 if (youtubeRegExp1.exec(src)) {
3088
3089 if (youtubewatch.exec(src)) {
3090 videoId = src.split('?v=');
3091
3092 } else if (youtubewatch.exec(src)) {
3093 videoId = src.split('embed/');
3094 }
3095
3096 } else if (youtube.exec(src)) {
3097 videoId = src.split('.be/');
3098 }
3099
3100 return '//youtube.com/embed/'+videoId[1];
3101
3102 break;
3103
3104 case 'vimeo':
3105
3106 var vimeoplayer = /player\.vimeo\.com/;
3107 var vimeovideo = /video/;
3108
3109 if (vimeoplayer.exec(src) && vimeovideo.exec(src)) {
3110 videoId = src.split('video/');
3111 } else if (vimeoRegExp.exec(src)) {
3112 videoId = src.split('.com/');
3113 }
3114
3115 return '//player.vimeo.com/video/'+videoId[1];
3116
3117 break;
3118 default:
3119 return src;
3120 }
3121 };
3122
3123 // Add widget section
3124 function pagelayer_add_widget(){
3125
3126 html='<div class="pagelayer-add-widget-area">'+
3127 '<i class="pagelayer-add-row fa fa-plus-circle"></i>'+
3128 '<p>Click here to add new row OR drag widgets</p>'+
3129 '</div>';
3130
3131 jQuery(pagelayer_editable).append(html);
3132
3133 var add_area = jQuery('.pagelayer-add-widget-area');
3134
3135 // Add a code before this
3136 var add_sc = function(tag){
3137
3138 // Create Row
3139 var row = jQuery('<div pagelayer-tag="pl_row"></div>');
3140 add_area.before(row);
3141 var row_id = pagelayer_onadd(row, false);
3142 var rEle = pagelayer_ele_by_id(row_id);
3143
3144 if(tag == 'pl_row'){
3145 rEle.click();
3146 return row_id;
3147 }
3148
3149 // Create Column
3150 var col = jQuery('<div pagelayer-tag="pl_col"></div>');
3151 rEle.find('.pagelayer-row-holder').append(col);
3152 var col_id = pagelayer_onadd(col, false);
3153 var cEle = pagelayer_ele_by_id(col_id);
3154
3155 if(tag == 'pl_col'){
3156 cEle.click();
3157 return col_id;
3158 }
3159
3160 // Create element
3161 var ele = jQuery('<div pagelayer-tag="'+tag+'"></div>');
3162 cEle.find('.pagelayer-col-holder').append(ele);
3163 var id = pagelayer_onadd(ele);
3164
3165 // Ensure the column is not empty
3166 pagelayer_empty_col(cEle.find('.pagelayer-col-holder'));
3167
3168 return id;
3169
3170 }
3171
3172 // Handle Click
3173 add_area.on('click', function(e){
3174 e.stopPropagation();
3175 add_sc('pl_col');
3176 });
3177
3178 // Handle Drag over
3179 add_area.on('dragover', function(e){
3180 //console.log(e)
3181 add_area.addClass('pagelayer-add-widget-drag');
3182 });
3183
3184 // Handle Drag Leave
3185 add_area.on('dragleave', function(e){
3186 //console.log(e)
3187 add_area.removeClass('pagelayer-add-widget-drag');
3188 });
3189
3190 // Handle On Drop
3191 add_area.on('drop', function(e){
3192
3193 //console.log(e);
3194 //console.log(e.originalEvent.dataTransfer.getData('tag'));
3195 add_area.removeClass('pagelayer-add-widget-drag');
3196 jQuery('.pagelayer-is-dragging').removeClass('pagelayer-is-dragging');
3197
3198 var tag = e.originalEvent.dataTransfer.getData('tag');
3199
3200 // Is it an existing element ?
3201 if(tag.length < 1){
3202 return false;
3203 }
3204
3205 e.preventDefault();
3206
3207 //console.log(tag);
3208
3209 add_sc(tag);
3210 });
3211 }
3212