PageSourceSearch

https://diromadelivery.com.br/templates/1/assets/js/carrinho-empty-sync-fix.js?v=24092026211835

js diromadelivery.com.br collected 2026-10-01 14:29:02 UTC 7,482 bytes, 300 lines download raw bytes

1/**
2 * Evita reidratar carrinho abandonado após esvaziar localmente e sair rápido de /carrinho.
3 * Patch leve no $pd — não exige rebuild do main.js.
4 *
5 * Proteções:
6 * - flag de esvaziamento em localStorage (WebViews como Instagram não persistem sessionStorage)
7 * - cancelamento de POSTs stale (last-write-wins)
8 * - sync vazio com retry antes de navegar ao cardápio
9 */
10(function () {
11  var CLEARED_TTL_MS = 10 * 60 * 1000;
12  var SAVE_DEBOUNCE_MS = 100;
13  var EMPTY_SYNC_RETRIES = 2;
14
15  function cookieName() {
16    return window.$CLIENTE + '_Cart';
17  }
18
19  function clearedFlagKey() {
20    return window.$CLIENTE + '_cart_user_cleared';
21  }
22
23  function getLocalItems() {
24    try {
25      var raw = localStorage.getItem(cookieName());
26      if (!raw) {
27        return [];
28      }
29      var parsed = JSON.parse(raw);
30      return Array.isArray(parsed) ? parsed : [];
31    } catch (e) {
32      return [];
33    }
34  }
35
36  function setLocalItems(items) {
37    try {
38      localStorage.setItem(cookieName(), JSON.stringify(items || []));
39    } catch (e) {}
40  }
41
42  function markCleared() {
43    var payload = JSON.stringify({ t: Date.now() });
44    try {
45      localStorage.setItem(clearedFlagKey(), payload);
46      sessionStorage.setItem(clearedFlagKey(), '1');
47    } catch (e) {}
48  }
49
50  function isCartUserCleared() {
51    if (getLocalItems().length > 0) {
52      return false;
53    }
54
55    try {
56      var raw = localStorage.getItem(clearedFlagKey());
57      if (raw) {
58        var parsed = JSON.parse(raw);
59        if (parsed && parsed.t && (Date.now() - parsed.t) < CLEARED_TTL_MS) {
60          return true;
61        }
62        localStorage.removeItem(clearedFlagKey());
63      }
64    } catch (e) {}
65
66    try {
67      if (sessionStorage.getItem(clearedFlagKey())) {
68        return true;
69      }
70    } catch (e2) {}
71
72    return false;
73  }
74
75  function clearClearedFlag() {
76    try {
77      localStorage.removeItem(clearedFlagKey());
78      sessionStorage.removeItem(clearedFlagKey());
79    } catch (e) {}
80  }
81
82  function bumpCartSaveGeneration(vm) {
83    vm.__cartSaveGeneration = (vm.__cartSaveGeneration || 0) + 1;
84    return vm.__cartSaveGeneration;
85  }
86
87  function abortCartSaveXhr(vm) {
88    if (vm.__cartSaveXhr && vm.__cartSaveXhr.readyState !== 4) {
89      try {
90        vm.__cartSaveXhr.abort();
91      } catch (e) {}
92    }
93    vm.__cartSaveXhr = null;
94  }
95
96  function cancelCartSaveTimeout(vm) {
97    if (vm.idTimeout) {
98      clearTimeout(vm.idTimeout);
99      vm.idTimeout = null;
100    }
101  }
102
103  function trackCartSaveXhr(vm, xhr) {
104    vm.__cartSaveXhr = xhr;
105    xhr.always(function () {
106      if (vm.__cartSaveXhr === xhr) {
107        vm.__cartSaveXhr = null;
108      }
109    });
110    return xhr;
111  }
112
113  function postCarrinhoAbandonado(payloadString) {
114    return window.jQuery.post(window.$ROOTURL + '/carrinho-abandonado', payloadString);
115  }
116
117  function postEmptyCart(vm, callback) {
118    abortCartSaveXhr(vm);
119    cancelCartSaveTimeout(vm);
120    var gen = bumpCartSaveGeneration(vm);
121    var payload = JSON.stringify({
122      json: {
123        itens: [],
124        removidos: vm.produtos_removidos || []
125      }
126    });
127
128    function tryPost(retriesLeft) {
129      var xhr = trackCartSaveXhr(vm, postCarrinhoAbandonado(payload));
130      xhr.done(function () {
131        if (gen !== vm.__cartSaveGeneration) {
132          return;
133        }
134        callback(true);
135      }).fail(function () {
136        if (gen !== vm.__cartSaveGeneration) {
137          return;
138        }
139        if (retriesLeft > 0) {
140          tryPost(retriesLeft - 1);
141          return;
142        }
143        callback(false);
144      });
145    }
146
147    tryPost(EMPTY_SYNC_RETRIES);
148  }
149
150  function patchVm(vm) {
151    if (!vm || vm.__carrinhoEmptySyncPatched) {
152      return false;
153    }
154
155    if (typeof vm.Cart__loadCarrinhoAbandonado !== 'function') {
156      return false;
157    }
158
159    vm.__carrinhoEmptySyncPatched = true;
160    vm.__cartSaveGeneration = vm.__cartSaveGeneration || 0;
161
162    var originalLoad = vm.Cart__loadCarrinhoAbandonado.bind(vm);
163    var originalSaveAbandonado = vm.Cart__saveCarrinhoAbandonado.bind(vm);
164
165    vm.Cart__loadCarrinhoAbandonado = function () {
166      if (isCartUserCleared()) {
167        if (vm.cart && vm.cart.items && vm.cart.items.length) {
168          vm.cart.items.splice(0, vm.cart.items.length);
169        }
170        vm.produtos_removidos = vm.produtos_removidos || [];
171
172        if (vm.usuario && vm.usuario.logged) {
173          postEmptyCart(vm, function (ok) {
174            if (ok) {
175              clearClearedFlag();
176            }
177          });
178        }
179        return;
180      }
181
182      return originalLoad();
183    };
184
185    vm.Cart__saveCarrinhoAbandonado = function () {
186      abortCartSaveXhr(vm);
187      bumpCartSaveGeneration(vm);
188
189      var jq = window.jQuery;
190      var originalPost = jq.post;
191
192      jq.post = function (url, data, success, dataType) {
193        if (typeof url === 'string' && url.indexOf('carrinho-abandonado') !== -1) {
194          var xhr = originalPost.call(jq, url, data, success, dataType);
195          trackCartSaveXhr(vm, xhr);
196          jq.post = originalPost;
197          return xhr;
198        }
199        return originalPost.apply(jq, arguments);
200      };
201
202      try {
203        originalSaveAbandonado();
204      } finally {
205        jq.post = originalPost;
206      }
207    };
208
209    vm.Cart__save = function () {
210      if (typeof vm.Cart__valideItens === 'function') {
211        vm.Cart__valideItens();
212      }
213
214      if (vm.cart && vm.cart.items) {
215        setLocalItems(vm.cart.items);
216        if (vm.cart.items.length === 0) {
217          markCleared();
218        } else {
219          clearClearedFlag();
220        }
221      }
222
223      if (typeof vm.Cart__cupom__check === 'function') {
224        vm.Cart__cupom__check();
225      }
226      if (typeof vm.Cart__cupom__add === 'function') {
227        var cupom = vm.cart && vm.cart.cupom ? vm.cart.cupom.cup_codigo : null;
228        vm.Cart__cupom__add(cupom);
229      }
230
231      cancelCartSaveTimeout(vm);
232
233      vm.idTimeout = setTimeout(function () {
234        vm.idTimeout = null;
235        if (vm.usuario && vm.usuario.logged && vm.pageReady && typeof vm.Cart__saveCarrinhoAbandonado === 'function') {
236          vm.Cart__saveCarrinhoAbandonado();
237        }
238      }, SAVE_DEBOUNCE_MS);
239    };
240
241    vm.Cart__voltarCardapio = function (url) {
242      var isEmpty = !vm.cart || !vm.cart.items || vm.cart.items.length === 0;
243
244      cancelCartSaveTimeout(vm);
245      setLocalItems(isEmpty ? [] : (vm.cart ? vm.cart.items : []));
246
247      if (isEmpty) {
248        markCleared();
249      }
250
251      var navigate = function () {
252        window.location.href = url;
253      };
254
255      if (vm.usuario && vm.usuario.logged && isEmpty && window.jQuery) {
256        postEmptyCart(vm, navigate);
257        return;
258      }
259
260      navigate();
261    };
262
263    if (typeof vm.Cart__set === 'function') {
264      var originalSet = vm.Cart__set.bind(vm);
265      vm.Cart__set = function () {
266        clearClearedFlag();
267        return originalSet.apply(vm, arguments);
268      };
269    }
270
271    return true;
272  }
273
274  function tryPatch() {
275    if (window.$pd && patchVm(window.$pd)) {
276      return true;
277    }
278    return false;
279  }
280
281  function startPolling() {
282    if (tryPatch()) {
283      return;
284    }
285
286    var attempts = 0;
287    var timer = window.setInterval(function () {
288      attempts += 1;
289      if (tryPatch() || attempts > 120) {
290        window.clearInterval(timer);
291      }
292    }, 50);
293  }
294
295  if (document.readyState === 'loading') {
296    document.addEventListener('DOMContentLoaded', startPolling);
297  } else {
298    startPolling();
299  }
300})();

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.