PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 2.2.2
Page Builder: Pagelayer – Drag and Drop website builder v2.2.2
2.2.2 2.2.1 2.2.0 2.1.9 2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 trunk 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 1.0.0 1.0.2 1.0.3 1.0.4 All 130 releases
← All changes | js/pagelayer-editor.js +503 -39 2.1.3 → 2.2.2 View file →
@@ -207,8 +207,11 @@
207 207
208 208 // ON comment mode
209 209 const urlParams = new URLSearchParams(window.location.search);
210 210 pagelayer.cmode = urlParams.get('cmode');
211 +
212 + // Start custom UX Improvements engine
213 + setTimeout(pagelayer_ux_improvements_init, 200);
211 214 }
212 215
213 216 // Post props attribute
214 217 function pagelayer_post_props_atts(prop, val, temp){
@@ -1986,10 +1989,10 @@
1986 1989 var html = '<div class="pagelayer-right-click-options" style="display:none;">'+
1987 1990 '<ul>'+
1988 1991 '<li><a class="pagelayer-right-edit">Edit</a></li>'+
1989 1992 '<li><a class="pagelayer-right-duplicate"><i class="far fa-clone" ></i> '+pagelayer_l('Duplicate')+'</a></li>'+
1990 - '<li><a class="pagelayer-right-copy"><i class="far fa-copy" ></i> '+pagelayer_l('Copy')+' <span style="float:right">Ctrl+c</span></a></li>'+
1991 - '<li><a class="pagelayer-right-paste pagelayer-context-disable" title="If the paste is not done correctly then use Ctrl+V"><i class="far fa-clipboard" ></i> '+pagelayer_l('Paste')+' <span style="float:right">Ctrl+v</span></a></li>'+
1993 + '<li><a class="pagelayer-right-copy"><i class="far fa-copy" ></i> '+pagelayer_l('Copy')+' <span style="margin-left:10px;opacity:0.6">Ctrl+c</span></a></li>'+
1994 + '<li><a class="pagelayer-right-paste pagelayer-context-disable" title="If the paste is not done correctly then use Ctrl+V"><i class="far fa-clipboard" ></i> '+pagelayer_l('Paste')+' <span style="margin-left:10px;opacity:0.6">Ctrl+v</span></a></li>'+
1992 1995 '<li><a class="pagelayer-right-delete"><i class="far fa-trash-alt" ></i> '+pagelayer_l('Delete')+'</a></li>'+
1993 1996 '<li><a class="pagelayer-right-save-global-widget" pro="1"><i class="far fa-save" ></i> '+pagelayer_l('save_global')+'</a></li>'+
1994 1997 '<li><a class="pagelayer-right-save-section" pro="1"><i class="far fa-heart" ></i> '+pagelayer_l('save_as_section')+'</a></li>'+
1995 1998 '<li><a class="pagelayer-right-save-global-section" pro="1"><i class="fas fa-globe" ></i> '+pagelayer_l('save_as_global_section')+'</a></li>'+
@@ -2448,9 +2451,9 @@
2448 2451
2449 2452 // ctrl+s handle
2450 2453 if(event.keyCode == 83 && event.ctrlKey){
2451 2454 event.preventDefault();
2452 - pagelayer.$$('.pagelayer-bottombar-holder').find('.pagelayer-update-button').click();
2455 + pagelayer.$$('.pagelayer-iframe-top-bar').find('.pagelayer-update-button').click();
2453 2456 }
2454 2457
2455 2458 // ctrl+d handle
2456 2459 if(event.keyCode == 68 && event.ctrlKey){
@@ -5219,22 +5222,26 @@
5219 5222 var html = '<div class="pagelayer-leftbar">'+
5220 5223 '<div class="pagelayer-leftbar-scroll">'+
5221 5224 '<div id="pagelayer-shortcodes" class="pagelayer-leftbar-tab pagelayer-shortcodes">'+
5222 5225 '<div class="pagelayer-widget-tabs">'+
5226 + '<div class="pagelayer-widget-tab" pagelayer-widget-tab="widgets" pagelayer-elpd-active-tab=1>Widgets</div>'+
5223 5227 '<div class="pagelayer-widget-tab pagelayer-settings" pagelayer-widget-tab="settings">Settings</div>'+
5224 - '<div class="pagelayer-widget-tab" pagelayer-widget-tab="widgets" pagelayer-elpd-active-tab=1>Widgets</div>'+
5225 - '<div class="pagelayer-widget-tab" pagelayer-widget-tab="global">Global</div>'+
5228 + '<div class="pagelayer-widget-tab" pagelayer-widget-tab="global">Globals</div>'+
5226 5229 '</div>'+
5227 5230 '<div class="pagelayer-shortcodes-widget">'+
5228 5231 '<div class="pagelayer-leftbar-search">'+
5229 - '<i class="pli pli-search" ></i><input class="pagelayer-search-field" /><span class="pagelayer-sf-empty pli">&times;</span>'+
5232 + '<i class="pli pli-search" ></i><input class="pagelayer-search-field" placeholder="Search Widget..." /><span class="pagelayer-sf-empty pli">&times;</span>'+
5230 5233 '</div>';
5231 5234
5232 5235 for(var x in pagelayer_groups){
5233 5236
5234 5237 // Title
5235 - html += '<div class="pagelayer-leftbar-group pagelayer-group-name-'+x+'"><h5>'+x+'</h5>';
5238 + var group_title = x;
5239 + if (x === 'Basic') group_title = 'Atomic Elements';
5240 + else if (x === 'Common') group_title = 'General';
5236 5241
5242 + html += '<div class="pagelayer-leftbar-group pagelayer-group-name-'+x+'"><h5>'+group_title+'</h5>';
5243 +
5237 5244 // Indivdual icon
5238 5245 for(var y in pagelayer_groups[x]){
5239 5246
5240 5247 var sc = pagelayer_groups[x][y];
@@ -6045,11 +6052,30 @@
6045 6052 alert(prefix+error);
6046 6053 };
6047 6054
6048 6055 function pagelayer_bottombar(){
6049 - var holder = pagelayer.$$('.pagelayer-bottombar-holder');
6050 - var html = '<div class="pagelayer-bottombar">'+
6051 - '<div class="pagelayer-bottombar-rightbuttons">'+
6056 + var holder = pagelayer.$$('.pagelayer-iframe-top-bar');
6057 + pagelayer.$$('.pagelayer-iframe-top-bar').show();
6058 +
6059 + // Get post title
6060 + var post_title = (typeof pagelayer_post !== 'undefined' && pagelayer_post.post_title) ? pagelayer_post.post_title : 'Page';
6061 +
6062 + var html = '<div class="pagelayer-top-header-bar">'+
6063 + '<div class="pagelayer-header-left">'+
6064 + '<span class="pagelayer-header-document-title">Editing: <span class="pagelayer-header-post-name">' + post_title + '</span></span>'+
6065 + '</div>'+
6066 + '<div class="pagelayer-header-center">'+
6067 + '<div class="pagelayer-device-selectors">'+
6068 + '<i class="screen-mode pli pli-desktop" pagelayer-mode-data="desktop" data-tlite="Desktop View"></i>'+
6069 + '<i class="screen-mode pli pli-tablet" pagelayer-mode-data="tablet" data-tlite="Tablet View"></i>'+
6070 + '<i class="screen-mode pli pli-mobile" pagelayer-mode-data="mobile" data-tlite="Mobile View"></i>'+
6071 + '</div>'+
6072 + '</div>'+
6073 + '<div class="pagelayer-header-right">'+
6074 + '<span data-tlite="'+pagelayer_l('preview_changes')+'" class="pagelayer-header-icon-wrap"><i class="pagelayer-preview pli pli-eye"></i></span>'+
6075 + '<span data-tlite="'+pagelayer_l('historyand_revisions')+'" class="pagelayer-header-icon-wrap"><i class="pagelayer-history-icon pli pli-history"></i></span>'+
6076 + '<span data-tlite="'+pagelayer_l('navigator')+'" class="pagelayer-header-icon-wrap"><i class="pagelayer-navigator-icon pli pli-tree"></i></span>'+
6077 + '<div class="pagelayer-header-divider"></div>'+
6052 6078 '<button data-tlite="Save Changes" class="pagelayer-update-button pagelayer-success-btn">'+
6053 6079 '<span class="pagelayer-update-loader">'+
6054 6080 '<span></span>'+
6055 6081 '<span></span>'+
@@ -6056,25 +6082,18 @@
6056 6082 '<span></span>'+
6057 6083 '</span>'+
6058 6084 '<span class="pagelayer-update-text">Update</span>'+
6059 6085 '</button>'+
6060 - '<button data-tlite="Close and Return to Admin Panel" class="pagelayer-close-button">Close</button>'+
6061 - '<div class="pagelayer-mode-wrapper">'+
6062 - '<div class="pagelayer-mode-buttons-wrapper">'+
6063 - '<i class="screen-mode pli pli-desktop" pagelayer-mode-data="desktop"></i>'+
6064 - '<i class="screen-mode pli pli-tablet" pagelayer-mode-data="tablet"></i>'+
6065 - '<i class="screen-mode pli pli-mobile" pagelayer-mode-data="mobile"></i>'+
6066 - '</div>'+
6067 - '</div>'+
6068 - '<i class="pagelayer-mode-button pli pli-desktop"></i>'+
6069 - '<span data-tlite="'+pagelayer_l('preview_changes')+'"><i class="pagelayer-preview pli pli-eye"></i></span>'+
6070 - '<span data-tlite="'+pagelayer_l('historyand_revisions')+'"><i class="pagelayer-history-icon pli pli-history"></i></span>'+
6071 - '<span data-tlite="'+pagelayer_l('navigator')+'"><i class="pagelayer-navigator-icon pli pli-tree"></i></span>'+
6072 - //'<span data-tlite="Close and Return to Admin Panel"><i class="pagelayer-close-button fa fa-close"></i></span>'+
6086 + '<button data-tlite="Close Editor" class="pagelayer-close-button"><i class="pli pli-cross"></i></button>'+
6073 6087 '</div>'+
6074 6088 '</div>';
6075 6089
6076 6090 holder.html(html);
6091 +
6092 + // Add active class on load
6093 + var current_mode = pagelayer.screen_mode || 'desktop';
6094 + holder.find('.screen-mode[pagelayer-mode-data="' + current_mode + '"]').addClass('active');
6095 +
6077 6096 holder.find('.pagelayer-update-button').on('click', function(){
6078 6097 pagelayer_save();
6079 6098 pagelayer_history_setup();// Setup history tab after update
6080 6099 });
@@ -6081,19 +6100,17 @@
6081 6100
6082 6101 holder.find('.pagelayer-close-button').on('click', function(){
6083 6102 pagelayer_close();
6084 6103 });
6104 +
6085 6105 holder.find('.screen-mode').on('click', function(){
6086 6106 var screen_mode = jQuery(this).attr('pagelayer-mode-data');
6087 6107 pagelayer_set_screen_mode(screen_mode);
6088 - holder.find('.pagelayer-mode-buttons-wrapper').toggle();
6108 + holder.find('.screen-mode').removeClass('active');
6109 + jQuery(this).addClass('active');
6089 6110 });
6090 6111
6091 - holder.find('.pagelayer-mode-button').on('click', function(){
6092 - holder.find('.pagelayer-mode-buttons-wrapper').toggle();
6093 - });
6094 -
6095 - holder.find('.pagelayer-history-icon').click(function(){
6112 + holder.find('.pagelayer-history-icon').closest('.pagelayer-header-icon-wrap').click(function(){
6096 6113 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text(pagelayer_l('pagelayer_history'));
6097 6114 pagelayer.$$('.pagelayer-logo').hide();
6098 6115 pagelayer_leftbar_tab('pagelayer-history');
6099 6116 pagelayer_active = {};
@@ -6099,9 +6116,9 @@
6099 6116 pagelayer_active = {};
6100 6117 pagelayer_history_setup();
6101 6118 });
6102 6119
6103 - holder.find('.pagelayer-navigator-icon').click(function(){
6120 + holder.find('.pagelayer-navigator-icon').closest('.pagelayer-header-icon-wrap').click(function(){
6104 6121 pagelayer.$$('.pagelayer-elpd-header').show().find('.pagelayer-elpd-title').text(pagelayer_l('pagelayer_navigator'));
6105 6122 pagelayer.$$('.pagelayer-logo').hide();
6106 6123
6107 6124 // If the navigator tab visible, then don't setup
@@ -6219,19 +6236,19 @@
6219 6236 });
6220 6237
6221 6238 // Show Pagelayer History
6222 6239 holder.find('.pagelayer-options-history-icon').click(function(){
6223 - pagelayer.$$('.pagelayer-bottombar-holder .pagelayer-history-icon').click();
6240 + pagelayer.$$('.pagelayer-iframe-top-bar .pagelayer-history-icon').click();
6224 6241 });
6225 6242
6226 6243 // Show Pagelayer Navigator
6227 6244 holder.find('.pagelayer-options-navigator-icon').click(function(){
6228 - pagelayer.$$('.pagelayer-bottombar-holder .pagelayer-navigator-icon').click();
6245 + pagelayer.$$('.pagelayer-iframe-top-bar .pagelayer-navigator-icon').click();
6229 6246 });
6230 6247
6231 6248 // Show Pagelayer Preview
6232 6249 holder.find('.pagelayer-options-preview').click(function(){
6233 - pagelayer.$$('.pagelayer-bottombar-holder .pagelayer-preview').click();
6250 + pagelayer.$$('.pagelayer-iframe-top-bar .pagelayer-preview').click();
6234 6251 });
6235 6252
6236 6253 // Show keyboard shortcut modal
6237 6254 holder.find('.pagelayer-open-keyboard-shortcuts').click(function() {
@@ -6537,11 +6554,14 @@
6537 6554 // Add widget section
6538 6555 function pagelayer_add_widget(){
6539 6556
6540 6557 html='<div class="pagelayer-add-widget-area">'+
6541 - '<button class="pagelayer-add-button pagelayer-add-section"><i class="pagelayer-add-row fas fa-file-alt"></i> &nbsp;Add New Section</button>'+
6542 - '<button class="pagelayer-add-button pagelayer-add-row"><i class="pagelayer-add-row fas fa-plus-circle"></i> &nbsp;Add New Row</button>'+
6543 - '<p>Click here to add new row OR drag widgets</p>'+
6558 + '<div class="pagelayer-add-buttons-container">'+
6559 + '<button type="button" class="pagelayer-add-circle-btn pagelayer-add-circle-plus" title="Add New Row"><i class="fas fa-plus"></i></button>'+
6560 + '<button type="button" class="pagelayer-add-circle-btn pagelayer-add-circle-folder pagelayer-add-section" title="Add Template"><i class="fas fa-folder"></i></button>'+
6561 + '<button type="button" class="pagelayer-add-circle-btn pagelayer-add-circle-ai pagelayer-add-ai" title="Build with AI"><i class="fas fa-magic"></i></button>'+
6562 + '</div>'+
6563 + '<p class="pagelayer-add-widget-text">Click here to add new row OR drag widgets</p>'+
6544 6564 '</div>';
6545 6565
6546 6566 jQuery(pagelayer_editable).append(html);
6547 6567
@@ -6605,20 +6625,44 @@
6605 6625 return id;
6606 6626
6607 6627 }
6608 6628
6609 - // Handle Click
6610 - add_area.on('click', function(e){
6629 + // Handle Click on Plus Button
6630 + add_area.find('.pagelayer-add-circle-plus').on('click', function(e){
6611 6631 e.stopPropagation();
6612 6632 add_sc('pl_col');
6613 6633 });
6614 6634
6615 - // Handle Click
6635 + // Handle Click on Template/Folder Button
6616 6636 add_area.find('.pagelayer-add-section').on('click', function(e){
6617 6637 e.stopPropagation();
6618 6638 pagelayer_add_section_area();// Setup and show sections modal
6619 6639 });
6620 6640
6641 + // Handle Click on Build with AI Button
6642 + add_area.find('.pagelayer-add-ai, .pagelayer-add-circle-ai').on('click', function(e){
6643 + e.stopPropagation();
6644 + if(typeof PagelayerAI !== 'undefined' && PagelayerAI.showPanel){
6645 + PagelayerAI.showPanel();
6646 + } else if(typeof window.parent !== 'undefined' && typeof window.parent.PagelayerAI !== 'undefined' && window.parent.PagelayerAI.showPanel){
6647 + window.parent.PagelayerAI.showPanel();
6648 + } else if(jQuery('.pagelayer-ai-topbar-btn').length > 0){
6649 + jQuery('.pagelayer-ai-topbar-btn').trigger('click');
6650 + } else if(window.parent && window.parent.jQuery && window.parent.jQuery('.pagelayer-ai-topbar-btn').length > 0){
6651 + window.parent.jQuery('.pagelayer-ai-topbar-btn').trigger('click');
6652 + }
6653 + });
6654 +
6655 +
6656 +
6657 + // Background click fallback (adds column if clicked outside circles)
6658 + add_area.on('click', function(e){
6659 + if(e.target === this || jQuery(e.target).hasClass('pagelayer-add-widget-text')){
6660 + e.stopPropagation();
6661 + add_sc('pl_col');
6662 + }
6663 + });
6664 +
6621 6665 // Handle Drag over
6622 6666 add_area.on('dragover', function(e){
6623 6667 //console.log(e)
6624 6668 add_area.addClass('pagelayer-add-widget-drag');
@@ -7715,4 +7759,424 @@
7715 7759 caretOffset = preCaretTextRange.text.length;
7716 7760 }
7717 7761 return caretOffset;
7718 7762 }
7763 +
7764 +// ==========================================================================
7765 +// PAGELAYER UX IMPROVEMENTS
7766 +// ==========================================================================
7767 +
7768 +var pagelayer_is_command_palette_open = false;
7769 +
7770 +function pagelayer_ux_improvements_init() {
7771 + // Setup global shortcuts inside Parent Window and Iframe Document
7772 + var setupShortcuts = function(doc) {
7773 + jQuery(doc).on('keydown', function(e) {
7774 + // Command Palette: Ctrl+K
7775 + if (e.key === 'k' && (e.ctrlKey || e.metaKey)) {
7776 + e.preventDefault();
7777 + pagelayer_toggle_command_palette();
7778 + }
7779 + });
7780 + };
7781 +
7782 + setupShortcuts(document);
7783 + if (pagelayer.gDocument) {
7784 + setupShortcuts(pagelayer.gDocument);
7785 + }
7786 +
7787 + // Hook selection callback to refresh Navigator if it is open in the right sidebar
7788 + pagelayer_add_action('pagelayer_element_clicked', function(jEle) {
7789 + if (jEle && jEle.length > 0) {
7790 + var isNavigatorOpen = pagelayer.$$('body').hasClass('pagelayer-right-sidebar-open') && pagelayer.$$('#pagelayer-navigator').is(':visible');
7791 + if (isNavigatorOpen) {
7792 + var newId = pagelayer_id(jEle);
7793 + if (newId) {
7794 + pagelayer_active.el = pagelayer_active.el || {};
7795 + pagelayer_active.el.id = newId;
7796 + }
7797 + pagelayer_navigator_setup();
7798 + }
7799 + }
7800 + });
7801 +
7802 + // Redirect Navigator & History/Revisions tabs to a new small right sidebar
7803 + window.pagelayer_close_right_sidebar = function() {
7804 + var sidebar = pagelayer.$$('.pagelayer-right-sidebar');
7805 + if (sidebar.length > 0) {
7806 + sidebar.css('right', '-300px');
7807 + pagelayer.$$('body').removeClass('pagelayer-right-sidebar-open');
7808 + pagelayer.$$('.pagelayer-navigator-icon, .pagelayer-history-icon').closest('.pagelayer-header-icon-wrap').removeClass('active');
7809 + pagelayer.$$('#pagelayer-navigator').hide();
7810 + pagelayer.$$('#pagelayer-history').hide();
7811 + }
7812 + };
7813 +
7814 + window.pagelayer_open_right_sidebar = function(tab) {
7815 + var sidebar = pagelayer.$$('.pagelayer-right-sidebar');
7816 + if (sidebar.length === 0) {
7817 + var sidebarHtml =
7818 + '<div class="pagelayer-right-sidebar">' +
7819 + '<div class="pagelayer-right-sidebar-header">' +
7820 + '<h4 class="pagelayer-right-sidebar-title"></h4>' +
7821 + '<button class="pagelayer-right-sidebar-close"><i class="pli pli-cross"></i></button>' +
7822 + '</div>' +
7823 + '<div class="pagelayer-right-sidebar-content">' +
7824 + '</div>' +
7825 + '</div>';
7826 + pagelayer.$$('body').append(sidebarHtml);
7827 + sidebar = pagelayer.$$('.pagelayer-right-sidebar');
7828 +
7829 + sidebar.find('.pagelayer-right-sidebar-close').on('click', function() {
7830 + window.pagelayer_close_right_sidebar();
7831 + });
7832 + }
7833 +
7834 + var isDark = pagelayer.$$('body').hasClass('pagelayer-dark');
7835 + if (isDark) {
7836 + sidebar.addClass('pagelayer-dark');
7837 + } else {
7838 + sidebar.removeClass('pagelayer-dark');
7839 + }
7840 +
7841 + pagelayer.$$('.pagelayer-navigator-icon, .pagelayer-history-icon').closest('.pagelayer-header-icon-wrap').removeClass('active');
7842 +
7843 + var title = '';
7844 + var iconClass = '';
7845 + if (tab === 'pagelayer-navigator') {
7846 + title = pagelayer_l('pagelayer_navigator') || 'Navigator';
7847 + iconClass = '.pagelayer-navigator-icon';
7848 + } else {
7849 + title = pagelayer_l('pagelayer_history') || 'History & Revisions';
7850 + iconClass = '.pagelayer-history-icon';
7851 + }
7852 +
7853 + sidebar.find('.pagelayer-right-sidebar-title').text(title);
7854 +
7855 + var isVisible = pagelayer.$$('body').hasClass('pagelayer-right-sidebar-open');
7856 + var targetContainer = pagelayer.$$('#' + tab);
7857 + if (isVisible && targetContainer.length > 0 && targetContainer.is(':visible')) {
7858 + window.pagelayer_close_right_sidebar();
7859 + return;
7860 + }
7861 +
7862 + pagelayer.$$(iconClass).closest('.pagelayer-header-icon-wrap').addClass('active');
7863 + sidebar.find('.pagelayer-right-sidebar-content').children().hide();
7864 +
7865 + if (targetContainer.parent().hasClass('pagelayer-right-sidebar-content') === false) {
7866 + sidebar.find('.pagelayer-right-sidebar-content').append(targetContainer);
7867 + }
7868 +
7869 + targetContainer.show().css({'height': '100%', 'position': 'static'});
7870 + sidebar.css('right', '0px');
7871 + pagelayer.$$('body').addClass('pagelayer-right-sidebar-open');
7872 + };
7873 +
7874 + var original_pagelayer_leftbar_tab = window.pagelayer_leftbar_tab;
7875 + window.pagelayer_leftbar_tab = function(tab) {
7876 + if (tab === 'pagelayer-navigator' || tab === 'pagelayer-history') {
7877 + window.pagelayer_open_right_sidebar(tab);
7878 + } else {
7879 + // Do not hide navigator or history tab if they are in the right sidebar
7880 + pagelayer.$$('.pagelayer-leftbar-tab').not('#pagelayer-navigator, #pagelayer-history').hide();
7881 + pagelayer.$$('#'+tab).show();
7882 + }
7883 + };
7884 +
7885 + var bindIcons = function() {
7886 + var $historyIcon = pagelayer.$$('.pagelayer-history-icon');
7887 + $historyIcon.off('click');
7888 + $historyIcon.closest('.pagelayer-header-icon-wrap').off('click').on('click', function(e) {
7889 + e.stopPropagation();
7890 + window.pagelayer_open_right_sidebar('pagelayer-history');
7891 + pagelayer_history_setup();
7892 + });
7893 +
7894 + var $navigatorIcon = pagelayer.$$('.pagelayer-navigator-icon');
7895 + $navigatorIcon.off('click');
7896 + $navigatorIcon.closest('.pagelayer-header-icon-wrap').off('click').on('click', function(e) {
7897 + e.stopPropagation();
7898 + var targetContainer = pagelayer.$$('#pagelayer-navigator');
7899 + if (!targetContainer.is(':visible')) {
7900 + pagelayer_navigator_setup();
7901 + }
7902 + window.pagelayer_open_right_sidebar('pagelayer-navigator');
7903 + });
7904 + };
7905 +
7906 + bindIcons();
7907 + setInterval(bindIcons, 3000);
7908 +}
7909 +
7910 +// Toggle Command Palette Modal (Figma / Bricks style search palette)
7911 +function pagelayer_toggle_command_palette() {
7912 + var modal = pagelayer.$$('.pagelayer-command-palette-modal');
7913 + if (modal.length > 0) {
7914 + if (modal.is(':visible')) {
7915 + modal.hide();
7916 + pagelayer_is_command_palette_open = false;
7917 + } else {
7918 + modal.show().find('.pagelayer-cmd-input').focus().val('');
7919 + pagelayer_is_command_palette_open = true;
7920 + pagelayer_render_command_palette_results('');
7921 + }
7922 + return;
7923 + }
7924 +
7925 + // Create modal in parent window
7926 + var modalHtml = '<div class="pagelayer-command-palette-modal" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(15, 23, 42, 0.4); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); z-index: 99999; display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;">' +
7927 + '<div class="pagelayer-cmd-container" style="width: 550px; background: #ffffff; border-radius: 12px; box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04); display: flex; flex-direction: column; overflow: hidden; border: 1px solid #e2e8f0; max-height: 450px;">' +
7928 + '<div class="pagelayer-cmd-search-bar" style="display: flex; align-items: center; padding: 14px 18px; border-bottom: 1px solid #f1f5f9; gap: 12px;">' +
7929 + '<i class="fas fa-search" style="color: #64748b; font-size: 16px;"></i>' +
7930 + '<input type="text" class="pagelayer-cmd-input" placeholder="Search widgets, actions, settings..." style="flex: 1; border: none; outline: none; font-size: 15px; color: #0f172a; padding: 0; background: transparent;" />' +
7931 + '<span style="font-size: 11px; background: #f1f5f9; color: #64748b; padding: 2px 6px; border-radius: 4px; border: 1px solid #cbd5e1;">ESC</span>' +
7932 + '</div>' +
7933 + '<div class="pagelayer-cmd-results" style="flex: 1; overflow-y: auto; padding: 8px 0; max-height: 380px;">' +
7934 + '</div>' +
7935 + '</div>' +
7936 + '</div>';
7937 +
7938 + pagelayer.$$('body').append(modalHtml);
7939 + modal = pagelayer.$$('.pagelayer-command-palette-modal');
7940 + pagelayer_is_command_palette_open = true;
7941 +
7942 + // Add dark mode support to command palette
7943 + if (pagelayer.$$('body').hasClass('pagelayer-dark')) {
7944 + modal.find('.pagelayer-cmd-container').css({ 'background': '#0b0f19', 'border-color': '#1e293b', 'color': '#f8fafc' });
7945 + modal.find('.pagelayer-cmd-search-bar').css({ 'border-bottom-color': '#1e293b' });
7946 + modal.find('.pagelayer-cmd-input').css({ 'color': '#f8fafc' });
7947 + modal.find('span').css({ 'background': '#1e293b', 'color': '#cbd5e1', 'border-color': '#334155' });
7948 + }
7949 +
7950 + modal.on('click', function(e) {
7951 + if (e.target === this) {
7952 + modal.hide();
7953 + pagelayer_is_command_palette_open = false;
7954 + }
7955 + });
7956 +
7957 + modal.find('.pagelayer-cmd-input').on('input', function() {
7958 + var q = jQuery(this).val();
7959 + pagelayer_render_command_palette_results(q);
7960 + });
7961 +
7962 + modal.find('.pagelayer-cmd-input').on('keydown', function(e) {
7963 + var results = modal.find('.pagelayer-cmd-item');
7964 + var active = modal.find('.pagelayer-cmd-item.active');
7965 +
7966 + if (e.key === 'ArrowDown') {
7967 + e.preventDefault();
7968 + if (active.length === 0 || active.is(':last-child')) {
7969 + results.removeClass('active').first().addClass('active').get(0).scrollIntoView({ block: 'nearest' });
7970 + } else {
7971 + active.removeClass('active').next().addClass('active').get(0).scrollIntoView({ block: 'nearest' });
7972 + }
7973 + } else if (e.key === 'ArrowUp') {
7974 + e.preventDefault();
7975 + if (active.length === 0 || active.is(':first-child')) {
7976 + results.removeClass('active').last().addClass('active').get(0).scrollIntoView({ block: 'nearest' });
7977 + } else {
7978 + active.removeClass('active').prev().addClass('active').get(0).scrollIntoView({ block: 'nearest' });
7979 + }
7980 + } else if (e.key === 'Enter') {
7981 + e.preventDefault();
7982 + if (active.length > 0) {
7983 + active.click();
7984 + }
7985 + } else if (e.key === 'Escape') {
7986 + modal.hide();
7987 + pagelayer_is_command_palette_open = false;
7988 + }
7989 + });
7990 +
7991 + modal.find('.pagelayer-cmd-input').focus();
7992 + pagelayer_render_command_palette_results('');
7993 +}
7994 +
7995 +function pagelayer_render_command_palette_results(query) {
7996 + var modal = pagelayer.$$('.pagelayer-command-palette-modal');
7997 + var resultsContainer = modal.find('.pagelayer-cmd-results');
7998 + resultsContainer.empty();
7999 +
8000 + query = query.toLowerCase().trim();
8001 + var items = [];
8002 +
8003 + // 1. Gather all shortcodes/widgets
8004 + var addedWidgets = {};
8005 +
8006 + // First, gather from pagelayer_groups to prioritize standard draggable widgets
8007 + for (var group in pagelayer_groups) {
8008 + for (var index in pagelayer_groups[group]) {
8009 + var key = pagelayer_groups[group][index];
8010 + if (addedWidgets[key]) continue;
8011 +
8012 + var sc = pagelayer_shortcodes[key];
8013 + if (!sc || !sc.name || 'not_visible' in sc) continue;
8014 +
8015 + if (query === '' || sc.name.toLowerCase().indexOf(query) > -1 || key.toLowerCase().indexOf(query) > -1) {
8016 + items.push({
8017 + type: 'widget',
8018 + title: sc.name,
8019 + subtitle: 'Add Widget',
8020 + key: key,
8021 + icon: sc.icon || '',
8022 + action: (function(k) {
8023 + return function() {
8024 + pagelayer_insert_widget(k);
8025 + };
8026 + })(key)
8027 + });
8028 + addedWidgets[key] = true;
8029 + }
8030 + }
8031 + }
8032 +
8033 + // Fallback to scan raw shortcodes to capture any miscellaneous widgets not categorized in sidebar groups
8034 + for (var key in pagelayer_shortcodes) {
8035 + if (addedWidgets[key]) continue;
8036 +
8037 + var sc = pagelayer_shortcodes[key];
8038 + if (!sc || !sc.name || 'not_visible' in sc) continue;
8039 +
8040 + if (query === '' || sc.name.toLowerCase().indexOf(query) > -1 || key.toLowerCase().indexOf(query) > -1) {
8041 + items.push({
8042 + type: 'widget',
8043 + title: sc.name,
8044 + subtitle: 'Add Widget',
8045 + key: key,
8046 + icon: sc.icon || '',
8047 + action: (function(k) {
8048 + return function() {
8049 + pagelayer_insert_widget(k);
8050 + };
8051 + })(key)
8052 + });
8053 + addedWidgets[key] = true;
8054 + }
8055 + }
8056 +
8057 + // 2. Gather editor actions
8058 + var actions = [
8059 + { title: 'Undo Last Edit', subtitle: 'History Action', icon: 'fas fa-undo', search: 'undo ctrl+z back', action: function() { pagelayer_do_history('undo'); } },
8060 + { title: 'Redo Edit', subtitle: 'History Action', icon: 'fas fa-redo', search: 'redo ctrl+y', action: function() { pagelayer_do_history('redo'); } },
8061 + { title: 'Switch to Desktop View', subtitle: 'Screen Mode', icon: 'fas fa-desktop', search: 'desktop screen responsive preview', action: function() { pagelayer_set_screen_mode('desktop'); } },
8062 + { title: 'Switch to Tablet View', subtitle: 'Screen Mode', icon: 'fas fa-tablet-alt', search: 'tablet screen responsive preview', action: function() { pagelayer_set_screen_mode('tablet'); } },
8063 + { title: 'Switch to Mobile View', subtitle: 'Screen Mode', icon: 'fas fa-mobile-alt', search: 'mobile screen responsive preview phone', action: function() { pagelayer_set_screen_mode('mobile'); } },
8064 + { title: 'Open Revisions & History', subtitle: 'Revision History', icon: 'fas fa-history', search: 'history revisions undo changes', action: function() { pagelayer.$$('.pagelayer-history-icon').click(); } },
8065 + { title: 'Save Page Changes', subtitle: 'Update Page', icon: 'fas fa-save', search: 'save update publish commit ctrl+s', action: function() { pagelayer.$$('.pagelayer-update-button').click(); } },
8066 + { title: 'Open Navigator / Elements Tree', subtitle: 'Navigator Panel', icon: 'fas fa-sitemap', search: 'navigator tree hierarchy layers structure outline', action: function() { pagelayer.$$('.pagelayer-navigator-icon').click(); } }
8067 + ];
8068 +
8069 + actions.forEach(function(act) {
8070 + if (query === '' || act.title.toLowerCase().indexOf(query) > -1 || act.search.indexOf(query) > -1) {
8071 + items.push({
8072 + type: 'action',
8073 + title: act.title,
8074 + subtitle: act.subtitle,
8075 + icon: act.icon,
8076 + action: act.action
8077 + });
8078 + }
8079 + });
8080 +
8081 + if (items.length === 0) {
8082 + resultsContainer.html('<div style="text-align: center; color: #64748b; padding: 24px 0; font-size: 14px;">No results found. Try another query.</div>');
8083 + return;
8084 + }
8085 +
8086 + var slice = items.slice(0, 100);
8087 + var isDark = pagelayer.$$('body').hasClass('pagelayer-dark');
8088 +
8089 + slice.forEach(function(item, idx) {
8090 + var iconClass = '';
8091 + if (item.type === 'widget') {
8092 + if (item.icon) {
8093 + iconClass = 'pagelayer-shortcode ' + item.icon;
8094 + } else {
8095 + iconClass = 'pagelayer-shortcode pli pagelayer-' + item.key;
8096 + }
8097 + } else {
8098 + iconClass = item.icon;
8099 + }
8100 + var itemHtml = jQuery('<div class="pagelayer-cmd-item ' + (idx === 0 ? 'active' : '') + '" style="display: flex; align-items: center; padding: 10px 18px; cursor: pointer; transition: background 0.15s, color 0.15s; gap: 14px; font-size: 14px;">' +
8101 + '<div class="pagelayer-cmd-icon" style="width: 28px; height: 28px; background: ' + (isDark ? '#1e293b' : '#f1f5f9') + '; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: #2563eb; font-size: 16px;"><i class="' + iconClass + '"></i></div>' +
8102 + '<div style="flex: 1; display: flex; flex-direction: column;">' +
8103 + '<span style="font-weight: 500; color: ' + (isDark ? '#f8fafc' : '#0f172a') + ';">' + item.title + '</span>' +
8104 + '<span style="font-size: 11px; color: #64748b;">' + item.subtitle + '</span>' +
8105 + '</div>' +
8106 + '</div>');
8107 +
8108 + var hoverBg = isDark ? '#1e293b' : '#f8fafc';
8109 +
8110 + itemHtml.hover(function() {
8111 + modal.find('.pagelayer-cmd-item').removeClass('active');
8112 + jQuery(this).addClass('active');
8113 + });
8114 +
8115 + itemHtml.on('click', function() {
8116 + modal.hide();
8117 + pagelayer_is_command_palette_open = false;
8118 + item.action();
8119 + });
8120 +
8121 + resultsContainer.append(itemHtml);
8122 + });
8123 +
8124 + var styleTag = pagelayer.$$('head #pagelayer-cmd-palette-styles');
8125 + if (styleTag.length === 0) {
8126 + pagelayer.$$('head').append('<style id="pagelayer-cmd-palette-styles">' +
8127 + '.pagelayer-cmd-item.active { background: ' + (isDark ? '#1e293b !important' : '#f1f5f9 !important') + '; }' +
8128 + '</style>');
8129 + }
8130 +}
8131 +
8132 +// Programmatic widget placement
8133 +function pagelayer_insert_widget(tag) {
8134 + var active = pagelayer_active.el;
8135 + var parentCol = null;
8136 + var target = null;
8137 + var method = 'append';
8138 +
8139 + if (active && active.$) {
8140 + var tag_active = pagelayer_tag(active.$);
8141 + if (tag_active === 'pl_col') {
8142 + parentCol = active.$.find('>.pagelayer-col-holder');
8143 + method = 'append';
8144 + } else if (tag_active === 'pl_row' || tag_active === 'pl_inner_row') {
8145 + parentCol = active.$.find('.pagelayer-col-holder').first();
8146 + method = 'append';
8147 + } else {
8148 + target = active.$.closest('.pagelayer-ele-wrap');
8149 + method = 'after';
8150 + }
8151 + } else {
8152 + parentCol = jQuery(pagelayer_editable).find('.pagelayer-col-holder').first();
8153 + method = 'append';
8154 + }
8155 +
8156 + if ((!parentCol || parentCol.length === 0) && (!target || target.length === 0)) {
8157 + var row = jQuery('<div pagelayer-tag="pl_row"></div>');
8158 + jQuery(pagelayer_editable).append(row);
8159 + var rowId = pagelayer_onadd(row, false);
8160 + var rEle = pagelayer_ele_by_id(rowId);
8161 +
8162 + var col = jQuery('<div pagelayer-tag="pl_col"></div>');
8163 + rEle.find('.pagelayer-row-holder').append(col);
8164 + var colId = pagelayer_onadd(col, false);
8165 + var cEle = pagelayer_ele_by_id(colId);
8166 + parentCol = cEle.find('.pagelayer-col-holder');
8167 + method = 'append';
8168 + }
8169 +
8170 + var ele = jQuery('<div pagelayer-tag="' + tag + '"></div>');
8171 + if (method === 'append') {
8172 + parentCol.append(ele);
8173 + pagelayer_empty_col(parentCol);
8174 + } else {
8175 + target.after(ele);
8176 + pagelayer_empty_col(target.closest('.pagelayer-col-holder'));
8177 + }
8178 +
8179 + var newId = pagelayer_onadd(ele, true);
8180 + pagelayer_do_dirty(ele);
8181 +}
8182 +