customizer-content.js (21870B)
1 (function ($) { 2 3 var listItemTemplate = _.template( 4 '<li class="full_row item" data-id="<%= sectionID %>">' + 5 ' <div class="reorder-handler"></div>' + 6 ' <div class="label-wrapper">' + 7 ' <input class="item-label" value="<%= label %>" />' + 8 ' <div class="anchor-info">' + 9 ' #<%= id.replace(/#/,\'\') %>' + 10 ' </div>' + 11 ' </div>' + 12 ' <div class="item-hover">' + 13 ' <% if(setting) { %>' + 14 ' <span title="' + window.CP_Customizer.translateCompanionString("Edit section settings") + '" data-setting="<%= setting %>" class="item-settings"></span>' + 15 ' <% } %>' + 16 ' <span title="' + window.CP_Customizer.translateCompanionString("Toggle visibility in primary menu") + '" class="item-menu-visible <%= (inMenu?\'active\':\'\') %>"></span>' + 17 ' <span title="' + window.CP_Customizer.translateCompanionString("Delete section from page") + '" class="item-remove"></span>' + 18 ' </div>' + 19 ' </li>' 20 ); 21 22 window.CP_Customizer.addModule(function (CP_Customizer) { 23 var control = wp.customize.panel('page_content_panel'); 24 25 if (!control) { 26 return; 27 } 28 29 var $contentLi = control.container.eq(0); 30 // remove default events 31 $contentLi.children('h3').addBack().off(); 32 33 $sectionsSidebarTogglers = $contentLi.find('.add-section-plus').add($contentLi.find('.cp-add-section')); 34 35 CP_Customizer.one(CP_Customizer.events.PREVIEW_LOADED, function () { 36 if (CP_Customizer.preview.data("can:change_page_settings")) { 37 $contentLi.find('span.section-icon.setting').removeClass('hidden').click(function (event) { 38 event.preventDefault(); 39 event.stopPropagation(); 40 41 var sectionID = "cp-current-page-settings"; 42 43 if (CP_Customizer.isRightSidebarVisible(sectionID)) { 44 CP_Customizer.hideRightSidebar(); 45 } else { 46 CP_Customizer.openRightSidebar(sectionID); 47 } 48 }); 49 } 50 }); 51 var sectionID = 'page_content_section'; 52 $sectionsSidebarTogglers.click(function (event) { 53 event.preventDefault(); 54 event.stopPropagation(); 55 56 57 if (CP_Customizer.isRightSidebarVisible(sectionID)) { 58 CP_Customizer.hideRightSidebar(); 59 $sectionsSidebarTogglers.removeClass('active'); 60 } else { 61 CP_Customizer.openRightSidebar(sectionID); 62 $sectionsSidebarTogglers.addClass('active'); 63 } 64 }); 65 66 CP_Customizer.focusContentSection = function (toFocus) { 67 CP_Customizer.openRightSidebar("page_content_section", { 68 focus: '[data-category=' + toFocus + ']' 69 }) 70 }; 71 72 function getNextInArray(data, start, separator) { 73 var increments = data.filter(function (item) { 74 return item.replace(start, '').length; 75 }).map(function (item) { 76 return parseInt(item.replace(start + (separator || '--'), '')) || 0; 77 }); 78 79 return increments.length ? Math.max.apply(Math, increments) + 1 : 1; 80 } 81 82 function getNextId(start) { 83 var ids = CP_Customizer.preview.getContentNodes().filter(function (item) { 84 return (item.tagName && item.tagName !== 'undefined' && item.tagName.toLowerCase() === 'div' && item.id.indexOf(start) === 0) 85 }).map(function (item) { 86 return item.id 87 }); 88 return start + "-" + getNextInArray(ids, start, '-'); 89 } 90 91 function getNextDataId(start) { 92 var dataIds = CP_Customizer.preview.getContentNodes().filter(function (item) { 93 return (item.tagName && item.tagName !== 'undefined' && item.tagName.toLowerCase() === 'div' && item.getAttribute('data-id') && (item.getAttribute('data-id') || "").indexOf(start) === 0) 94 }).map(function (item) { 95 return item.getAttribute('data-id') 96 }); 97 98 return start + "--" + getNextInArray(dataIds, start); 99 } 100 101 102 CP_Customizer.preview.insertSectionFromData = function (data, skipEvent) { 103 if (data) { 104 var $content = $(data.content), 105 dataId = getNextDataId(data.category || data.elementId); 106 107 $content.attr('id', getNextId(data.category || data.elementId)); 108 $content.attr('data-id', dataId); 109 110 var index; 111 112 if (data.prepend === true || parseInt(data.prepend) === 1) { 113 index = 0; 114 } 115 116 CP_Customizer.preview.insertContentSection($content, index); 117 118 var sectionStyle = CP_Customizer.getSectionExports(data.id).sectionStyle; 119 if (sectionStyle) { 120 _.each(sectionStyle, function (selectors, media) { 121 _.each(selectors, function (props, selector) { 122 CP_Customizer.contentStyle.setProps('[data-id="' + dataId + '"] ' + selector, "", props, media); 123 }); 124 }); 125 } 126 127 if (skipEvent !== true) { 128 CP_Customizer.trigger('UPDATE_SECTIONS_LIST'); 129 } 130 } 131 132 return { 133 index: index, 134 $content: $content 135 }; 136 }; 137 138 var $sectionsList = $("#page_full_rows"); 139 140 $sectionsList.sortable({ 141 scroll: true, 142 appendTo: "body", 143 axis: 'y', 144 handle: '.reorder-handler', 145 start: function (event, ui) { 146 ui.placeholder.width(ui.item[0].offsetWidth); 147 ui.placeholder.height(ui.item[0].offsetHeight); 148 startPosition = ui.item.index(); 149 }, 150 sort: function (event, ui) { 151 ui.helper.css({ 152 'left': '18px', 153 'position': 'fixed', 154 'top': event.clientY 155 }); 156 157 }, 158 stop: function (event, ui) { 159 var node = CP_Customizer.preview.getRootNode().children('[data-id="' + ui.item.data('id') + '"]'); 160 var nodes = CP_Customizer.preview.getRootNode().children('[data-id]').not(node); 161 var prevNode; 162 var newPos = ui.item.index(); 163 //get dropped node gutenberg comments 164 var startCommentNode = CP_Customizer.preview.getGutenbergBlockCommentStart(node.get(0)); 165 var endCommentNode = CP_Customizer.preview.getGutenbergBlockCommentEnd(node.get(0)); 166 167 //get dropped node sibling 168 if (newPos < nodes.length) { 169 prevNode = nodes.eq(newPos); 170 } else { 171 prevNode = nodes.last(); 172 } 173 174 //get dropped node sibling gutenberg comments 175 var prevNodeCommentNode = CP_Customizer.preview.getGutenbergBlockCommentStart(prevNode.get(0)); 176 var prevNodeEndCommentNode = CP_Customizer.preview.getGutenbergBlockCommentEnd(prevNode.get(0)); 177 178 179 if (newPos < nodes.length) { 180 nodes.eq(newPos).before(node); 181 } else { 182 nodes.last().after(node); 183 } 184 185 //reorder gutenberg comments to not break gutenberg sections 186 $(startCommentNode).insertBefore(node); 187 $(endCommentNode).insertAfter(node); 188 189 $(prevNodeCommentNode).insertBefore(prevNode); 190 $(prevNodeEndCommentNode).insertAfter(prevNode); 191 192 CP_Customizer.setContent(); 193 } 194 }); 195 196 $sectionsList.on('click', '.full_row .item-remove', function (event) { 197 event.preventDefault(); 198 var sectionID = $(this).parents('.item').data('id'); 199 var node = CP_Customizer.preview.getSectionByDataId(sectionID); 200 var exportID = CP_Customizer.preview.getNodeExportId(node); 201 var anchor = node.attr('id'); 202 203 $(this).parents('.item').fadeOut(200); 204 CP_Customizer.hooks.doAction('before_section_remove', $(node)); 205 $(node).remove(); 206 $(this).parents('.item').remove(); 207 208 $('[data-type="row-list-control"] [data-name="page_content"] [data-id="' + exportID + '"]').removeClass('already-in-page'); 209 CP_Customizer.updateState(false, false); 210 CP_Customizer.overlays.hideMovableOverlays(); 211 212 if (CP_Customizer.menu.anchorExistsInPrimaryMenu(anchor)) { 213 CP_Customizer.menu.removeAnchorFromPrimaryMenu(anchor); 214 } 215 }); 216 217 218 var labelChange = _.debounce(function () { 219 var $item = $(this).closest('.full_row'); 220 var node = CP_Customizer.preview.getSectionByDataId($item.data('id')); 221 var oldValue = node.attr('data-label'); 222 var value = this.value.trim(); 223 224 if (value === oldValue) { 225 return; 226 } 227 228 if (value.length === 0) { 229 value = oldValue; 230 this.value = oldValue; 231 } 232 233 node.attr('data-label', value); 234 node.data('label', value); 235 236 var slug = CP_Customizer.getSlug(value); 237 238 if (!slug) { 239 return; 240 } 241 242 if (CP_Customizer.preview.getRootNode().find('[id="' + slug + '"]').length) { 243 var found = false, 244 index = 1; 245 while (!found) { 246 if (CP_Customizer.preview.getRootNode().find('[id="' + slug + '-' + index + '"]').length === 0) { 247 slug += '-' + index; 248 found = true; 249 } else { 250 index++; 251 } 252 } 253 } 254 var oldId = node.attr('id'); 255 node.attr('id', slug); 256 $(this).siblings('.anchor-info').text('#' + slug); 257 258 if (CP_Customizer.menu.anchorExistsInPrimaryMenu(oldId)) { 259 CP_Customizer.menu.updatePrimaryMenuAnchor(oldId, { 260 anchor: slug, 261 title: value 262 }); 263 } 264 265 CP_Customizer.setContent(); 266 }, 500); 267 268 269 $sectionsList.on('keyup', '.full_row input', labelChange); 270 271 $sectionsList.on('dblclick', '.anchor-info', function () { 272 this.contentEditable = true; 273 }); 274 275 $sectionsList.on('keypress', '.anchor-info', function (event) { 276 277 if (event.which === 13) { 278 event.preventDefault(); 279 event.stopPropagation(); 280 this.contentEditable = false; 281 } 282 283 }); 284 285 $sectionsList.on('focusout', '.anchor-info', function () { 286 var slug = $(this).text(); 287 slug = CP_Customizer.getSlug(slug); 288 $(this).text('#' + slug); 289 290 var $item = $(this).closest('.full_row'); 291 var node = CP_Customizer.preview.getSectionByDataId($item.data('id')); 292 var oldId = node.attr('id'); 293 node.attr('id', slug); 294 node.attr('id', slug); 295 if (CP_Customizer.menu.anchorExistsInPrimaryMenu(oldId)) { 296 CP_Customizer.menu.updatePrimaryMenuAnchor(oldId, { 297 anchor: "#" + slug, 298 title: $item.find('input.item-label').val() 299 }); 300 } 301 302 this.contentEditable = false; 303 CP_Customizer.setContent(); 304 }); 305 306 307 $sectionsList.on('click', '.full_row .item-menu-visible', function (event) { 308 event.stopPropagation(); 309 event.preventDefault(); 310 event.stopImmediatePropagation(); 311 312 var $item = $(this).closest('.full_row'), 313 $node = CP_Customizer.preview.getSectionByDataId($item.data('id')); 314 315 if (false === CP_Customizer.menu.getPrimaryMenuID()) { 316 CP_Customizer.menu.createPrimaryMenu(); 317 } 318 319 var anchor = $node.attr('id'); 320 var label = $node.attr('data-label'); 321 322 if (CP_Customizer.menu.anchorExistsInPrimaryMenu(anchor)) { 323 CP_Customizer.menu.removeAnchorFromPrimaryMenu(anchor); 324 $(this).removeClass('active'); 325 } else { 326 CP_Customizer.menu.addAnchorToPrimaryMenu(anchor, label); 327 $(this).addClass('active'); 328 } 329 }); 330 331 function focusSection(item) { 332 333 var section = CP_Customizer.preview.getSectionByDataId($(item).data('id')); 334 335 CP_Customizer.preview.find('html,body').animate({ 336 scrollTop: section.offset().top 337 }, 500); 338 339 $(item).addClass('focused').siblings().removeClass('focused'); 340 341 CP_Customizer.trigger('section_focused', section); 342 } 343 344 $sectionsList.on('click', '.full_row .item-settings', function (event) { 345 event.preventDefault(); 346 event.stopPropagation(); 347 var customizerSection = $(this).attr('data-setting'); 348 349 var section = CP_Customizer.preview.getSectionByDataId($(this).closest('.full_row').data('id')); 350 351 if (CP_Customizer.isRightSidebarVisible(customizerSection)) { 352 CP_Customizer.hideRightSidebar(); 353 } 354 355 CP_Customizer.openRightSidebar(customizerSection, { 356 floating: CP_Customizer.hooks.applyFilters('content_section_setting_float', true), 357 y: $(this).offset().top, 358 section: section 359 }); 360 361 focusSection($(this).closest('.full_row')); 362 363 }); 364 365 366 $sectionsList.on('click', '.full_row', function () { 367 368 var section = CP_Customizer.preview.getSectionByDataId($(this).data('id')); 369 370 if (!section.length) { 371 return; 372 } 373 374 focusSection($(this)); 375 376 CP_Customizer.hideRightSidebar(); 377 378 379 }); 380 381 var skipableKeyCodes = [8, 46, 16, 17, 18]; 382 var labelValidaton = function (event) { 383 384 if (skipableKeyCodes.indexOf(event.keyCode) === -1 && event.key.length === 1) { 385 if (!event.key.match(/[A-Za-z0-9\s]/)) { 386 event.preventDefault(); 387 event.stopPropagation(); 388 } 389 } 390 }; 391 $sectionsList.on('keydown', '.full_row input', labelValidaton); 392 393 var gutenbergCounter = 1; 394 var isGutenbergSection = false; 395 function getListModel(elem) { 396 var $node = $(elem); 397 398 //add gutenberg sections to list 399 isGutenbergSection = false; 400 if ($node.attr("class") && $node.attr("class").indexOf("wp-block") !== -1 || elem.tagName == "P") 401 { 402 var gutenbergId = "gutenberg-section-" + gutenbergCounter++; 403 $node.attr({"id": gutenbergId, "data-id": gutenbergId, "data-export-id": gutenbergId, "data-label" :"Gutenberg"}); 404 isGutenbergSection = true; 405 } 406 407 var 408 label = $node.attr('data-label') || $node.attr('id'), 409 id = $node.attr('id') || "", 410 sectionID = $node.attr('data-id'), 411 exportID = $node.attr('data-export-id'), 412 inMenu = CP_Customizer.menu.anchorExistsInPrimaryMenu(id), 413 setting = $node.attr('data-setting') ? $node.attr('data-setting') : false; 414 setting = CP_Customizer.hooks.applyFilters('content_section_setting', setting); 415 416 return { 417 label: label, 418 id: id, 419 setting: (isGutenbergSection? false : setting), 420 sectionID: sectionID, 421 exportID: exportID, 422 inMenu: inMenu 423 }; 424 } 425 426 var openedSectionsCategories = {}; 427 428 function updateSectionsList() { 429 var data = CP_Customizer.preview.getRootNode().children().map(function (index, elem) { 430 return getListModel(elem); 431 }); 432 433 $sectionsList.children('.item.full_row').remove(); 434 435 var availableRowsList = $('[data-type="row-list-control"] [data-name="page_content"]'); 436 var $controlItems = availableRowsList.find('li.available-item'); 437 438 var allowMultiple = (availableRowsList.closest('[data-selection="multiple"]').length > 0); 439 440 441 function openCategory($category) { 442 var $this = $($category); 443 444 var $items = $this.data('items'); 445 446 if (!$items || $items.length === 0) { 447 $items = $this.nextUntil('li.category-title', 'li.available-item'); 448 $this.data('items', $items); 449 } 450 451 $items.fadeIn(50); 452 $this.attr('data-item-open', 1); 453 $this.removeAttr('data-item-closed'); 454 openedSectionsCategories[$this.attr('data-category')] = true; 455 } 456 457 function closeCategory($category) { 458 var $this = $($category); 459 460 var $items = $this.data('items'); 461 462 if (!$items || $items.length === 0) { 463 $items = $this.nextUntil('li.category-title', 'li.available-item'); 464 $this.data('items', $items); 465 } 466 467 $items.fadeOut(50); 468 $this.removeAttr('data-item-open'); 469 $this.attr('data-item-closed', 1); 470 openedSectionsCategories[$this.attr('data-category')] = false; 471 } 472 473 474 var $categoryTitles = availableRowsList.find('li.category-title'); 475 $categoryTitles.addClass('closeable'); 476 $categoryTitles.each(function (index) { 477 if (!$(this).attr('data-item-closed')) { 478 $(this).attr('data-item-open', 1); 479 } 480 481 if (index > 1 && !openedSectionsCategories[$(this).attr('data-category')]) { 482 closeCategory($(this)); 483 } 484 } 485 ); 486 487 $categoryTitles.off('click').on('click', function () { 488 489 490 if ($(this).attr('data-item-open')) { 491 closeCategory($(this)); 492 } else { 493 openCategory($(this)); 494 } 495 }); 496 497 498 data.each(function (index, _data) { 499 500 // ignore elements injected by plugins and that do not match the companion structure 501 if (!_data.exportID) { 502 return; 503 } 504 505 $sectionsList.children('.empty').before(listItemTemplate(_data)); 506 507 508 if (allowMultiple && !data.once) { 509 return; 510 } 511 512 $controlItems.filter('[data-id="' + _data.exportID + '"]').addClass('already-in-page'); 513 }); 514 515 516 availableRowsList.parent().off('cp.item.click').on('cp.item.click', function (event, itemID, enabled) { 517 var $ = CP_Customizer.preview.jQuery(); 518 var data = CP_Customizer.pluginOptions.contentSections[itemID]; 519 520 if (data['pro-only']) { 521 522 CP_Customizer.popUpInfo(window.CP_Customizer.translateCompanionString('This item requires PRO theme'), 523 '<div class="pro-popup-preview-container">' + 524 ' <img class="pro-popup-preview-image" src="' + data.preview + '">' + 525 ' <h3>' + window.CP_Customizer.translateCompanionString('This item is available only in the PRO version') + '</h3>' + 526 ' <p>' + window.CP_Customizer.translateCompanionString('Please upgrade to the PRO version to use this item and many others.') + '</p>' + 527 ' <br/>' + 528 ' <a href="https://extendthemes.com/go/materialis-upgrade" class="button button-orange" target="_blank">' + 529 window.CP_Customizer.translateCompanionString('Upgrade to PRO') + '</a> ' + 530 '</div>' 531 ); 532 533 return; 534 } 535 536 var response = CP_Customizer.preview.insertSectionFromData(data, true); 537 538 var _data = getListModel(response.$content); 539 540 var $listChildren = $sectionsList.children().not('.empty') 541 if (!_.isUndefined(response.index) && $listChildren.length) { 542 $listChildren.eq(response.index).before(listItemTemplate(_data)); 543 } else { 544 $sectionsList.children('.empty').before(listItemTemplate(_data)); 545 } 546 }); 547 } 548 549 CP_Customizer.bind('PREVIEW_LOADED', updateSectionsList); 550 CP_Customizer.bind('UPDATE_SECTIONS_LIST', updateSectionsList); 551 552 CP_Customizer.bind(CP_Customizer.events.RIGHT_SECTION_CLOSED, function (ev, sidebar) { 553 $contentLi.find('.cp-add-section.active').removeClass('active'); 554 }); 555 556 CP_Customizer.bind('content.section.hovered', function (event, $el) { 557 var sectionId = $el.attr('data-id'); 558 var $item = $sectionsList.find('[data-id="' + sectionId + '"]'); 559 $item.addClass('focused').siblings().removeClass('focused'); 560 561 if (!$item.length) { 562 return; 563 } 564 565 $item[0].scrollIntoViewIfNeeded(); 566 }); 567 568 }); 569 })(jQuery, window);