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

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