// ==UserScript== // @name ficUpdate // @namespace ficscript // @version 2.1 // @description bulk copy-paste all the chapters from Word on ficbook // @author Dimava // @match https://ficbook.net/home/myfics/* // @grant none // @downloadURL none // ==/UserScript== if (!/\/home\/myfics\/\d+.?$/.test(location.href)) throw Error('Для групповой загрузки перейдите на страницу редактирования фанфика!'); q('.edi') && q('.edi').remove(); var ops = document.querySelector('.myfic'); var b1 = elm('button', 'Подготовить'); b1.onclick = prepare; var b2 = elm('button', 'Добавить отсутствующие'); b2.onclick = addNewParts; var b3 = elm('button', 'Обновить'); b3.onclick = updateParts; var cb = document.createElement('input'); cb.type = 'checkbox'; cb.checked = true; var l = elm('label', ' ', cb, ' Черновик'); var notPublishedCheckbox = cb; var text = elm('div'); text.contentEditable = true; text.style.cssText = 'background:white;border:1px dotted gray; width:49.5%; float:left;'; var text2 = elm('div'); text2.style.cssText = 'background:hsl(0,0%,95%);border:1px dotted gray; width:49.5%; float:right;'; ops.append(elm('div.edi', elm('div', b1, b2, b3, l), elm('br'), elm('div', text, text2))); var parts, prepared; //text.innerHTML = localStorage.temp; function prepare() { let t = text.innerHTML; if (!t.match(/

])[^>]*>/g, ''); // remove bad tags let t3 = t2.replace(/<(\/?)(h1|br|b|s|i|center|right)(?=[\s|>])[^>]*>/g, '<$1$2>'); // remove attributes parts = t3.split(/]*>/).map(e=>e.split('

')).slice(1).map(e=>({ name: htext(e[0]).replace(/\s+/g, ' ').trim(), text: tabber(e[1]), })) text2.innerHTML = [].concat(...parts.map(p=>['

', p.name, '


', p.text.replace(/\n/g, '
')])).join('\n'); prepared = true; } async function addPart(part) { let f = elm('iframe'); ops.prepend(f) let res; let p = new Promise(r=>res = r); f.addEventListener('load', res); f.addEventListener('load', (res=>console.log('loaded'))); f.src = q('.add-part a').href f.style.cssText = 'height:200px;width:100%' await p; let d = f.contentWindow.document; q('[name=title]', d).value = part.name; q('#content', d).value = part.text; q('#not_published_chb', d).checked = notPublishedCheckbox.checked; p = new Promise(r=>res = r); f.addEventListener('load', res); f.addEventListener('load', (res=>console.log('loaded'))); q('#savePartForm [type=submit]', d).click(); await p; f.remove() done('Часть добвлена', part.name); } async function updatePart(part) { let f = elm('iframe'); ops.prepend(f) let res; let p = new Promise(r=>res = r); f.addEventListener('load', res); f.addEventListener('load', (res=>console.log('loaded'))); let tts = partAdded(part); if (!tts) { return err('Часть ещё не добавлена!', part.name) } f.src = tts.href; f.style.cssText = 'height:200px;width:100%' await p; let d = f.contentWindow.document; let changed = false; if (q('[name=title]', d).value == part.name && q('#content', d).value == part.text) { info('Часть не изменилась', part.name); f.remove(); return; } q('[name=title]', d).value = part.name; q('#content', d).value = part.text; p = new Promise(r=>res = r); f.addEventListener('load', res); f.addEventListener('load', (res=>console.log('loaded'))); q('#savePartForm [type=submit]', d).click(); await p; f.remove(); done('Часть изменена', part.name); } function htext(h) { let a = document.createElement('a'); a.innerHTML = h; return a.innerText; } function elm(sel, ...childs) { let el = document.createElement(sel.match(/^[a-zA-Z\-_]+/)[0]); (sel.match(/\.[a-zA-Z\-_]+/) || []).forEach(c=>el.classList.add(c.replace(/\./, ''))); if (childs.length) el.append(...childs); return el; } function tabber(s) { let hTexts = {}; function hText(s) { if (hTexts[s]) return hTexts[s]; let a = document.createElement('a'); a.innerHTML = s; return hTexts[s] = a.innerText; } const nbsp = '\xa0'; //hText(' '); const emsp = '\u2003'; //hText(' '); const ndash = '\u2013'; //hText('–'); const replacers = [[/\n/g, ' '], [/^\s+|\s+$/gm, '\n\n\n'], [/&[^;]{2,7};/g, hText], [/
|<.div>]*>|<.div>|]*>/g, '\n'], [/]*(center|right)[^>]*>([^]*?)<\/p>/g, '\n<$1>\n$2\n\n'], [/<\/p>\s*]*>/g, '\n'], [/<\/p>\s*|\s*]*>/g, '\n'], [/