window.EditorMovie = (function () { 'use strict'; var STORAGE_KEY = 'omdb-api-key'; var BEGIN = ''; var END = ''; function firstHeading(text) { var m = text.match(/^#{1,6}\s+(.+?)\s*$/m); return m ? m[1].trim() : ''; } function parseTitleYear(raw) { var m = raw.match(/^(.+?)\s*\((\d{4})\)\s*$/); return m ? { title: m[1].trim(), year: m[2] } : { title: raw.trim(), year: null }; } function safe(v) { return (!v || v === 'N/A') ? '' : String(v); } function esc(s) { return String(s) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function buildBlock(m) { var out = [BEGIN, '', END); return out.join('\n'); } function replaceRange(ta, start, end, text) { ta.focus(); ta.selectionStart = start; ta.selectionEnd = end; document.execCommand('insertText', false, text); } function insertOrReplace(ta, markup) { var t = ta.value || ''; var b = t.indexOf(BEGIN); var e = t.indexOf(END); if (b !== -1 && e !== -1 && e > b) { replaceRange(ta, b, e + END.length, markup); } else { var h = t.match(/^#{1,6}\s+.+?\s*$/m); if (h) { var idx = t.indexOf(h[0]) + h[0].length; replaceRange(ta, idx, idx, '\n\n' + markup); } else { replaceRange(ta, 0, 0, t ? markup + '\n\n' : markup); } } } function fetchMovie(key, title, year) { var url = 'https://www.omdbapi.com/?apikey=' + encodeURIComponent(key) + '&type=movie&t=' + encodeURIComponent(title); if (year) url += '&y=' + encodeURIComponent(year); return fetch(url).then(function (r) { return r.json(); }); } function showMessage(title, msg) { openModal({ title: title, body: msg, confirm: { label: 'OK' } }); } function promptForKey(rejected, onSaved) { var body = document.createDocumentFragment(); if (rejected) { var notice = document.createElement('p'); notice.textContent = 'The previously stored key was rejected by OMDb.'; body.appendChild(notice); } var info = document.createElement('p'); info.appendChild(document.createTextNode('Enter your OMDb API key. Get one at ')); var link = document.createElement('a'); link.href = 'https://www.omdbapi.com/apikey.aspx'; link.target = '_blank'; link.rel = 'noopener'; link.textContent = 'omdbapi.com/apikey.aspx'; info.appendChild(link); info.appendChild(document.createTextNode('.')); body.appendChild(info); var input = document.createElement('input'); input.type = 'text'; input.className = 'modal-input'; input.placeholder = 'OMDb API key'; body.appendChild(input); openModal({ title: 'OMDb API key required', body: body, confirm: { label: 'SAVE', onConfirm: function () { var key = input.value.trim(); if (!key) return; localStorage.setItem(STORAGE_KEY, key); closeModal(); onSaved(key); }, }, }); } function importWithKey(textarea, key, initialTitle) { var input = document.createElement('input'); input.type = 'text'; input.className = 'modal-input'; input.placeholder = 'Title, optionally with (YYYY)'; input.value = initialTitle; openModal({ title: 'Import movie', body: input, confirm: { label: 'IMPORT', onConfirm: function () { var raw = input.value.trim(); if (!raw) return; var parsed = parseTitleYear(raw); closeModal(); fetchMovie(key, parsed.title, parsed.year) .then(function (data) { if (data && data.Response === 'False' && data.Error === 'Invalid API key!') { localStorage.removeItem(STORAGE_KEY); promptForKey(true, function (newKey) { importWithKey(textarea, newKey, raw); }); return; } if (!data || data.Response === 'False') { showMessage('Not found', (data && data.Error) || 'Movie not found.'); return; } insertOrReplace(textarea, buildBlock(data)); }) .catch(function () { showMessage('Import failed', 'OMDb lookup failed.'); }); }, }, }); } function run(textarea) { var initialTitle = firstHeading(textarea.value || ''); var key = localStorage.getItem(STORAGE_KEY); if (!key) { promptForKey(false, function (newKey) { importWithKey(textarea, newKey, initialTitle); }); return; } importWithKey(textarea, key, initialTitle); } return { run: run }; })();