initial commit
This commit is contained in:
+100
@@ -0,0 +1,100 @@
|
||||
# Inline Script Bridging Checklist
|
||||
|
||||
When adding a plain `<script>` (non-module) to a page that uses ES modules, the inline script has NO access to module-level imports. Three categories of globals are commonly missing:
|
||||
|
||||
## 1. `closeModal` / Modal Helpers
|
||||
|
||||
**Symptom:** `onclick="closeModal('...')"` on buttons does nothing, or JS code calls `closeModal()` and gets `ReferenceError`.
|
||||
|
||||
**Diagnosis:**
|
||||
```bash
|
||||
grep -c 'window.closeModal' page.html
|
||||
# 0 = missing
|
||||
```
|
||||
|
||||
**Fix:** Add at the top of the inline script block:
|
||||
```javascript
|
||||
window.closeModal = function(id) {
|
||||
var m = document.getElementById(id);
|
||||
if (m) { m.classList.add('hidden'); m.setAttribute('aria-hidden', 'true'); }
|
||||
};
|
||||
```
|
||||
|
||||
(Note: `shared/modal-manager.js` exports `closeModal` as a named ES module export — it does NOT set `window.closeModal`. Don't assume it's globally available.)
|
||||
|
||||
## 2. `escapeHtml` / Sanitization Functions
|
||||
|
||||
**Symptom:** `escapeHtml is not defined` when rendering user data in dynamically created HTML.
|
||||
|
||||
**Diagnosis:** `shared/sanitize.js` exports `escapeHtml` as a named ES module export only. It is NOT on `window`.
|
||||
|
||||
**Fix:** Add a local polyfill at the top of the inline script:
|
||||
```javascript
|
||||
function escapeHtml(text) {
|
||||
var d = document.createElement('div');
|
||||
d.appendChild(document.createTextNode(text));
|
||||
return d.innerHTML;
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Module-Level Data Functions
|
||||
|
||||
**Symptom:** Inline script needs to call a function defined in a module (e.g., `batchCreateAppointments`, `loadAppointments`) but can't import it.
|
||||
|
||||
**Fix (exporter side — in the module):**
|
||||
```javascript
|
||||
// In appointments.js or similar module file
|
||||
window.batchCreateAppointments = async function(data) {
|
||||
// Uses module-scoped `addDoc`, `collection`, `db`, `currentUser` etc.
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
**Fix (consumer side — in the inline script):**
|
||||
```javascript
|
||||
// Call the window-exposed function
|
||||
const result = await window.batchCreateAppointments(selectedAppointments);
|
||||
```
|
||||
|
||||
Place the `window.*` assignment in the module file, AFTER the function's dependencies are initialized (after `onAuthStateChanged` has fired, after imports are resolved).
|
||||
|
||||
## 4. Timing: Module vs Inline Execution Order
|
||||
|
||||
**Symptom:** `window.someFunction is not a function` when the inline script calls it at page load.
|
||||
|
||||
**Root cause:** Classic `<script>` tags run synchronously before deferred `<script type="module">` tags. The module may not have executed yet.
|
||||
|
||||
**Safe pattern:** Only call `window.*` functions in **event handlers** (click, submit, etc.), not at script load time. By the time the user interacts, the module has loaded.
|
||||
|
||||
If you MUST call at load time, use a polling guard:
|
||||
```javascript
|
||||
function waitFor(fn, timeout) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const start = Date.now();
|
||||
const check = () => {
|
||||
if (typeof fn === 'function') return resolve();
|
||||
if (Date.now() - start > timeout) return reject(new Error('Timeout waiting for function'));
|
||||
setTimeout(check, 50);
|
||||
};
|
||||
check();
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Nginx Proxy for CORS-Sensitive APIs
|
||||
|
||||
**Symptom:** `fetch()` to an external API fails with CORS errors in the browser console.
|
||||
|
||||
**Fix:** Proxy the external API through nginx on the same origin:
|
||||
```nginx
|
||||
location /deepseek/ {
|
||||
proxy_pass https://api.deepseek.com/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host api.deepseek.com;
|
||||
proxy_set_header Authorization "Bearer YOUR_API_KEY";
|
||||
}
|
||||
```
|
||||
|
||||
Then call `/deepseek/chat/completions` (relative URL) from the inline script — no CORS issue.
|
||||
|
||||
**Verify:** The proxy location must be in the same `server { }` block that serves the page. If the page is served on port 3447 but the proxy is on port 80, the relative URL won't reach it.
|
||||
Reference in New Issue
Block a user