PageSourceSearch

https://www.portalderwirtschaft.de/js/company-form-state.js?v=1790341207

js portalderwirtschaft.de collected 2026-10-02 10:55:04 UTC 8,211 bytes, 184 lines download raw bytes

1(() => {
2  'use strict';
3  const form = document.getElementById('company-create-form');
4  if (!form) return;
5  const params = new URLSearchParams(location.search);
6  const switchKey = 'company-profile-switch';
7  const draftKey = 'company-profile-draft:' + (form.dataset.companyMode || 'basic');
8  const fields = Array.from(form.elements).filter(el => el.name &&
9    !['hidden', 'password', 'button', 'submit'].includes(el.type));
10  let busy = false;
11  let restoredFiles = true;
12  const notice = document.createElement('div');
13  notice.setAttribute('role', 'alert');
14  notice.style.cssText = 'display:none;background:#f8d7da;padding:12px;margin:12px 0';
15  form.prepend(notice);
16  const message = text => {
17    notice.textContent = text;
18    notice.style.display = 'block';
19    notice.scrollIntoView({ block: 'center' });
20  };
21  window.removeEventListener('beforeunload', window.saveFormData);
22
23  function database() {
24    return new Promise((resolve, reject) => {
25      const request = indexedDB.open('pdw-company-profile-state', 1);
26      request.onupgradeneeded = () => request.result.createObjectStore('transfers');
27      request.onsuccess = () => resolve(request.result);
28      request.onerror = () => reject(request.error);
29      request.onblocked = () => reject(new Error('Storage blocked'));
30    });
31  }
32  async function transfer(mode, token, value) {
33    const db = await database();
34    try {
35      return await new Promise((resolve, reject) => {
36        const tx = db.transaction('transfers', 'readwrite');
37        const store = tx.objectStore('transfers');
38        let result;
39        if (mode === 'save') {
40          const cursor = store.openCursor();
41          cursor.onsuccess = () => {
42            const entry = cursor.result;
43            if (!entry) return;
44            if (Date.now() - entry.value.timestamp > 10 * 60 * 1000) entry.delete();
45            entry.continue();
46          };
47          store.put(value, token);
48        } else if (mode === 'remove') store.delete(token);
49        else {
50          const request = store.get(token);
51          request.onsuccess = () => { result = request.result; store.delete(token); };
52        }
53        tx.oncomplete = () => resolve(result);
54        tx.onerror = () => reject(tx.error);
55        tx.onabort = () => reject(tx.error || new Error('Storage aborted'));
56      });
57    } finally { db.close(); }
58  }
59  const token = () => Array.from(crypto.getRandomValues(new Uint32Array(4)),
60    value => value.toString(16).padStart(8, '0')).join('');
61  const snapshot = path => ({ timestamp: Date.now(), path,
62    fields: fields.map(el => ({ name: el.name, type: el.type,
63      value: el.type === 'file' ? '' : el.value, checked: el.checked,
64      files: el.type === 'file' ? Array.from(el.files) : undefined })) });
65  async function save(key, path) {
66    const id = token();
67    sessionStorage.setItem(key, id);
68    await transfer('save', id, snapshot(path));
69  }
70  function restoreSnapshot(saved) {
71    if (!saved || !Array.isArray(saved.fields) || saved.path !== location.pathname ||
72        Date.now() - saved.timestamp > 10 * 60 * 1000) return;
73    fields.forEach(el => {
74      const entry = saved.fields.find(item => item.name === el.name && item.type === el.type &&
75        (!['checkbox', 'radio'].includes(el.type) || item.value === el.value));
76      if (!entry) return;
77      if (el.type === 'file') {
78        if (!entry.files?.length) return;
79        if (el.pdwUpload?.restoreFiles) el.pdwUpload.restoreFiles(entry.files);
80        else restoredFiles = false;
81      } else if (['checkbox', 'radio'].includes(el.type)) el.checked = entry.checked;
82      else el.value = entry.value;
83    });
84    if (!restoredFiles) message('Einige hochgeladene Dateien konnten nicht wiederhergestellt werden. Bitte wählen Sie diese erneut aus.');
85  }
86  function restoreEditor(editor) {
87    const element = editor.getElement();
88    if (!form.contains(element)) return;
89    const setContent = () => editor.setContent(element.value);
90    if (editor.initialized) setContent();
91    else editor.on('init', setContent);
92  }
93  const ready = (async () => {
94    try {
95      const switchToken = sessionStorage.getItem(switchKey);
96      if (switchToken) {
97        const saved = await transfer('read', switchToken);
98        sessionStorage.removeItem(switchKey);
99        restoreSnapshot(saved);
100      }
101      if (params.has('error')) {
102        const savedToken = sessionStorage.getItem(draftKey);
103        if (savedToken) {
104          const saved = await transfer('read', savedToken);
105          sessionStorage.removeItem(draftKey);
106          restoreSnapshot(saved);
107        }
108      }
109      if (window.tinymce) {
110        const editor = tinymce.get('editor');
111        if (editor) restoreEditor(editor);
112        tinymce.on('AddEditor', event => restoreEditor(event.editor));
113      }
114    } catch (_) {
115      message('Die gespeicherten Eingaben konnten nicht wiederhergestellt werden. Bitte wählen Sie Dateien gegebenenfalls erneut aus.');
116    }
117  })();
118  const invalid = new Set(params.has('error') ? (params.get('fields') || '').split(',') : []);
119  const style = document.createElement('style');
120  style.textContent = '#company-create-form .company-invalid{background-color:#f8d7da!important;}#company-recaptcha.company-invalid{padding:8px;border:1px solid #dc3545;}';
121  document.head.append(style);
122  fields.forEach(el => {
123    if (!invalid.has(el.name)) return;
124    const target = el.type === 'radio' ? el.closest('#anrede') : el;
125    target?.classList.add('company-invalid');
126    target?.setAttribute('aria-invalid', 'true');
127  });
128  if (invalid.has('g-recaptcha-response')) {
129    const target = document.getElementById('company-recaptcha');
130    target?.classList.add('company-invalid');
131    target?.setAttribute('aria-invalid', 'true');
132  }
133  ['basic-btn', 'premium-btn'].forEach(id => {
134    const link = document.getElementById(id);
135    if (!link) return;
136    link.addEventListener('click', async event => {
137      event.preventDefault();
138      if (busy) return;
139      busy = true;
140      try {
141        await ready;
142        const destination = new URL(link.href, location.href);
143        if (destination.origin !== location.origin || destination.pathname === location.pathname) return;
144        if (window.tinymce) tinymce.triggerSave();
145        await save(switchKey, destination.pathname);
146        location.assign(destination.href);
147      } catch (_) {
148        message('Der Profilwechsel konnte nicht gesichert werden. Ihre Eingaben bleiben hier erhalten. Bitte erlauben Sie den Browserspeicher und versuchen Sie es erneut.');
149      } finally { busy = false; }
150    });
151  });
152  async function submit() {
153    await ready;
154    if (busy) return;
155    if (window.tinymce) tinymce.triggerSave();
156    try { await save(draftKey, location.pathname); }
157    catch (_) {
158      message('Die Eingaben konnten nicht gesichert werden. Bitte erlauben Sie den Browserspeicher, bevor Sie erneut absenden. Ihre Eingaben bleiben auf dieser Seite erhalten.');
159      return;
160    }
161    busy = true;
162    form.setAttribute('aria-busy', 'true');
163    try {
164      const response = await fetch(form.action, { method: 'POST', body: new FormData(form),
165        credentials: 'same-origin', headers: { 'X-Company-Form': '1' } });
166      const result = await response.json();
167      if (!response.ok || typeof result.redirect !== 'string' || typeof result.created !== 'boolean') throw new Error('Unexpected response');
168      const destination = new URL(result.redirect, location.href);
169      if (destination.origin !== location.origin) throw new Error('Unexpected destination');
170      if (result.created) {
171        const savedToken = sessionStorage.getItem(draftKey);
172        if (savedToken) await transfer('remove', savedToken);
173        sessionStorage.removeItem(draftKey);
174      }
175      location.assign(destination.href);
176    } catch (_) {
177      message('Die Übermittlung konnte nicht bestätigt werden. Ihre Eingaben bleiben erhalten. Bitte prüfen Sie vor erneutem Absenden, ob das Unternehmensprofil bereits angelegt wurde.');
178      busy = false;
179      form.removeAttribute('aria-busy');
180    }
181  }
182  window.BsubmitForm = submit;
183  form.addEventListener('submit', event => { event.preventDefault(); submit(); });
184})();

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.