PageSourceSearch

https://remarketyi.co.kr/assets/js/header-style-templates.js?v=1.1.2

js remarketyi.co.kr collected 2026-10-06 12:23:54 UTC 15,684 bytes, 442 lines download raw bytes

1/**
2 * 헤더 — 지점명 · 고객센터 · 1차 메뉴 디자인 템플릿 (localStorage + DB)
3 * v1.1.2 — 선택 시 API로 we_page_layout 저장 (컨텐츠 레이아웃과 동일)
4 */
5(function () {
6    'use strict';
7
8    var STORAGE_BRANCH = 'rm-header-branch-style';
9    var STORAGE_PHONE = 'rm-header-phone-style';
10    var STORAGE_BRANCH_NAV = 'rm-header-branch-nav-style';
11
12    function parseJson(el, fallback) {
13        if (!el) {
14            return fallback;
15        }
16        try {
17            var raw = (el.textContent || '').trim();
18            if (!raw) {
19                return fallback;
20            }
21            return JSON.parse(raw);
22        } catch (e) {
23            return fallback;
24        }
25    }
26
27    var branchRegistryEl = document.getElementById('rm-header-branch-style-registry');
28    var phoneRegistryEl = document.getElementById('rm-header-phone-style-registry');
29    var branchNavRegistryEl = document.getElementById('rm-header-branch-nav-style-registry');
30    var branchDefaultsEl = document.getElementById('rm-header-branch-style-default');
31    var phoneDefaultsEl = document.getElementById('rm-header-phone-style-default');
32    var branchNavDefaultsEl = document.getElementById('rm-header-branch-nav-style-default');
33    var layoutManagedEl = document.getElementById('rm-header-style-layout-managed');
34    var styleSaveApiEl = document.getElementById('rm-header-style-save-api');
35
36    var branchRegistry = parseJson(branchRegistryEl, {});
37    var phoneRegistry = parseJson(phoneRegistryEl, {});
38    var branchNavRegistry = parseJson(branchNavRegistryEl, {});
39    var branchDefault = parseJson(branchDefaultsEl, 'classic');
40    var phoneDefault = parseJson(phoneDefaultsEl, 'gradient-cta');
41    var branchNavDefault = parseJson(branchNavDefaultsEl, 'plain');
42    var layoutManaged = parseJson(layoutManagedEl, false);
43    var styleSaveApi = parseJson(styleSaveApiEl, null);
44
45    if (!Object.keys(branchRegistry).length && !Object.keys(phoneRegistry).length && !Object.keys(branchNavRegistry).length) {
46        return;
47    }
48
49    var branchModal = document.getElementById('rm-header-branch-style-modal');
50    var phoneModal = document.getElementById('rm-header-phone-style-modal');
51    var branchNavModal = document.getElementById('rm-header-branch-nav-style-modal');
52
53    var branchTargets = document.querySelectorAll('[data-rm-branch-style-target]');
54    var phoneTargets = document.querySelectorAll('[data-rm-phone-style-target]');
55    var branchNavTargets = document.querySelectorAll('[data-rm-branch-nav-style-target]');
56
57    function unique(list) {
58        var seen = {};
59        var out = [];
60        list.forEach(function (item) {
61            if (item && !seen[item]) {
62                seen[item] = true;
63                out.push(item);
64            }
65        });
66        return out;
67    }
68
69    var branchClasses = unique(Object.keys(branchRegistry).map(function (id) {
70        return branchRegistry[id] && branchRegistry[id].class;
71    }));
72    var phoneClasses = unique(Object.keys(phoneRegistry).map(function (id) {
73        return phoneRegistry[id] && phoneRegistry[id].class;
74    }));
75    var branchNavClasses = unique(Object.keys(branchNavRegistry).map(function (id) {
76        return branchNavRegistry[id] && branchNavRegistry[id].class;
77    }));
78
79    function readStorage(key) {
80        try {
81            return localStorage.getItem(key) || '';
82        } catch (e) {
83            return '';
84        }
85    }
86
87    function writeStorage(key, value) {
88        try {
89            localStorage.setItem(key, value);
90        } catch (e) {
91            /* ignore */
92        }
93    }
94
95    function clearStorage(key) {
96        try {
97            localStorage.removeItem(key);
98        } catch (e) {
99            /* ignore */
100        }
101    }
102
103    function readBranchStyleFromDom() {
104        var el = document.querySelector('[data-rm-branch-style-target]');
105        if (!el) {
106            return '';
107        }
108        var styleId = el.getAttribute('data-rm-branch-style') || '';
109        return styleId && branchRegistry[styleId] ? styleId : '';
110    }
111
112    function readPhoneStyleFromDom() {
113        var el = document.querySelector('[data-rm-phone-style-target]');
114        if (!el) {
115            return '';
116        }
117        var styleId = el.getAttribute('data-rm-phone-style') || '';
118        return styleId && phoneRegistry[styleId] ? styleId : '';
119    }
120
121    function readBranchNavStyleFromDom() {
122        var el = document.querySelector('[data-rm-branch-nav-style-target]');
123        if (!el) {
124            return '';
125        }
126        var styleId = el.getAttribute('data-rm-branch-nav-style') || '';
127        return styleId && branchNavRegistry[styleId] ? styleId : '';
128    }
129
130    function resolveBranchStyle() {
131        if (layoutManaged) {
132            return readBranchStyleFromDom() || branchDefault;
133        }
134        var stored = readStorage(STORAGE_BRANCH);
135        if (stored && branchRegistry[stored]) {
136            return stored;
137        }
138        return readBranchStyleFromDom() || branchDefault;
139    }
140
141    function resolvePhoneStyle() {
142        if (layoutManaged) {
143            return readPhoneStyleFromDom() || phoneDefault;
144        }
145        var stored = readStorage(STORAGE_PHONE);
146        if (stored && phoneRegistry[stored]) {
147            return stored;
148        }
149        return readPhoneStyleFromDom() || phoneDefault;
150    }
151
152    function resolveBranchNavStyle() {
153        if (layoutManaged) {
154            return readBranchNavStyleFromDom() || branchNavDefault;
155        }
156        var stored = readStorage(STORAGE_BRANCH_NAV);
157        if (stored && branchNavRegistry[stored]) {
158            return stored;
159        }
160        return readBranchNavStyleFromDom() || branchNavDefault;
161    }
162
163    function applyBranchStyle(styleId) {
164        var style = branchRegistry[styleId];
165        if (!style) {
166            return;
167        }
168
169        branchTargets.forEach(function (el) {
170            branchClasses.forEach(function (cls) {
171                el.classList.remove(cls);
172            });
173            el.classList.add(style.class);
174            el.setAttribute('data-rm-branch-style', styleId);
175        });
176
177        if (branchModal) {
178            branchModal.querySelectorAll('[data-rm-branch-style-id]').forEach(function (btn) {
179                var active = btn.getAttribute('data-rm-branch-style-id') === styleId;
180                btn.classList.toggle('is-active', active);
181                btn.setAttribute('aria-selected', active ? 'true' : 'false');
182            });
183        }
184    }
185
186    function applyPhoneStyle(styleId) {
187        var style = phoneRegistry[styleId];
188        if (!style) {
189            return;
190        }
191
192        phoneTargets.forEach(function (el) {
193            phoneClasses.forEach(function (cls) {
194                el.classList.remove(cls);
195            });
196            el.classList.add(style.class);
197            el.setAttribute('data-rm-phone-style', styleId);
198        });
199
200        if (phoneModal) {
201            phoneModal.querySelectorAll('[data-rm-phone-style-id]').forEach(function (btn) {
202                var active = btn.getAttribute('data-rm-phone-style-id') === styleId;
203                btn.classList.toggle('is-active', active);
204                btn.setAttribute('aria-selected', active ? 'true' : 'false');
205            });
206        }
207    }
208
209    function applyBranchNavStyle(styleId) {
210        var style = branchNavRegistry[styleId];
211        if (!style) {
212            return;
213        }
214
215        branchNavTargets.forEach(function (el) {
216            branchNavClasses.forEach(function (cls) {
217                el.classList.remove(cls);
218            });
219            el.classList.add(style.class);
220            el.setAttribute('data-rm-branch-nav-style', styleId);
221        });
222
223        if (branchNavModal) {
224            branchNavModal.querySelectorAll('[data-rm-branch-nav-style-id]').forEach(function (btn) {
225                var active = btn.getAttribute('data-rm-branch-nav-style-id') === styleId;
226                btn.classList.toggle('is-active', active);
227                btn.setAttribute('aria-selected', active ? 'true' : 'false');
228            });
229        }
230    }
231
232    function persistStyleSelection(target, styleId) {
233        if (!styleSaveApi || !styleSaveApi.url) {
234            return Promise.resolve({ ok: true, skipped: true });
235        }
236
237        var formData = new FormData();
238        formData.append('target', target);
239        formData.append('style_id', styleId);
240
241        return fetch(styleSaveApi.url, {
242            method: 'POST',
243            body: formData,
244            credentials: 'same-origin',
245            headers: {
246                'X-Requested-With': 'XMLHttpRequest'
247            }
248        })
249            .then(function (response) {
250                var contentType = response.headers.get('content-type') || '';
251                if (contentType.indexOf('application/json') === -1) {
252                    return {
253                        ok: false,
254                        error: '스타일 저장 응답 오류입니다. 관리자 로그인 상태를 확인해 주세요.'
255                    };
256                }
257                return response.json();
258            })
259            .then(function (data) {
260                if (data && data.ok) {
261                    layoutManaged = true;
262                }
263                return data || { ok: false };
264            })
265            .catch(function () {
266                return { ok: false, error: '스타일 저장 요청에 실패했습니다.' };
267            });
268    }
269
270    function notifyStyleSaveError(data) {
271        var message = data && data.error ? data.error : '스타일 저장에 실패했습니다. 다시 시도해 주세요.';
272        window.alert(message);
273    }
274
275    function commitStyleChange(target, styleId, storageKey, applyFn) {
276        writeStorage(storageKey, styleId);
277        applyFn(styleId);
278
279        return persistStyleSelection(target, styleId).then(function (data) {
280            if (styleSaveApi && styleSaveApi.url && data && !data.ok && !data.skipped) {
281                notifyStyleSaveError(data);
282            }
283            return data;
284        });
285    }
286
287    function openModal(modal) {
288        if (!modal) {
289            return;
290        }
291        if (modal.parentElement !== document.body) {
292            document.body.appendChild(modal);
293        }
294        modal.hidden = false;
295        modal.removeAttribute('hidden');
296        modal.classList.add('is-open');
297        document.body.classList.add('rm-header-style-modal-open');
298    }
299
300    function closeModal(modal) {
301        if (!modal) {
302            return;
303        }
304        modal.hidden = true;
305        modal.setAttribute('hidden', '');
306        modal.classList.remove('is-open');
307        if (!document.querySelector('.rm-header-style-modal.is-open')) {
308            document.body.classList.remove('rm-header-style-modal-open');
309        }
310    }
311
312    function closeAllModals() {
313        [branchModal, phoneModal, branchNavModal].forEach(function (modal) {
314            closeModal(modal);
315        });
316    }
317
318    document.querySelectorAll('[data-rm-style-open="branch"]').forEach(function (btn) {
319        btn.addEventListener('click', function (event) {
320            event.preventDefault();
321            event.stopPropagation();
322            applyBranchStyle(resolveBranchStyle());
323            openModal(branchModal);
324        });
325    });
326
327    document.querySelectorAll('[data-rm-style-open="phone"]').forEach(function (btn) {
328        btn.addEventListener('click', function (event) {
329            event.preventDefault();
330            event.stopPropagation();
331            applyPhoneStyle(resolvePhoneStyle());
332            openModal(phoneModal);
333        });
334    });
335
336    document.querySelectorAll('[data-rm-style-open="branch-nav"]').forEach(function (btn) {
337        btn.addEventListener('click', function (event) {
338            event.preventDefault();
339            event.stopPropagation();
340            applyBranchNavStyle(resolveBranchNavStyle());
341            openModal(branchNavModal);
342        });
343    });
344
345    [branchModal, phoneModal, branchNavModal].forEach(function (modal) {
346        if (!modal) {
347            return;
348        }
349
350        modal.querySelectorAll('[data-rm-style-close]').forEach(function (el) {
351            el.addEventListener('click', function () {
352                closeModal(modal);
353            });
354        });
355    });
356
357    if (branchModal) {
358        branchModal.querySelectorAll('[data-rm-branch-style-id]').forEach(function (btn) {
359            btn.addEventListener('click', function () {
360                var styleId = btn.getAttribute('data-rm-branch-style-id');
361                if (!styleId || !branchRegistry[styleId]) {
362                    return;
363                }
364                commitStyleChange('branch', styleId, STORAGE_BRANCH, applyBranchStyle).then(function () {
365                    closeModal(branchModal);
366                });
367            });
368        });
369
370        var branchReset = document.getElementById('rm-header-branch-style-reset');
371        if (branchReset) {
372            branchReset.addEventListener('click', function () {
373                clearStorage(STORAGE_BRANCH);
374                commitStyleChange('branch', branchDefault, STORAGE_BRANCH, applyBranchStyle).then(function () {
375                    closeModal(branchModal);
376                });
377            });
378        }
379    }
380
381    if (phoneModal) {
382        phoneModal.querySelectorAll('[data-rm-phone-style-id]').forEach(function (btn) {
383            btn.addEventListener('click', function () {
384                var styleId = btn.getAttribute('data-rm-phone-style-id');
385                if (!styleId || !phoneRegistry[styleId]) {
386                    return;
387                }
388                commitStyleChange('phone', styleId, STORAGE_PHONE, applyPhoneStyle).then(function () {
389                    closeModal(phoneModal);
390                });
391            });
392        });
393
394        var phoneReset = document.getElementById('rm-header-phone-style-reset');
395        if (phoneReset) {
396            phoneReset.addEventListener('click', function () {
397                clearStorage(STORAGE_PHONE);
398                commitStyleChange('phone', phoneDefault, STORAGE_PHONE, applyPhoneStyle).then(function () {
399                    closeModal(phoneModal);
400                });
401            });
402        }
403    }
404
405    if (branchNavModal) {
406        branchNavModal.querySelectorAll('[data-rm-branch-nav-style-id]').forEach(function (btn) {
407            btn.addEventListener('click', function () {
408                var styleId = btn.getAttribute('data-rm-branch-nav-style-id');
409                if (!styleId || !branchNavRegistry[styleId]) {
410                    return;
411                }
412                commitStyleChange('branch_nav', styleId, STORAGE_BRANCH_NAV, applyBranchNavStyle).then(function () {
413                    closeModal(branchNavModal);
414                });
415            });
416        });
417
418        var branchNavReset = document.getElementById('rm-header-branch-nav-style-reset');
419        if (branchNavReset) {
420            branchNavReset.addEventListener('click', function () {
421                clearStorage(STORAGE_BRANCH_NAV);
422                commitStyleChange('branch_nav', branchNavDefault, STORAGE_BRANCH_NAV, applyBranchNavStyle).then(function () {
423                    closeModal(branchNavModal);
424                });
425            });
426        }
427    }
428
429    document.addEventListener('keydown', function (event) {
430        if (event.key === 'Escape') {
431            closeAllModals();
432        }
433    });
434
435    function initHeaderStyles() {
436        applyBranchStyle(resolveBranchStyle());
437        applyPhoneStyle(resolvePhoneStyle());
438        applyBranchNavStyle(resolveBranchNavStyle());
439    }
440
441    initHeaderStyles();
442})();

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.