1/* 2 * rara_collage_view.js (v2) 3 * ê²ìí ë·°íì´ì§ìì ì½ë¼ì£¼ ë ì´ììì ë³µì/ì 리íë ì¤í¬ë¦½í¸. 4 * 5 * ì²ë¦¬ ë´ì©: 6 * 1) ì ì ì½ë¼ì£¼(2ì¥ ì´ì): ë¹ì¨ ê¸°ë° ëì¼ ëì´ flex ë ì´ìì ë³µì 7 * 2) ìì¬ ì½ë¼ì£¼(1ì¥ ì´í): ìëí°ì ëì¼íê² "í´ì²´" - ì½ë¼ì£¼ ê»ë°ê¸°ë¥¼ ê±·ì´ë´ê³ 8 * ì´ë¯¸ì§ë¥¼ ê°ë³ ì¬ì§ í¬ê¸°(ê°ë¡ 100%)ë¡ ë³µì 9 * 3) ë ëì´ ìì¬ë¬¼: ì½ë¼ì£¼ ë°ì¸ë° ì½ë¼ì£¼ ìì ìì±(data-rara-flex ë±)ì´ë 10 * figure flex ì¤íì¼ì´ ë¨ì ì´ë¯¸ì§ë¥¼ ê°ë³ ì¬ì§ í¬ê¸°ë¡ ì 리 11 * 12 * ì¬ì©: /www/extend/rara_collage.extend.php ê° ìëì¼ë¡ ì´ íì¼ì ë¡ëí¨. 13 * ê²ìí ì¤í¨(ë·°íì´ì§)ì ì í ìì í íì ìì. 14 */ 15(function(){ 16 'use strict'; 17 18 var GAP = 4; 19 20 function isImg(el){ 21 return el && el.tagName === 'IMG' && (el.getAttribute('src') || ''); 22 } 23 24 function setImportant(el, styles){ 25 if(!el || !el.style) return; 26 Object.keys(styles || {}).forEach(function(name){ 27 el.style.setProperty(name, styles[name], 'important'); 28 }); 29 } 30 31 function getRatio(img){ 32 if(!img) return 1; 33 var w = parseFloat(img.getAttribute('data-original-width') || img.getAttribute('data-width') || img.getAttribute('width') || img.naturalWidth || 0);
34 var h = parseFloat(img.getAttribute('data-original-height') || img.getAttribute('data-height') || img.getAttribute('height') || img.naturalHeight || 0); 35 if(!w || !h){ 36 var rect = img.getBoundingClientRect ? img.getBoundingClientRect() : null; 37 if(rect && rect.width && rect.height){ 38 w = rect.width; 39 h = rect.height; 40 } 41 } 42 if(!w || !h) return 1; 43 return Math.max(0.35, Math.min(3.5, w / h)); 44 } 45 46 function collageRowSize(count, layout){ 47 if(layout === 'free3' && count <= 3) return count; 48 return 2; 49 } 50 51 function measureCollageRows(col){ 52 if(!col || !col.querySelectorAll) return; 53 var figs = Array.prototype.slice.call(col.children).filter(function(child){ 54 return child.nodeType === 1 && child.querySelector && child.querySelector('img'); 55 }); 56 if(!figs.length) return; 57 var layout = col.getAttribute('data-rara-collage-layout') || 'paired'; 58 var rowSize = collageRowSize(figs.length, layout); 59 var rect = col.getBoundingClientRect ? col.getBoundingClientRect() : null; 60 var width = (rect && rect.width) || col.clientWidth || (col.parentNode && col.parentNode.getBoundingClientRect && col.parentNode.getBoundingClientRect().width) || 720; 61 var gap = parseFloat(window.getComputedStyle ? window.getComputedStyle(col).gap : GAP) || GAP; 62 for(var i = 0; i < figs.length; i += rowSize){ 63 var row = figs.slice(i, i + rowSize); 64 var fullSingle = layout === 'paired' && row.length === 1; 65 var ratioSum = row.reduce(function(sum, fig){ 66 return sum + getRatio(fig.querySelector('img')); 67 }, 0) || row.length; 68 var available = Math.max(1, Math.floor(width - (gap * Math.max(0, row.length - 1)))); 69 var rowHeight = fullSingle ? null : Math.max(80, Math.floor(available / ratioSum)); 70 var used = 0; 71 row.forEach(function(fig, rowIndex){ 72 var img = fig.querySelector('img'); 73 if(fullSingle){ 74 fig.style.removeProperty('--rara-collage-row-height'); 75 fig.style.setProperty('--rara-collage-item-width', '100%'); 76 fig.style.setProperty('flex', '0 0 100%', 'important'); 77 fig.style.setProperty('width', '100%', 'important'); 78 fig.style.setProperty('height', 'auto', 'important'); 79 if(img){ 80 img.style.setProperty('width', '100%', 'important'); 81 img.style.setProperty('height', 'auto', 'important'); 82 img.style.setProperty('object-fit', 'contain', 'important'); 83 } 84 } else { 85 var ratio = getRatio(img); 86 var itemWidth = rowIndex === row.length - 1 ? Math.max(1, available - used) : Math.max(1, Math.floor(ratio * rowHeight)); 87 used += itemWidth; 88 fig.style.setProperty('--rara-collage-item-width', itemWidth + 'px'); 89 fig.style.setProperty('--rara-collage-row-height', rowHeight + 'px'); 90 fig.style.setProperty('height', rowHeight + 'px', 'important'); 91 fig.style.setProperty('width', itemWidth + 'px', 'important'); 92 fig.style.setProperty('flex', '0 0 ' + itemWidth + 'px', 'important'); 93 if(img){ 94 img.style.setProperty('width', '100%', 'important'); 95 img.style.setProperty('height', '100%', 'important'); 96 img.style.setProperty('object-fit', 'contain', 'important'); 97 img.style.setProperty('background', 'transparent', 'important'); 98 } 99 } 100 }); 101 } 102 } 103 104 function scheduleCollageMeasure(col){ 105 if(!col) return; 106 measureCollageRows(col); 107 setTimeout(function(){ measureCollageRows(col); }, 50); 108 setTimeout(function(){ measureCollageRows(col); }, 250); 109 if(window.requestAnimationFrame) requestAnimationFrame(function(){ measureCollageRows(col); }); 110 } 111 112 /* ì´ë¯¸ì§ë¥¼ ìì í ê°ë³ ì¬ì§ ìíë¡ ë³µì (ìëí°ì resetToIndividualê³¼ ëì¼) */ 113 function resetToIndividual(img){ 114 img.removeAttribute('data-rara-ci'); 115 img.removeAttribute('data-rara-flex'); 116 img.removeAttribute('width'); 117 img.removeAttribute('height'); 118 img.removeAttribute('sizes'); 119 img.style.cssText = 'display:block;width:100%;max-width:100%;height:auto;'; 120 } 121 122 function isOrphanCollageImg(img){ 123 if(!isImg(img)) return false; 124 if(img.closest('.jodit-wysiwyg')) return false; 125 if(img.closest('.rara-collage') || img.closest('[data-rara-collage]')) return false;
126 return img.hasAttribute('data-rara-ci') || 127 img.hasAttribute('data-rara-collage-image') || 128 (img.classList && (img.classList.contains('rara-collage-img') || img.classList.contains('rara-naver-collage-img'))); 129 } 130 131 function rebuildOrphanCollages(){ 132 document.querySelectorAll('#bo_v_con, .rara-view-content, .member-view-content, .member-notice-content').forEach(function(root){ 133 var run = []; 134 135 function blockImage(block){ 136 if(!block || block.nodeType !== 1) return null; 137 var imgs = Array.prototype.slice.call(block.querySelectorAll ? block.querySelectorAll('img') : []).filter(isOrphanCollageImg); 138 if(!imgs.length && block.tagName === 'IMG' && isOrphanCollageImg(block)) imgs = [block]; 139 if(imgs.length !== 1) return null; 140 var text = (block.textContent || '').replace(/\s+/g, ''); 141 var cap = block.querySelector ? block.querySelector('figcaption,.rara-collage-caption') : null; 142 if(text && (!cap || text !== (cap.textContent || '').replace(/\s+/g, ''))) return null; 143 return imgs[0]; 144 } 145 146 function flush(){ 147 if(run.length < 2){ 148 run = []; 149 return; 150 } 151 var col = document.createElement('div'); 152 col.className = 'rara-collage rara-naver-collage rara-collage-' + run.length + ' rara-naver-collage-count-' + run.length; 153 col.setAttribute('data-rara-collage', String(run.length)); 154 root.insertBefore(col, run[0].block); 155 run.forEach(function(item, i){ 156 var fig = document.createElement('figure'); 157 fig.className = 'rara-naver-collage-item'; 158 item.img.setAttribute('data-rara-ci', String(i)); 159 item.img.setAttribute('data-rara-collage-image', '1'); 160 item.img.removeAttribute('data-rara-paste-image'); 161 if(item.img.classList){ 162 item.img.classList.remove('rara-paste-img'); 163 item.img.classList.add('rara-collage-img'); 164 item.img.classList.add('rara-naver-collage-img'); 165 } 166 fig.appendChild(item.img); 167 if(item.caption) fig.appendChild(item.caption); 168 col.appendChild(fig); 169 if(item.block !== item.img && item.block.parentNode && !item.block.querySelector('img')) item.block.remove(); 170 }); 171 restoreCollage(col); 172 run = []; 173 } 174 175 Array.prototype.slice.call(root.childNodes).forEach(function(node){ 176 if(node.nodeType === 3 && !(node.textContent || '').trim()) return; 177 if(node.nodeType !== 1){ 178 flush(); 179 return; 180 } 181 var img = blockImage(node); 182 if(img){ 183 run.push({ 184 block: node, 185 img: img, 186 caption: node.querySelector ? node.querySelector('figcaption,.rara-collage-caption') : null 187 }); 188 } else { 189 flush(); 190 } 191 }); 192 flush(); 193 }); 194 } 195 196 /* ì½ë¼ì£¼ ê»ë°ê¸°ë¥¼ ê±·ì´ë´ê³ ì´ë¯¸ì§ë¤ì ê°ë³ ì¬ì§ì¼ë¡ ë³µì */ 197 function dissolveOnView(col, imgs){ 198 imgs.forEach(function(img){ 199 var fig = img.closest ? img.closest('figure') : null; 200 var caption = fig && fig.querySelector ? fig.querySelector('figcaption,.rara-collage-caption') : null; 201 var p = document.createElement('p'); 202 resetToIndividual(img); 203 p.style.cssText = 'margin:12px 0;width:100%;max-width:100%;box-sizing:border-box;'; 204 p.appendChild(img); 205 if(caption) p.appendChild(caption); 206 if(col.parentNode) col.parentNode.insertBefore(p, col); 207 }); 208 col.remove(); 209 } 210 211 function restoreCollage(col){ 212 /* ìëí° ìììë ìëí° ì¤í¬ë¦½í¸ê° ì²ë¦¬íë¯ë¡ ê±´ëë */ 213 if(col.closest && col.closest('.jodit-wysiwyg')) return; 214 215 var imgs = Array.prototype.slice.call(col.querySelectorAll('img')).filter(isImg); 216 217 /* â 1ì¥ ì´í = ìì¬ ì½ë¼ì£¼ â ë·°ììë í´ì²´íì¬ ê°ë³ ì¬ì§ í¬ê¸°ë¡ ë³µì 218 (ì´ ì²ë¦¬ê° ìì¼ë©´ ë°í ì ì½ë¼ì£¼ ìì í¬ê¸° ê·¸ëë¡ ë³´ì´ë ë²ê·¸ ë°ì) */ 219 if(imgs.length < 2){ 220 dissolveOnView(col, imgs); 221 return; 222 } 223 224 /* figure 구조 íì¸/복구 */ 225 var figs = []; 226 imgs.forEach(function(img){ 227 var fig = img.closest('figure'); 228 if(!fig || fig.parentNode !== col){ 229 var nf = document.createElement('figure'); 230 /* ì´ë¯¸ì§ì íì¬ ìì¹ì figure를 ë§ë¤ì´ ê°ì¼ë¤ */ 231 img.parentNode.insertBefore(nf, img); 232 nf.appendChild(img); 233 /* figureê° ì½ë¼ì£¼ ë°ë¡ ìëì ìëë¡ ì´ë */ 234 if(nf.parentNode !== col) col.appendChild(nf); 235 fig = nf; 236 } 237 figs.push(fig); 238 }); 239 240 /* figure ë°ì ë¨ì ìì¬ ë ¸ë(ë¹ figure ë±) ì 리 */
241 Array.prototype.slice.call(col.children).forEach(function(c){ 242 if(c.tagName === 'FIGURE' && !c.querySelector('img')) c.remove(); 243 }); 244 245 var count = imgs.length; 246 var layout = col.getAttribute('data-rara-collage-layout') || (col.classList.contains('rara-collage-free3') ? 'free3' : 'paired'); 247 if(layout !== 'free3' || count > 3) layout = 'paired'; 248 col.setAttribute('data-rara-collage', String(count)); 249 col.setAttribute('data-rara-collage-layout', layout); 250 col.classList.remove('rara-collage-paired', 'rara-collage-free3'); 251 col.classList.add(layout === 'free3' ? 'rara-collage-free3' : 'rara-collage-paired'); 252 253 /* 컨í ì´ë ì¤íì¼ */ 254 if(count === 4){ 255 col.style.cssText = 'display:flex;flex-wrap:wrap;gap:' + GAP + 'px;width:100%;max-width:100%;margin:12px 0;padding:0;background:transparent;box-sizing:border-box;align-items:flex-start;clear:both;'; 256 setImportant(col, {display:'flex', 'flex-wrap':'wrap', gap:GAP + 'px', width:'100%', 'max-width':'100%', margin:'12px 0', padding:'0', background:'transparent', 'box-sizing':'border-box', 'align-items':'flex-start'}); 257 } else { 258 col.style.cssText = 'display:flex;flex-wrap:wrap;gap:' + GAP + 'px;width:100%;max-width:100%;margin:12px 0;padding:0;background:transparent;box-sizing:border-box;align-items:flex-start;clear:both;'; 259 setImportant(col, {display:'flex', 'flex-wrap':'wrap', gap:GAP + 'px', width:'100%', 'max-width':'100%', margin:'12px 0', padding:'0', background:'transparent', 'box-sizing':'border-box', 'align-items':'flex-start'}); 260 } 261 262 figs.forEach(function(fig, i){ 263 fig.classList.add('rara-collage-item', 'rara-naver-collage-item'); 264 fig.classList.toggle('rara-collage-full', layout === 'paired' && count % 2 === 1 && i === count - 1); 265 var base = 'display:flex;align-items:stretch;justify-content:center;margin:0;padding:0;overflow:visible;background:transparent;border-radius:0;min-width:0;max-width:100%;box-sizing:border-box;'; 266 if(count === 4){ 267 var savedFour = fig.getAttribute('data-rara-flex') || 268 (imgs[i] ? imgs[i].getAttribute('data-rara-flex') : '') || '1'; 269 fig.style.cssText = base + 'flex:' + savedFour + ' 1 0;--rara-collage-flex:' + savedFour + ';'; 270 setImportant(fig, {display:'flex', 'align-items':'stretch', 'justify-content':'center', margin:'0', padding:'0', overflow:'visible', background:'transparent', 'border-radius':'0', 'min-width':'0', 'max-width':'100%', 'box-sizing':'border-box', flex:String(savedFour) + ' 1 0'}); 271 } else { 272 var saved = fig.getAttribute('data-rara-flex') || 273 (imgs[i] ? imgs[i].getAttribute('data-rara-flex') : '') || '1'; 274 fig.style.cssText = base + 'flex:' + saved + ' 1 0;--rara-collage-flex:' + saved + ';'; 275 setImportant(fig, {display:'flex', 'align-items':'stretch', 'justify-content':'center', margin:'0', padding:'0', overflow:'visible', background:'transparent', 'border-radius':'0', 'min-width':'0', 'max-width':'100%', 'box-sizing':'border-box', flex:String(saved) + ' 1 0'}); 276 } 277 }); 278 279 imgs.forEach(function(img, i){ 280 img.style.cssText = 'display:block;width:100%;max-width:100%;height:100%;object-fit:contain;background:transparent;box-sizing:border-box;'; 281 setImportant(img, {display:'block', width:'100%', 'max-width':'100%', height:'100%', 'object-fit':'contain', background:'transparent', 'box-sizing':'border-box'}); 282 img.setAttribute('data-rara-collage-image', '1'); 283 img.removeAttribute('data-rara-paste-image'); 284 if(img.classList){ 285 img.classList.remove('rara-paste-img'); 286 img.classList.add('rara-collage-img'); 287 } 288 289 /* ì ì¥ë ë¹ì¨ì´ ìì¼ë©´ ì´ë¯¸ì§ ë¡ë í ê³ì° */ 290 if(!figs[i].getAttribute('data-rara-flex') && !img.getAttribute('data-rara-flex')){ 291 (function(fig){ 292 function adjust(){ 293 if(img.naturalWidth && img.naturalHeight){ 294 var flexValue = String(Math.max(img.naturalWidth / img.naturalHeight, 0.3).toFixed(4)); 295 fig.style.setProperty('--rara-collage-flex', flexValue); 296 fig.style.setProperty('flex', flexValue + ' 1 0', 'important'); 297 fig.setAttribute('data-rara-flex', flexValue); 298 img.setAttribute('data-rara-flex', flexValue); 299 scheduleCollageMeasure(col); 300 } 301 }
302 if(img.complete && img.naturalWidth) adjust(); 303 else img.addEventListener('load', adjust); 304 })(figs[i]); 305 } 306 }); 307 308 Array.prototype.slice.call(col.querySelectorAll('figcaption,.rara-collage-caption')).forEach(function(cap){ 309 cap.style.cssText = 'display:block;margin:6px 0 0;padding:0 2px;color:#666;font:13px/1.45 var(--rara-font-global);text-align:center;word-break:keep-all;overflow-wrap:anywhere;box-sizing:border-box;'; 310 setImportant(cap, {display:'block', margin:'6px 0 0', padding:'0 2px', color:'#666', 'font-size':'13px', 'line-height':'1.45', 'text-align':'center', 'word-break':'keep-all', 'overflow-wrap':'anywhere', 'box-sizing':'border-box'}); 311 }); 312 scheduleCollageMeasure(col); 313 } 314 315 /* â ë ëì´ ìì¬ë¬¼ ì 리: ì½ë¼ì£¼ ë°ì¸ë° ì½ë¼ì£¼ ìì íì ì´ ë¨ì ì´ë¯¸ì§ë¤. 316 í´ì²´ë ì´ë¯¸ì§ê° data-rara-flex ìì±ì´ë flex ì¤íì¼ì´ 걸린 figureì 317 ì¸ì¸ ì± ë°íëë©´ ì½ë¼ì£¼ í¬ê¸°ë¡ ë³´ì´ë¯ë¡, ê°ë³ ì¬ì§ í¬ê¸°ë¡ ë³µìíë¤. */ 318 function cleanupOrphans(){ 319 document.querySelectorAll('#bo_v_con img, .member-view-content img, .member-notice-content img').forEach(function(img){ 320 if(img.closest('.jodit-wysiwyg')) return; 321 if(img.closest('.rara-collage') || img.closest('[data-rara-collage]')) return; 322 img.removeAttribute('width'); 323 img.removeAttribute('height'); 324 img.removeAttribute('sizes'); 325 img.style.width = '100%'; 326 img.style.maxWidth = '100%'; 327 img.style.height = 'auto'; 328 }); 329 330 /* 1) ì½ë¼ì£¼ ë°ì¸ë° ì½ë¼ì£¼ ìì±ì´ ë¨ì ì´ë¯¸ì§ */ 331 document.querySelectorAll('img[data-rara-flex], img[data-rara-ci]').forEach(function(img){ 332 if(img.closest('.jodit-wysiwyg')) return; 333 if(img.closest('.rara-collage') || img.closest('[data-rara-collage]')) return; 334 resetToIndividual(img); 335 neutralizeWrapper(img); 336 }); 337 338 /* 2) ì½ë¼ì£¼ ë°ì¸ë° flex ì¤íì¼ì´ 걸린 figure ìì ì´ë¯¸ì§ */ 339 document.querySelectorAll('figure[data-rara-flex], figure[style*="flex"]').forEach(function(fig){ 340 if(fig.closest('.jodit-wysiwyg')) return; 341 if(fig.closest('.rara-collage') || fig.closest('[data-rara-collage]')) return; 342 var img = fig.querySelector('img'); 343 if(img){ 344 resetToIndividual(img); 345 } 346 fig.removeAttribute('data-rara-flex'); 347 fig.style.cssText = 'margin:12px 0;width:100%;max-width:100%;box-sizing:border-box;'; 348 }); 349 } 350 351 /* ì´ë¯¸ì§ë¥¼ ê°ì¼ figure/ëí¼ì ì½ë¼ì£¼ ìì¬ ì¤íì¼ ë¬´ë ¥í */ 352 function neutralizeWrapper(img){ 353 var fig = img.closest('figure'); 354 if(fig && !fig.closest('.rara-collage')){ 355 fig.removeAttribute('data-rara-flex'); 356 fig.style.cssText = 'margin:12px 0;width:100%;max-width:100%;box-sizing:border-box;'; 357 } 358 } 359 360 function run(){ 361 rebuildOrphanCollages(); 362 document.querySelectorAll('.rara-collage, [data-rara-collage]').forEach(restoreCollage); 363 cleanupOrphans(); 364 } 365 366 if(document.readyState === 'loading'){ 367 document.addEventListener('DOMContentLoaded', run); 368 } else { 369 run(); 370 } 371 /* ì§ì° ë¡ëëë ì½í ì¸ (ëê¸ ë´ ì´ë¯¸ì§ ë±) ëì */ 372 [50, 250, 800, 1500, 3000].forEach(function(ms){ 373 setTimeout(run, ms); 374 }); 375 try { 376 var timer = null; 377 new MutationObserver(function(){ 378 clearTimeout(timer); 379 timer = setTimeout(run, 80); 380 }).observe(document.body, {childList:true, subtree:true}); 381 } catch(e){} 382})();
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.