1console.log('loading js tinymce-blazor'); 2 3const CreateScriptLoader = () => { 4 let unique = 0; 5 6 const uuid = (prefix) => { 7 const time = Date.now(); 8 const random = Math.floor(Math.random() * 1000000000); 9 unique++; 10 return prefix + '_' + random + unique + String(time); 11 }; 12 const state = { 13 scriptId: uuid('tiny-script'), 14 listeners: [], 15 scriptLoaded: false 16 }; 17 18 const injectScript = (scriptId, doc, url, injectionCallback) => { 19 const scriptTag = doc.createElement('script'); 20 scriptTag.referrerPolicy = 'origin'; 21 scriptTag.type = 'application/javascript'; 22 scriptTag.id = scriptId; 23 scriptTag.src = url; 24 25 const handler = () => { 26 scriptTag.removeEventListener('load', handler); 27 injectionCallback(); 28 }; 29 scriptTag.addEventListener('load', handler); 30 if (doc.head) { 31 doc.head.appendChild(scriptTag); 32 } 33 }; 34 35 const load = (doc, url, cb) => { 36 if (state.scriptLoaded) { 37 cb(); 38 } else { 39 state.listeners.push(cb); 40 if (!doc.getElementById(state.scriptId)) { 41 injectScript(state.scriptId, doc, url, () => { 42 state.listeners.forEach((fn) => fn()); 43 state.scriptLoaded = true; 44 }); 45 } 46 } 47 } 48 49 return { 50 load 51 } 52} 53 54if (!window.tinymceBlazorLoader) { 55 window.tinymceBlazorLoader = CreateScriptLoader(); 56} 57 58const getGlobal = () => (typeof window !== 'undefined' ? window : global); 59 60const getTiny = () => { 61 const global = getGlobal(); 62 return global && global.tinymce ? global.tinymce : null; 63}; 64 65const updateTinyVal = (id, val) => { 66 if (getTiny() && getTiny().get(id).getContent() !== val) { 67 getTiny().get(id).setContent(val); 68 } 69}; 70 71const tinyEventHandler = (() => { 72 const eventCache = {}; 73 const bindEvent = (editor, event, fn) => { 74 if (!eventCache[editor.id]) eventCache[editor.id] = []; 75 eventCache[editor.id].push({ name: event, fn }); 76 editor.on(event, fn); 77 }; 78 const unbindEditor = (editorId) => { 79 const editor = getTiny().get(editorId); 80 eventCache[editorId].forEach((event, i) => { 81 editor.off(event.name, event.fn); 82 }); 83 delete eventCache.editorId; 84 }; 85 return { 86 bindEvent, 87 unbindEditor 88 } 89})(); 90 91const chunkMap = (() => { 92 const map = new Map(); 93 const next = (streamId, editorId, val, index, size) => { 94 const acc = (map.has(streamId) ? map.get(streamId) : "") + val; 95 if (index === size) { 96 updateTinyVal(editorId, acc); 97 map.delete(streamId); 98 } else { 99 map.set(streamId, acc); 100 } 101 }; 102 return { 103 push: next 104 }; 105})(); 106 107window.tinymceBlazorWrapper = { 108 insertContent: (id, content, args) => { 109 const tiny = getTiny().get(id); 110 tiny?.insertContent(content, args); 111 }, 112 updateMode: (id, disable) => { 113 const tiny = getTiny().get(id); 114 if (tiny.mode && typeof tiny.mode.set === 'function') { 115 tiny.mode.set(disable ? 'readonly' : 'design'); 116 } else { 117 tiny.setMode(disable ? 'readonly' : 'design'); 118 } 119 }, 120 updateValue: (id, streamId, value, index, chunks) => { 121 chunkMap.push(streamId, id, value, index, chunks); 122 }, 123 init: (el, blazorConf, dotNetRef) => { 124 const chunkSize = 16 * 1024; 125 const update = (format, content) => { 126 const updateFn = format === 'text' ? 'UpdateText' : 'UpdateModel'; 127 const chunks = Math.floor(content.length / chunkSize) + 1; 128 const streamId = (Date.now() % 100000) + ''; 129 for (let i = 0; i < chunks; i++) { 130 const chunk = content.substring(chunkSize * i, chunkSize * (i + 1)); 131 dotNetRef.invokeMethodAsync(updateFn, streamId, i + 1, chunk, chunks); 132 } 133 }; 134 const getJsObj = (objectPath) => { 135 const jsConf = (objectPath !== null && typeof objectPath === 'string') ? objectPath.split('.').reduce((acc, current) => { 136 return acc !== undefined ? acc[current] : undefined; 137 }, window) : undefined; 138 return (jsConf !== undefined && typeof jsConf === 'object') ? jsConf : {}; 139 }; 140 const tinyConf = { ...getJsObj(blazorConf.jsConf), ...blazorConf.conf }; 141 tinyConf.inline = blazorConf.inline; 142 tinyConf.readonly = blazorConf.disabled; 143 tinyConf.target = el; 144 tinyConf._setup = tinyConf.setup; 145 tinyConf.setup = (editor) => { 146 tinyEventHandler.bindEvent(editor, 'init', (e) => dotNetRef.invokeMethodAsync('GetValue').then(value => { editor.setContent(value); })); 147 tinyEventHandler.bindEvent(editor, 'change', (e) => { dotNetRef.invokeMethodAsync('OnChange'); }); 148 tinyEventHandler.bindEvent(editor, 'input', (e) => { dotNetRef.invokeMethodAsync('OnInput'); }); 149 tinyEventHandler.bindEvent(editor, 'setcontent', (e) => update('text', editor.getContent({ format: 'text' }))); 150 tinyEventHandler.bindEvent(editor, blazorConf.modelEvents, (e) => { 151 update('html', editor.getContent()); 152 update('text', editor.getContent({ format: 'text' })); 153 }); 154 if (tinyConf._setup && typeof tinyConf._setup === 'function') { 155 tinyConf._setup(editor, tinyEventHandler); 156 } 157 } 158 159 if (getTiny()) { 160 getTiny().init(tinyConf); 161 } else { 162 if (el && el.ownerDocument) { 163 // inject tiny here 164 window.tinymceBlazorLoader.load(el.ownerDocument, blazorConf.src, () => { 165 getTiny().init(tinyConf); 166 }); 167 } 168 } 169 }, 170 destroy: (el, id) => { 171 if (getTiny() && getTiny().get(id)) { 172 tinyEventHandler.unbindEditor(id); 173 getTiny().get(id).remove(); 174 } 175 } 176}
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.