PageSourceSearch

https://showmasterokda.com/messenger/assets/mention-autocomplete.js?v=1791063425

js showmasterokda.com collected 2026-10-05 07:04:25 UTC 5,132 bytes, 119 lines download raw bytes

1(function(){
2function shmaEscHtml(s){var d=document.createElement("div");d.textContent=s;return d.innerHTML;}
3function shmaEscAttr(s){return String(s).replace(/&/g,"&").replace(/"/g,""");}
4function shmaMentionJsonOr401(r){
5  if(r.status===401){
6    window.__shmaApi401=1;
7    return Promise.reject();
8  }
9  if(!r.ok)return Promise.reject();
10  window.__shmaApi401=0;
11  return r.json();
12}
13window.shmaMentionAttach=function(textarea, opts){
14  if(!textarea||!opts||!opts.api||!opts.csrf)return;
15  var api=opts.api, csrf=opts.csrf;
16  var scope=opts.scope||"room";
17  var threadId=+opts.threadId||0;
18  var wrap=textarea.closest(".composer-fields")||textarea.parentElement;
19  if(!wrap)return;
20  var pop=document.createElement("div");
21  pop.className="shma-mention-pop";
22  pop.setAttribute("role","listbox");
23  pop.setAttribute("hidden","");
24  wrap.insertBefore(pop, wrap.firstChild);
25  var sel=0, rows=[], tmr=null;
26  function parse(){
27    var v=textarea.value, c=textarea.selectionStart|0;
28    var before=v.slice(0,c);
29    var m=before.match(/@([a-zA-Z0-9_]*)$/);
30    if(!m)return null;
31    return {start:c-m[0].length, query:m[1]};
32  }
33  function hide(){pop.setAttribute("hidden","");pop.innerHTML="";rows=[];}
34  function pos(){
35    if(pop.hasAttribute("hidden"))return;
36    var rect=textarea.getBoundingClientRect();
37    var w=Math.min(Math.max(rect.width,220),400);
38    pop.style.position="fixed";
39    pop.style.left=Math.max(8,rect.left)+"px";
40    pop.style.width=w+"px";
41    var h=pop.offsetHeight||160;
42    var top=rect.top-h-6;
43    if(top<8)top=rect.bottom+6;
44    if(top+h>window.innerHeight-8)top=Math.max(8,window.innerHeight-h-8);
45    pop.style.top=top+"px";
46  }
47  function render(){
48    sel=0;
49    if(!rows.length){hide();return;}
50    pop.innerHTML=rows.map(function(u,i){
51      var av=u.avatar_url?'<img src="'+shmaEscAttr(u.avatar_url)+'" alt="" width="28" height="28" loading="lazy" referrerpolicy="no-referrer">':'<span class="shma-mention-pop__ph"></span>';
52      return '<button type="button" class="shma-mention-pop__row'+(i===0?' is-active':'')+'" data-i="'+i+'">'+av+'<span class="shma-mention-pop__meta"><span class="shma-mention-pop__name">'+shmaEscHtml(u.display_name||u.login)+'</span><span class="shma-mention-pop__login">@'+shmaEscHtml(u.login)+'</span></span></button>';
53    }).join("");
54    pop.removeAttribute("hidden");
55    requestAnimationFrame(pos);
56  }
57  function selUpd(){
58    var btns=pop.querySelectorAll(".shma-mention-pop__row");
59    for(var i=0;i<btns.length;i++)btns[i].classList.toggle("is-active",i===sel);
60  }
61  function applyAt(u){
62    var p=parse();
63    if(!p||!u)return;
64    var v=textarea.value, c=textarea.selectionStart|0;
65    var before=v.slice(0,p.start);
66    var after=v.slice(c);
67    var ins="@"+u.login+" ";
68    textarea.value=before+ins+after;
69    var caret=before.length+ins.length;
70    textarea.focus();
71    textarea.setSelectionRange(caret,caret);
72    hide();
73    textarea.dispatchEvent(new Event("input",{bubbles:true}));
74  }
75  function fetchQ(q){
76    if(tmr)clearTimeout(tmr);
77    tmr=setTimeout(function(){
78      fetch(api+"?action=shma_api",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({sub:"mention_suggest",q:q,scope:scope,thread_id:threadId,csrf:csrf})})
79      .then(shmaMentionJsonOr401)
80      .then(function(d){
81        var cur=parse();
82        if(!cur||cur.query!==q)return;
83        rows=(d&&d.ok&&d.users)?d.users:[];
84        render();
85        requestAnimationFrame(pos);
86      }).catch(function(){});
87    },170);
88  }
89  function onInput(){
90    var p=parse();
91    if(!p){hide();return;}
92    if(scope==="room"&&p.query.length===0){hide();return;}
93    fetchQ(p.query);
94  }
95  textarea.addEventListener("input",onInput);
96  textarea.addEventListener("keyup",function(){requestAnimationFrame(pos);});
97  textarea.addEventListener("click",function(){setTimeout(onInput,0);});
98  pop.addEventListener("mousedown",function(e){
99    var b=e.target&&e.target.closest?e.target.closest(".shma-mention-pop__row"):null;
100    if(!b)return;
101    e.preventDefault();
102    var i=parseInt(b.getAttribute("data-i"),10);
103    if(rows[i])applyAt(rows[i]);
104  });
105  window.addEventListener("resize",function(){requestAnimationFrame(pos);});
106  document.addEventListener("mousedown",function(e){
107    if(pop.hasAttribute("hidden"))return;
108    if(e.target===textarea||textarea.contains(e.target)||pop.contains(e.target))return;
109    hide();
110  },true);
111  textarea.addEventListener("keydown",function(e){
112    if(pop.hasAttribute("hidden")||!rows.length)return;
113    if(e.key==="ArrowDown"){e.preventDefault();e.stopPropagation();sel=(sel+1)%rows.length;selUpd();return;}
114    if(e.key==="ArrowUp"){e.preventDefault();e.stopPropagation();sel=(sel+rows.length-1)%rows.length;selUpd();return;}
115    if(e.key==="Enter"&&!e.shiftKey&&!e.isComposing){e.preventDefault();e.stopPropagation();if(rows[sel])applyAt(rows[sel]);return;}
116    if(e.key==="Escape"){e.preventDefault();e.stopPropagation();hide();return;}
117  },true);
118};
119})();

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.