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

2,498 lines 58.9 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 }
16
17 // Lets start
18 jQuery(document).ready(function(){
19
20 pagelayer_shortcodes['pl_inner_row'] = JSON.parse(JSON.stringify(pagelayer_shortcodes['pl_row']));
21 pagelayer_shortcodes['pl_inner_row']['name'] = 'Inner Row';
22 pagelayer_groups['grid'].push('pl_inner_row');
23
24 // Make the Topbar
25 pagelayer_bottombar();
26
27 // Make the Leftbar
28 pagelayer_leftbar();
29
30 // Add widget section
31 pagelayer_add_widget();
32
33 // Setup the ELPD
34 pagelayer_elpd_setup();
35
36 // Setup the properties of the elements
37 pagelayer_element_setup();
38
39 // An image to show for drag
40 jQuery('body').append('<img src="'+pagelayer_url+'/images/drag-ghost.png" class="pagelayer-drag-show" />');
41
42 // Setup the grid drag
43 pagelayer_setup_drag();
44
45 // Set to desktop
46 pagelayer_set_screen_mode('desktop');
47
48 // Set up right click
49 pagelayer_left_click();
50 pagelayer_right_click();
51
52 });
53
54 // The jQuery Object of the ELPD
55 var pagelayer_elpd;
56
57 function pagelayer_closest_corner(jEle){
58 var corners = [];
59 var w = jEle.outerWidth();
60 var h = jEle.outerHeight();
61 var topleft = jEle.offset();
62
63 // 0 - Top Left
64 corners.push(topleft);
65
66 // 1 - Top Right
67 corners.push({top: topleft.top, left: topleft.left+w});
68
69 // 2 - Bottom Right
70 corners.push({top: topleft.top+h, left: topleft.left+w});
71
72 // 3 - Bottom Left
73 corners.push({top: topleft.top+h, left: topleft.left});
74
75 //console.log(corners);
76
77 // Calculate the closest to the mouse
78 var distances = {};
79 for(var c in corners){
80 var dist = Math.hypot(pagelayer.mouse.x - corners[c].left, pagelayer.mouse.y - corners[c].top);
81 distances[c] = dist;
82 }
83 //console.log(distances);
84
85 var corner = Object.keys(distances).sort(function(a,b){return distances[a]-distances[b]})[0];
86 //console.log(corner);
87
88 return corner;
89
90 };
91
92 // Make rows and cols draggable
93 function pagelayer_setup_drag(){
94
95 // The object to show as drag
96 var shower = jQuery('.pagelayer-drag-show');
97
98 // Delete any prospect
99 var clear_prospect = function(){
100 jQuery('.pagelayer-drag-prospect').remove();
101
102 // Shows the wrap as active
103 jQuery('.pagelayer-drag-ele-hover').removeClass('pagelayer-drag-ele-hover');
104 }
105
106 // Reset the complete drag stuff
107 var reset_dragging = function(){
108 pagelayer.dragging = false;
109 pagelayer.drag_is_new = false;
110 pagelayer.drag_mouse = {x: 0, y: 0};
111 reset_on_drag();
112 }
113
114 // Reset the element on you were last
115 var reset_on_drag = function(){
116 pagelayer.drag_closest = false;
117 pagelayer.drag_closest_corner = null;
118 }
119
120 // Scroll by
121 var scrollPx = 7;
122 var scrollDist = 30;
123
124 // If we are too close too the window edge, then scroll
125 var handle_scroll = function(e){
126
127 var windowHeight = jQuery(window).height();
128 var windowWidth = jQuery(window).width();
129
130 // Are we to close to the top or bottom
131 if(e.clientY < scrollDist){
132 window.scrollBy(0, -scrollPx);
133 }else if((windowHeight - e.clientY) < scrollDist){
134 window.scrollBy(0, scrollPx);
135 }
136
137 // Are we to close to the top or bottom
138 if(e.clientX < scrollDist){
139 window.scrollBy(-scrollPx, 0);
140 }else if((windowWidth - e.clientX) < scrollDist){
141 window.scrollBy(scrollPx, 0);
142 }
143
144 }
145
146 // SET the values
147 reset_dragging();
148
149 var ondragover = function(e) {
150 //console.log(e);
151
152 pagelayer.mouse.x = parseInt(e.pageX);
153 pagelayer.mouse.y = parseInt(e.pageY);
154 //console.log(pagelayer.mouse);
155
156 // Are we dragging ?
157 if(pagelayer.dragging){
158
159 //console.log(e);
160
161 e.preventDefault();
162 //e.stopPropagation();
163
164 // The wrap of the element being dragged
165 var wrap = pagelayer.dragging;
166
167 // New addition
168 var is_new = pagelayer.drag_is_new;
169 var ele;
170 var tag = pagelayer_tag(wrap);
171 var id = pagelayer_id(wrap);
172
173 // If existing element then add we are dragging
174 if(!is_new){
175
176 // Start Dragging
177 if(!wrap.hasClass('pagelayer-is-dragging')){
178 wrap.addClass('pagelayer-is-dragging');
179 }
180
181 //shower.hide();
182
183 ele = document.elementFromPoint(e.clientX, e.clientY);
184 //console.log(ele);
185
186 // Drag the show object
187 //shower.show();
188 //var offset = {top: (e.pageY-10)+'px', left: (e.pageX-10)+'px'}
189 //shower.css(offset);
190
191 }else{
192 ele = document.elementFromPoint(e.clientX, e.clientY);
193 }
194 //console.log(e);
195
196 // Have we moved more than 5px;
197 var dist = Math.hypot(pagelayer.mouse.x - pagelayer.drag_mouse.x, pagelayer.mouse.y - pagelayer.drag_mouse.y);
198 //console.log(dist);
199 /*if(dist && dist < 5){
200 return false;
201 }*/
202
203 // Handle the scroll
204 handle_scroll(e);
205
206 // Find the closest wrap
207 var onWrap;
208
209 // If we are a column, we can be over another column or row
210 if(tag == 'pl_col'){
211 onWrap = jQuery(ele).closest('.pagelayer-wrap-col,.pagelayer-wrap-row,.pagelayer-wrap-inner-row');
212 //console.log(pagelayer_id(onWrap));
213
214 // If we are a row, we can be over another row or a column
215 }else if(tag == 'pl_row'){
216 onWrap = jQuery(ele).closest('.pagelayer-wrap-row');
217 //console.log(pagelayer_id(onWrap));
218
219 // For inner row we restrict to 1 level only
220 }else if(tag == 'pl_inner_row'){
221 var ele_wrap = jQuery(ele).parents('.pagelayer-wrap-col')
222 if(ele_wrap.length == 1){
223 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-col');
224 }else{
225 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-inner-row');
226 }
227 // For every other element, we can be over a col or ele
228 }else{
229 onWrap = jQuery(ele).closest('.pagelayer-wrap-ele,.pagelayer-wrap-col');
230 }
231 //console.log(onWrap);
232
233 // If we find nothing
234 if(pagelayer_empty(onWrap) || onWrap.length < 1){
235 clear_prospect();// Clear existing prospects
236 reset_on_drag();// Also reset the last on item
237 return false;
238 }
239
240 // Get the ID
241 var onId = onWrap.attr('pagelayer-wrap-id');
242 var onEle = onWrap.children('.pagelayer-ele');
243
244 // Do we have a parent ?
245 var pOnId = pagelayer_get_parent(onEle);
246
247 if(pOnId){
248 onId = pOnId;
249 onEle = pagelayer_ele_by_id(onId);
250 onWrap = pagelayer_wrap_by_id(onId);
251 }
252
253 var changed = false;
254
255 // Was it the same ID like the one we were on before
256 if(pagelayer.drag_closest != onId){
257 pagelayer.drag_closest = onId;
258 changed = true;
259 }
260 //console.log(onId+' '+pagelayer.drag_closest)
261
262 var req_corners = {0: 'top', 1: 'top', 2: 'bottom', 3: 'bottom'};
263
264 // For columns we redefine the top and bottom
265 if(tag == 'pl_col'){
266 req_corners[1] = 'bottom';
267 req_corners[3] = 'top';
268 }
269
270 // Determine the previous and next
271 var next = wrap.next('.pagelayer-ele-wrap');
272 var prev = wrap.prev('.pagelayer-ele-wrap');
273
274 if(next.length == 1 && pagelayer_id(next) == onId){
275 req_corners = {0: 'bottom', 1: 'bottom', 2: 'bottom', 3: 'bottom'};
276 }
277
278 if(prev.length == 1 && pagelayer_id(prev) == onId){
279 req_corners = {0: 'top', 1: 'top', 2: 'top', 3: 'top'};
280 }
281
282 // Which corner are we closest to ?
283 var corner_num = pagelayer_closest_corner(onWrap);
284 var corner = req_corners[corner_num];
285
286 //console.log(corner+' != '+pagelayer.drag_closest_corner)
287 if(corner != pagelayer.drag_closest_corner){
288 pagelayer.drag_closest_corner = corner;
289 changed = true;
290 }
291
292 //console.log(changed);
293
294 // If we are on our self then clear return false
295 if(onId == id){
296 clear_prospect();// Clear existing prospects
297 reset_on_drag();// Also reset the last on item
298 return false;
299 }
300
301 // Then lets start showing
302 if(changed){
303
304 // Record the mouse points
305 pagelayer.drag_mouse.x = parseInt(e.pageX);
306 pagelayer.drag_mouse.y = parseInt(e.pageY);
307
308 // Clear any existing prospect
309 clear_prospect();
310
311 // Add new prospect
312 var prospect = '<div class="pagelayer-drag-prospect" pagelayer-corner="'+corner+'"></div>';
313
314 if(corner == 'bottom'){
315 onWrap.append(prospect);
316 }else if(corner == 'top'){
317 onWrap.prepend(prospect);
318 }
319
320 prospect = jQuery('.pagelayer-drag-prospect')
321 var animate_props = {height: '5px'};
322
323 // For column add a special class
324 if(tag == 'pl_col'){
325 prospect.addClass('pagelayer-drag-prospect-col');
326 animate_props['width'] = '5px';
327
328 // Adjust the left and right
329 var css = {};
330 css[(corner == 'bottom' ? 'right' : 'left')] = '0px';
331 prospect.css(css);
332 }
333
334 // Animate the prospect
335 prospect.animate(animate_props, 200);
336
337 // Highlight the wrap via overlay
338 onWrap.children('.pagelayer-ele-overlay').addClass('pagelayer-drag-ele-hover');
339
340 }
341
342 }
343 }
344
345 // When mouse is pressed down
346 var ondragstart = function(e){
347
348 //console.log(e);
349
350 // Target
351 var tEle = jQuery(e.target);
352 var wrap = tEle.closest('.pagelayer-ele-wrap');
353 //console.log(jEle[0]);
354
355 // Is it an existing element ?
356 if(wrap.length < 1){
357 return false;
358 }
359
360 // Do we have a parent ?
361 var id = pagelayer_id(wrap);
362 var jEle = pagelayer_ele_by_id(id);
363 var pId = pagelayer_get_parent(jEle);
364
365 if(pId){
366 wrap = pagelayer_wrap_by_id(pId);
367 }
368
369 //e.preventDefault();
370
371 var tag = pagelayer_tag(wrap);
372
373 e.originalEvent.dataTransfer.setData('Text', 1);
374 var img = document.createElement('img');
375 img.src = shower.attr('src');
376 e.originalEvent.dataTransfer.setDragImage(img, 32, 32);
377
378 pagelayer.dragging = wrap;
379
380 }
381
382 // When mouse is pressed down
383 var ondrop = function(e){
384
385 //console.log(e);
386
387 // Stop dragging ?
388 if(pagelayer.dragging){
389
390 e.preventDefault();
391
392 var wrap = pagelayer.dragging;
393 var tag = pagelayer_tag(wrap);
394 var fromEl = wrap.parent();
395 var id;
396 wrap.removeClass('pagelayer-is-dragging');
397
398 // Find any prospect
399 var prospect = jQuery('.pagelayer-drag-prospect');
400 //console.log(prospect[0]);
401
402 // It should be exactly 1
403 if(prospect.length == 1){
404
405 var onWrap = prospect.parent();
406 var onId = pagelayer_id(onWrap);
407 var onTag = pagelayer_tag(onWrap);
408 var dropped;
409 var corner = prospect.attr('pagelayer-corner');
410 var method = (corner == 'top') ? 'before' : 'after';
411
412 // Create the element if it needs to be created
413 if(pagelayer.drag_is_new){
414 dropped = jQuery('<div pagelayer-tag="'+tag+'"></div>');
415
416 // Move the object
417 }else{
418 dropped = wrap;
419 dropped.detach();
420 }
421
422 // If I am a column or row, then I go only before or after my same type !
423 if((onTag == 'pl_col' || onTag == 'pl_row') && onTag == tag){
424
425 // If I am a column and I am on a row
426 // OR I am a normal element and I am on column
427 }else if((tag == 'pl_col' && (onTag == 'pl_row' || onTag == 'pl_inner_row')) || onTag == 'pl_col'){
428 // We need to find the holder and add the prospect there
429 var holder = pagelayer_shortcodes[onTag]['holder'];
430 onWrap = onWrap.children('.pagelayer-ele').children(holder);
431 method = (corner == 'top') ? 'prepend' : 'append';
432 }
433
434 // Attach or shift the element
435 onWrap[method](dropped);
436 //console.log(dropped);
437
438 // Trigger the onadd
439 if(pagelayer.drag_is_new){
440 id = pagelayer_onadd(dropped);
441
442 // Existing elements
443 }else{
444 id = pagelayer_id(wrap);
445 }
446
447 // Defining the variables as needed
448 var jEle = pagelayer_ele_by_id(id);
449 wrap = pagelayer_wrap_by_id(id);
450 var toEl = wrap.parent();
451
452 // Column number handle
453 if(tag == 'pl_col'){
454
455 var row_holder = jEle.parent().closest('.pagelayer-row-holder');
456
457 // Renumber the col where you are going
458 pagelayer_renumber_col(row_holder);
459
460 // Renumber the old columns as well
461 if(!pagelayer.drag_is_new){
462 var from_row = fromEl.closest('.pagelayer-row-holder');
463 pagelayer_renumber_col(from_row);
464 }
465 }
466
467 // Handle the empty col
468 if(tag != 'pl_col'){
469
470 pagelayer_empty_col(toEl.closest('.pagelayer-col-holder'));
471
472 if(!pagelayer.drag_is_new){
473 pagelayer_empty_col(fromEl.closest('.pagelayer-col-holder'));
474 }
475
476 }
477
478 }
479
480 // Clear prospect
481 clear_prospect();
482 }
483
484 reset_dragging();
485
486 }
487
488 // Add the events for inner content - as we are using the drag API
489 jQuery(document).on('dragstart', ondragstart);
490 jQuery(document).on('dragover', ondragover);
491 jQuery(document).on('drop', ondrop);
492
493 // For addition of new elements
494 pagelayer.$$('[pagelayer-tag]').on('dragstart', function(e){
495 //console.log(e);
496
497 var tEle = jQuery(e.target);
498 var jEle = tEle.closest('.pagelayer-shortcode-drag');
499
500 // Is it an existing element ?
501 if(jEle.length < 1){
502 return false;
503 }
504
505 e.originalEvent.dataTransfer.setData('tag', pagelayer_tag(jEle));
506
507 pagelayer.dragging = jEle;
508 pagelayer.drag_is_new = true;
509
510 });
511
512 };
513
514 // Handle empty col
515 // selector should be col holder
516 function pagelayer_empty_col(selector){
517
518 // Loop through
519 jQuery(selector).each(function(){
520
521 var jEle = jQuery(this);// jEle is the COL HOLDER
522
523 // Are we a col ?
524 if(!jEle.hasClass('pagelayer-col-holder')){
525 return;
526 }
527
528 // Column is becoming blank, so show add ele
529 if(jEle.children().length < 1){
530 //from.addClass('pagelayer-empty-col');
531 jEle.append('<div class="pagelayer-add-ele pagelayer-ele-wrap"><i class="fa fa-plus"><br>Empty column please add something</div>');
532 var h = jEle.parent().parent().children('.pagelayer-ele-overlay').height();
533 jEle.children('.pagelayer-add-ele').height(h);
534
535 // Any add ele sign with non-empty columns here ?
536 }else if(jEle.children('.pagelayer-add-ele').length > 0){
537 jEle.children('.pagelayer-add-ele').remove();
538 }
539
540 });
541
542 };
543
544 // Reset the column widths
545 // The selector should be a ROW HOLDER
546 function pagelayer_renumber_col(selector){
547
548 var pEle = jQuery(selector);
549 var children = pEle.children('.pagelayer-ele-wrap');
550 var cols = Math.floor(12 / (children.length));
551 var obj = {col: cols};
552
553 // Find out the number of cols of other cols
554 children.each(function(){
555
556 // This is the wrapper
557 var jEle = jQuery(this);
558
559 // The real element
560 var Ele = jEle.find('>.pagelayer-ele');
561
562 for(var x=1; x<=12; x++){
563 if(jEle.hasClass('pagelayer-col-'+x)){
564 jEle.removeClass('pagelayer-col-'+x);
565 Ele.removeClass('pagelayer-col-'+x);
566 break;
567 }
568 }
569 jEle.addClass('pagelayer-col-'+cols);
570 Ele.addClass('pagelayer-col-'+cols);
571
572 // Set the att
573 pagelayer_set_atts(Ele, obj);
574 });
575 }
576
577 // Handle addition of elements from the left
578 // NOTE : At this point the addition is FINALIZED
579 // The add element cannot be prevented !
580 function pagelayer_onadd(jEle, toClick){
581
582 toClick = arguments.length == 2 ? toClick : true;
583
584 //console.log(jEle);
585 var id = pagelayer_element_added(jEle);
586 var jEle = jQuery("[pagelayer-id="+id+"]");
587
588 if(toClick){
589 //console.log('here');
590 jEle.click();
591 }
592
593 return id;
594
595 };
596
597 // Add an element into the POST
598 function pagelayer_element_added(jEle){
599
600 var sc = jEle.attr('pagelayer-tag');
601 var id, par_id;
602
603 // Generate the HTML
604 html = pagelayer_create_sc(sc);
605 id = pagelayer_assign_id(html);
606 par_id = id;
607
608 // Insert the HTML
609 jEle[0].outerHTML = html[0].outerHTML;
610
611 // Setup the properties of the elements
612 pagelayer_element_setup("[pagelayer-id="+par_id+"], [pagelayer-id="+par_id+"] .pagelayer-ele", true);
613
614 // Any children to add ?
615 if(!('widget' in pagelayer_shortcodes[sc])){
616
617 // The element props
618 var props = pagelayer_shortcodes[sc];
619
620 // Do we have to create children ?
621 if('has_group' in props){
622
623 var has_group = props['has_group'];
624 var gProp = props[has_group['section']][has_group['prop']];
625
626 for(var i=0; i < gProp['count']; i++){
627 var cid = pagelayer_element_add_child(jQuery("[pagelayer-id="+id+"]"), gProp['sc']);
628 //pagelayer_element_setup('[pagelayer-id='+cid+']', true);
629 }
630
631 }
632
633 }
634
635 return id;
636
637 };
638
639 // Add an element
640 function pagelayer_element_add_child(pEle, sc){
641 var child = pagelayer_create_sc(sc);
642 var cid = pagelayer_assign_id(child);
643 pagelayer_set_parent(child, pagelayer_assign_id(pEle));
644
645 // Does the parent have a holder ?
646 var tag = pagelayer_tag(pEle);
647
648 // There is a holder
649 if('holder' in pagelayer_shortcodes[tag]){
650
651 pEle.find(pagelayer_shortcodes[tag]['holder']).append(child);
652
653 // No holder, just append
654 }else{
655 pEle.append(child);
656 }
657
658 pagelayer_element_setup('[pagelayer-id='+cid+']', true);
659
660 // Do we have to create children ?
661 if('has_group' in pagelayer_shortcodes[sc]){
662
663 var has_group = pagelayer_shortcodes[sc]['has_group'];
664 var gProp = pagelayer_shortcodes[sc][has_group['section']][has_group['prop']];
665
666 for(var i=0; i < gProp['count']; i++){
667 var in_cid = pagelayer_element_add_child(jQuery("[pagelayer-id="+cid+"]"), gProp['sc']);
668 }
669
670 }
671
672 return cid;
673 };
674
675 // Return an element by ID
676 function pagelayer_ele_by_id(id){
677 return jQuery('[pagelayer-id='+id+']');
678 };
679
680 // Return the wrap by ID
681 function pagelayer_wrap_by_id(id){
682 return jQuery('[pagelayer-wrap-id='+id+']');
683 };
684
685 // Give the Pagelayer ID
686 function pagelayer_id(jEle){
687
688 var id = jEle.attr('pagelayer-wrap-id');
689 if(id){
690 return id;
691 }
692
693 id = jEle.attr('pagelayer-id');
694
695 return id;
696
697 }
698
699 // Assign the jQuery object an ID
700 function pagelayer_assign_id(jEle){
701
702 // Do you have the pagelayer id
703 var id = jEle.attr("pagelayer-id");
704 if(!id || id.length < 1){
705 id = pagelayer_randstr(16);
706 jEle.attr("pagelayer-id", id);
707 }
708
709 return id;
710
711 }
712
713 // Show the edit options
714 function pagelayer_element_clicked(selector, e){
715
716 var jEle = jQuery(selector);
717 e = e || false;
718
719 // You must be a element atleast
720 if(!jEle.hasClass('pagelayer-ele')){
721 return false;
722 }
723
724 // Get the parent
725 var pId = pagelayer_get_parent(jEle);
726
727 // If we found a parent
728 if(pId){
729 jEle = pagelayer_ele_by_id(pId);
730 }
731
732 // Lets not rebuild everything to make it faster
733 if(pagelayer_is_active(jEle)){
734 return false;
735 }
736
737 // Make the editable fields active
738 pagelayer_clear_editable();// First clear
739 jEle.find('[pagelayer-editable]').each(function (){
740 pagelayer_make_editable(jQuery(this), e);
741 });
742
743 // Set this as the active element
744 pagelayer_set_active(jEle);
745
746 // Show the properties
747 pagelayer_elpd_open(jEle);
748
749 }
750
751 // The edit option
752 function pagelayer_edit_element(selector){
753 pagelayer_element_clicked(selector);
754 }
755
756 // Setup the properties on a single click
757 function pagelayer_element_setup(selector, render){
758
759 var selector = selector || ".pagelayer-ele";
760 render = render || false;
761
762 // Loop through
763 jQuery(selector).each(function(){
764
765 var jEle = jQuery(this);
766
767 // Assign an ID if not there
768 var id = pagelayer_assign_id(jEle);
769 var pId = pagelayer_get_parent(jEle) || '';// Options to show on hover
770 var selector = '[pagelayer-id='+id+']';
771
772 if(render){
773 pagelayer_sc_render(jEle);
774 }
775
776 // Get the tag
777 var tag = pagelayer_tag(jEle);
778
779 // Lets check if we are the child of a parent i.e. element of a group
780 if(pagelayer_empty(pId)){
781
782 // Get the parent
783 var pEle = jEle.parent().closest('.pagelayer-ele');
784
785 // If we found a parent
786 if(pEle.length > 0){
787
788 var pTag = pagelayer_tag(pEle);
789
790 // Is the parent a group of this child ?
791 if(!pagelayer_empty(pagelayer_shortcodes[pTag]) && pagelayer_is_group(pTag)){
792
793 var has_group = pagelayer_shortcodes[pTag]['has_group'];
794 var child_type = pagelayer_shortcodes[pTag][has_group['section']][has_group['prop']]['sc'];
795
796 // If the type is the same as jEle
797 if(child_type == pagelayer_tag(jEle)){
798 pId = pagelayer_assign_id(pEle);
799 pagelayer_set_parent(jEle, pId);
800 }
801 }
802
803 }
804
805 }
806
807 // Make the wraps
808 jEle.wrap('<div class="pagelayer-ele-wrap" pagelayer-wrap-id="'+id+'"></div>');
809 var wrap = jEle.parent();
810
811 // For column we have to do some kidas !
812 if(tag == 'pl_col'){
813
814 var col;
815 for(var x=1; x<=12; x++){
816 if(jEle.hasClass('pagelayer-col-'+x)){
817 col = 'pagelayer-col-'+x;
818 break;
819 }
820 }
821
822 var is_custom_width = pagelayer_get_att(jEle, 'col');
823 var col_width = pagelayer_get_att(jEle, 'col_width');
824 if(pagelayer_empty(is_custom_width) && col_width){
825 wrap.css('width', col_width+'%');
826 }
827
828 wrap.addClass('pagelayer-col '+col);
829 //jEle.removeClass('pagelayer-col '+col);
830 wrap.addClass('pagelayer-wrap-col');
831
832 }else if(tag == 'pl_row'){
833 wrap.addClass('pagelayer-wrap-row');
834 }else if(tag == 'pl_inner_row'){
835 wrap.addClass('pagelayer-wrap-inner-row');
836 }else{
837 wrap.addClass('pagelayer-wrap-ele');
838 }
839
840 // Create the overlay
841 wrap.prepend('<div class="pagelayer-ele-overlay"></div>');
842
843 var overlay = wrap.children('.pagelayer-ele-overlay');
844 var html;
845
846 if(tag == 'pl_row' || tag == 'pl_inner_row'){
847
848 overlay.addClass('pagelayer-row-hover');
849
850 if(jEle.hasClass('pagelayer-row-stretch-full')){
851 pagelayer_sc_render(jEle);
852 }
853
854 html = '<div class="pagelayer-row-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
855 '<i class="fa fa-clone pagelayer-eoi" onclick="pagelayer_copy_element(\''+selector+'\')" />'+
856 '<i class="fa fa-trash pagelayer-eoi" onclick="pagelayer_delete_element(\''+selector+'\')" />'+
857 '<i class="fa fa-pencil pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
858 '</div>';
859
860 }else if(tag == 'pl_col'){
861
862 overlay.addClass('pagelayer-col-hover');
863
864 html = '<div class="pagelayer-col-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
865 '<i class="fa fa-columns pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
866 '</div>';
867
868 // Is it an empty col ?
869 pagelayer_empty_col(jEle.children('.pagelayer-col-holder'));
870
871 }else{
872
873 html = '<div class="pagelayer-ele-option" pagelayer-option-edit pagelayer-option-id="'+id+'">'+
874 '<i class="fa fa-clone pagelayer-eoi" onclick="pagelayer_copy_element(\''+selector+'\')" />'+
875 '<i class="fa fa-trash pagelayer-eoi" onclick="pagelayer_delete_element(\''+selector+'\')" />'+
876 '<i class="fa fa-pencil pagelayer-eoi" onclick="pagelayer_edit_element(\''+selector+'\', event)" />'+
877 '</div>';
878
879 }
880
881 // Append to the child
882 overlay.append(html);
883 jQuery('[pagelayer-option-id='+id+']').hide();
884
885 // Setup the HOVER events ABD create WRAPS IF we dont have a parent
886 if(pId.length > 0){
887 return;
888 }
889
890 // Make the wrap draggable, but only of independent or parent elements
891 wrap.attr('draggable', 'true');
892
893 wrap.hover(function(){
894
895 // Is there an element option shower ?
896 var opts = jQuery('[pagelayer-option-id='+id+']');
897
898 // Give the overlay the hover class
899 opts.parent().addClass('pagelayer-ele-hover');
900
901 // Show them
902 opts.show();
903
904 }, function(){
905
906 // Is there an element option shower ?
907 var opts = jQuery('[pagelayer-option-id='+id+']');
908
909 // Remove hover class
910 opts.parent().removeClass('pagelayer-ele-hover');
911
912 // Hide opts
913 opts.hide();
914
915 });
916
917 });
918 }
919
920 // Left Click
921 function pagelayer_left_click(){
922
923 jQuery('.entry-content').on('click', function(e){
924
925 // Hide the context menu
926 jQuery('.pagelayer-right-click-options').hide();
927
928 // Target
929 var tEle = jQuery(e.target);
930
931 // If its an edit option click
932 if(tEle.hasClass('pagelayer-eoi')){
933 return false;
934 }
935
936 pagelayer_element_clicked(tEle.closest('.pagelayer-ele'), e);
937
938 return false;
939
940 });
941 };
942
943 // Right Click Menu
944 function pagelayer_right_click(){
945
946 var html = '<div class="pagelayer-right-click-options" style="display:none;">'+
947 '<ul>'+
948 '<li><a class="pagelayer-right-edit">Edit</a></li>'+
949 '<li><a class="pagelayer-right-duplicate">Duplicate</a></li>'+
950 '<li><a class="pagelayer-right-copy">Copy</a></li>'+
951 '<li><a class="pagelayer-right-paste">Paste</a></li>'+
952 '<li><a class="pagelayer-right-delete">Delete</a></li>'+
953 '</ul>'+
954 '</div>';
955
956 jQuery('body').append(html);
957
958 var $contextMenu = jQuery('.pagelayer-right-click-options');
959
960 jQuery('.entry-content').on('contextmenu', function(e){
961
962 var tEle = jQuery(e.target);
963 var jEle = tEle.closest('.pagelayer-ele-wrap').children('.pagelayer-ele');
964
965 // Get the parent
966 var pId = pagelayer_get_parent(jEle);
967
968 // If we found a parent
969 if(pId){
970 jEle = pagelayer_ele_by_id(pId);
971 }
972
973 // The basics
974 var id = pagelayer_assign_id(jEle);
975 var tag = pagelayer_tag(jEle);
976
977 $contextMenu.find('.pagelayer-right-edit').attr('onclick', 'pagelayer_edit_element("[pagelayer-id='+id+']")').html('Edit '+pagelayer_shortcodes[tag]['name']);
978 $contextMenu.find('.pagelayer-right-duplicate').attr('onclick', 'pagelayer_copy_element("[pagelayer-id='+id+']")');
979 $contextMenu.find('.pagelayer-right-copy').attr('onclick', 'pagelayer_copy_select("[pagelayer-id='+id+']")');
980 $contextMenu.find('.pagelayer-right-paste').attr('onclick', 'pagelayer_paste_element("[pagelayer-id='+id+']")');
981 $contextMenu.find('.pagelayer-right-delete').attr('onclick', 'pagelayer_delete_element("[pagelayer-id='+id+']")');
982
983 // Are we to hide the paste ?
984 if(!pagelayer_empty(pagelayer.copy_selected) && pagelayer_can_copy_to(jEle)){
985 //console.log(pagelayer_can_copy_to(jEle));
986 $contextMenu.find('.pagelayer-right-paste').parent().show();
987 }else{
988 $contextMenu.find('.pagelayer-right-paste').parent().hide();
989 }
990
991 $contextMenu.css({
992 display: "block",
993 left: e.pageX,
994 top: e.pageY
995 });
996
997 return false;
998
999 });
1000
1001 jQuery('html').on('click', function(e){
1002 $contextMenu.hide();
1003 });
1004 }
1005
1006 // Set the parent for the group
1007 function pagelayer_set_parent(jEle, id){
1008 jEle.attr('pagelayer-parent', id);
1009 };
1010
1011 // Set the parent for the group
1012 function pagelayer_get_parent(jEle){
1013 return jEle.attr('pagelayer-parent');
1014 };
1015
1016 // Sets the screen mode
1017 function pagelayer_set_screen_mode(mode){
1018 var modes = ['desktop', 'tablet', 'mobile'];
1019 var body = pagelayer.$$('.pagelayer-iframe-holder iframe');
1020 var current = '';
1021
1022 for(var x in modes){
1023
1024 if(body.hasClass('pagelayer-screen-'+modes[x]) && modes[x] != mode){
1025 current = modes[x];
1026 body.removeClass('pagelayer-screen-'+modes[x]);
1027 }
1028 }
1029
1030 // Add the class
1031 body.addClass('pagelayer-screen-'+mode);
1032
1033 // Add the class to the button
1034 pagelayer.$$('.pagelayer-mode-button').removeClass('fa-'+current).addClass('fa-'+mode);
1035
1036 // Trigger screen change if any
1037 pagelayer.$$('.pagelayer-elp-screen').trigger('pagelayer-screen-changed');
1038
1039 };
1040
1041 // Get the current screen mode
1042 function pagelayer_get_screen_mode(){
1043 var modes = ['desktop', 'tablet', 'mobile'];
1044 var body = pagelayer.$$('.pagelayer-iframe-holder iframe');
1045
1046 for(var x in modes){
1047 if(body.hasClass('pagelayer-screen-'+modes[x])){
1048 return modes[x];
1049 }
1050 }
1051 }
1052
1053 // Handle key press events
1054 jQuery(document).keydown(function(event){
1055 //alert(String.fromCharCode(event.which));
1056
1057 // Delete
1058 if(event.keyCode == 46){
1059 pagelayer_delete_element('[pagelayer-active]');
1060 }
1061
1062 });
1063
1064 // Delete an element as per the selector
1065 function pagelayer_delete_element(selector){
1066 var jEle = jQuery(selector);
1067
1068 // Anything found ?
1069 if(jEle.length > 0){
1070
1071 var id = pagelayer_assign_id(jEle);
1072
1073 // Is there a wrap
1074 var wrap = jQuery('[pagelayer-wrap-id="'+id+'"]');
1075
1076 var par = wrap.parent();
1077
1078 wrap.remove();
1079
1080 pagelayer_empty_col(par);
1081
1082 if(pagelayer_active.el && pagelayer_active.el.id == id){
1083 pagelayer.$$('.pagelayer-elpd-close').click();
1084 }
1085
1086 }
1087 pagelayer_isDirty = true;
1088 };
1089
1090 // Select an element
1091 function pagelayer_copy_select(selector){
1092 pagelayer.copy_selected = selector;
1093 }
1094
1095 function pagelayer_can_copy_to(to){
1096 var jEle = jQuery(pagelayer.copy_selected);
1097 var tEle = jQuery(to);
1098
1099 var eTag = pagelayer_tag(jEle);
1100 var tTag = pagelayer_tag(tEle);
1101 //console.log(eTag+' - '+tTag);
1102 // Final to
1103 var fTo;
1104
1105 // Selected element is a Row, can go only after a row
1106 if(eTag == 'pl_row'){
1107 fTo = tEle.closest('.pagelayer-ele.pagelayer-row');
1108 if(fTo.length != 1) return false;
1109 return fTo;
1110 }
1111
1112 // Selected element is a Column, can go only after a col
1113 if(eTag == 'pl_col'){
1114 fTo = tEle.closest('.pagelayer-ele.pagelayer-col');
1115 if(fTo.length != 1) return false;
1116 return fTo;
1117 }
1118
1119 // Is the TARGET a row or column when the selected item is a element
1120 if(tTag == 'pl_row' || tTag == 'pl_col'){
1121 return false;
1122 }
1123
1124 return tEle;
1125
1126 }
1127
1128 // Select an element
1129 function pagelayer_paste_element(to){
1130
1131 var fTo = pagelayer_can_copy_to(to);
1132
1133 // Is it a valid to
1134 if(!fTo){
1135 return false;
1136 }
1137
1138 pagelayer_copy_element(pagelayer.copy_selected, fTo);
1139 }
1140
1141 // Copy an element
1142 // Note : insertAfter should always be an pagelayer-ele
1143 function pagelayer_copy_element(selector, insertAfter){
1144 var src = jQuery(selector);
1145 var html = src[0].outerHTML;
1146 var tag = pagelayer_tag(src);
1147 insertAfter = insertAfter || src;
1148 insertAfter = insertAfter.parent();
1149
1150 var jEle = jQuery(html);
1151 jEle.removeAttr('pagelayer-id');
1152 jEle.find('[pagelayer-id]').removeAttr('pagelayer-id');
1153 jEle.find('[pagelayer-parent]').removeAttr('pagelayer-parent');// Remove the parent attribute as it will be reset during pagelayer_element_setup
1154 jEle.find('style').remove();
1155 jEle.find('.pagelayer-ele-overlay').remove();
1156
1157 // Unwrap the wraps
1158 jEle.find('.pagelayer-ele').each(function (){
1159 var ele = jQuery(this);
1160 if(ele.parent().is('.pagelayer-ele-wrap')){
1161 ele.unwrap();
1162 }
1163 });
1164
1165 // Give it an ID
1166 var id = pagelayer_assign_id(jEle);
1167
1168 jQuery(insertAfter).after(jEle);
1169
1170 pagelayer_element_setup('[pagelayer-id='+id+'], [pagelayer-id='+id+'] .pagelayer-ele', true);
1171
1172 //If column then renumber columns
1173 if(tag == 'pl_col'){
1174 var row = src.parent().closest('.pagelayer-row');
1175 pagelayer_renumber_col(row);
1176 }
1177
1178 pagelayer_isDirty = true;
1179
1180 return id;
1181 };
1182
1183 // Language key
1184 function pagelayer_l(k){
1185 return k;
1186 }
1187
1188 // Set the given jELE as active
1189 function pagelayer_set_active(jEle){
1190
1191 // Make all other element as inactive
1192 jQuery('[pagelayer-active]').each(function(){
1193 var $j = jQuery(this);
1194 $j.removeAttr('pagelayer-active');
1195 });
1196
1197 jEle.attr('pagelayer-active', 1);
1198
1199 // Add and remove the class
1200 jQuery('.pagelayer-active').removeClass('pagelayer-active');
1201
1202 jEle.parent().children('.pagelayer-ele-overlay').addClass('pagelayer-active');
1203
1204 }
1205
1206 function pagelayer_sc(sc){
1207 return sc.replace('pl_', '');
1208 };
1209
1210 // Create a HTML dom element of the Short code
1211 // Return the jEle
1212 function pagelayer_create_sc(sc){
1213
1214 var html;
1215 var _sc = pagelayer_sc(sc);
1216 var func = window['pagelayer_sc_'+sc];
1217
1218 // Generate the HTML
1219 if(typeof func == 'function'){
1220 html = window['pagelayer_sc_'+sc]();
1221 }else{
1222 html = '<div '+pagelayer_sc_atts('pagelayer-'+_sc)+'></div>';
1223 }
1224
1225 html = jQuery(html);
1226
1227 // Add the tag
1228 html.attr('pagelayer-tag', sc);
1229
1230 // Give it an ID
1231 id = pagelayer_assign_id(html);
1232
1233 // Try to set the default values over 5 loops
1234 pagelayer_set_default_atts(html, 5);
1235
1236 return html;
1237
1238 };
1239
1240 // Returns a list of default attributes to set as per the current selection
1241 function pagelayer_set_default_atts(jEle, set){
1242
1243 set = set || 0;
1244 var hasSet = false;
1245
1246 for(var i = 1; i <= set;i++){
1247
1248 //console.log('[pagelayer_set_default_atts] Loop :'+i);
1249 //console.log(jEle);
1250
1251 // Get existing data
1252 var el = pagelayer_data(jEle, true);
1253
1254 // If it is the last loop and we are greater than 1
1255 if(i > 1 && i == set){
1256 console.log('[pagelayer_default_atts] Still vars to set. Please check your shortcode params !');
1257 }
1258
1259 // We are supposed to set !
1260 if('set' in el && !pagelayer_empty(el.set)){
1261 pagelayer_set_atts(jEle, el.set);
1262 hasSet = true;
1263 }else{
1264 break;
1265 }
1266 }
1267
1268 return hasSet;
1269 }
1270
1271 // Returns the tag
1272 function pagelayer_tag(jEle){
1273
1274 // It could be the wrap
1275 if(jEle.hasClass('pagelayer-ele-wrap')){
1276 return jEle.children('.pagelayer-ele').attr('pagelayer-tag');
1277 }
1278
1279 // It could be the row or col holder
1280 if(jEle.hasClass('pagelayer-row-holder') || jEle.hasClass('pagelayer-col-holder')){
1281 return jEle.parent().attr('pagelayer-tag');
1282 }
1283
1284 return jEle.attr('pagelayer-tag');
1285 }
1286
1287 // Gets a single attribute value
1288 function pagelayer_get_att(jEle, att){
1289 return jEle.attr('pagelayer-a-'+att);
1290 };
1291
1292 // Gets a single attribute value
1293 function pagelayer_get_tmp_att(jEle, att){
1294 return jEle.attr('pagelayer-tmp-'+att);
1295 };
1296
1297 // This function will just set atts and not do anything else
1298 // Atts can be string or object. If its string, then val is needed
1299 function pagelayer_set_atts(jEle, atts, val){
1300
1301 if(typeof atts == 'string'){
1302 var tmp = {};
1303 tmp[atts] = val;
1304 atts = tmp;
1305 }
1306
1307 if(typeof atts != 'object'){
1308 return false;
1309 }
1310
1311 var tag = pagelayer_tag(jEle);
1312 var trigger_onchange = 0;
1313
1314 if(pagelayer_empty(tag)){
1315 console.log('Set atts found no tag');
1316 console.log(jEle);
1317 return;
1318 }
1319
1320 // All props
1321 var all_props = pagelayer_shortcodes[tag];//console.log(tag);console.log(jEle);
1322 var trigger_props = {};
1323 var no_val = {};
1324 var defaults = {};
1325
1326 // Loop through all props
1327 for(var i in pagelayer_tabs){
1328
1329 var tab = pagelayer_tabs[i];
1330
1331 for(var section in all_props[tab]){
1332
1333 var props = section in pagelayer_shortcodes[tag] ? pagelayer_shortcodes[tag][section] : pagelayer_styles[section];
1334
1335 for(var x in props){
1336
1337 if('default' in props[x]){
1338 defaults[x] = 1;
1339 }
1340
1341 // Dont set any val, but we set temp value
1342 if('no_val' in props[x]){
1343 no_val[x] = 1;
1344 }
1345
1346 if('req' in props[x] || 'show' in props[x]){
1347 var show = 'req' in props[x] ? props[x]['req'] : props[x]['show'];
1348 for(var showParam in show){
1349 var val = show[showParam];
1350 var except = showParam.substr(0, 1) == '!' ? true : false;
1351 showParam = except ? showParam.substr(1) : showParam;
1352 trigger_props[showParam] = 1;
1353 }
1354
1355 }
1356
1357 }
1358
1359 }
1360
1361 }
1362
1363 for(var x in atts){
1364
1365 // Are we to trigger change
1366 if(x in trigger_props){
1367 trigger_onchange = 1;
1368 }
1369
1370 //console.log(x+'-'+atts[x]);
1371
1372 if(x in no_val){
1373 pagelayer_set_tmp_atts(jEle, x, atts[x]);
1374 continue;
1375 }
1376
1377 // Remove the attribute if its BLANK and there is no default for it
1378 // If there is a default, we set it to blank to keep record of the current val
1379 if(atts[x].length < 1){
1380
1381 // Dont remove the value as there is a default
1382 if(!(x in defaults)){
1383 jEle.removeAttr('pagelayer-a-'+x);
1384 // Otherwise blank it
1385 }else{
1386 jEle.attr('pagelayer-a-'+x, atts[x]);
1387 }
1388
1389 // Remove the tmp atts anyway
1390 var to_del = new Array();
1391 var regexp = new RegExp('pagelayer\-tmp\-'+x, 'gi');
1392
1393 jQuery.each(jEle[0].attributes, function(index, att){
1394 if(!att) return;
1395 if(att.name.match(regexp)){
1396 to_del.push(att.name);
1397 }
1398 });
1399
1400 //console.log(to_del);
1401 for(var n in to_del){
1402 jEle.removeAttr(to_del[n]);
1403 }
1404
1405 // Set the value
1406 }else{
1407 jEle.attr('pagelayer-a-'+x, atts[x]);
1408 }
1409
1410 // Are you the active element
1411 if(pagelayer_is_active(jEle)){
1412
1413 // TODO : Record Undo and Redo
1414
1415 }
1416
1417 }
1418
1419 // Trigger the change of the parameter and show the required properties
1420 if(trigger_onchange){
1421 pagelayer_elpd_show_rows();
1422 }
1423
1424 pagelayer_isDirty = true;
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_tmp_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 for(var x in atts){
1442 jEle.attr('pagelayer-tmp-'+x, atts[x]);
1443 }
1444
1445 };
1446
1447 // Set the att and classes of an HTML which is not yet created
1448 function pagelayer_sc_atts(classes, atts){
1449
1450 if(typeof atts != 'object'){
1451 atts = new Object();
1452 }
1453
1454 var r = new Array();
1455
1456 for(var x in atts){
1457 r.push('pagelayer-a-'+x+'="'+atts[x]+'"');
1458 }
1459
1460 return 'class="'+classes+' pagelayer-ele" '+r.join(' ');
1461 }
1462
1463 // Is the jEle the active element ?
1464 function pagelayer_is_active(jEle){
1465
1466 // Is this the active Element ?
1467 if(pagelayer_empty(pagelayer_active.el) || jEle.attr('pagelayer-id') != pagelayer_active.el.id){
1468 return false;
1469 }
1470
1471 return true;
1472
1473 };
1474
1475 // Removes {{}} from the variable name
1476 function pagelayer_var(val){
1477 return val.substring(2, (val.length - 2));
1478 }
1479
1480 // Take care of the CSS
1481 function pagelayer_css_render(css, val, seperator){
1482 //console.log('CSS '+css+' | '+val);
1483
1484 // Seperator
1485 seperator = seperator || ',';
1486
1487 // Replace the val
1488 css = css.split('{{val}}').join(val);
1489
1490 // If there is an array
1491 if(css.match(/val\[\d/)){
1492 val = val.split(seperator);
1493 for(var i in val){
1494 css = css.split('{{val['+i+']}}').join(val[i]);
1495 }
1496 }
1497
1498 //console.log('Final CSS '+css);
1499
1500 return css;
1501
1502 };
1503
1504 // Replace the variables
1505 function pagelayer_parse_vars(str, el){
1506
1507 for(var x in el.tmp){
1508 str = str.split('{{{'+x+'}}}').join(el.tmp[x]);
1509 }
1510
1511 for(var x in el.atts){
1512 str = str.split('{{'+x+'}}').join(el.atts[x]);
1513 }
1514
1515 return str;
1516 };
1517
1518 // Render the Element
1519 function pagelayer_sc_render(jEle){
1520
1521 // We render only the active element
1522 if(!pagelayer_is_active(jEle)){
1523 //return false;
1524 }
1525
1526 // Handle the CSS part
1527 // Get the id, tag, atts, data, etc
1528 var el = pagelayer_data(jEle, true);
1529 var all_props = pagelayer_shortcodes[el.tag];
1530 var elCSS = {
1531 classes: [],
1532 remove_classes: [],
1533 attr: [],
1534 remove_attr: [],
1535 css: [],
1536 edit: [],
1537 sel: '[pagelayer-id="'+el.id+'"]'
1538 };
1539
1540 // Create a reference
1541 el.CSS = elCSS;
1542
1543 //console.log(el.atts);
1544
1545 for(var i in pagelayer_tabs){
1546 var tab = pagelayer_tabs[i];
1547 for(var section in all_props[tab]){ //console.log(tab+' '+section);
1548
1549 var props = section in pagelayer_shortcodes[el.tag] ? pagelayer_shortcodes[el.tag][section] : pagelayer_styles[section];//console.log(props);
1550
1551 // Loop the props
1552 for(var x in props){
1553
1554 // pagelayer_data will return attributes even if they are BLANK e.g. attr=""
1555 // Render doesnt consider BLANK values as values, and we are unsetting them now
1556 // If in any situation you need to consider blank values, please handle in the JS / PHP function of the Shortcode
1557 if(x in el.atts && el.atts[x].length < 1){
1558 delete el.atts[x];
1559 }
1560
1561 // Any editor ?
1562 if('edit' in props[x]){
1563 elCSS.edit.push({prop: x, sel: props[x]['edit']});
1564 }
1565
1566 // Do we have a addClass ?
1567 // We are checking before the element has a value so that we can add or remove the class
1568 if('addClass' in props[x]){
1569
1570 var addClasses;
1571
1572 // Convert the string to an array
1573 if(typeof props[x]['addClass'] === 'string'){
1574 addClasses = [props[x]['addClass']];
1575 }else{
1576 addClasses = props[x]['addClass'];
1577 }
1578
1579 for(var c in addClasses){
1580
1581 // The selector
1582 var tSel = jQuery.isNumeric(c) ? '' : c;
1583
1584 // If there is a VAL
1585 // NOTE : Only val is allowed when there is a list
1586 if(addClasses[c].match(/\{\{val\}\}/) && 'list' in props[x]){
1587
1588 for(var l in props[x]['list']){
1589
1590 var tmp = {'sel': tSel, 'val': addClasses[c].replace('{{val}}', l)};
1591
1592 if(el.atts[x] == l){
1593 elCSS['classes'].push(tmp);
1594 }else{
1595 elCSS['remove_classes'].push(tmp);
1596 }
1597
1598 }
1599
1600 }else{
1601
1602 var tmp = {'sel': tSel, 'val': addClasses[c]};
1603
1604 // If the value is there
1605 if(x in el.atts){
1606 elCSS['classes'].push(tmp);
1607 }else{
1608 elCSS['remove_classes'].push(tmp);
1609 }
1610
1611 }
1612 }
1613 }
1614
1615 // Do we have a addAttr ?
1616 // We are checking before the element has a value so that we can add or remove the attr
1617 if('addAttr' in props[x]){
1618
1619 var addAttr;
1620
1621 // Convert the string to an array
1622 if(typeof props[x]['addAttr'] === 'string'){
1623 addAttr = [props[x]['addAttr']];
1624 }else{
1625 addAttr = props[x]['addAttr'];
1626 }
1627
1628 for(var c in addAttr){
1629
1630 // The selector
1631 var tSel = jQuery.isNumeric(c) ? '' : c;
1632 var tmp = {'sel': tSel, 'val': addAttr[c]};
1633
1634 // If the value is there
1635 if(x in el.atts){
1636 elCSS['attr'].push(tmp);
1637 }else{
1638 elCSS['remove_attr'].push(tmp);
1639 }
1640 }
1641 }
1642
1643 // Do we have a CSS ?
1644 if('css' in props[x]){
1645
1646 var css;
1647
1648 // Convert the string to an array
1649 if(typeof props[x]['css'] === 'string'){
1650 css = [props[x]['css']];
1651 }else{
1652 css = props[x]['css'];
1653 }
1654
1655 // Screen modes
1656 var modes = {desktop: '', tablet: '_tablet', mobile: '_mobile'};
1657
1658 for(var m in modes){
1659
1660 var xm = x+modes[m];
1661
1662 // If the value is there
1663 if(!(xm in el.atts)){
1664 continue;
1665 }
1666
1667 for(var c in css){
1668
1669 // The selector
1670 var tSel = jQuery.isNumeric(c) ? '{{element}}' : c;
1671 var tmp = {
1672 sel: tSel,
1673 val: pagelayer_css_render(css[c], el.atts[xm], (props[x].sep || ',')),
1674 };
1675
1676 // Is this a tablet
1677 if(m == 'tablet'){
1678 tmp.sel = '@media (max-width: 768px) and (min-width: 361px){'+tmp.sel;
1679 tmp.val = tmp.val+'}';
1680 }
1681
1682 // Is this a mobile mode ?
1683 if(m == 'mobile'){
1684 tmp.sel = '@media (max-width: 360px){'+tmp.sel;
1685 tmp.val = tmp.val+'}';
1686 }
1687
1688 // Push to store
1689 elCSS.css.push(tmp);
1690 }
1691
1692 }
1693
1694 }
1695
1696 }
1697
1698 }
1699
1700 }
1701
1702 // If there is an HTML, then process it
1703 if('html' in pagelayer_shortcodes[el.tag]){
1704
1705 el.iHTML = jQuery('<div>'+pagelayer_shortcodes[el.tag]['html']+'</div>');
1706
1707 // Lets process the 'if-ext'
1708 el.iHTML.find('[if-ext]').each(function (){
1709 var $j = jQuery(this);
1710 var reqvar = pagelayer_var($j.attr('if-ext'));
1711 $j.removeAttr('if-ext');
1712
1713 // Is the element there ?
1714 if(!(reqvar in el.atts && !pagelayer_empty(el.atts[reqvar]))){
1715 //console.log('HERE');
1716 $j[0].outerHTML = $j.html();
1717 }
1718
1719 });
1720
1721 // Lets process the 'if'
1722 el.iHTML.find('[if]').each(function (){
1723 var $j = jQuery(this);
1724 var reqvar = pagelayer_var($j.attr('if'));
1725 $j.removeAttr('if');
1726
1727 // Is the element there ?
1728 if(!(reqvar in el.atts && !pagelayer_empty(el.atts[reqvar]))){
1729 //console.log('HERE');
1730 $j.remove();
1731 }
1732
1733 });
1734
1735 // Is there a function to render ?
1736 var fn = window['pagelayer_render_'+jEle.attr('pagelayer-tag')];
1737
1738 if(typeof fn == 'function'){
1739 fn(el);
1740 }
1741
1742 //console.log(el.atts);
1743
1744 // Parse the variables
1745 var new_html = pagelayer_parse_vars(el.iHTML.html(), el);
1746 el.iHTML.html(new_html);
1747
1748 // Do we have to wrap the innerHTML ?
1749 if('holder' in pagelayer_shortcodes[el.tag]){
1750
1751 var hSel = pagelayer_shortcodes[el.tag]['holder'];
1752 var holder = jEle.find(hSel).first();
1753
1754 // Detach the holder
1755 holder.detach();
1756
1757 // Add the new HTML
1758 el.$.html(el.iHTML.html());
1759
1760 // reAttach the children only
1761 el.$.find(hSel).html(holder.children());
1762
1763 // No holder
1764 }else{
1765
1766 //console.log(el.iHTML.html());
1767 el.$.html(el.iHTML.html());
1768
1769 }
1770
1771 // Rows, Cols and Groups
1772 }else{
1773
1774 // Is there a function to render ?
1775 var fn = window['pagelayer_sc_render_'+jEle.attr('pagelayer-tag')];
1776
1777 if(typeof fn == 'function'){
1778 fn(el);
1779 }
1780
1781 }
1782
1783 // Is there a function to render after HTML insertion but before CSS and attr ?
1784 var post = window['pagelayer_render_html_'+jEle.attr('pagelayer-tag')];
1785
1786 if(typeof post == 'function'){
1787 post(el);
1788 }
1789
1790 ////////////////////////////
1791 // Are there any edit fields ?
1792 ////////////////////////////
1793
1794 if(elCSS.edit.length > 0){
1795
1796 for(var c in elCSS.edit){
1797 var prop = elCSS.edit[c]['prop'];
1798 var tSel = elCSS.edit[c]['sel'];
1799 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1800 node.attr('pagelayer-editable', prop);
1801 }
1802
1803 }
1804
1805 ////////////////////////////
1806 // Are there any addClass ?
1807 ////////////////////////////
1808
1809 // If we have any classes to add
1810 if(elCSS.classes.length > 0){
1811 //console.log(elCSS.classes);
1812
1813 for(var c in elCSS.classes){
1814 var tSel = elCSS.classes[c]['sel'];
1815 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1816 if(!node.hasClass(elCSS.classes[c]['val'])){
1817 node.addClass(elCSS.classes[c]['val']);
1818 }
1819 }
1820 }
1821
1822 // If we have any classes to remove
1823 if(elCSS.remove_classes.length > 0){
1824 //console.log(elCSS.remove_classes);
1825
1826 for(var c in elCSS.remove_classes){
1827 var tSel = elCSS.remove_classes[c]['sel'];
1828 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1829 if(node.hasClass(elCSS.remove_classes[c]['val'])){
1830 node.removeClass(elCSS.remove_classes[c]['val']);
1831 }
1832 }
1833 }
1834
1835 ////////////////////////////
1836 // Are there any addAttr ?
1837 ////////////////////////////
1838
1839 // If we have any attributes to add
1840 if(elCSS.attr.length > 0){
1841 //console.log(elCSS.attr);
1842
1843 for(var c in elCSS.attr){
1844 var tSel = elCSS.attr[c]['sel'].replace('{{element}}', '');
1845 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1846 var att = elCSS.attr[c]['val'].split('=');
1847 att[1] = pagelayer_parse_vars(att[1], el);
1848 att[1] = pagelayer_trim(att[1], '"');
1849
1850 // Is it the same val ?
1851 if(!node.attr(att[0]) != att[1]){
1852 node.attr(att[0], att[1]);
1853 }
1854 }
1855 }
1856
1857 // If we have any attributes to add
1858 if(elCSS.remove_attr.length > 0){
1859 //console.log(elCSS.remove_attr);
1860
1861 for(var c in elCSS.remove_attr){
1862 var tSel = elCSS.remove_attr[c]['sel'].replace('{{element}}', '');
1863 var node = tSel.length < 1 ? jEle : jEle.find(tSel);
1864 var att = elCSS.remove_attr[c]['val'].split('=');
1865
1866 if(node.is('['+att[0]+']')){
1867 node.removeAttr(att[0]);
1868 }
1869 }
1870 }
1871
1872 // The style element
1873 var style = pagelayer.$('[pagelayer-style-id='+el.id+']');
1874
1875 // If we have any RULES CSS, then handle it
1876 if(elCSS.css.length > 0){
1877
1878 // Did we find it ?
1879 if(style.length < 1){
1880 jEle.prepend('<style pagelayer-style-id="'+el.id+'"></style>');
1881 }
1882
1883 // Get it again
1884 style = pagelayer.$('[pagelayer-style-id='+el.id+']');
1885
1886 // Make the rules
1887 var rules = [];
1888
1889 // Loop
1890 for(var c in elCSS.css){
1891 var tSel = elCSS.css[c]['sel'].replace('{{element}}', elCSS.sel);
1892 var rule = pagelayer_parse_vars(elCSS.css[c]['val'], el);
1893 rules.push(tSel+'{'+rule+'}');
1894 }
1895
1896 // Set the style
1897 style.html(rules.join("\n"));
1898 //console.log(style);
1899 }else{
1900 style.remove();
1901 }
1902
1903 // Is there a function to render at the end ?
1904 var end = window['pagelayer_render_end_'+jEle.attr('pagelayer-tag')];
1905
1906 if(typeof end == 'function'){
1907 end(el);
1908 }
1909
1910 // If the element have any parent
1911 var par = pagelayer_get_parent(jEle);
1912 if(par){
1913 pagelayer_sc_render(pagelayer_ele_by_id(par));
1914 }
1915
1916 };
1917
1918 // Is the given tag a group
1919 function pagelayer_is_group(tag){
1920
1921 if('has_group' in pagelayer_shortcodes[tag] && !pagelayer_empty(pagelayer_shortcodes[tag]['has_group'])){
1922 return true;
1923 }
1924
1925 return false;
1926
1927 }
1928
1929 // Save the post
1930 function pagelayer_save(){
1931
1932 var post = pagelayer_generate_sc(".entry-content");//alert(post);return;
1933 var pagelayerajaxurl = pagelayer_ajax_url+'&action=pagelayer_save_content&postID='+pagelayer_postID;
1934 jQuery.ajax({
1935 type: "POST",
1936 url: pagelayerajaxurl,
1937 data: {
1938 pagelayer_update_content : post,
1939 nonce: pagelayer_ajax_nonce
1940 },
1941 success: function(response, status, xhr){
1942 //alert(data);
1943 var obj = jQuery.parseJSON(response);
1944 //alert(obj);
1945 if(obj['error']){
1946 alert(obj['error']);
1947 }else{
1948 pagelayer_isDirty = false;
1949 alert(obj['success']);
1950 }
1951 },
1952 error: function(errorThrown){
1953 console.log(errorThrown);
1954 }
1955 });
1956
1957 };
1958
1959 //Close the Editor
1960 function pagelayer_close(){
1961 if(pagelayer_isDirty == true){
1962 var r = confirm('Your Data has not been Saved yet! \n Press OK to stay on the Page.'+
1963 '\n Press Cancel to Close Editor. ');
1964 if(r == false){
1965 window.top.location.href = pagelayer_returnURL;
1966 }
1967 }else{
1968 window.top.location.href = pagelayer_returnURL;
1969 }
1970 };
1971
1972 // Generate Shortcode Post to save
1973 function pagelayer_generate_sc(selector){
1974
1975 var txt = '';
1976
1977 jQuery(selector).children(".pagelayer-ele-wrap").each(function(){
1978
1979 var jEle = jQuery(this).children('.pagelayer-ele');
1980
1981 // The ID
1982 var id = jEle.attr('pagelayer-id');
1983
1984 // If there is an Add element wrapper
1985 if(pagelayer_empty(id)){
1986 return;
1987 }
1988
1989 // Find the type of tag
1990 var tag = jEle.attr('pagelayer-tag');
1991 var final_tag = tag;
1992
1993 // Define inner row and inner column
1994 if(tag == 'pl_row' && jQuery(this).closest('.pagelayer-col-holder').length > 0){
1995 final_tag = 'pl_inner_row';
1996 }
1997 if(tag == 'pl_col' && jQuery(this).closest('.pagelayer-col-holder').length > 0){
1998 final_tag = 'pl_inner_col';
1999 }
2000 //console.log(tag);
2001
2002 // Is there an innerHTML ele
2003 var inner = '';
2004 if('innerHTML' in pagelayer_shortcodes[tag]){
2005 inner = pagelayer_shortcodes[tag]['innerHTML'];
2006 }
2007
2008 // Create the tag
2009 var data = '['+final_tag;
2010
2011 // Get the attributes to store
2012 jQuery.each(jEle[0].attributes, function(i, attrib){
2013 var res = attrib.name.match(/^pagelayer-a-(.+)/i);
2014 if(res && res[1] != inner){
2015 //console.log(attrib.name+' '+res[1]);
2016 data += ' '+res[1]+'="'+pagelayer_escapeHTML(attrib.value)+'"';
2017 }
2018 });
2019
2020 data = data+']';
2021
2022 // Add to the text
2023 txt = txt+data+"\n";
2024
2025 // Any internal function to handle the save ?
2026 var func = window['pagelayer_tag_'+tag];
2027 if(typeof func == 'function'){
2028
2029 var content = '';
2030 content = func(jEle);
2031
2032 if(content.length > 0){
2033 txt = txt+content;
2034 }
2035
2036 // If its a Row or Column or Group then it will have children
2037 }else if(jEle.hasClass('pagelayer-row') || jEle.hasClass('pagelayer-col') || jEle.hasClass('pagelayer-inner_row') || pagelayer_is_group(tag)){
2038
2039 var sel = "[pagelayer-id="+id+"]";
2040
2041 // Any holder which holds children ?
2042 if('holder' in pagelayer_shortcodes[tag]){
2043 sel = sel+' '+pagelayer_shortcodes[tag]['holder'];
2044 }
2045
2046 var childrens = pagelayer_generate_sc(jQuery(sel).first());
2047 if(childrens.length > 0){
2048 txt = txt+childrens;
2049 }
2050
2051 // Its a normal element so we might need to handle the content
2052 }else{
2053
2054 var content = '';
2055 if(inner.length > 0){
2056 content = jEle.attr('pagelayer-a-'+inner);
2057 if(!content){
2058 content = '';
2059 }
2060 }else{
2061 content = '';//jEle.html();
2062 }
2063
2064 if(content.length > 0){
2065 txt = txt+content;
2066 }
2067
2068 }
2069
2070 // Close the tag
2071 txt = txt+"[/"+final_tag+"]\n";
2072
2073 });
2074
2075 return txt;
2076
2077 };
2078
2079 // Escape charaters in attributes
2080 var pagelayer_escapeChars = {
2081 '\\]' : '#93',
2082 '\\[' : '#91',
2083 //'=' : '#61',
2084 '<' : 'lt',
2085 '>' : 'gt',
2086 '"' : 'quot',
2087 //'&' : 'amp',
2088 '\'' : '#39'
2089 };
2090
2091 // To unescape
2092 var pagelayer_unescapeChars = {
2093 '#93' : ']',
2094 '#91' : '[',
2095 //'#61' : '=',
2096 'lt' : '<',
2097 'gt' : '>',
2098 'quot' : '"',
2099 //'amp' : '&',
2100 '#39' : '\''
2101 };
2102
2103 var pagelayer_escaperegex_S = '[';
2104 for(var key in pagelayer_escapeChars) {
2105 pagelayer_escaperegex_S += key;
2106 }
2107 pagelayer_escaperegex_S += ']';
2108
2109 var pagelayer_escaperegex = new RegExp( pagelayer_escaperegex_S, 'g');
2110
2111 // The function which escapes everything
2112 function pagelayer_escapeHTML(str) {
2113 return str.replace(pagelayer_escaperegex, function(m) {
2114 if(m == '[' || m == ']') m = '\\'+m;
2115 return '&' + pagelayer_escapeChars[m] + ';';
2116 });
2117 };
2118
2119 // This will unescape everything
2120 function pagelayer_unescapeHTML(str){
2121 return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
2122 if(entityCode in pagelayer_unescapeChars){
2123 return pagelayer_unescapeChars[entityCode];
2124 }else{
2125 return entity;
2126 }
2127 });
2128 };
2129
2130 // Sets up the leftbar
2131 function pagelayer_leftbar(){
2132
2133 // Toggle the holder
2134 pagelayer.$$('.pagelayer-leftbar-toggle').on('click', function(){
2135 pagelayer.$$('.pagelayer-leftbar-table').toggle();
2136 });
2137
2138 var html = '<div class="pagelayer-leftbar">'+
2139 '<div class="pagelayer-leftbar-scroll">'+
2140 '<div class="pagelayer-shortcodes">'+
2141 '<div class="pagelayer-leftbar-search">'+
2142 '<input class="pagelayer-search-field" />'+
2143 '</div>';
2144
2145 for(var x in pagelayer_groups){
2146
2147 // Title
2148 html += '<div class="pagelayer-leftbar-group"><h5>'+x+'</h5>';
2149
2150 // Indivdual icon
2151 for(var y in pagelayer_groups[x]){
2152
2153 var sc = pagelayer_groups[x][y];
2154
2155 if('not_visible' in pagelayer_shortcodes[sc]){
2156 continue;
2157 }
2158
2159 html += '<div class="pagelayer-shortcode-drag" draggable="true" pagelayer-tag="'+sc+'">'+
2160 '<div class="pagelayer-sc">'+
2161 '<center class="pagelayer-shortcode-inner">';
2162
2163 if('icon' in pagelayer_shortcodes[sc]){
2164 html += '<i class="pagelayer-shortcode fa fa-'+pagelayer_shortcodes[sc]['icon']+'"></i>';
2165 }else{
2166 html += '<i class="pagelayer-shortcode pagelayer-'+sc+'"></i>';
2167 }
2168
2169 html += '</center>'+
2170 '<span class="pagelayer-shortcode-text">'+pagelayer_shortcodes[sc]['name']+'</span>'+
2171 '</div>'+
2172 '</div>';
2173
2174 }
2175
2176 html += '</div>';
2177
2178 }
2179
2180 html += '</div>'+
2181 '<div id="pagelayer-elpd" class="pagelayer-elpd"></div>'+
2182 '</div>'+
2183 '</div>';
2184
2185 pagelayer.$$('.pagelayer-leftbar-holder').prepend(html);
2186
2187 pagelayer.$$('.pagelayer-leftbar-scroll').slimScroll({
2188 height: '100%',
2189 railVisible: false,
2190 alwaysVisible: true,
2191 color: '#000',
2192 size: '5px',
2193 });
2194
2195 // Hide the ones which are not supposed to be shown
2196 pagelayer.$$('.pagelayer-search-field').on('input', function(){
2197
2198 var val = jQuery(this).val();
2199 var re = new RegExp(val, 'i');
2200
2201 // Show only the required tags
2202 pagelayer.$$('.pagelayer-leftbar-group').each(function(){
2203
2204 var group = jQuery(this);
2205 var res = group.find('[pagelayer-tag]');
2206 var hidden = 0;
2207
2208 res.each(function(){
2209
2210 var tEle = jQuery(this);
2211 if(tEle.find('.pagelayer-shortcode-text').html().match(re)){
2212 tEle.show();
2213 }else{
2214 hidden += 1;
2215 tEle.hide();
2216 }
2217
2218 });
2219
2220 // Hide the whole group
2221 if(hidden == res.length){
2222 group.hide();
2223 }else{
2224 group.show();
2225 }
2226
2227 });
2228 });
2229
2230 };
2231
2232 // Report an error
2233 function pagelayer_error(error, func){
2234 var prefix = func || '';
2235 alert(prefix+error);
2236 };
2237
2238 function pagelayer_bottombar(){
2239 var holder = pagelayer.$$('.pagelayer-bottombar-holder');
2240 var html = '<div class="pagelayer-bottombar">'+
2241 '<div class="pagelayer-bottombar-rightbuttons">'+
2242 '<button class="pagelayer-update-button">Update</button>'+
2243 '<button class="pagelayer-close-button">Close</button>'+
2244 '<div class="pagelayer-mode-wrapper">'+
2245 '<i class="pagelayer-mode-button fa fa-desktop"></i>'+
2246 '<div class="pagelayer-mode-buttons-wrapper">'+
2247 '<i class="screen-mode fa fa-desktop" pagelayer-mode-data="desktop"></i>'+
2248 '<i class="screen-mode fa fa-tablet" pagelayer-mode-data="tablet"></i>'+
2249 '<i class="screen-mode fa fa-mobile" pagelayer-mode-data="mobile"></i>'+
2250 '</div>'+
2251 '</div>'+
2252 '</div>'+
2253 '</div>';
2254
2255 holder.html(html);
2256 holder.find('.pagelayer-update-button').on('click', function(){
2257 pagelayer_save();
2258 });
2259 holder.find('.pagelayer-close-button').on('click', function(){
2260 pagelayer_close();
2261 });
2262 holder.find('.screen-mode').on('click', function(){
2263 var screen_mode = jQuery(this).attr('pagelayer-mode-data');
2264 pagelayer_set_screen_mode(screen_mode);
2265 holder.find('.pagelayer-mode-buttons-wrapper').toggle();
2266 });
2267
2268 holder.find('.pagelayer-mode-button').on('click', function(){
2269 holder.find('.pagelayer-mode-buttons-wrapper').toggle();
2270 });
2271 }
2272
2273
2274 ///////////////////////////////
2275 // Miscellaneuos Functions
2276 ///////////////////////////////
2277
2278 // Generates a random string of "n" characters
2279 function pagelayer_randstr(n, special){
2280 var text = '';
2281 var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2282
2283 special = special || 0;
2284 if(special){
2285 possible = possible + '&#$%@';
2286 }
2287
2288 for(var i=0; i < n; i++){
2289 text += possible.charAt(Math.floor(Math.random() * possible.length));
2290 }
2291
2292 return text;
2293 };
2294
2295 function pagelayer_update_site_title(val){
2296 if(!pagelayer_empty(val)){
2297 var site_name = jQuery('.pagelayer-wp-title').attr('pagelayer-a-site_name');
2298 if(!pagelayer_empty(site_name)){
2299 var site_title = jQuery.ajax({
2300 url: pagelayer_ajax_url+'&action=pagelayer_fetch_site_title',
2301 type: 'post',
2302 async: false
2303 }).responseText;
2304
2305 if(site_title != site_name){
2306 var site_title = jQuery.ajax({
2307 url: pagelayer_ajax_url+'&action=pagelayer_update_site_title',
2308 type: 'post',
2309 data: {'site_title': site_name},
2310 async: false
2311 }).responseText;
2312 }
2313 }
2314 }
2315 }
2316
2317 function pagelayer_trim(str, charlist){
2318 // discuss at: http://locutus.io/php/trim/
2319
2320 if(typeof str != 'string'){
2321 return str;
2322 }
2323
2324 var whitespace = [' ', '\n', '\r', '\t', '\f', '\x0b', '\xa0', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u200b', '\u2028', '\u2029', '\u3000' ].join('')
2325 var l = 0
2326 var i = 0
2327 str += ''
2328
2329 if (charlist) {
2330 whitespace = (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1')
2331 }
2332
2333 l = str.length
2334 for (i = 0; i < l; i++) {
2335 if (whitespace.indexOf(str.charAt(i)) === -1) {
2336 str = str.substring(i)
2337 break
2338 }
2339 }
2340
2341 l = str.length
2342 for (i = l - 1; i >= 0; i--) {
2343 if (whitespace.indexOf(str.charAt(i)) === -1) {
2344 str = str.substring(0, i + 1)
2345 break
2346 }
2347 }
2348
2349 return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''
2350 };
2351
2352 // Convert the regular URL of a Video to a Embed URL
2353 function pagelayer_video_url(src){
2354
2355 var youtubeRegExp = /youtube\.com|youtu\.be/;
2356 var vimeoRegExp = /vimeo\.com/;
2357 var match = '';
2358 var videoId = '';
2359
2360 if (youtubeRegExp.exec(src)) {
2361 match = 'youtube';
2362 } else if (vimeoRegExp.exec(src)) {
2363 match = 'vimeo';
2364 }
2365
2366 switch(match){
2367 case 'youtube':
2368
2369 var youtubeRegExp1 = /youtube\.com/;
2370 var youtubewatch = /watch/;
2371 var youtubeembed = /embed/;
2372 var youtube = /youtu\.be/;
2373
2374 if (youtubeRegExp1.exec(src)) {
2375
2376 if (youtubewatch.exec(src)) {
2377 videoId = src.split('?v=');
2378
2379 } else if (youtubewatch.exec(src)) {
2380 videoId = src.split('embed/');
2381 }
2382
2383 } else if (youtube.exec(src)) {
2384 videoId = src.split('.be/');
2385 }
2386
2387 return '//youtube.com/embed/'+videoId[1];
2388
2389 break;
2390
2391 case 'vimeo':
2392
2393 var vimeoplayer = /player\.vimeo\.com/;
2394 var vimeovideo = /video/;
2395
2396 if (vimeoplayer.exec(src) && vimeovideo.exec(src)) {
2397 videoId = src.split('video/');
2398 } else if (vimeoRegExp.exec(src)) {
2399 videoId = src.split('.com/');
2400 }
2401
2402 return '//player.vimeo.com/video/'+videoId[1];
2403
2404 break;
2405 default:
2406 return src;
2407 }
2408 };
2409
2410 // Add widget section
2411 function pagelayer_add_widget(){
2412
2413 html='<div class="pagelayer-add-widget-area">'+
2414 '<i class="pagelayer-add-row fa fa-plus-circle"></i>'+
2415 '<p>Click here to add new row OR drag widgets</p>'+
2416 '</div>';
2417
2418 jQuery('.entry-content').append(html);
2419
2420 var add_area = jQuery('.pagelayer-add-widget-area');
2421
2422 // Add a code before this
2423 var add_sc = function(tag){
2424
2425 // Create Row
2426 var row = jQuery('<div pagelayer-tag="pl_row"></div>');
2427 add_area.before(row);
2428 var row_id = pagelayer_onadd(row, false);
2429 var rEle = pagelayer_ele_by_id(row_id);
2430
2431 if(tag == 'pl_row'){
2432 rEle.click();
2433 return row_id;
2434 }
2435
2436 // Create Column
2437 var col = jQuery('<div pagelayer-tag="pl_col"></div>');
2438 rEle.find('.pagelayer-row-holder').append(col);
2439 var col_id = pagelayer_onadd(col, false);
2440 var cEle = pagelayer_ele_by_id(col_id);
2441
2442 if(tag == 'pl_col'){
2443 cEle.click();
2444 return col_id;
2445 }
2446
2447 // Create element
2448 var ele = jQuery('<div pagelayer-tag="'+tag+'"></div>');
2449 cEle.find('.pagelayer-col-holder').append(ele);
2450 var id = pagelayer_onadd(ele);
2451
2452 // Ensure the column is not empty
2453 pagelayer_empty_col(cEle.find('.pagelayer-col-holder'));
2454
2455 return id;
2456
2457 }
2458
2459 // Handle Click
2460 add_area.on('click', function(){
2461 add_sc('pl_col');
2462 });
2463
2464 // Handle Drag over
2465 add_area.on('dragover', function(e){
2466 //console.log(e)
2467 add_area.addClass('pagelayer-add-widget-drag');
2468 });
2469
2470 // Handle Drag Leave
2471 add_area.on('dragleave', function(e){
2472 //console.log(e)
2473 add_area.removeClass('pagelayer-add-widget-drag');
2474 });
2475
2476 // Handle On Drop
2477 add_area.on('drop', function(e){
2478
2479 //console.log(e);
2480 //console.log(e.originalEvent.dataTransfer.getData('tag'));
2481 add_area.removeClass('pagelayer-add-widget-drag');
2482 jQuery('.pagelayer-is-dragging').removeClass('pagelayer-is-dragging');
2483
2484 var tag = e.originalEvent.dataTransfer.getData('tag');
2485
2486 // Is it an existing element ?
2487 if(tag.length < 1){
2488 return false;
2489 }
2490
2491 e.preventDefault();
2492
2493 //console.log(tag);
2494
2495 add_sc(tag);
2496 });
2497 }
2498