PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
← All changes | assets/js/admin/admin.js +136 -15 2.2.82.3.2 View file →
@@ -1,6 +1,12 @@
1 1 "use strict";
2 2
3 +function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
4 +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5 +function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6 +function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7 +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
8 +function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
3 9 function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4 10 ;
5 11 (function ($, window, document, undefined) {
6 12 'use strict';
@@ -16,9 +22,18 @@
16 22 $('.merchant-module-page-content').on('change keypress change.merchant', function (e) {
17 23 if ($(e.target).hasClass('merchant-backup-file') || $(e.target).hasClass('merchant-search-field')) {
18 24 return;
19 25 }
20 - if (!$(this).is('.merchant-module-question-answer-textarea, .merchant-license-code-input')) {
26 +
27 + // Nothing in the preview is a setting. Its controls are there to be played
28 + // with, so a module whose mock-up has working fields cannot dirty the form.
29 + if ($(e.target).closest('.merchant-module-page-preview').length) {
30 + return;
31 + }
32 +
33 + // The licence key and the module feedback textarea save through their
34 + // own handlers, so editing them leaves the save bar alone.
35 + if (!$(e.target).is('.merchant-module-question-answer-textarea, .merchant-license-code-input')) {
21 36 if (!merchant.show_save) {
22 37 $ajaxHeader.addClass('merchant-show');
23 38 $ajaxHeader.removeClass('merchant-saving');
24 39 merchant.show_save = true;
@@ -483,9 +498,25 @@
483 498 init: function init() {
484 499 this.initiate_datepicker();
485 500 this.events();
486 501 },
502 + // Date() cannot parse the bare 'H:i' a time-only picker stores, so pin it to today.
503 + parseInitialDate: function parseInitialDate(value, fieldOptions) {
504 + if (!value) {
505 + return [];
506 + }
507 + if (fieldOptions.onlyTimepicker && /^\d{1,2}:\d{2}$/.test(value)) {
508 + var _value$split = value.split(':'),
509 + _value$split2 = _slicedToArray(_value$split, 2),
510 + hours = _value$split2[0],
511 + minutes = _value$split2[1];
512 + return [new Date(new Date().setHours(Number(hours), Number(minutes), 0, 0))];
513 + }
514 + var date = new Date(value);
515 + return isNaN(date) ? [] : [date];
516 + },
487 517 initiate_datepicker: function initiate_datepicker() {
518 + var self = this;
488 519 var elements = $('.merchant-module-page-setting-field .merchant-datetime-field');
489 520 if (elements.length === 0) {
490 521 return;
491 522 }
@@ -490,11 +521,12 @@
490 521 return;
491 522 }
492 523 elements.each(function (index) {
493 524 var input = $(this).find('input'),
525 + fieldOptions = $(this).data('options') || {},
494 526 options = {
495 527 locale: JSON.parse(merchant_datepicker_locale),
496 - selectedDates: input.val() ? [new Date(input.val())] : [],
528 + selectedDates: self.parseInitialDate(input.val(), fieldOptions),
497 529 onSelect: function onSelect(_ref) {
498 530 var date = _ref.date,
499 531 formattedDate = _ref.formattedDate,
500 532 datepicker = _ref.datepicker;
@@ -505,23 +537,20 @@
505 537 }
506 538 input.trigger('change.merchant');
507 539 input.trigger('change.merchant-datepicker', [formattedDate, input, options, index]);
508 540 }
509 - },
510 - fieldOptions = $(this).data('options');
541 + };
511 542 // add buttons to fieldOptions
512 543 fieldOptions.buttons = ['clear'];
513 - if (fieldOptions) {
514 - if (fieldOptions.minDate !== undefined && fieldOptions.minDate === 'today') {
515 - fieldOptions.minDate = new Date();
516 - if (fieldOptions.timeZone !== undefined && fieldOptions.timeZone !== '') {
517 - fieldOptions.minDate = new Date(fieldOptions.minDate.toLocaleString('en-US', {
518 - timeZone: fieldOptions.timeZone
519 - }));
520 - }
544 + if (fieldOptions.minDate !== undefined && fieldOptions.minDate === 'today') {
545 + fieldOptions.minDate = new Date();
546 + if (fieldOptions.timeZone !== undefined && fieldOptions.timeZone !== '') {
547 + fieldOptions.minDate = new Date(fieldOptions.minDate.toLocaleString('en-US', {
548 + timeZone: fieldOptions.timeZone
549 + }));
521 550 }
522 - options = Object.assign(options, fieldOptions);
523 551 }
552 + options = Object.assign(options, fieldOptions);
524 553 var datepickerObj = new AirDatepicker(input.getPath(), options);
525 554 input.attr('readonly', true);
526 555 $(document).trigger('initiated.merchant-datepicker', [datepickerObj, input, options, index]);
527 556 });
@@ -2139,9 +2168,9 @@
2139 2168 parent.find('.merchant-selected-products-preview ul').append($(this));
2140 2169 parent.find('.merchant-selections-products-preview').html('').hide();
2141 2170 parent.find('.merchant-search-field').val('').change();
2142 2171 if (oldValue === '') {
2143 - valueField.val($(this).data('id'));
2172 + valueField.val($(this).data('id')).change();
2144 2173 } else {
2145 2174 if (!multiple) {
2146 2175 valueField.val($(this).data('id')).change();
2147 2176 } else {
@@ -2500,9 +2529,17 @@
2500 2529 });
2501 2530 $(document).on('dragenter', '.merchant-upload-button-drag-drop', function (e) {
2502 2531 $(this).closest('.merchant-module-page-setting-field-upload').find('.merchant-upload-button').click();
2503 2532 });
2504 - var initSelectAjax = function initSelectAjax($selectAjax) {
2533 +
2534 + // Callers pass a collection, and reading the source off a collection would give
2535 + // every select the first field's source, so each field is set up on its own.
2536 + var initSelectAjax = function initSelectAjax($selectAjaxFields) {
2537 + $selectAjaxFields.each(function () {
2538 + initSelectAjaxField($(this));
2539 + });
2540 + };
2541 + var initSelectAjaxField = function initSelectAjaxField($selectAjax) {
2505 2542 var $select = $selectAjax.find('select');
2506 2543 var $source = $select.data('source');
2507 2544 var $config = window.merchant_admin_options;
2508 2545 var $object = {
@@ -2676,8 +2713,92 @@
2676 2713 $moduleAlert.find('.merchant-module-alert-close').on('click', function (e) {
2677 2714 e.preventDefault();
2678 2715 $moduleAlert.removeClass('merchant-show');
2679 2716 $(document).off('click.merchant-alert-close');
2717 + });
2718 + }
2719 +
2720 + // AI Prompt Examples Modal
2721 + var $aiPromptsModal = $('#merchant-ai-prompts-modal');
2722 + if ($aiPromptsModal.length) {
2723 + var $aiPromptsList = $aiPromptsModal.find('.merchant-ai-prompts-modal-list');
2724 + var copyHintText = window.merchant.ai_prompt_copy_hint || 'Click to copy';
2725 + var copiedLabelText = window.merchant.ai_prompt_copied_label || 'Copied!';
2726 + var copyIconSvg = '<svg width="14" height="14" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="5" y="5" width="8" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M3 10V3.5C3 2.67157 3.67157 2 4.5 2H10.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>';
2727 + var checkIconSvg = '<svg width="14" height="14" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 4.5L6 12L2.5 8.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>';
2728 + var copyTextToClipboard = function copyTextToClipboard(text, onCopied) {
2729 + if (navigator.clipboard && navigator.clipboard.writeText) {
2730 + navigator.clipboard.writeText(text).then(onCopied);
2731 + return;
2732 + }
2733 + var $temp = $('<textarea readonly></textarea>').val(text).css({
2734 + position: 'fixed',
2735 + top: '-1000px'
2736 + });
2737 + $('body').append($temp);
2738 + $temp[0].select();
2739 + document.execCommand('copy');
2740 + $temp.remove();
2741 + onCopied();
2742 + };
2743 + $(document).on('click', '.merchant-ai-badge', function (e) {
2744 + e.preventDefault();
2745 + e.stopPropagation();
2746 + var prompts = $(this).data('aiPrompts');
2747 + $aiPromptsModal.find('.merchant-ai-prompts-modal-title-text').text($(this).data('aiTitle') || '');
2748 + $aiPromptsModal.find('.merchant-ai-prompts-modal-blurb').text($(this).data('aiBlurb') || '');
2749 + $aiPromptsList.empty();
2750 + if (Array.isArray(prompts)) {
2751 + prompts.forEach(function (prompt) {
2752 + var $row = $('<button type="button" class="merchant-ai-prompt-row"></button>').attr('data-prompt', prompt);
2753 + $row.append($('<span class="merchant-ai-prompt-text"></span>').text(prompt));
2754 + $row.append($('<span class="merchant-ai-prompt-icon"></span>').html(copyIconSvg));
2755 + $row.attr('aria-label', copyHintText);
2756 + $aiPromptsList.append($row);
2757 + });
2758 + }
2759 + $aiPromptsModal.addClass('merchant-show');
2760 + var $badgeIcon = $aiPromptsModal.find('.merchant-ai-prompts-modal-badge svg');
2761 + $badgeIcon.removeClass('merchant-ai-badge-spin');
2762 + void $badgeIcon[0].offsetWidth;
2763 + $badgeIcon.addClass('merchant-ai-badge-spin');
2764 + });
2765 + $(document).on('keydown', '.merchant-ai-badge', function (e) {
2766 + if (e.key === 'Enter' || e.key === ' ') {
2767 + e.preventDefault();
2768 + $(this).trigger('click');
2769 + }
2770 + });
2771 + $aiPromptsList.on('click', '.merchant-ai-prompt-row', function () {
2772 + var $row = $(this);
2773 + if ($row.hasClass('is-copied')) {
2774 + return;
2775 + }
2776 + copyTextToClipboard($row.attr('data-prompt'), function () {
2777 + $row.addClass('is-copied').attr('aria-label', copiedLabelText);
2778 + $row.find('.merchant-ai-prompt-icon').html(checkIconSvg);
2779 + setTimeout(function () {
2780 + $row.removeClass('is-copied').attr('aria-label', copyHintText);
2781 + $row.find('.merchant-ai-prompt-icon').html(copyIconSvg);
2782 + }, 1600);
2783 + });
2784 + });
2785 + var closeAiPromptsModal = function closeAiPromptsModal() {
2786 + $aiPromptsModal.removeClass('merchant-show');
2787 + $aiPromptsModal.find('.merchant-ai-prompts-modal-badge svg').removeClass('merchant-ai-badge-spin');
2788 + };
2789 + $(document).on('click', '.merchant-ai-prompts-modal-close', function () {
2790 + closeAiPromptsModal();
2791 + });
2792 + $aiPromptsModal.on('click', function (e) {
2793 + if ($(e.target).is($aiPromptsModal)) {
2794 + closeAiPromptsModal();
2795 + }
2796 + });
2797 + $(document).on('keydown', function (e) {
2798 + if (e.key === 'Escape' && $aiPromptsModal.hasClass('merchant-show')) {
2799 + closeAiPromptsModal();
2800 + }
2680 2801 });
2681 2802 }
2682 2803 });
2683 2804