PageSourceSearch

https://www.autostraddle.com/wp-content/plugins/autostraddle-2025-…/assets/js/gf-paywall-modal.js?ver=1.2.1

js autostraddle.com collected 2026-09-24 08:40:55 UTC 5,293 bytes, 219 lines download raw bytes

1/**
2 * Gravity Forms Paywall Modal
3 *
4 * Handles form submission interception and modal display for members-only forms
5 *
6 * @package AutostraddleFeatures
7 * @since 1.0.0
8 */
9
10(function ($) {
11  "use strict";
12
13  /**
14   * Initialize paywall functionality
15   */
16  function init() {
17    // Check if user already has access - if so, no need to block anything
18    if (gfPaywallData.hasAccess) {
19      return;
20    }
21
22    // Find all Gravity Forms on the page with paywall enabled
23    $('form[data-gf-paywall-enabled="1"]').each(function () {
24      var $form = $(this);
25      attachPaywallHandlers($form);
26    });
27
28    // Set up modal close handlers
29    setupModalHandlers();
30  }
31
32  /**
33   * Attach paywall handlers to a form
34   *
35   * @param {jQuery} $form Form element
36   */
37  function attachPaywallHandlers($form) {
38    // Intercept form submission
39    $form.on("submit.gfpaywall", function (e) {
40      // Check if we've already validated
41      if ($form.data("gf-paywall-validated")) {
42        return true;
43      }
44
45      // Only 
45intercept if user doesn't have access
46      if (!gfPaywallData.hasAccess) {
47        e.preventDefault();
48        e.stopImmediatePropagation();
49        showModal($form);
50        return false;
51      }
52
53      return true;
54    });
55
56    // Intercept button clicks
57    $form
58      .find('.gform_button, .gform_next_button, input[type="submit"]')
59      .on("click.gfpaywall", function (e) {
60        if (!gfPaywallData.hasAccess && !$form.data("gf-paywall-validated")) {
61          e.preventDefault();
62          e.stopImmediatePropagation();
63          showModal($form);
64          return false;
65        }
66      });
67  }
68
69  /**
70   * Show the paywall modal
71   *
72   * @param {jQuery} $form The form that triggered the modal
73   */
74  function showModal($form) {
75    var $modal = $("#gf-paywall-modal");
76
77    if (!$modal.length) {
78      console.error("Paywall modal not found");
79      return;
80    }
81
82    // Get form name and replace placeholder in modal content
83    var formName = $form.attr("data-gf-paywall-form-name") || "this form";
84    var contentTemplate = gfPaywallData.modalContentTemplate || "";
85    var modalContent = contentTemplate.replace(/\{form_name\}/g, formName);
86
87    // Update modal content
88    var $modalContent = $modal.find("#gf-paywall-modal-content");
89    if ($modalContent.length) {
90      $modalContent.text(modalContent);
91    }
92
93    // Show modal
94    $modal.removeClass("hidden");
95
96    // Prevent body scroll
97    $("body").addClass("overflow-hidden");
98
99    // Focus trap
100    trapFocus($modal);
101
102    // Trigger custom event
103    $(document).trigger("gf-paywall-modal-opened", [formName]);
104  }
105
106  /**
107   * Hide the paywall modal
108   */
109  function hideModal() {
110    var $modal = $("#gf-paywall-modal");
111
112    // Hide modal
113    $modal.addClass("hidden");
114
115    // Restore body scroll
116    $("body").removeClass("overflow-hidden");
117
118    // Trigger custom event
119    $(document).trigger("gf-paywall-modal-closed");
120  }
121
122  /**
123   * Set up modal event handlers
124   */
125  function setupModalHandlers() {
126    var $modal = $("#gf-paywall-modal");
127
128    if (!$modal.length) {
129      return;
130    }
131
132    // Close button
133    $modal.find(".gf-paywall-close").on("click", function (e) {
134      e.preventDefault();
135      hideModal();
136    });
137
138    // Close on overlay click
139    $modal.find(".fixed.inset-0.bg-black").on("click", function (e) {
140      if (e.target === this) {
141        hideModal();
142      }
143    });
144
145    // Close on ESC key
146    $(document).on("keydown", function (e) {
147      if (e.key === "Escape" && !$modal.hasClass("hidden")) {
148        hideModal();
149      }
150    });
151  }
152
153  /**
154   * Trap focus within modal
155   *
156   * @param {jQuery} $modal Modal element
157   */
158  function trapFocus($modal) {
159    var focusableElements = $modal.find(
160      'a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])'
161    );
162    var firstElement = focusableElements.first();
163    var lastElement = focusableElements.last();
164
165    // Focus first element
166    firstElement.focus();
167
168    // Trap focus
169    $modal.off("keydown.focustrap").on("keydown.focustrap", function (e) {
170      if (e.key !== "Tab") {
171        return;
172      }
173
174      if (e.shiftKey) {
175        // Shift + Tab
176        if (document.activeElement === firstElement[0]) {
177          e.preventDefault();
178          lastElement.focus();
179        }
180      } else {
181        // Tab
182        if (document.activeElement === lastElement[0]) {
183          e.preventDefault();
184          firstElement.focus();
185        }
186      }
187    });
188  }
189
190  /**
191   * Initialize on document ready
192   */
193  $(document).ready(function () {
194    init();
195  });
196
197  /**
198   * Re-initialize after AJAX content load (for multi-page forms)
199   */
200  $(document).on("gform_post_render", function (event, formId, currentPage) {
201    // Only re-initialize if user doesn't have access
202    if (gfPaywallData.hasAccess) {
203      return;
204    }
205
206    // Re-attach handlers to the form if it has paywall enabled
207    var $form = $("#gform_" + formId);
208    if ($form.attr("data-gf-paywall-enabled") === "1") {
209      // Remove old handlers first
210      $form.off(".gfpaywall");
211      $form
212        .find('.gform_button, .gform_next_button, input[type="submit"]')
213        .off(".gfpaywall");
214
215      // Re-attach
216      attachPaywallHandlers($form);
217    }
218  });
219})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.