1import { Controller } from '@hotwired/stimulus'; 2 3// íµí© ìì± ì»´í¬ì â ë§í¬(ð)를 ì¼ë©´ "íë§ë"ìì "ë´ì¤ ê³µì "ë¡ ì ííë¤(§3.7 Phase 1). 4// ê°ì í¼ì action·íëëª ì articles#createì ë§ì¶° ë°ê¿ 컨í¸ë¡¤ë¬ë¥¼ ì¬ì¬ì©íë¤. 5// íë§ë: POST /short_posts { body, tag_name } 6// ë´ì¤: POST /articles { article[url], comment(=본문), article[owned_tag_list][](=ì´ì) } 7export default class extends Controller { 8 static targets = ['url', 'urlWrap', 'body', 'tag', 'submit', 'newsField']; 9 static values = { shortPostsUrl: String, articlesUrl: String }; 10 11 connect() { 12 this.newsMode = false; 13 this.apply(); 14 // ì¸ë¶ í¸ë¦¬ê±°(compose:open)ê° news·tag ìë를 ë´ì ì´ë©´ ê·¸ ìíë¡ ë§ì¶ë¤. 15 // ì: "ë´ì¤ ì¶ê°" â ë§í¬ 모ë, ì´ì íì´ì§ í¸ë¦¬ê±° â ê·¸ ì´ì를 ì´ì ì í기ì í리ì ë í¸. 16 this._onOpen = (e) => { 17 const wantNews = !!(e.detail && e.detail.news); 18 if (wantNews !== this.newsMode) this.toggleUrl(); 19 20 const tag = e.detail && e.detail.tag; 21 if (tag && this.hasTagTarget && this.tagTarget.tomselect) { 22 const ts = this.tagTarget.tomselect; 23 ts.addOption({ name: tag, label: tag }); 24 ts.setValue(tag, true); // silent: change ì´ë²¤í¸ ìì´ ì í 25 } 26 }; 27 window.addEventListener('compose:open', this._onOpen); 28 } 29 30 disconnect() { 31 if (this._onOpen) window.removeEventListener('compose:open', this._onOpen); 32 } 33 34 toggleUrl() { 35 this.newsMode = !this.newsMode; 36 this.urlWrapTarget.classList.toggle('tw-hidden', !this.newsMode); 37 this.apply(); 38 if (this.newsMode) this.urlTarget.focus(); 39 } 40 41 // ë¤ë¥¸ íìì¼ë¡ ì¹ê²©(§3.7 Phase 2) â ì ë ¥í ê¸Â·ì´ì를 ë기며 í´ë¹ new í¼ì¼ë¡ ì´ëíë¤. 42 escalate(event) { 43 event.preventDefault(); 44 const path = event.currentTarget.dataset.newPath; 45 if (!path) return; 46 const body = this.bodyTarget.value.trim(); 47 const tag = this.hasTagTarget ? (this.tagTarget.value || '') : ''; 48 49 // 본문ì POSTë¡ ëê¸´ë¤ â 긴 ì견ì GET 쿼리ì¤í¸ë§ì ë´ì¼ë©´ nginx 414(URI Too Large)ê° ëë¤. 50 const form = document.createElement('form'); 51 form.method = 'post'; 52 form.action = path; 53 const token = document.querySelector('meta[name="csrf-token"]')?.content; 54 const addField = (name, value) => { 55 const input = document.createElement('input'); 56 input.type = 'hidden'; 57 input.name = name; 58 input.value = value; 59 form.appendChild(input); 60 }; 61 if (token) addField('authenticity_token', token); 62 if (body) addField('body', body); 63 if (tag) addField('tag', tag); 64 document.body.appendChild(form); 65 form.submit(); 66 } 67 68 apply() { 69 const news = this.newsMode; 70 this.element.action = news ? this.articlesUrlValue : this.shortPostsUrlValue; 71 this.bodyTarget.name = news ? 'comment' : 'body'; 72 if (this.hasTagTarget) this.tagTarget.name = news ? 'article[owned_tag_list][]' : 'tag_name'; 73 // ë´ì¤ ì ì© íë(url·is_recent·published_at)ë ë´ì¤ì¼ ëë§ ì ì¡íë¤ 74 this.newsFieldTargets.forEach((f) => { f.disabled = !news; }); 75 if (this.hasUrlTarget) this.urlTarget.required = news; 76 this.submitTarget.value = news ? 'ë´ì¤ ê³µì ' : 'ì견 ë¨ê¸°ê¸°'; 77 } 78}
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.